Write docs
write_docsWrite, delete, move and rename markdown documentation files — this is how a site gets its pages and how its structure is changed, including a site just created from scratch by create_workspace. EVERYTHING in one call lands in ONE atomic git commit: batch a restructure (the moves, the deletions, and the pages whose links they change) into a single call rather than calling this repeatedly — a rename split across two commits leaves the published site with a broken link in between. files writes whole files. operations says what a content array cannot: {op:'delete', path, redirect_to?} removes a page, {op:'move', from, to, content?} renames or relocates one (its body carries over untouched unless you pass content; naming a directory moves every page under it). Operations are applied before files, so writing a page at a path you just moved away from leaves a stub behind rather than cancelling the move. Every move — and every delete that names redirect_to — is recorded in the site's redirect map in the same commit, so the old URL keeps working instead of 404-ing every external link to it. Publishes to the Docsbook-hosted repository using Docsbook's own GitHub credentials, so the user needs no GitHub access; the repository is created on the first write if it does not exist yet. The result carries site_url — report that link, do not construct one. It also carries widget_review: a read of the markdown you just wrote, naming any widget marker that will NOT render (unclosed, misspelled, nested, switched off) and any region that has the shape of a content widget and was left as plain markdown — a stacked set of snippets in three languages, a bare list of links closing the page, numbered step headings, a bolded Note:. Act on the ones that fit the page with a follow-up call; list_content_widgets has each widget's full contract. And style_review: where the prose departs from the house style — a paragraph past four lines, four paragraphs with nothing between them, identifiers (--flag, API_KEY, fooBar, file.json) written outside inline code, a long page with no links. list_content_widgets → writing_style is the style itself; read it before your first page. Every written page carries a LIFECYCLE — a status and a version in its own frontmatter — and this call maintains it: a new page opens at generated 0.1, an edit bumps the version, and an edit to an approved page sends it back to review, because the sign-off was of the text that just changed. The result's lifecycle says where each page landed; report a demotion rather than describing the docs as settled. Thaw it with set_doc_status first. set_doc_status is the separate, deliberate act.
operations as a single commit. Optional only when operations is given.files, in the order given.Closes #N, so merging it closes the work — on GitHub as well as here — and the board folds the change into that issue's card instead of drawing it as unattached work. Pass them even when the review mode merges immediately: the record is what makes the change readable in six weeks.unmeasured — which is the honest word, and the debt somebody pays later by reconstructing what you already knew. Write the claim first with add_hypothesis; this call attaches it.support_load, upkeep_time, manual_checks, ai_spend, broken_pages, time_to_answer, ai_citations, new_markets, organic_traffic, conversion, first_visit_bounce, repeat_readers, hands_on_time.problems are markers that will not render (unclosed, misspelled, nested, switched off), suggestions are regions shaped like a content widget and left as plain markdown, each with the exact marker to wrap it in.- A site served from a repository in the user's OWN GitHub account is refused (NO_GITHUB_ACCESS) rather than committed to hosting the site does not read — the refusal names the routes that can write it.
- A page at
lockedorarchivedREFUSES the whole call (DOC_FROZEN, naming the pages) — nothing is written, because everything here is one commit. - This call can never produce
approvedorlocked, whatever the frontmatter you send says: approving your own output in the same breath as writing it is the one thing the lifecycle exists to prevent. - REQUIRES a read-write MCP token — a read-only token gets a READ_ONLY_TOKEN error.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_docs",
"arguments": {
"impact_metric": "support_load"
}
}
}{
"committed": true,
"published": true,
"pull_request": {},
"site_url": "<site_url>",
"note": "<note>",
"widget_review": {}
}