Skip to main content
Jenks Guo

Docs / reference

Admin API

Authenticated endpoints that edit the site's content through validated git commits.

All admin endpoints need an agent service token: Authorization: Bearer jgx_agt_… (the CLI reads env JENKSGUO_ADMIN_TOKEN). Jenks creates tokens in the console at https://admin.jenksguo.xyz/admin → Access after signing in with Google (Cloudflare Access); each is named, scoped (content, media, publish; every token can read), expires and can be revoked. Writing to branch main also needs publish. Every write and every refused attempt goes to the audit log. See Give an AI agent access. Writes are validated with the same schema as the build, then committed to GitHub. CI translates changed entries into every language, rebuilds and deploys: main → jenksguo.pages.dev and jenksguo.xyz, dev → dev.jenksguo.xyz.

Method Path Tool
GET · POST /api/admin/tokens — (people only: list or create agent tokens; SSO)
DELETE /api/admin/tokens/{id} — (people only: revoke; SSO)
POST /api/admin/login · /api/admin/logout — (local development only)
GET /api/admin/whoami admin_whoami
GET /api/admin/audit admin_audit_log
GET /api/admin/schema admin_schema
GET /api/admin/files admin_list_files
GET /api/admin/file admin_read_file
POST /api/admin/validate admin_validate
PUT /api/admin/file admin_write_file
DELETE /api/admin/file admin_delete_file
POST /api/admin/changes admin_commit_changes
POST /api/admin/ai-edit admin_ai_edit
GET /api/admin/translation admin_read_translation
PUT /api/admin/translation admin_write_translation
GET /api/admin/copy admin_read_copy
PUT /api/admin/copy admin_write_copy
GET /api/admin/deploys admin_deploy_status
POST /api/admin/promote admin_promote
POST /api/admin/cv admin_publish_cv
GET /api/admin/media admin_list_media
POST /api/admin/media admin_upload_media
PATCH /api/admin/media admin_update_media
DELETE /api/admin/media admin_delete_media

Errors: 401 unauthorized · unknown_token · token_expired · token_revoked, 403 missing_scope (with needs[]) · sso_required · forbidden_path (only content files are writable), 422 invalid with errors[], 409/502 github_error, 503 github_not_configured.

admin_whoami — Who am I

Check your credential: who you are (SSO email or agent token name), your scopes, when your token expires, and whether publishing (GitHub) is configured.

  • MCP: admin_whoami on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/whoami (agent token)
  • Scope: read
  • CLI: jenks admin whoami

No arguments.

curl -s "https://jenksguo.pages.dev/api/admin/whoami" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_audit_log — Audit log

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.

  • MCP: admin_audit_log on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/audit?limit=&token= (agent token)
  • Scope: read
  • CLI: jenks admin audit [--limit 50]
Argument Type Required Notes
limit integer no
token string no Only this agent token id (people only)
curl -s "https://jenksguo.pages.dev/api/admin/audit" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_schema — Content schema

The content model: entry fields and rules, tags, lenses, kinds, writable paths, documents, and editing conventions. Read this before writing.

  • MCP: admin_schema on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/schema (agent token)
  • Scope: read
  • CLI: jenks admin schema

No arguments.

curl -s "https://jenksguo.pages.dev/api/admin/schema" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_list_files — List content files

List editable content files on a branch (path, size, sha), optionally inside one folder such as content/corpus/experiences.

  • MCP: admin_list_files on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/files?dir=&branch= (agent token)
  • Scope: read
  • CLI: jenks admin ls [dir]
Argument Type Required Notes
dir string no e.g. content/corpus/projects (default: all content)
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s "https://jenksguo.pages.dev/api/admin/files" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_read_file — Read a content file

Read the raw Markdown/JSON source of a content file (with its sha). Pass path, or slug for an entry, lens or skill.

  • MCP: admin_read_file on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/file?path=&slug=&branch= (agent token)
  • Scope: read
  • CLI: jenks admin get <slug|path>
Argument Type Required Notes
path string no
slug string no
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s "https://jenksguo.pages.dev/api/admin/file" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_validate — Validate a change

Validate file content against the content schema without committing. Returns a list of problems (empty = valid).

  • MCP: admin_validate on https://jenksguo.pages.dev/mcp/admin
  • REST: POST /api/admin/validate (agent token)
  • Scope: read
  • CLI: jenks admin validate <path> <file>
