Skip to content
Blume
Esc
↑↓navigate↵open⌘Jpreview
Guides

Agents

Add an MCP server to your docs

Let coding agents search and read your docs from inside the editor, through an MCP server that deploys with your site.

By 6 min read

By the end of this guide, your docs serve a Model Context Protocol (MCP) server at /mcp, deployed with the rest of the site, and a coding agent like Claude Code or Cursor can search and read them from inside the editor. The examples use the Acme Messages API docs from Generate API docs from an OpenAPI spec, but every step works on any Blume site.

The server gives agents your docs, and only your docs. Its tools read pages; they never call your API's operations or change anything.

What an agent gets

Blume's MCP server exposes four read-only tools, plus every page as an MCP resource for clients that attach context by URI:

ToolWhat it returns
search_docsPages matching a query, each with its title, route, URL, content type, and an excerpt. Up to 8 by default, 20 at most.
get_pageOne page as Markdown, with components turned into plain Markdown.
list_pagesEvery page with its route, title, and description.
get_navigationThe header tabs and sidebar, as your readers see them.

A typical retrieval is two calls. Asked how to authenticate with the Acme API, an agent first searches:

{ "name": "search_docs", "arguments": { "query": "authenticate requests" } }

The result is a JSON list of hits. Trimmed to the first one, it looks like this:

[
  {
    "contentType": "doc",
    "excerpt": "Send an API key as a bearer token with every request to the Acme Messages API.",
    "route": "/api/authentication",
    "title": "Authentication",
    "url": "https://docs.acme.example/api/authentication"
  }
]

The excerpt is the page's description when it has one, which is a good reason to write descriptions. The agent then passes the route to get_page and gets the whole page as Markdown, the same text a reader gets by adding .md to the page's URL.

Those results are the same every time for the same docs. What the model writes from them isn't: the answer in your editor is the model's own summary, so it can still get details wrong. The tool results are what you can check.

Do you need MCP?

Maybe not. Every Blume site already serves two things agents can read, on by default and on any host, including static ones like GitHub Pages:

  • /llms.txt, an index of every page with a summary, and /llms-full.txt, every page in one file.
  • A Markdown copy of every page: add .md to any page URL. On Vercel and Cloudflare, the page URL itself answers in Markdown when an agent sends Accept: text/markdown: see Serve HTML and Markdown from the same documentation URL.

An agent that can fetch URLs can use those today, as long as it knows your docs' address. MCP is worth adding when you want more than that:

  • Search the agent can call. search_docs runs its own full-text index, so the agent finds the right page without guessing URLs. It works whatever search provider your site uses, even with site search turned off.
  • Installed once. Add the server to Claude Code or Cursor, and every session can reach your docs without being told where they are.
  • Scoped results. Both search and page listing can filter by content type, locale, and docs version.

The cost is that MCP needs a host that runs server code. If your docs must stay on a static host, stick with llms.txt and the Markdown copies.

Turn on the MCP server

The server is off by default. Turning it on is one line in blume.config.ts:

agents: {
  mcp: {
    enabled: true,
  },
},

