WritedocsWritedocs

MCP server

Every writedocs site can run an MCP server at /mcp. An AI tool connected to it searches and reads your docs directly, always the published version, instead of relying on what it remembers.

It’s on by default. writedocs build writes everything it needs into dist/, and writedocs dev serves it at http://localhost:4321/mcp while you write.

What an AI tool gets

Three tools, answered from your pages:

  • list_docs — every page, with its title, URL and description.
  • search_docs — the best-matching pages for a query, optionally only one docs version or language (taken from your navigation’s versions and languages).
  • get_doc — a page’s full content as Markdown. It accepts the page’s path or URL, as the tool or a reader would write it.

Pages read the way they show on the site: imported snippets included, variables filled in, code examples exactly as written. Pages with seo.noindex are left out, as they are from llms.txt.

Connecting

Point the client at your site’s /mcp address:

.claude/settings.json (Claude Code)
{
  "mcpServers": {
    "acme-docs": { "url": "https://docs.example.com/mcp" }
  }
}

In Cursor: Settings → MCP → Add server, and paste the URL. Opening /mcp in a browser shows a short description of the server.

Readers don’t need to find the URL themselves: every page’s contextual menu has Copy MCP server URL, Connect to Cursor and Connect to VS Code - the last two add the server to the editor in one click.

Deploying

writedocs build adds these to dist/:

FileWhat it’s for
mcp-index.jsonYour pages, as the server reads them
_worker.jsThe server, ready to run on Cloudflare
_routes.jsonCloudflare Pages: only /mcp runs the server; every other path stays a static file
.assetsignoreCloudflare Workers: keeps _worker.js and _routes.json from being published as files

Cloudflare Pages — deploy dist/ as usual. Pages picks up _worker.js on its own, and /mcp works.

Cloudflare Workers (static assets) — use dist/_worker.js as the Worker and dist/ as its assets:

wrangler.jsonc
{
  "name": "my-docs",
  "main": "dist/_worker.js",
  "compatibility_date": "2026-09-01",
  "assets": { "directory": "dist", "binding": "ASSETS" }
}

Other hosts that run code (Netlify, Vercel, your own server) — the same server is part of the package. Serve dist/ as usual and route /mcp to it:

import { handleMcpHttp } from '@writedocs/generator/mcp';

// Any runtime with Web-standard Request/Response - a Netlify or Vercel function, a Worker, Node 18+.
export default async function mcp(request) {
  return handleMcpHttp(request, {
    loadIndex: async () => (await fetch(new URL('/mcp-index.json', request.url))).json(),
  });
}

Static-only hosts (GitHub Pages, S3) can’t run a server, so /mcp isn’t available there. llms.txt and llms-full.txt still are.

A project that already has its own _worker.js or _routes.json in public/, or a Cloudflare Pages functions/ folder, keeps them: the build doesn’t write _worker.js (Pages ignores functions/ once one exists) and says so. Add /mcp to your own worker with @writedocs/generator/mcp.

Turning it off

writedocs.json
{
  "mcp": false
}

The build then leaves out mcp-index.json, _worker.js, _routes.json and .assetsignore.