Argument Type Required Notes
path string yes
content string yes
curl -s -X POST https://jenksguo.pages.dev/api/admin/validate \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"path":"content/corpus/projects/example.md","content":"<content>"}'

admin_write_file — Create or update a content file

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.

  • MCP: admin_write_file on https://jenksguo.pages.dev/mcp/admin
  • REST: PUT /api/admin/file (agent token)
  • Scope: content (+ publish for branch main)
  • CLI: jenks admin put <path> <file> -m <message>
Argument Type Required Notes
path string yes
content string yes
message string yes Commit message
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s -X PUT https://jenksguo.pages.dev/api/admin/file \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"path":"content/corpus/projects/example.md","content":"<content>","message":"<message>"}'

admin_delete_file — Delete a content file

Delete one content file (e.g. remove an entry) with a commit message. Git history keeps it recoverable.

  • MCP: admin_delete_file on https://jenksguo.pages.dev/mcp/admin
  • REST: DELETE /api/admin/file?path=&message=&branch= (agent token)
  • Scope: content (+ publish for branch main)
  • CLI: jenks admin rm <path> -m <message>
Argument Type Required Notes
path string yes
message string yes
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s -X DELETE https://jenksguo.pages.dev/api/admin/file \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"path":"content/corpus/projects/example.md","message":"<message>"}'

admin_commit_changes — Commit several files at once

Validate and commit several file changes as ONE commit. Each change is {path, content} or {path, delete: true}.

  • MCP: admin_commit_changes on https://jenksguo.pages.dev/mcp/admin
  • REST: POST /api/admin/changes (agent token)
  • Scope: content (+ publish for branch main)
  • CLI: jenks admin commit <changes.json> -m <message>
Argument Type Required Notes
changes array yes
message string yes
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s -X POST https://jenksguo.pages.dev/api/admin/changes \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"changes":"<changes>","message":"<message>"}'

admin_ai_edit — Draft an edit with AI

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.

  • MCP: admin_ai_edit on https://jenksguo.pages.dev/mcp/admin
  • REST: POST /api/admin/ai-edit (agent token)
  • Scope: content
  • CLI: jenks admin ai-edit <slug|path> "<instruction>" [--apply]
Argument Type Required Notes
path string no
slug string no
instruction string yes
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
content string no Optional unsaved file text to draft from (default: the saved file).
curl -s -X POST https://jenksguo.pages.dev/api/admin/ai-edit \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"instruction":"<instruction>"}'

admin_read_translation — Read a translation

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.

  • MCP: admin_read_translation on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/translation?path=&slug=&locale=&branch= (agent token)
  • Scope: read
  • CLI: jenks admin tr get <slug|path> <locale>
Argument Type Required Notes
path string no
slug string no
locale zh · zh-hant · ja · fr · es · eo yes
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s "https://jenksguo.pages.dev/api/admin/translation" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_write_translation — Edit a translation

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.

  • MCP: admin_write_translation on https://jenksguo.pages.dev/mcp/admin
  • REST: PUT /api/admin/translation (agent token)
  • Scope: content (+ publish for branch main)
  • CLI: jenks admin tr put <slug|path> <locale> <fields.json> -m <message>
Argument Type Required Notes
path string no
slug string no
locale zh · zh-hant · ja · fr · es · eo yes
fields object yes e.g. {"summary": "…", "body": "## …"}
message string no Commit message
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s -X PUT https://jenksguo.pages.dev/api/admin/translation \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"locale":"<locale>","fields":"<fields>"}'

admin_read_copy — Read site copy

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.

  • MCP: admin_read_copy on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/copy?locale=&prefix=&branch= (agent token)
  • Scope: read
  • CLI: jenks admin copy get <locale> [prefix]
Argument Type Required Notes
locale en · zh · zh-hant · ja · fr · es · eo yes
prefix string no
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s "https://jenksguo.pages.dev/api/admin/copy" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_write_copy — Edit site copy

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.

  • MCP: admin_write_copy on https://jenksguo.pages.dev/mcp/admin
  • REST: PUT /api/admin/copy (agent token)
  • Scope: content (+ publish for branch main)
  • CLI: jenks admin copy set <locale> <key> "<text>" -m <message>
