MCP Tool List

ToolDescriptionParameters
describe_collectionsList every collection this server has (blog, docs, any user-registered ones, tokens, nav, collections, site, permissions, taxonomies) and its shape — extra metadata fields (with real current defaults) for entry-style collections, the known token names for tokens, an example items/cta shape for nav, an example shape for collections/site/permissions/taxonomies. Discover what a collection accepts before calling create_entry/update_entry/update_single (name: "tokens"/"nav"/"site"/"taxonomies"/"collections")/update_permissions against it. Call describe_taxonomies (not this tool) for live values currently in use per taxonomy.(none)
describe_componentsList purpose-built components available beyond plain HTML (e.g. video-embed) — the tag to write, its required attributes, and a real usage example. Discover these instead of guessing at a raw <iframe> or similar, which will be rejected.(none)
search_iconsFind a real icon name to use with the icon component (see describe_components) — matches the query against ~1750 Lucide icon names and their upstream keyword tags (e.g. "cart" also finds shopping-cart via its own tags), case-insensitive substring, not relevance-ranked. Name matches sort before tag-only matches. Use this instead of guessing an icon name — an unrecognized name gets the whole <icon> element dropped at write time.query, limit?
list_entriesList entries from a collection, each with its editorial status (drafting / in review / changes requested / published / archived) derived from git/PR statecollection?
read_entryRead an entry's content and metadataslug, collection?
create_entryCreate a new entry (allowlist-validated), commit it to the content repo. Call describe_components first for the full HTML vocabulary — layout primitives (stack/wrap/card/carousel/column/section/grid), video-embed, and button classes — beyond plain text.slug, html, title, date, draft?, tags?, collection?, excerpt?, featuredImage?, seoMetadata?, category?, pillar?, taxonomyValues?, order?, section?, path?
update_entryUpdate content/metadata of an existing entry (allowlist-validated), commit the change. Call describe_components first for the full HTML vocabulary — layout primitives (stack/wrap/card/carousel/column/section/grid), video-embed, and button classes — beyond plain text.slug, html?, title?, date?, draft?, tags?, collection?, excerpt?, featuredImage?, seoMetadata?, category?, pillar?, taxonomyValues?, order?, section?, path?
delete_entryRemove an entry, commit the deletionslug, collection?
read_singleRead one of the site's config singles — "tokens" (design tokens), "nav" (top nav), "site" (global identity), "taxonomies" (the taxonomy registry), or "collections" (user-registered collections beyond blog/docs). Each returns the exact shape describe_collections documents for it (colorTokens/navShape/siteShape/taxonomiesShape/collectionsShape). permissions has its own dedicated read_permissions tool instead, not this one.name
update_singleChange one of the site's config singles. Pass "name" plus the one matching data field ("tokens"/"nav"/"site"/"taxonomies"/"collections") for the fields you want to set — whichever sub-fields you omit within it keep their current stored value, same partial-update posture each of these had as its own tool. taxonomies/collections replace their full list wholesale (pass every item you want to keep, not just the one you're changing) — same posture they always had. Like any other collection, create_draft/publish_content/submit_for_review/discard_draft all work here too — pass slug/collection matching name, e.g. slug: "nav", collection: "nav". permissions has its own dedicated update_permissions tool instead, not this one.name, tokens?, nav?, site?, taxonomies?, collections?
read_permissionsRead who can do what on the remote MCP server (this local server stays full-access regardless — permissions only govern workers/mcp-remote). Two parts: "roles" (permission-set name -> the tool names it grants — writer/editor/designer/dev are the built-in defaults, listed here only where explicitly overridden) and "assignments" (GitHub username -> role name). A username with no explicit assignment falls back to GitHub's own collaborator permission level (admin/maintain -> designer, write -> writer).(none)
update_permissionsChange who can do what on the remote MCP server. Grants access — use with real care, this is the one tool that controls every other tool's reach there. "roles" merges by name over the built-in writer/editor/designer/dev tool lists: defining "writer" replaces the built-in writer list; defining a new name (e.g. "marketing") adds a wholly new permission set. Pass the complete tool-name list for any role you set, not a delta. "assignments" merges by username: pass only the usernames you want to add or change, existing ones not mentioned keep their current assignment. Call describe_collections first to see every real tool name that exists. Like any other collection, create_draft/publish_content/submit_for_review/discard_draft all work here too — pass slug: "permissions", collection: "permissions".roles?, assignments?
describe_taxonomiesList every registered taxonomy plus every distinct value currently in use for it, computed live across its applicable collections. Call this before writing taxonomyValues on an entry, so you reuse an existing value instead of accidentally minting a near-duplicate (e.g. "Guide" vs "guide").(none)
upload_imageUpload an image (base64-encoded) into an existing entry's image directory and commit it to the content repo. Reference it in the entry's HTML as <img src="<filename>" alt="...">, a bare filename — do not write <picture>/srcset/width/height, those are generated automatically at build time.slug, filename, data, collection?
create_draftStart (or resume) the draft branch for an entry. Fails if another draft is already checked out for this slug — see spec §5.4 "Per-entry draft locking".slug, collection?
discard_draftDiscard an entry's draft without publishing, releasing the lock on itslug, collection?
diffShow an entry's draft-branch changes against main (or another ref)slug, against?, collection?
publish_contentPublish an entry's draft — makes it live. mode picks direct git merge vs. open+merge a real GitHub PR; omit it to use whatever PUBLISH_MODE defaults to server-wide. Pass mode: "pr" to open a PR and stop there without merging (needs MCP_PUSH_TOKEN with "Pull requests: Write" scope) — the old submit_for_review behavior, now this same tool. Batch-publishing several entries? Pass revalidateNow: false on every call but the last (or call revalidate standalone once afterward) — one rebuild for N publishes, not N rebuilds; revalidateNow is ignored for mode: "pr" (nothing goes live from opening a PR alone).slug, collection?, revalidateNow?, mode?
previewPush an entry's draft branch to the content repo and get back a hosted preview URL a reviewer can open, if PREVIEW_WORKER_URL is configured — omitted otherwise (the branch still pushes either way).slug, collection?
revalidateTrigger a Cloudflare Pages rebuild via its deploy hook(none)
deploy_statusRead the most recent Cloudflare Pages deployment's real state — closes the loop publish/revalidate open, since a deploy hook accepting a POST doesn't prove the build actually succeeded(none)
search_entriesGrep-shaped full-text search across every entry in every collection, including drafts not yet merged to main — matches the query against title + raw HTML, case-insensitive substring, not a relevance-ranked search. Distinct from the site's own Pagefind search: that only sees the published live site, not drafts, and isn't a tool a model can call. Real use: hunting stale terminology after a rename, or leftover references to something already removed, across every entry at once instead of reading them one at a time.query, collection?
search_imagesGrep-shaped substring search over every uploaded image's auto-generated description + alt text, across every entry in every collection (drafts included) — case-insensitive, not relevance-ranked, same posture as search_entries. Returns each match's collection/slug/filename/description/altText, enough to reference the image (<img src="<filename>">) without a separate read. Use this to find an existing image by what's in it instead of remembering filenames. Only images uploaded while an image-description API key was configured (see edit_site) appear here.query, collection?
list_imagesList every uploaded image with an auto-generated description across every entry (drafts included) — collection/slug/filename/description/altText for each, no query filter. The whole media library at once; use search_images to filter by what's in an image. Only images uploaded while an image-description API key was configured (see edit_site) appear here.collection?
rollbackRevert to a previous commit — pass slug to revert just that entry, omit it to revert a whole commit repo-widecommitHash, slug?, collection?