DX Heroes logo
#ai
#mcp
#security

MCP Tool Permissions: Controlling Which Tools an AI Agent Can Call

Length: 

8 min

Published: 

July 23, 2026

MCP Tool Permissions: Controlling Which Tools an AI Agent Can Call

Connect an AI agent to an MCP server and, by default, it can call every tool that server exposes. Read a file, delete a repository, drop a table, post to a customer channel. As far as the protocol is concerned, they are all just tools in a list, and the agent may call any of them. For a hobby project that is fine. For a regulated enterprise it is the first thing a security review flags, because "the agent can call anything we connected" is not a permission model. It is the absence of one.

We hit this concretely. A regulated enterprise running an MCP Gateway POC with us asked a very specific question. Can we let the agent use most tools freely, block a few outright, and force a human to approve the rest before they run? Yes, but not in the client. The answer runs through the MCP elicitation mechanism and ends up at the gateway, and the parts that are still rough have nothing to do with the spec.

"All or nothing" is not a permission model

A single MCP server can expose twenty or more tools. Wire two or three servers into an agent and it is holding a keyring of fifty capabilities, most of which it will never legitimately need for the task in front of it. Some of those tools are read-only and harmless. Some of them delete, update, or create things that are expensive to get wrong.

The default MCP behaviour treats all of them identically: registered means callable. That collapses two very different questions into one. Can the agent reach this tool, and should it be allowed to fire that tool without a human in the loop. Enterprises need them separated. The shape they ask for is almost always three states per tool:

  • Allowed. The agent calls it freely, with no approval step.
  • Blocked. The agent cannot call it at all, regardless of what it decides it wants.
  • Requires permission. The agent may propose the call, but a human has to approve it before it executes.

That third state is the interesting one, and it is where the protocol-level machinery comes in.

Where elicitation fits

The MCP specification has a mechanism called elicitation: a structured way for a server to pause mid-operation and ask a human for input before continuing. A tool call is normally fire-and-return. Elicitation lets the server stop in the middle, say "before I run this, I need a person to confirm", and pass that request back through the client to the user.

That is exactly what a "requires permission" state needs. Block and allow are static policy, decided up front. "Requires permission" is dynamic: it has to interrupt a running agent, reach a human, wait for a yes or no, and only then let the call through. Elicitation is the protocol's answer to that pause-and-ask pattern.

Prokop Simek, who owns the product and UX thinking here, framed the principle we build against. Read-only tools should auto-approve. They cannot do harm, so making someone confirm them is pure friction. Tools that delete, update, or create things are the other case. There the user, especially one still learning to work with AI, should get to confirm the action first.

Claude Desktop already does a version of this natively, per connector. The problem is that "per connector, in one specific client" is not where an enterprise lives.

How we built it: tool-agnostic and client-agnostic

The requirement from the customer was blunt. Miloš Halda, who implemented it, put it this way:

The client wanted to be able to approve tool calls manually if they configured it that way — to enforce human-in-the-loop. They did not care whether it was enforced on the AI client side or on the Gateway. Claude has this feature by adding metadata to the tool description, but that flag is Claude-specific. In other harnesses, like Cursor or Google Antigravity IDE, a tool call annotated that way would just pass through.

That last sentence is the whole engineering problem in one line. The clean path is a metadata flag on the tool that tells the client "make the user confirm this." It works in Claude. Everywhere else it quietly does nothing. For a customer that has not standardised on a single AI harness, a permission model that only holds in one client is not a permission model. So the approval had to move somewhere every client goes through: the gateway.

Miloš used elicitation to make it client-agnostic:

The MCP specification offers elicitation — forcing communication with a human, either through a form or directly at an external URL. I added the second variant so that the MCP Gateway creates an approval page that only the owner of the MCP server added to the Gateway can access. They have to click approve on the web, and only then can the call be confirmed in the AI client.

So the gateway becomes the enforcement point. A tool marked "requires permission" does not execute on the agent's say-so. The gateway holds the call, creates an approval page, and lets it through only once a human with the right to approve has said yes there. Because the check lives at the gateway rather than in the client, it holds no matter which harness the developer happens to be using that day.

Where the ecosystem is still rough

The implementation depends on an uncomfortable fact: elicitation is in the spec, but real clients lag it. Miloš again:

