Governance for MCP tool calls
The Model Context Protocol gives agents a clean way to discover and call tools. It does not give you a way to control which tools, by whom, with what arguments. That gap is a policy problem.
What MCP gives you, and what it doesn't
The Model Context Protocol standardises how an agent discovers and invokes tools exposed by an external server. Connect an MCP server, get a typed catalogue of tools, call them. The protocol handles transport, schemas, and identity at the connection level.
What MCP deliberately doesn't ship is policy. There's no built-in answer to:
- Which of the 47 tools on this server is this agent actually allowed to call?
- Are some of those tools allowed only with specific argument ranges?
- Does this user / session / tenant get a different subset of allowed tools?
- Is this call allowed without human approval, or does it need to escalate?
- Where's the audit trail of every MCP invocation, with the policy that decided it?
Each MCP server you wire up expands the agent's blast radius. Without a policy layer between the agent and the protocol, you're trusting every connected server's surface area equally.
The policy layer pattern
The fix is the same policy-as-code pattern used everywhere else: put a deterministic policy engine between the caller and the executor.
For MCP, that means: when the agent decides to call tool.fooBaron an MCP server, the runtime first emits a tool_call event with the tool name, arguments, server identity, and session context. A Rego policy evaluates that event. The result is one of:
- Allow. The MCP call proceeds.
- Deny. The call never reaches the server. The agent gets a structured rejection it can react to.
- Escalate. The call pauses while a human approves or rejects asynchronously.
Every decision is logged with the policy version. That's what an auditor or an incident responder needs.
Examples of MCP policies you can write
- "Only the
billingagent may call MCP tools taggedfinance.write, and only with amounts below $1000 without approval." - "Any MCP call to a server marked
untrustedmust strip confidential session data before transmission." - "In production, deny
shell.execoutright. In staging, allow but require approval." - "Cap MCP calls per session at 200, regardless of which server."
Why MCP governance is a general policy problem, not an MCP problem
MCP is one transport. An agent can also call native Python tools, hand-rolled adapters, REST APIs, internal RPCs. The same governance question applies to all of them: was this agent allowed to invoke this action, in this context? MCP governance is one slice of broader governance for AI agents, applied to one specific tool transport.
That's why Kite Logik treats MCP calls as one source of tool_callevents, alongside every other tool surface. One policy engine, one audit log, one source of truth — independent of how the call was transported. The same engine that gates an MCP call also gates the comparison against output validators or dialogue rails on the model side.
Frequently asked questions
Does the Model Context Protocol have built-in policy enforcement?
No. MCP standardises tool discovery, schemas, and transport. Authorisation — which agent can call which tool with which arguments — is intentionally out of scope. That gap is what a policy layer fills.
How do you control which MCP tools an agent can call?
You put a deterministic policy engine between the agent and the MCP transport. Each tool invocation becomes a structured event that's evaluated against an OPA/Rego policy before it reaches the MCP server. The policy can allow, deny, or escalate the call to a human reviewer.
What's the audit trail for MCP tool calls under Kite Logik?
Every governed MCP call is recorded as an immutable event with the tool name, arguments, server identity, session context, the policy version that evaluated it, and the resulting decision. That log is what an auditor or incident responder needs to answer "what did the agent do, and why was it allowed."
Can you require human approval for specific MCP tools?
Yes. A Rego rule can return an "escalate" decision for any subset of tools (e.g. anything tagged `finance.write`, anything pointing at production, anything above a transaction threshold). The MCP call pauses until a human approves or rejects it asynchronously.
Is MCP governance different from governing native tool calls?
Conceptually, no. MCP is one transport for tool calls; native Python tools, REST APIs, and internal RPCs are others. The same authorisation question applies to all of them. Kite Logik treats MCP calls as one source of `tool_call` events alongside every other tool surface — one policy engine, one audit log, one source of truth.