MCP connections
Connect servers you run yourself. Their tools join the catalog and pass through the same four gates as a built-in tool.
The client
The MCP client is written by hand: JSON-RPC 2.0 over Streamable HTTP with SSE, OAuth, elicitation and task polling, in 3,342 non-test lines across twelve files. It is one of the two crates in the workspace permitted to open a socket, and it is not reached at all until you list a connection.
This page said "roughly 430 lines with a single use std" for a long time. That was true at the first commit and was never re-derived while the protocol grew; measured on 6 September 2026 it is 3,342 lines, 4,667 with the tests, and 11 use std lines across six files. The point the sentence was making survives — there is no client library underneath, and 3,342 lines of plain Rust is still something one person can read — but a number in a paragraph about auditability has to be the real one.
Configuring a server
Connections live in mcp.json in the config directory. TACET_MCP_CONFIG points at a different file. The file is created with restrictive permissions, because a connection list often carries a token and an mcp.json written by hand in an editor picks up whatever the default umask gives it.
tacet mcp list # the connections, and whether they answer
tacet mcp try <name> # call one by hand before trusting it
tacet mcp try <name> --call <tool> --args '{"path":"x"}'
tacet mcp login <name> # OAuth, where the server wants it
tacet mcp logout <name>A remote tool gets no extra privilege
Discovered tools are registered into the router alongside the built-in ones and are subject to the same name gate, the same schema gate, the same approval question in a session that has touched personal data, and the same cancellation. Output from a remote server is framed as untrusted data rather than folded into the conversation as if the model had said it.
Before you trust one
tacet mcp try calls a tool once, by hand, and shows you the raw result. That is worth doing before a server's tools are in the catalog for a real conversation, because a remote catalog can be large enough to change which nine tools the router shows.
The router shows the model nine tools out of however many exist. A machine with 29 MCP tools attached is answering a different question than a fresh install, which is why tacet bench check --portable exists.