MCP security: govern which tools an agent may call
An MCP server turns a model into something that can act. Governance is the layer that decides which of those actions may happen, and leaves evidence behind either way.
The failure mode worth preventing
Most MCP incidents are not exotic. A tool that can delete, deploy or send gets discovered by an agent that was only asked a question, and it acts on an instruction that came from a document, a web page or a ticket. There is rarely a human in the loop and rarely a record of what was proposed.
The fix has three parts: know the tool inventory the runtime actually declares, decide per call rather than per server, and keep the decision.
What Descles does today
Tool calls in the model response are parsed on the request path. A rule can allow, deny or require approval, scoped to the tool or to specific argument values. A denied call is stripped before the runtime sees it; an approval holds it until a named operator decides.
- Inventory: every tool a runtime declares appears in the console with its effective policy status.
- Per-call decisions rather than a flat allowlist per connection.
- Argument scoping for the keys that matter — paths, commands, URLs, queries.
- Approvals bound to the exact parameters and consumed once.
- A signed record of the decision alongside the trace.
Start with the inventory, not a big policy
Load the starter policy, look at what your runtime declares, and mark only the tools that can destroy or publish. An inventory you have read is worth more than a policy nobody can explain — and unlisted tools are allowed, so the defaults matter.
defaults:
tools:
shell.rm: deny # nobody deletes files through an agent
shell.kubectl.delete: require_approval
require_approval:
- github.create_issueQuestions
Does this work with a self-hosted MCP server?
The policy surface is runtime-independent: rules match the tool names your agent declares. A self-hosted MCP server behind an integrated runtime gets the same treatment as a hosted one.
Is a denied tool call enough to stop a determined agent?
It stops that call, because the runtime never receives it. An agent that can reach the same capability through another path is governed by the rule for that path — keep the inventory honest and put a sandbox behind anything you cannot afford to lose.
Are tool results verified?
No, and the difference is stated rather than blurred: a runtime-reported result is evidence that the runtime reported it, not independent proof the local action succeeded.
Related
- Agent approvals — Autonomy is fine until the tool call is `kubectl delete pod checkout-api` in production. Approval puts one named person in that gap, and only for the calls that need it.
- AI agent control plane — A control plane sits beside the data plane: your agents keep talking to their model providers, and the control plane decides who they are, what they may spend, which tool calls they may make, who reviews the risky ones, and what record survives afterwards.
- Claude Code governance — A coding agent with a shell is the most useful and most dangerous agent most teams run. Descles keeps the Anthropic credential off laptops and puts a policy in front of the tool calls it proposes.
- Documentation — endpoints, provider keys, and the full policy reference.
Try it on one agent: 1,000 governed requests free, no card. Request packs add 25,000 more to the same workspace. Questions: outreach@descles.com. See also terms and privacy.