Developer documentation
MCP
Last reviewed 31 August 2026
Protecting an MCP server
MCP is where an agent actually reaches the world, so it is the highest-value
thing to put a decision in front of.
The shape of it
Instead of your client talking to your MCP server directly, it talks to MCPGate,
which decides and then forwards:
MCP client -> MCPGate (decides, enforces) -> your MCP server -> tool runs
One command
cain protect mcp ./my-server
That inspects the target and prints what to change. It does not rewrite your
MCP client configuration -- reconfiguring a developer's environment unprompted is
the kind of surprise that loses trust, so the change is shown and applied only
with --apply.
It reports what it found: whether the target exists, whether it is a local
directory or a remote URL, and how many tools appear to be declared. The tool
count is derived by reading source files, not by executing the server -- a
security tool that runs an unknown MCP server to enumerate its tools would be a
remarkable thing.
Then prove the path
cain test --mcp
This is the check that matters, because "I pointed my client at the gateway" and
"calls are actually being decided" are different claims. Note that the client-side
suite reports MCP path enforcement as SKIP when it cannot observe it directly
-- a skip is not a pass, and it withholds the conformance claim.
Declaring servers
mcp:
servers:
- ./my-server
- https://tools.internal/mcp
cain test checks these are declared. With none listed, the MCP suite skips
rather than passing vacuously.
What is protected, and what is not
Protected: the decision to allow a tool call, made before the call reaches your
server, recorded as evidence.
Not protected by this alone: anything that talks to your MCP server without
going through the gateway. If the server is still reachable directly, a client
that skips the gateway skips the decision. Bind it to localhost, or put it on a
network only the gateway can reach. cain doctor cannot see this for you, and
does not claim to.