Run the proxy
The transparent MCP proxy listens on :9003 over HTTP. It can sit in front of an MCP server directly, or be chained inside an existing proxy path.
Developers / Quickstart
The shortest path to a governed action: point an MCP client at the transparent proxy, write one rule, watch the call stop, and find the record it left. Nothing is installed inside the agent.
BEFORE YOU START
The transparent MCP proxy is chosen here because it needs the least existing infrastructure — no gateway at all. If you already run an Envoy-family gateway, the ext_proc adapter is the shorter route in production.
governor-mcp-proxy binary. It is built from the GovernorAI source tree (go build ./cmd/governor-mcp-proxy), or as a container image from the shared adapter Dockerfile (--build-arg BINARY=governor-mcp-proxy), which targets linux only. There is no prebuilt release artifact for this adapter: the signed release matrix covers the governor CLI alone (linux amd64/arm64, darwin amd64/arm64, windows amd64).The transparent MCP proxy listens on :9003 over HTTP. It can sit in front of an MCP server directly, or be chained inside an existing proxy path.
Change the MCP client's server URL to the proxy. Nothing else in the client changes, and the agent is unaware of the interception.
Governed: tools/call. Passed through untouched: initialize, tools/list, ping and notifications — so discovery and handshake behave exactly as before.
Start with a rule narrow enough that you can trigger it deliberately: one tool name, denied unconditionally. Policy is a reviewed artifact, so this is a file, not a console setting.
Invoke the tool through the agent as normal. The call is intercepted, evaluated, and stopped before it reaches the MCP server: on this seam a deny is returned as a JSON-RPC error, and a pause as an approval response.
The decision is written as it happens, into the hash-chained ledger. This is the step that separates governance from blocking: the point is not only that the call stopped, but that you can show an assessor why.
Stop the policy engine and repeat the call. It must be denied, not allowed. Any transport error, timeout, non-2xx or unparseable response resolves to deny — enforcement does not degrade quietly.
There is nothing to set. Where the Envoy filter needs failure_mode_allow: false declared explicitly, the MCP proxy has no equivalent knob: its decision client is constructed fail-closed, and no environment variable, flag or config field turns that off. A transport error, a timeout, any non-2xx, an unparseable response, a body over 1 MiB, a tools/call missing its tool name, and a tools/call inside a JSON-RPC batch all resolve to -32002 and are never forwarded upstream — including a non-2xx whose body says allow. The only adjacent setting is GOVERNOR_MCP_DECISION_TIMEOUT (default 5s), which bounds how long a hung gateway takes to become a deny.
This path governs one tool call on one seam. It does not make an agent governed — discovery has not run, no policy covers the rest of the tool surface, and nothing has been said about the model call itself. It is the smallest thing that is genuinely true, which is a better starting point than a demo that implies more.