tools/call, with no change to the agent or the server. The operator
server lets the person who has to answer an approval answer it from the assistant they are
already talking to. This documentation is itself an MCP server your coding tool can search. And
the gateway is listed where MCP servers are discovered.
Enforcement: the gateway
ctrlrun gateway is a process between the agent and the tool server. Every tools/call
becomes an action named mcp.<alias>.<tool>, decided by the same ctrlrun.yaml the decorator
uses, bound to a human’s approval where the policy says so, reserved by effect key so the same
consequence runs once across retries and workers, relayed, and recorded. Everything else on the
wire is relayed untouched.
- No code changes: the agent and the server are untouched.
- Works in any language: the gateway fronts an HTTP endpoint.
- Approvals bound to the exact tool call, arguments included.
- Every call that reaches a decision leaves a receipt, denied ones included. A call still waiting on a human has not been decided yet and has none until it is.
- Measure first with observe mode, in the same policy file.
Learning: this site is an MCP server
Every page here is reachable through an MCP server hosted with the site, with one tool, a search across the documentation. Add it to Cursor, VS Code or any MCP client and the assistant answers from these pages rather than from memory. Use the docs from your editor has the configuration.Discovery: the registries
The operator server is the MCP server this project publishes, and it is listed in the official MCP registry asio.github.CTRLRun/ctrlrun-mcp-operator, and on Glama.
A client that installs from a registry gets ctrlrun mcp-operator --stdio, which is the
configuration in Approve from your assistant.
The gateway is not listed, and the reason is what it is: a proxy you run in front of an MCP
server you already have, not a server a registry can point a client at.
Answering: the operator server
ctrlrun mcp-operator is an MCP server that exposes the operator’s own commands as tools. An
approver asks their assistant what is waiting, reads the action and its arguments, and answers —
without a checkout, a shell or a store path.
- Read tools —
list_pending_approvals,inspect_action,receipts,effects,stats. - Write tools —
approve,deny,resolve. Each needs a credential that names a human, from the identity provider you configured; never a name the client asserts. - Every answer is recorded under that person’s name, and the name reaches the receipt the action leaves.
- It is not a second approval path:
approveanddenyare the two store callsctrlrun approveandctrlrun denymake, against the same record, with the same hash binding, single use and expiry. - Nothing here can make an agent act. There is no tool that proposes or executes an action, and no auto-approve.
- Over HTTP it binds loopback and has no flag that changes that, because its read tools answer
without a credential. With
--stdioit binds nothing: the client that launched it is its only client, and the approver is that client’s OS login.
What MCP does not change
The guarantees are the same three ways in. A refund refused by the gateway is refused for the same reason, recorded in the same receipt shape, and verified by the samectrlrun verify as
one refused by the decorator. An agent that calls a ctrlrun tool to check its own actions would
not be enforcement, because a tool the agent chooses to call is a tool it can choose not to; the
gateway is in the path whether the agent likes it or not.