Argument Type Required Notes
locale en · zh · zh-hant · ja · fr · es · eo yes
values object yes e.g. {"hero.sub": "…"}
message string no
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s -X PUT https://jenksguo.pages.dev/api/admin/copy \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"locale":"<locale>","values":"<values>"}'

admin_deploy_status — Deploy status

Recent CI runs (translate → build → deploy) with status, branch, commit and links.

  • MCP: admin_deploy_status on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/deploys?branch= (agent token)
  • Scope: read
  • CLI: jenks admin deploys
Argument Type Required Notes
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s "https://jenksguo.pages.dev/api/admin/deploys" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_promote — Promote dev to production

Merge the dev branch into main, publishing everything previewed on dev.jenksguo.xyz to the live site (jenksguo.pages.dev and jenksguo.xyz).

  • MCP: admin_promote on https://jenksguo.pages.dev/mcp/admin
  • REST: POST /api/admin/promote (agent token)
  • Scope: publish
  • CLI: jenks admin promote
Argument Type Required Notes
message string no
curl -s -X POST https://jenksguo.pages.dev/api/admin/promote \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{}'

admin_publish_cv — Publish a new CV version

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/.pdf then serves the new file.

  • MCP: admin_publish_cv on https://jenksguo.pages.dev/mcp/admin
  • REST: POST /api/admin/cv (agent token)
  • Scope: content + media (+ publish for branch main)
  • CLI: jenks admin cv publish <slug> <file.pdf> --cv-version 2026.10 [--preview /media/…]
Argument Type Required Notes
slug string yes ai, web3, or a new kebab-case id
version string yes e.g. 2026.10
filename string no
data string no PDF bytes, base64
url string no Alternative to data: https URL of the PDF
preview string no Optional: an already uploaded /media/… image of page 1
title string no
summary string no
message string no Commit message
branch main · dev no main publishes the live site (jenksguo.pages.dev and its mirror jenksguo.xyz); dev previews on dev.jenksguo.xyz (default main).
curl -s -X POST https://jenksguo.pages.dev/api/admin/cv \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"slug":"<slug>","version":"<version>"}'

admin_list_media — List media

List uploaded images, videos and PDFs (newest first): url, type, size, dimensions, alt text, ready-to-paste Markdown, and which entries use each file.

  • MCP: admin_list_media on https://jenksguo.pages.dev/mcp/admin
  • REST: GET /api/admin/media?prefix=&cursor=&limit= (agent token)
  • Scope: read
  • CLI: jenks admin media ls [prefix]
Argument Type Required Notes
prefix string no Key prefix such as 2026/10
cursor string no
limit integer no
curl -s "https://jenksguo.pages.dev/api/admin/media" \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN"

admin_upload_media — Upload media

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).

  • MCP: admin_upload_media on https://jenksguo.pages.dev/mcp/admin
  • REST: POST /api/admin/media (agent token)
  • Scope: media
  • CLI: jenks admin media upload <file|https-url> [--alt "…"]
Argument Type Required Notes
filename string no Original file name; becomes the readable part of the url.
data string no File bytes, base64 (a data: URL prefix is allowed).
url string no Alternative to data: an https URL the server downloads.
alt string no Alt text: what the image shows, for screen readers and the bot.
width integer no
height integer no
curl -s -X POST https://jenksguo.pages.dev/api/admin/media \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{}'

admin_update_media — Update media alt text

Change the stored alt text of an uploaded file (the default alt when it is inserted into content).

  • MCP: admin_update_media on https://jenksguo.pages.dev/mcp/admin
  • REST: PATCH /api/admin/media (agent token)
  • Scope: media
  • CLI: jenks admin media alt <key> "<alt text>"
Argument Type Required Notes
key string yes Media key or url, e.g. 2026/10/xero-talk-1a2b3c4d5e.webp
alt string yes
curl -s -X PATCH https://jenksguo.pages.dev/api/admin/media \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"key":"<key>","alt":"<alt>"}'

admin_delete_media — Delete media

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.

  • MCP: admin_delete_media on https://jenksguo.pages.dev/mcp/admin
  • REST: DELETE /api/admin/media?key=&force= (agent token)
  • Scope: media
  • CLI: jenks admin media rm <key> [--force]
Argument Type Required Notes
key string yes
force boolean no
curl -s -X DELETE https://jenksguo.pages.dev/api/admin/media \
  -H "Authorization: Bearer $JENKSGUO_ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"key":"<key>"}'

.md