writ proxy
Govern an MCP server at the tool boundary.
writ proxy <file> -- <server command> [arguments...]This is sidecar mode. The proxy starts the MCP server, speaks MCP on standard
input and standard output, and applies the mcp grants of the writ to each
tool call.
Your agent does not change. You point the agent at the proxy instead of the server.
| Flag | Purpose |
|---|---|
--set <name>=<value> |
Give a placeholder a value. |
The writ for a proxy
Section titled “The writ for a proxy”The writ needs an mcp grant. The grant names the tools that the agent can
call:
writ: github-readermandate: "Answer questions about the issues of the repository."
grants: - mcp: { tools: ["search_issues", "get_issue", "list_comments"] }The proxy denies each tool that the list does not contain.
Run the proxy
Section titled “Run the proxy”writ proxy github-reader.yaml -- npx -y @modelcontextprotocol/server-githubThe -- separates the flags of Writ from the command of the server. Each
argument after -- belongs to the server.
Configure your agent
Section titled “Configure your agent”In the MCP configuration of your agent, replace the server command with the proxy command:
{ "mcpServers": { "github": { "command": "writ", "args": [ "proxy", "github-reader.yaml", "--", "npx", "-y", "@modelcontextprotocol/server-github" ] } }}The record in sidecar mode
Section titled “The record in sidecar mode”The record goes to standard error, because standard output carries the MCP protocol. The session ends when the client disconnects.
Which mode to use
Section titled “Which mode to use”| You want | Use |
|---|---|
| To govern an agent that you already have, with no change to the code | writ proxy |
| Bounds, invariants, satisfaction, and a complete record | writ issue |
Sidecar mode is the way to start. It answers one question with little work: which tools does this agent really call?