The problem is that Claude, despite its own documentation, still does not actually have URL elicitation implemented. So I added a fallback: the tool's approval-page URL is handed straight into the chat with the user. The URL comes back in the error a harness returns when it calls a tool without implemented elicitation. The user copies it, opens it in a browser, approves the call there — and on the next call the tool goes through.

It is not the most elegant UX. Copy a URL out of an error, approve in a browser, retry, and we would not pretend otherwise. But it works today across clients that have not caught up to the elicitation spec. The alternative was waiting for every harness to implement a feature its docs already claim. That gap between what the docs say and what actually runs is the kind of thing you only learn by building against it.

Two operating modes, and where the Gateway adds a layer

Per-tool gating is not one feature; it is two operating models, depending on who holds the policy. Matyáš Křeček, who leads how we position the Gateway, drew the line:

It depends on the mode the company runs "per-tool gating" in. Either they let people manage it themselves — every developer sets in their own AI harness that, say, the agent may not call the delete-repository tool on the GitHub MCP. Or — and this is my picture of deploying our Gateway in enterprises — an admin or a security manager sets centrally: these MCPs may be used by developers and agent builders, these tools yes, these no, and these require manual approval every time. Our product also brings a Profiles layer, so one team can have a different per-tool gating than another even when both have the same MCPs exposed.

Those two modes are worlds apart for a security team. Developer-managed gating is convenient and completely unauditable. It depends on every engineer configuring their own harness correctly and never changing it. Centrally-managed gating is the one that survives a review: policy set by someone accountable, applied to everyone. "This tool always needs approval" becomes an organisational rule rather than a personal preference.

The Profiles layer is what makes centrally-managed gating practical at scale. The same set of MCP servers can be exposed to two teams with entirely different per-tool policies. The platform team gets write access to infrastructure tools; the analytics team gets the same servers, read-only. Without that, per-tool gating degrades into either one blunt policy for everyone or an unmanageable pile of per-person exceptions. This is the same control-plane thinking we described in Building MCP Governance for Enterprise and the security baseline in Enterprise MCP Gateway Security. Per-tool permissions are one piece of that larger governance layer.

What to watch out for

If you are building or evaluating per-tool gating, these are the sharp edges we ran into or expect.

UX friction is the failure mode. The fastest way to kill a permission model is to make people approve things that never needed approving. Prokop's read-only-auto-approves rule is not a nice-to-have; it is what keeps the "requires permission" prompt meaningful. If every third tool call pops an approval, people stop reading them and click through on reflex. That is worse than no gate. You now have the illusion of control plus a documented human "approval" on every destructive call.

Agent identity versus user identity. When the gateway asks "who is allowed to approve this," the answer is a person, not the agent. Our approval page is scoped to the owner of the MCP server for exactly this reason. The moment the thing approving the call is another automated step, you have gated nothing.

The audit trail is the point, not a byproduct. "Requires permission" is only worth the friction if every approval is recorded: which tool, which arguments, who approved, when. That record is what a regulated buyer actually asks to see. Gating without an audit log gives you the friction and none of the evidence.

Defaults decide everything. Does an unconfigured tool default to allowed or blocked? For a regulated customer, unknown-means-blocked is the only defensible answer, even though it is the more annoying one on day one. A permission model that fails open is a permission model in name only.

Where this fits

If you are connecting AI agents to real systems, "the agent can call every tool we registered" is the position you have to move off before a security team will sign off. Per-tool gating with three states, allowed, blocked, and requires-permission, is the minimum shape. Elicitation is the protocol mechanism that makes the "ask a human" state real. And where you enforce it, in the client or at the gateway, decides whether the policy holds across every harness your developers use or only the one that happens to implement the spec.

Profiles, audit and the security baseline are covered in Building MCP Governance for Enterprise and Enterprise MCP Gateway Security. For where the market stands, read the MCP governance landscape for early 2026. If your teams need to get fluent in this directly, our AI Security & Governance workshop walks through secure MCP development, human-in-the-loop patterns, and OWASP for LLMs. And if you want to see per-tool gating running against a real workflow, the supported layer is MCP Gateway Enterprise. Get in touch and we will bring the gateway, the permission questions enterprises have actually asked us, and an honest read on which parts are elegant and which are still catching up to the spec.

Want to stay one step ahead?

Don't miss our best insights. No spam, just practical analyses, invitations to exclusive events, and podcast summaries delivered straight to your inbox.