That mounts the server at /mcp. Three other settings are there if you need them: route moves it, name sets the name clients show (your site's title by default), and instructions passes a short hint to every agent that connects, such as when to reach for your docs.

Switch to server output

The MCP server answers requests live, so it can't ship in a static build. If you build with it enabled and no host adapter, the build stops with BLUME_SERVER_FEATURE_REQUIRED: "MCP server requires server output, but this is a static build."

Name your host with an adapter from blume/deploy to build for the server instead:

AdapterHostNotes
vercel()VercelShips with Blume. Detects your site URL.
netlify()NetlifyInstall @astrojs/netlify. Detects your site URL.
cloudflare()Cloudflare WorkersInstall @astrojs/cloudflare. Set site.
node()Your own Node server or containerShips with Blume. Set site.

This guide uses Vercel. For Cloudflare, see Deploy documentation and an MCP endpoint to Cloudflare Workers. With Vercel, your config now looks like this:

import { defineConfig } from "blume";
import { vercel } from "blume/deploy";

export default defineConfig({
  agents: {
    mcp: {
      enabled: true,
    },
  },
  deployment: vercel(),
});

On a host Blume can't detect the URL for, pass it to the adapter, as in node({ site: "https://docs.acme.example" }). The site URL matters here: without it, search hits carry bare paths instead of full URLs, and the Connect to MCP menu on your pages stays hidden.

Try it locally

Run npx blume dev, and the server is live at http://localhost:4321/mcp. Opening that in a browser shows "Method Not Allowed", which is expected: the endpoint only answers MCP requests, sent as POST. To check it, ask it for its tools:

curl -s http://localhost:4321/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The response lists search_docs, get_page, list_pages, and get_navigation. To run a search the same way, swap the body for a tools/call:

curl -s http://localhost:4321/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_docs","arguments":{"query":"authenticate requests"}}}'

Deploy

Commit, push, and import the repository in Vercel, with the project's Node.js version set to 22 or later. Once it's live on your domain, the server is at https://docs.acme.example/mcp. Blume also publishes a discovery document for it at /.well-known/mcp.json, and lists it in your llms.txt, so agents that read either can find it.

Connect a client

In Claude Code, add the server by name and URL:

claude mcp add --transport http acme-docs https://docs.acme.example/mcp

That adds it for you, in the current project. Pass --scope project to write it to a .mcp.json you commit so your whole team gets it, or --scope user to use it in every project. Then check the connection:

claude mcp list

acme-docs should show as connected. Start a session and ask something your docs answer, like "How do I authenticate a request to the Acme Messages API?" The transcript shows the agent calling search_docs, then get_page, before it answers. Inside a session, /mcp shows the server and its tools.

In Cursor, add the server to .cursor/mcp.json in your project, or to ~/.cursor/mcp.json for every project:

{
  "mcpServers": {
    "acme-docs": {
      "url": "https://docs.acme.example/mcp"
    }
  }
}

Your readers don't need these steps. Once the site URL is known, every page gets a Connect to MCP menu that copies the command for Claude Code or Codex and opens an install link for Cursor or VS Code.

What you run now

The server runs on your host alongside your pages, from a snapshot of your docs taken at build time, so it updates when you deploy. There's no separate service or index to keep in sync. For Specific, that's why it's on: it was one line of config. The agents page covers everything else Blume serves to agents, and MCP server in the docs has the content type and facet filters for larger sites.

Troubleshooting

The build fails with BLUME_SERVER_FEATURE_REQUIRED

The build is static. Set deployment to a host adapter from blume/deploy. If you already have one, remove output: "static" from it.

The build warns that the MCP server was not generated

A content page or custom page already uses /mcp, so Blume leaves the route to that page. Move the server with agents.mcp.route, and use the new path when you connect clients.

The endpoint shows "Method Not Allowed"

That's a browser, or anything else sending GET. The server only answers MCP requests. Test it with a client or the curl commands above.

The client fails to connect

Run the tools/list request against the exact URL the client uses. If it fails too, check the URL ends in your MCP route, that the deployment is a server build on your production domain, and that no password or login protection sits in front of it. If curl works and the client doesn't, remove the server from the client and add it again.

Search returns pages in other languages

On a translated site, search_docs searches every language unless the agent passes locale. Ask for results in your language, or add that to agents.mcp.instructions.

Search hits have paths instead of URLs

Blume doesn't know the site URL. Set site on your adapter, or deploy to a host Blume detects it on.

Next step

Give agents your docs

Turn it on in your config, deploy, and connect your own editor to it.

Read the MCP server docs

A step here not working for you? Report a broken step.

Keep going.More guides.

Upgrade your docs with Blume.

Install today and ship a production-grade docs site in minutes. Free and open source, forever.

npx blume init