# MCP server

URL: /docs/agents/mcp
Markdown: /docs/agents/mcp.md

> The sakura mcp serve server, which exposes the compiler to agents as Model Context Protocol tools, and @tool export of your own functions.

> **Pre-alpha**
>
> The source-built compiler runs the core language and much of M3 on JavaScript: contracts, typed effects and failures, std handlers, permissions, LSP and MCP. M3 is still in progress; no release or stable compatibility contract exists. See the [roadmap](/docs/roadmap) for implemented features and remaining gates.

`sakura mcp serve` runs the compiler as a [Model Context Protocol](https://modelcontextprotocol.io) server. An agent calls compiler functions directly instead of running shell commands and parsing their output.

The CLI, the language server (`sakura lsp`), and the MCP server are thin adapters over one Rust analysis library (`sakura_analysis`). They report the same diagnostics, in the same [JSON format](/docs/agents/diagnostics), for the same input.

## Client configuration [#client-configuration]

A client entry would look like this. The transport options are not fixed yet.

```json
{
  "mcpServers": {
    "sakura": {
      "command": "sakura",
      "args": ["mcp", "serve"]
    }
  }
}
```

## Snapshots [#snapshots]

The compiler never reads the filesystem during analysis. It works on an immutable **workspace snapshot**. Every tool returns a `snapshot` id, and tools that read or change code take one. This makes results reproducible and lets the server detect stale edits: a patch built against an old snapshot conflicts instead of applying to the wrong text.

## Tools in v0 [#tools-in-v0]

| Tool | Parameters | Returns |
| --- | --- | --- |
| `compiler_info` | none | Information about the running compiler. Exact fields are not specified yet. |
| `check` | `snapshot`, `paths`, `budget_ms` | Diagnostic, hole, and obligation records ([Diagnostics](/docs/agents/diagnostics)). |
| `symbol_query` | `name`, `id`, or `type_pattern` | Matching symbols with full signatures, including effect rows, error unions, and contracts. |
| `hole_context` | `snapshot`, `hole_id` | One [typed hole](/docs/agents/typed-holes) record. |
| `docs_query` | `topic` or `symbol`, `budget_tokens` | Documentation text within a token budget. |
| `explain_diagnostic` | `code` or `id` | The explanation for a code such as `V3001`, the same as `sakura explain`. |
| `format` | `snapshot`, `paths` | A patch with the canonical formatting. |
| `check_patch` | `snapshot`, `edits` | Diagnostics for the patched code, plus the interface delta: which signatures the patch changes. |
| `apply_patch` | `snapshot`, `patch_id` | A new snapshot, or a conflict. |
| `test` | `snapshot`, `selectors`, `seed`, `budget` | Test results under deterministic handlers. |

Planned for v1: `verify`, `refactor`, `impact`.

### Checking a patch before applying it [#checking-a-patch-before-applying-it]

`check_patch` lets an agent try an edit without changing anything. The interface delta tells the agent, and the reviewer, whether the edit changes a public signature, effect row, or error union. `apply_patch` then commits it and returns the new snapshot.

`apply_patch` enforces **frozen specs** (design §7.3). It rejects any patch that modifies a frozen symbol's signature, effect row, error union, `requires`/`ensures`/`where` clauses, or any `test`/`property` body, with diagnostic `V8020 spec_frozen` naming the clause. The CLI equivalent is `sakura check --frozen-specs <symbols|all>`.

### Authority [#authority]

Tools that execute code, such as `test`, run with capabilities issued by the host. A caller cannot name authority in a tool call. Tests run with deterministic default handlers and network access denied.

## Exporting your own functions as tools [#exporting-your-own-functions-as-tools]

Planned separately from the implemented compiler tools: `sakura mcp serve --tools a,b` would export functions from your program as MCP tools (design §11.2). `Tool.of` works in-process today; the export flag is not implemented.

A tool function is marked `@tool("description")`. Its parameters and result must be `Schema` types, and its error union must be made of `Schema` tags. From design §15.8:

```sakura
import std/http.{Http, HttpError, RateLimited, Response, Status}
import std/json.{DecodeError}

error SearchDown

@tool("Search the internal knowledge base; returns up to 5 snippets")
fn kb_search(query: String) -> List<String> ! {Http, Fail<SearchDown | HttpError | RateLimited | DecodeError>} {
  let resp = Http.get(url"https://kb.internal/search?q={query}")
  if resp.status != Status.from(200) { fail SearchDown }
  let snippets: List<String> = Response.json(resp, 100_000)
  snippets
}
```

`Tool.of(kb_search)` builds a `Tool` value. Its JSON Schema comes from the parameter types, refinements included. When called, it validates the JSON arguments, runs the function under the caller's current handlers, and maps failures to a public `ToolError` with the tag name and payload. The same `Tool` values are used in-process by `Agent.run`, which takes them in the `tools` field of its `Agent` configuration record (see the [standard library](/docs/stdlib)).

When exported over MCP, the model never supplies authority. The handlers installed by the serving program decide what `Http` can reach, and the manifest's `[permissions]` table is the ceiling.

## Next [#next]

[Diagnostics](/docs/agents/diagnostics): the JSON format every tool returns.
