Expose the Krate compiler to AI agents over the Model Context Protocol with `krate mcp`.
#MCP Server (Agent-Native)
krate mcp starts an MCP (Model Context Protocol) server that exposes the Krate compiler to AI agents. The agent talks to the real compiler — routes, AST, diagnostics, content graph — instead of grepping a filesystem.
The server speaks JSON-RPC 2.0 over stdio and has no external dependencies.
#Setup
Register the server once in your agent/editor config. The working directory (or a trailing path argument) selects the project root.
#Claude Desktop / Claude Code
claude_desktop_config.json:
{
"mcpServers": {
"krate": { "command": "krate", "args": ["mcp", "/abs/path/to/site"] }
}
}Omit the path to use the current working directory: "args": ["mcp"].
#Cursor / VS Code / opencode
The shape is the same, under the client's own key:
- Cursor —
.cursor/mcp.json - VS Code —
.vscode/mcp.json(under"servers") - opencode —
opencode.json
{
"mcpServers": {
"krate": { "command": "krate", "args": ["mcp"] }
}
}#Tools
| Tool | Description |
|---|---|
list_routes | Every route with source file, render mode, and dynamic params |
read_page | A page's source, kind-tagged AST document, or rendered HTML (format selectable) |
read_content | Content-collection entries: list a collection or read one entry (raw file + frontmatter + body) |
search_docs | Search Krate's built-in framework docs (ranked, via the docfind engine); returns slugs, excerpts, and optional full text |
build | Build the site; returns diagnostics and a per-route summary |
check | Run the quality gates (a11y/SEO/perf); builds first when needed |
explain | Explain a route from the compiled site graph: mode, source, dependencies, dependents, and emitted output files |
create_page | Create a page from a template; returns a diff (dry-run by default) |
edit_ast | Replace a page's AST with an edited document; returns a diff |
edit_page | Edit any project file's source directly (full replace or find+replace); returns a diff |
list_files | List project files (skips node_modules/.git/dist), with an optional glob |
read_file | Read any project file by path (text + language, or a binary marker) |
create_file | Create a new file (refuses to overwrite; parse-gated); returns a diff |
delete_file | Delete a file (files only); preview unless apply |
move_file | Move/rename a file; preview unless apply |
create_component | Scaffold a component (client/static/server, optional CSS); returns a diff |
create_content | Create an entry in a content collection, validated against its schema; returns a diff |
edit_content | Edit a content entry (full replace, frontmatter rewrite, or find+replace); schema-checked |
Every tool advertises annotations (read-only, additive, destructive) so clients know what to auto-approve and what to flag for confirmation.
#Read tools
list_routes, read_page, read_content, search_docs, build, and check never write source files.
read_page lets the agent choose what it needs with format (default source):
source— the raw file text, so the agent can read and edit the actual page.ast— the kind-tagged AST document (the same format JS plugins receive), withlossyTypesreporting TypeScript constructs the parser drops.html— the rendered output when the site has been built.all— source, AST, and rendered HTML together.
read_content lists a collection's entries (slug, project path, frontmatter) when collection alone is given, or returns a single entry's raw file, parsed frontmatter, and markdown body (plus rendered HTML for .md) when slug is added.
search_docs searches Krate's own framework documentation — the content that powers the docs site — which is embedded into the compiler at build time, so it works the same from any project and offline. It is backed by the docfind WASM engine running in-process (the same engine Krate uses for docs search during development builds): results are ranked, and each hit carries a short excerpt, a slug, and a resource (krate://docs/{slug}) for reading the whole page.
limitcaps the number of hits (default 8).maxCharssizes theexcerptwindow (default 240); it only affects the excerpt, never the full text.full: trueadds acontentfield with the hit's complete cleaned text (plain text with newlines).
It does not scan the current project's content; use read_content/krate://content for that.
#File tools
The file tools let the agent discover and manage arbitrary project files (components, styles, assets), not just pages:
list_fileslists project-relative paths (skippingnode_modules,.git,dist, …). Filter withglob(src/components/*/.tsx), scope withdir, and setincludeDenied: trueto see policy-denied paths.read_filereturns a file's text with a language hint (or abinarymarker). Sensitive paths are refused (see the policy below).create_file,delete_file, andmove_fileround out the lifecycle.create_filerefuses to overwrite (useedit_pageto modify) and parse-gates editable source; all three default to a dry-run preview.create_componentscaffolds a component undersrc/components/<kebab-name>/:kindselectsclient(imports the runtime),static, orserver;withCss: trueadds a companion.cssfile. Continue withedit_pagefor changes.
#Write tools
create_page, edit_ast, edit_page, create_file, delete_file, move_file, create_component, create_content, and edit_content default to a dry-run that returns a unified diff. Pass "apply": true to write. This gives the agent (and you) an approval step before anything changes on disk.
#Permissions (.krate/mcp.json)
By default the agent may read and write any project file except a small set of sensitive paths — environment files (.env), private keys (.pem, *.key, id_rsa, …), .git/, npm/pypi/netrc credential files, and the policy file itself. Those require an explicit allow entry. A committed policy at .krate/mcp.json customises this:
{
"allow": ["config/public.env"],
"deny": ["src/generated/**"],
"readOnly": ["krate.config.ts"]
}allowoverrides the default-deny list (e.g. permit one checked-in.env.example).denyalways wins, even overallow.readOnlypermits reading but never writing.
Every write also rejects absolute paths and traversal outside the project root, resolving symlinks so a symlinked directory cannot redirect a write elsewhere.
create_pagescaffolds a page from a template —static(default),content-list,detail, andblank(raw source override). For content-backed templates you can passcollectionand acontentEntryobject so the matching markdown entry is authored alongside the page, andwithLayout: truecreates a missing_layout.tsx. Applying a page also regenerates the generated route/content types.edit_astaccepts a kind-tagged AST document — typically one read withread_page, modified, and sent back. The compiler validates it by decoding the document and re-parsing the printed source before writing. If the page uses TypeScript constructs the parser drops (interfaces, type aliases, annotations),edit_astrefuses rather than silently stripping them.edit_pageedits the actual file — before reaching for a patch. It takes aroute(a page route like/about, or a project-relative path likesrc/pages/about.tsx,src/styles/main.css, orsrc/content/blog/hello.md) plus one of two modes: -content— replace the entire file (creates the file when it does not exist). -find+replace— a targeted in-place edit.findmust match exactly once, or passreplaceAll: trueto replace every occurrence; a missing or ambiguous match returns a helpful error instead of guessing.
Editable source (.ts, .tsx, .js, .jsx) is re-parsed after the edit: anything that would not parse is never written (dry-run or apply). Existing line endings (LF/CRLF) are preserved, and paths are anchored to the project root with traversal rejected. A diff is returned in either mode.
create_contentwrites a new entry to a content collection.datais validated against the collection schema (required fields, type checks) before any file is created; the entry is refused if it already exists or the slug would escape the collection directory. Plugin-contributed collections (like the docs collection) are supported alongside configuredcontent:entries.
edit_contentedits an existing content entry. Three modes: full-file replace viacontent, frontmatter rewrite viadata(body preserved unlessbodyis given), or a targeted find+replace. The result is re-parsed and validated against the collection schema before any write, so a broken frontmatter change is never written to disk.
#Resources and resource templates
Resources provide pull-based context an agent can attach automatically.
| URI | Contents |
|---|---|
krate://routes | Every route in the project (JSON) |
krate://page/{route} | A single page by route, e.g. krate://page/about |
krate://docs/{slug} | A Krate framework documentation page as raw markdown, e.g. krate://docs/features/mcp |
krate://content | Effective content collections (configured content: plus plugin-contributed, e.g. docs) and their entries, with each collection's schema fields |
krate://manifest | The built site manifest (empty when unbuilt) |
krate://config | The resolved Krate config (relative paths, no env values) |
krate://graph | The compiled site graph: routes with mode, dependencies, dependents, and emitted output files (JSON) |
krate://page/{route} and krate://docs/{slug} are resource templates, advertised through resources/templates/list. The server also provides argument completions (completions/complete) for routes, page templates, and content collections (and collection slugs for the content tools), so clients can offer values while the agent is filling in a tool call or prompt argument.
#Prompts
Prompts package recurring workflows so agents reach for the right tools:
add-page— create a page the Krate way: match house style first, thencreate_pagewith the chosen template, and confirm viabuild/check.publish-content— author a new entry into a typed content collection viacreate_content(schema-validated) and wire it into a page.fix-checks— run the quality gates, then fix the worst findings withedit_page.explore— summarize the project from routes, config, and outstanding checks.
#Protocol
- Version negotiation:
initializehandlesprotocolVersionnegotiation, supporting2024-11-05through2025-11-25. - Cancellation:
notifications/cancelledaborts a pending request; the server responds with error code-32800(Request Cancelled) when appropriate. Long-runningbuild/checkcalls observe the cancellation context. - Instructions:
initializeincludes agent-facing instructions that describe the tool set, the dry-run convention, and Krate's pages/layout/ content conventions. - Notifications (
notifications/initialized,exit) never produce a response.
#Example session
An agent asked to add a pricing page can:
list_routes— see existing routes and their source files.read_pageon a similar page (format: "source") — learn component and styling conventions.create_page { route: "/pricing" }— receive a diff.- You approve, then the agent calls it again with
"apply": true. build— surface diagnostics in the same turn.check— fix any accessibility or SEO findings withedit_page.
Because the server holds the compiler in-process, each step is fast and the agent never has to invoke a shell.
For how the server is implemented (no SDK dependency, stdout discipline, path anchoring), see Contributing → Architecture.
Last updated: 2026-10-16
Contributors: Noinkin