{
  "openapi": "3.1.0",
  "info": {
    "title": "Jenks Guo — agent API",
    "version": "1.4.0",
    "description": "Read API about Jenks Guo plus the admin content API. Every operation is also an MCP tool (https://jenksguo.pages.dev/mcp, https://jenksguo.pages.dev/mcp/admin) and a `jenks` CLI command. Docs: https://jenksguo.pages.dev/agents/docs",
    "contact": {
      "email": "jenksguo@gmail.com",
      "url": "https://jenksguo.pages.dev/agents"
    }
  },
  "servers": [
    {
      "url": "https://jenksguo.pages.dev"
    },
    {
      "url": "https://dev.jenksguo.xyz",
      "description": "dev preview"
    }
  ],
  "components": {
    "securitySchemes": {
      "adminToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Agent service token (jgx_agt_…) created by Jenks in the console after SSO sign-in; scoped: content, media, publish (see x-scope)"
      }
    }
  },
  "paths": {
    "/api/v1/brief": {
      "get": {
        "operationId": "get_brief",
        "summary": "Get Jenks's brief",
        "description": "A one-page Markdown brief about Jenks Guo: positioning, current role, career arc, strengths, languages, contact, and how to explore further. Start here.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "get_brief",
        "x-cli": "jenks brief"
      }
    },
    "/api/v1/entries": {
      "get": {
        "operationId": "list_experience",
        "summary": "List experience",
        "description": "List Jenks's experiences, projects, community roles and education (newest first), optionally filtered by industry tag, role lens or kind. Returns short forms: title, organisation, period, summary, key result, page URL.",
        "parameters": [
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "it",
                "engineering",
                "ai",
                "devrel",
                "web3",
                "business",
                "marketing",
                "consulting",
                "hospitality",
                "community",
                "creative"
              ]
            }
          },
          {
            "name": "lens",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "head-of-ai",
                "ai-transformation-consultant",
                "engineering-manager",
                "solution-architect",
                "system-integrator",
                "support-engineer",
                "ict-specialist",
                "developer-advocate",
                "developer-evangelist",
                "digital-marketer",
                "hospitality"
              ]
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "experience",
                "education",
                "community",
                "project"
              ]
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "list_experience",
        "x-cli": "jenks list [--tag it] [--lens solution-architect] [--kind project]"
      }
    },
    "/api/v1/entries/{slug}": {
      "get": {
        "operationId": "get_entry",
        "summary": "Get one entry",
        "description": "Full long-form write-up of one experience, project, community role or education entry by slug: overview, what Jenks did, achievements, why it matters to employers, key results, skills, proof links.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entry slug, e.g. xero-developer-evangelist"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "get_entry",
        "x-cli": "jenks get <slug>"
      }
    },
    "/api/v1/lenses": {
      "get": {
        "operationId": "list_lenses",
        "summary": "List role lenses",
        "description": "The role lenses employers can view Jenks through (Head of AI, solution architect, developer advocate, digital marketer, hospitality…) with a pitch, honest gaps and evidence counts.",
        "parameters": [
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "list_lenses",
        "x-cli": "jenks lenses"
      }
    },
    "/api/v1/search": {
      "get": {
        "operationId": "search_jenks",
        "summary": "Search the corpus",
        "description": "Keyword search across every entry and document. Returns the best-matching passages with their slugs.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "search_jenks",
        "x-cli": "jenks search \"<query>\""
      }
    },
    "/api/v1/documents/{name}": {
      "get": {
        "operationId": "get_document",
        "summary": "Get a document",
        "description": "One of Jenks's reference documents: profile (core profile), credentials (education, certifications), capabilities (capability → evidence map), talks (talks, podcasts, writing), thinking (point of view: seven views, each explained in plain words with examples, plus further beliefs).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "profile",
                "credentials",
                "capabilities",
                "talks",
                "thinking"
              ]
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "get_document",
        "x-cli": "jenks doc <name>"
      }
    },
    "/api/v1/cv": {
      "get": {
        "operationId": "list_cvs",
        "summary": "List Jenks's CVs",
        "description": "Jenks's downloadable CV (PDF) — the AI Lead CV — with version, date, a stable PDF url, a download url, a preview image and earlier versions. For questions about his Web3 experience, get_cv with slug web3 returns the AI and Web3 CV (not listed here).",
        "parameters": [
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "list_cvs",
        "x-cli": "jenks cv"
      }
    },
    "/api/v1/cv/{slug}": {
      "get": {
        "operationId": "get_cv",
        "summary": "Get one CV",
        "description": "One CV by slug: title, summary, version, the stable PDF url (always the current version, e.g. https://jenksguo.pages.dev/cv/ai.pdf), the download url and all versions. Use ai for the AI Lead CV; use web3 for the AI and Web3 CV when someone asks about his Web3 experience.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ai (the AI Lead CV) or web3 (the AI and Web3 CV, for Web3 questions)"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "get_cv",
        "x-cli": "jenks cv <slug> [--download] [-o file.pdf]"
      }
    },
    "/api/v1/arguments": {
      "get": {
        "operationId": "list_arguments",
        "summary": "List the case for Jenks",
        "description": "The arguments for Jenks by capability — AI transformation, agentic systems, leadership, enterprise integration, DevRel, Web3 partnerships and cross-project technical program leadership — each with its claim, qualifier and strength.",
        "parameters": [
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "list_arguments",
        "x-cli": "jenks argue"
      }
    },
    "/api/v1/arguments/{slug}": {
      "get": {
        "operationId": "get_argument",
        "summary": "Get one argument, with objections",
        "description": "One argument by slug: the formal argument (premises → conclusion), evidence with numbers (entry slugs), market statistics with sources, honest limits, fair objections with answers, fallacious attacks (formal and informal) with replies, and when the argument does not apply. Use it to test Jenks's fit, not only to promote it.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ai-transformation, agentic-systems, leadership, enterprise-integration, devrel, web3-partnerships or technical-program-leadership"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ],
              "description": "Language for translated fields (default en)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "get_argument",
        "x-cli": "jenks argue <slug>"
      }
    },
    "/api/v1/ask": {
      "post": {
        "operationId": "ask_jenks",
        "summary": "Ask Jenks's assistant",
        "description": "Ask the Ask Jenks assistant a natural-language question (role fit, consulting scoping, AI transformation advice, STAR stories, governance…). It runs its own tools over the corpus and answers in the requested language. Rate-limited.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "question": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "locale": {
                    "type": "string",
                    "enum": [
                      "en",
                      "zh",
                      "zh-hant",
                      "ja",
                      "fr",
                      "es",
                      "eo"
                    ],
                    "description": "Language for translated fields (default en)."
                  },
                  "history": {
                    "type": "array",
                    "maxItems": 14,
                    "items": {
                      "type": "object",
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "assistant"
                          ]
                        },
                        "content": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "role",
                        "content"
                      ]
                    },
                    "description": "Optional earlier turns."
                  }
                },
                "required": [
                  "question"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-mcp-tool": "ask_jenks",
        "x-cli": "jenks ask \"<question>\""
      }
    },
    "/api/admin/whoami": {
      "get": {
        "operationId": "admin_whoami",
        "summary": "Who am I",
        "description": "Check your credential: who you are (SSO email or agent token name), your scopes, when your token expires, and whether publishing (GitHub) is configured.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_whoami",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin whoami"
      }
    },
    "/api/admin/audit": {
      "get": {
        "operationId": "admin_audit_log",
        "summary": "Audit log",
        "description": "Recent admin actions, newest first: who (SSO email or agent token), what, which files, branch, host and result. An agent token sees only its own actions.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "token",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only this agent token id (people only)"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_audit_log",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin audit [--limit 50]"
      }
    },
    "/api/admin/schema": {
      "get": {
        "operationId": "admin_schema",
        "summary": "Content schema",
        "description": "The content model: entry fields and rules, tags, lenses, kinds, writable paths, documents, and editing conventions. Read this before writing.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_schema",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin schema"
      }
    },
    "/api/admin/files": {
      "get": {
        "operationId": "admin_list_files",
        "summary": "List content files",
        "description": "List editable content files on a branch (path, size, sha), optionally inside one folder such as content/corpus/experiences.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "e.g. content/corpus/projects (default: all content)"
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "main",
                "dev"
              ],
              "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_list_files",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin ls [dir]"
      }
    },
    "/api/admin/file": {
      "get": {
        "operationId": "admin_read_file",
        "summary": "Read a content file",
        "description": "Read the raw Markdown/JSON source of a content file (with its sha). Pass `path`, or `slug` for an entry, lens or skill.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "main",
                "dev"
              ],
              "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_read_file",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin get <slug|path>"
      },
      "put": {
        "operationId": "admin_write_file",
        "summary": "Create or update a content file",
        "description": "Validate and commit one content file (create or replace). Publishing is automatic: CI re-translates changed entries into all languages, rebuilds and deploys (main → jenksguo.pages.dev and jenksguo.xyz, dev → dev.jenksguo.xyz) in a few minutes.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string",
                    "description": "Commit message"
                  },
                  "branch": {
                    "type": "string",
                    "enum": [
                      "main",
                      "dev"
                    ],
                    "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
                  }
                },
                "required": [
                  "path",
                  "content",
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_write_file",
        "x-scope": [
          "content"
        ],
        "x-cli": "jenks admin put <path> <file> -m <message>"
      },
      "delete": {
        "operationId": "admin_delete_file",
        "summary": "Delete a content file",
        "description": "Delete one content file (e.g. remove an entry) with a commit message. Git history keeps it recoverable.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "main",
                "dev"
              ],
              "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_delete_file",
        "x-scope": [
          "content"
        ],
        "x-cli": "jenks admin rm <path> -m <message>"
      }
    },
    "/api/admin/validate": {
      "post": {
        "operationId": "admin_validate",
        "summary": "Validate a change",
        "description": "Validate file content against the content schema without committing. Returns a list of problems (empty = valid).",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  }
                },
                "required": [
                  "path",
                  "content"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_validate",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin validate <path> <file>"
      }
    },
    "/api/admin/changes": {
      "post": {
        "operationId": "admin_commit_changes",
        "summary": "Commit several files at once",
        "description": "Validate and commit several file changes as ONE commit. Each change is {path, content} or {path, delete: true}.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "changes": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 30,
                    "items": {
                      "type": "object",
                      "properties": {
                        "path": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string"
                        },
                        "delete": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "path"
                      ]
                    }
                  },
                  "message": {
                    "type": "string"
                  },
                  "branch": {
                    "type": "string",
                    "enum": [
                      "main",
                      "dev"
                    ],
                    "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
                  }
                },
                "required": [
                  "changes",
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_commit_changes",
        "x-scope": [
          "content"
        ],
        "x-cli": "jenks admin commit <changes.json> -m <message>"
      }
    },
    "/api/admin/ai-edit": {
      "post": {
        "operationId": "admin_ai_edit",
        "summary": "Draft an edit with AI",
        "description": "Ask the site's model to rewrite one content file from a plain-English instruction. Returns the proposed content, a diff and validation problems. Does NOT commit — review, then call admin_write_file.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "instruction": {
                    "type": "string"
                  },
                  "branch": {
                    "type": "string",
                    "enum": [
                      "main",
                      "dev"
                    ],
                    "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
                  },
                  "content": {
                    "type": "string",
                    "description": "Optional unsaved file text to draft from (default: the saved file)."
                  }
                },
                "required": [
                  "instruction"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_ai_edit",
        "x-scope": [
          "content"
        ],
        "x-cli": "jenks admin ai-edit <slug|path> \"<instruction>\" [--apply]"
      }
    },
    "/api/admin/translation": {
      "get": {
        "operationId": "admin_read_translation",
        "summary": "Read a translation",
        "description": "One content file in another language: the English source fields, the current translation and its status (current, outdated, edited by hand, missing). Works for entries, lenses, CVs, arguments, point-of-view pages, credentials, talks and the docs. Languages: zh, zh-hant, ja, fr, es, eo.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ]
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "main",
                "dev"
              ],
              "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_read_translation",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin tr get <slug|path> <locale>"
      },
      "put": {
        "operationId": "admin_write_translation",
        "summary": "Edit a translation",
        "description": "Write one content file's text in another language (zh, zh-hant, ja, fr, es, eo) — for example a better Chinese summary. Give only the fields to change; read admin_read_translation first for the field names. Markdown must keep the English headings, code blocks and links. The edit is kept until the English changes; then that language is translated again automatically. English is the source: change it with admin_write_file.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "locale": {
                    "type": "string",
                    "enum": [
                      "zh",
                      "zh-hant",
                      "ja",
                      "fr",
                      "es",
                      "eo"
                    ]
                  },
                  "fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "e.g. {\"summary\": \"…\", \"body\": \"## …\"}"
                  },
                  "message": {
                    "type": "string",
                    "description": "Commit message"
                  },
                  "branch": {
                    "type": "string",
                    "enum": [
                      "main",
                      "dev"
                    ],
                    "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
                  }
                },
                "required": [
                  "locale",
                  "fields"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_write_translation",
        "x-scope": [
          "content"
        ],
        "x-cli": "jenks admin tr put <slug|path> <locale> <fields.json> -m <message>"
      }
    },
    "/api/admin/copy": {
      "get": {
        "operationId": "admin_read_copy",
        "summary": "Read site copy",
        "description": "The site's interface text in one language — menus, page titles, the one-line page intros, the hero headline, buttons, SEO descriptions — as key → text, with the English (and Chinese for zh-hant) alongside. Filter with prefix, e.g. hero or career.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "zh",
                "zh-hant",
                "ja",
                "fr",
                "es",
                "eo"
              ]
            }
          },
          {
            "name": "prefix",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "main",
                "dev"
              ],
              "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_read_copy",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin copy get <locale> [prefix]"
      },
      "put": {
        "operationId": "admin_write_copy",
        "summary": "Edit site copy",
        "description": "Change interface text in one language: values is key → text (\"\" removes your edit). en and zh are the hand-written sources: an English change is translated into ja, fr, es and eo automatically — also set zh. An edit in another language is kept until its source text changes. Keep {placeholders} exactly.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locale": {
                    "type": "string",
                    "enum": [
                      "en",
                      "zh",
                      "zh-hant",
                      "ja",
                      "fr",
                      "es",
                      "eo"
                    ]
                  },
                  "values": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "e.g. {\"hero.sub\": \"…\"}"
                  },
                  "message": {
                    "type": "string"
                  },
                  "branch": {
                    "type": "string",
                    "enum": [
                      "main",
                      "dev"
                    ],
                    "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
                  }
                },
                "required": [
                  "locale",
                  "values"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_write_copy",
        "x-scope": [
          "content"
        ],
        "x-cli": "jenks admin copy set <locale> <key> \"<text>\" -m <message>"
      }
    },
    "/api/admin/deploys": {
      "get": {
        "operationId": "admin_deploy_status",
        "summary": "Deploy status",
        "description": "Recent CI runs (translate → build → deploy) with status, branch, commit and links.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "branch",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "main",
                "dev"
              ],
              "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_deploy_status",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin deploys"
      }
    },
    "/api/admin/promote": {
      "post": {
        "operationId": "admin_promote",
        "summary": "Promote dev to production",
        "description": "Merge the dev branch into main, publishing everything previewed on dev.jenksguo.xyz to the live site (jenksguo.pages.dev and jenksguo.xyz).",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_promote",
        "x-scope": [
          "publish"
        ],
        "x-cli": "jenks admin promote"
      }
    },
    "/api/admin/cv": {
      "post": {
        "operationId": "admin_publish_cv",
        "summary": "Publish a new CV version",
        "description": "Upload a new PDF for a CV (ai, web3 or a new slug) and make it the current version in one step: the PDF goes to the media library, the previous version moves to the CV's history (still downloadable), and the change is committed (CI publishes it). Optional preview image and new title/summary. The stable url /cv/<slug>.pdf then serves the new file.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slug": {
                    "type": "string",
                    "description": "ai, web3, or a new kebab-case id"
                  },
                  "version": {
                    "type": "string",
                    "description": "e.g. 2026.10"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "data": {
                    "type": "string",
                    "description": "PDF bytes, base64"
                  },
                  "url": {
                    "type": "string",
                    "description": "Alternative to data: https URL of the PDF"
                  },
                  "preview": {
                    "type": "string",
                    "description": "Optional: an already uploaded /media/… image of page 1"
                  },
                  "title": {
                    "type": "string"
                  },
                  "summary": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string",
                    "description": "Commit message"
                  },
                  "branch": {
                    "type": "string",
                    "enum": [
                      "main",
                      "dev"
                    ],
                    "description": "main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main)."
                  }
                },
                "required": [
                  "slug",
                  "version"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_publish_cv",
        "x-scope": [
          "content",
          "media"
        ],
        "x-cli": "jenks admin cv publish <slug> <file.pdf> --cv-version 2026.10 [--preview /media/…]"
      }
    },
    "/api/admin/media": {
      "get": {
        "operationId": "admin_list_media",
        "summary": "List media",
        "description": "List uploaded images, videos and PDFs (newest first): url, type, size, dimensions, alt text, ready-to-paste Markdown, and which entries use each file.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "prefix",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Key prefix such as 2026/10"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_list_media",
        "x-scope": [
          "read"
        ],
        "x-cli": "jenks admin media ls [prefix]"
      },
      "post": {
        "operationId": "admin_upload_media",
        "summary": "Upload media",
        "description": "Store an image (webp, jpg, png, gif, avif, svg), video (mp4, webm) or PDF, up to 25 MB, in Cloudflare R2 and get its public /media/… url and Markdown. Send base64 `data` with a `filename`, or a public https `url` to import. Files are public by URL immediately; reference them from content with admin_write_file. The REST endpoint also accepts multipart/form-data (field `file`).",
        "security": [
          {
            "adminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filename": {
                    "type": "string",
                    "description": "Original file name; becomes the readable part of the url."
                  },
                  "data": {
                    "type": "string",
                    "description": "File bytes, base64 (a data: URL prefix is allowed)."
                  },
                  "url": {
                    "type": "string",
                    "description": "Alternative to data: an https URL the server downloads."
                  },
                  "alt": {
                    "type": "string",
                    "maxLength": 300,
                    "description": "Alt text: what the image shows, for screen readers and the bot."
                  },
                  "width": {
                    "type": "integer"
                  },
                  "height": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_upload_media",
        "x-scope": [
          "media"
        ],
        "x-cli": "jenks admin media upload <file|https-url> [--alt \"…\"]"
      },
      "patch": {
        "operationId": "admin_update_media",
        "summary": "Update media alt text",
        "description": "Change the stored alt text of an uploaded file (the default alt when it is inserted into content).",
        "security": [
          {
            "adminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_update_media",
        "x-scope": [
          "media"
        ],
        "x-cli": "jenks admin media alt <key> \"<alt text>\""
      },
      "delete": {
        "operationId": "admin_delete_media",
        "summary": "Delete media",
        "description": "Permanently delete an uploaded file. Refused while published content still uses it, unless force is true. Not recoverable — unlike content files there is no git history.",
        "security": [
          {
            "adminToken": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "force",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Not found"
          },
          "422": {
            "description": "Validation failed"
          }
        },
        "x-mcp-tool": "admin_delete_media",
        "x-scope": [
          "media"
        ],
        "x-cli": "jenks admin media rm <key> [--force]"
      }
    }
  }
}
