Sakura Lang

MCP server

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 for implemented features and remaining gates.

sakura mcp serve runs the compiler as a Model Context Protocol 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, for the same input.

Client configuration

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

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

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

ToolParametersReturns
compiler_infononeInformation about the running compiler. Exact fields are not specified yet.
checksnapshot, paths, budget_msDiagnostic, hole, and obligation records (Diagnostics).
symbol_queryname, id, or type_patternMatching symbols with full signatures, including effect rows, error unions, and contracts.
hole_contextsnapshot, hole_idOne typed hole record.
docs_querytopic or symbol, budget_tokensDocumentation text within a token budget.
explain_diagnosticcode or idThe explanation for a code such as V3001, the same as sakura explain.
formatsnapshot, pathsA patch with the canonical formatting.
check_patchsnapshot, editsDiagnostics for the patched code, plus the interface delta: which signatures the patch changes.
apply_patchsnapshot, patch_idA new snapshot, or a conflict.
testsnapshot, selectors, seed, budgetTest results under deterministic handlers.

Planned for v1: verify, refactor, impact.

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

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

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:

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).

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

Diagnostics: the JSON format every tool returns.

Edit on GitHub

On this page