MCP server
tessera mcp # stdiotessera mcp --http 127.0.0.1:8765 # Streamable HTTP on POST /mcp, health on GET /healthBoth transports start answering at once. The first index builds in the
background; until it exists, tool calls return isError: true with “Index is
building … retry in a few seconds”. After that, a file watcher re-indexes
changed files within about 200 ms.
Protocol
Section titled “Protocol”Tessera is a dual-era server:
- Modern clients (2026-07-28). Requests carry
_meta["io.modelcontextprotocol/protocolVersion"]and are served statelessly.server/discoverlists the supported versions. An unsupported version gets error-32022with thesupportedlist. - Legacy clients (2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05). They
use the
initializehandshake. Tessera echoes the requested version when it supports it, and otherwise answers 2025-11-25.
Errors follow JSON-RPC:
| Code | Meaning |
|---|---|
-32700 |
parse error |
-32600 |
invalid request; batches are not supported |
-32601 |
unknown method |
-32602 |
unknown tool or invalid arguments |
A tool that runs but fails returns a normal result with isError: true, so
the model can read the message and recover. Notifications never get a reply.
HTTP specifics:
Originmust be absent orlocalhost/127.0.0.1/[::1]; any other origin gets 403.- Notifications get 202.
GETandDELETEon/mcpget 405.- Modern requests must send
MCP-Protocol-Version,Mcp-Method, and, fortools/call,Mcp-Name, all matching the body. A missing or mismatched header gets 400 with code-32020.
Every tool is read-only (readOnlyHint: true) and rejects unknown arguments.
Responses are compact text by default; pass "format": "json" for
machine-readable output. List tools are paginated: limit (default 25) and
cursor. When there is more, the text ends with cursor o:N.
| Tool | Use it for | Arguments |
|---|---|---|
find |
Where a symbol is defined: kind, file:line, signature, optional body. With path, outline a file or directory plus its imports. |
symbol or path, include_body |
search |
Fuzzy or glob name search with filters. unused: true lists functions nothing calls. |
pattern, kinds, languages, path, exported, unused |
refs |
Every reference to a symbol with its confidence, or the files importing a file. | target, tests_only, min_confidence |
blast |
Callers ranked by impact, plus test files to run, for a symbol or a git diff. | symbol or diff_from (+diff_to), depth |
verify |
Does a symbol exist; does every call in a snippet resolve; did a change break a call site, an import, or a contract? | symbol, snippet + language, or changed / staged / diff_from |
context |
Body, callees, callers, tests, and siblings in one budgeted bundle. | symbol, budget_tokens |
path |
Shortest call chain from one symbol to another, across services through routes and gRPC calls. | from, to, depth |
map |
Contracts between services: routes, gRPC methods, topics, tables, with both sides; or what a service serves and calls. | kind (route, rpc, topic, table, service), query |
status |
Index root, freshness, counts, and setup hints. | none |
import_cycles |
Circular dependency cycles between imported modules. | path, limit |
affected |
The test files a change reaches, each with the call path (across contracts) that selects it; changed and failed tests always run, lockfile, build, config and fixture changes run everything. | rev or staged, failed, explain, package, depth |
Symbols can be written name, Class.method, or A::B. References and
callers are resolved through scope, imports, and declared types, and each
carries a confidence: unmarked lines are exact, “likely” lines matched a
unique name, “possible” lines are ambiguous or name-level. See
accuracy.
Checking conformance yourself
Section titled “Checking conformance yourself”The repository’s tests/mcp_conformance.rs drives the binary through full
stdio and HTTP sessions. To poke the server interactively:
npx @modelcontextprotocol/inspector tessera mcpnpx @modelcontextprotocol/inspector --cli tessera mcp --method tools/list