What happens after someone saves a restriction rule
An admin ticks a tool in the Governance screen, saves, and closes the tab. Whether that rule holds depends on how many places a tool call can enter from. A rule that only filtered a tool list would be a suggestion. A rule that only ran at execution would let the model waste turns on tools it can never call. MCP tool restriction enforcement is everything in between.
This post follows one rule from the moment it is written to the last check before the request leaves. It names each place Elaichi checks the rule. It ends with the check that reads the fully resolved outbound URL rather than the tool's name.
A restriction is Elaichi's rule about which connectors and tools a role or a member may reach. It is not a permission, which is what a role lets a member do. It is not a share, which is who may use a given connection or toolbox. Keeping those three layers apart is most of understanding what follows.
What does MCP tool restriction enforcement check first, the name or the operation?
It checks the operation for allow rules, and either the name or the operation for blocks. When the rule is saved, Elaichi looks each named connector and tool up in the organization's catalog. A name it cannot find is refused with a 400. Each tool's operation, meaning its resource and method, is stored beside the name.
That stored operation is what MCP tool restriction enforcement uses afterwards. An allow rule matches a tool only by its stored operation. A block rule matches by name or by operation.
The asymmetry is deliberate. A connector's tool_name documentation entries replace the tool names Elaichi advertises, matched by resource and method. A tool's label is therefore something whoever edits the connector controls. A block written against a label would be escaped by a rename; a block written against the operation would not. Why blocks match tool names but allows don't works through that choice.
A rule has a mode, allow or block, and a target. It carries a list of whole connectors and a list of single tools, each tool written as a connector and tool-name pair. One rule can name connectors from any number of vendors, up to 1000 connectors and 1000 tools.
Who the rule applies to, and who it cannot
In Elaichi, restriction targets are role or user only; the organization default is the absence of a rule, which means allow everything. A rule written on a role applies to every member who holds it. To keep a team's members off a tool, write the rule on the role they hold, or write one rule per member.
A member is governed by two layers at once: the rules on their role and the rules aimed at them personally. A connector or tool is reachable only when both layers admit it. A personal rule can narrow what a role allows. It never replaces or loosens a role rule. Within each layer, allow rules merge into one allowlist and block rules into one blocklist, and a block always beats an allow.
The empty allow rule is the trap. An allow rule turns on the allowlist for its layer just by existing, whatever it names. An allow rule that names nothing blocks every connector and tool for its target. Its summary says so: "Allows nothing. Every connector and tool is blocked."
The mirror of that trap is a block-only layer. A layer with only block rules has no allowlist, so everything it does not block passes. Blocking some of an app's write tools leaves every write tool the rule does not name reachable. On Microsoft Intune, msintune_managed_devices_execute_action stays reachable unless a rule names it.
Where the check runs
Restrictions are enforced through the same evaluators everywhere a member can reach a connector or tool. The list of enforcement points is longer than four:
- Listing connectors and their tools, in the console, the REST API and the AI catalog operations.
- Connecting or reconnecting an account.
- Forking a connector.
- Saving a toolbox entry or a synthetic tool step.
- Advertising tools to a client: MCP
tools/list,search_toolsand toolbox views. - Executing any tool call.
- The final outbound-request guard.
- Opening a stored tool file that came out of a now-restricted tool.
A toolbox entry or synthetic tool step cannot be saved naming a tool restricted for the person saving it. The write is refused: "Tool <name> (<connector>) is restricted for your account". An entry saved before the restriction existed is not refused again on later saves. It is withheld when the toolbox resolves, and refused when called.
At advertise time, a restricted tool is left out of tools/list and out of a toolbox's runnable tools. The check runs for the person using the toolbox, on the catalog tool's own name and operation. An entry's rename, schema override or frozen parameters change nothing.
Search is the one place a restricted tool is still named. search_tools searches the tools the caller may run. It then ranks their restricted tools separately against the same query and returns those matches by name, flagged restricted and with a restricted_count. A flagged row carries no description, no schema and no way to call the tool. A connector blocked whole shows as one row for the connector. The person can see what to ask for.
Clients and admin platforms have controls of their own, and they sit elsewhere. Claude's connector tool permissions take Always allow, Needs approval or Blocked. Each setting applies to a whole connector, a category of its tools or a single tool (Anthropic's help page, checked October 2026). Cursor's beforeMCPExecution hook runs before each MCP tool call and answers allow, deny or ask (Cursor's hooks documentation, checked October 2026). Power Platform advanced connector policies let an admin block an entire MCP server. Microsoft says granular control over individual MCP tools within an MCP server is currently not available there (Microsoft's documentation, checked October 2026). Each of those controls runs on the client or on the admin's own platform. Elaichi's checks run on the endpoint, so they hold whatever client sends the call.
Every call passes one clamp, evaluated for the caller
Every connected-tool call Elaichi runs passes one restriction clamp, evaluated for the member the call acts as. MCP tools/call and execute_tool, toolbox.execute, the in-app assistant and each step of a synthetic tool all go through the same executor. That executor checks the member's role and personal rules before the connection is used.
Two consequences follow. Restrictions bind whatever client or automation sends the call, not just the console. And they narrow what a member can do through a connection, whatever the credential behind it could do upstream. A toolbox shared at use runs its entries on the delegator's connection, but the restrictions applied are the caller's own. A restriction that blocks a tool for a member blocks it inside every toolbox entry for that member, frozen or not. Restrictions match the catalog tool, not the entry's name.
A restriction is also the wrong instrument for closing the unfrozen path around a locked argument. It would block the frozen entry too. Close that path by not sharing the connection. Locking AI agent tool arguments covers the case in full.
Inside a declared fork chain, Elaichi compares what a called tool really sends with what each blocked upstream tool sends. It compares the HTTP method, the path and the host. Renaming a tool does not escape a block written against the original, and neither does renaming the resource and method keys inside a fork's config.
The last check: the substituted outbound URL
As a final step before a call leaves, Elaichi compares the fully resolved outbound URL with the block rules that name tool-level HTTP operations. Those rules are read from the called connector and its declared ancestors. Every redirect hop is compared the same way. A match is refused.
The word to notice is resolved. By this point path parameters have been substituted and the URL is the one that will actually be sent. The guard never refuses a request merely for reaching a host; a whole-connector block is enforced earlier, before the request is built. Redirect hops are checked too, so a 302 cannot carry a call onto a blocked operation.
A block on a connector also blocks every fork that declares descent from it, including forks of forks. The lineage is walked toward its root for up to 8 hops. A chain that is longer, loops or is broken is refused outright rather than checked partially. Lineage only ever adds blocks: an allow rule naming a connector does not admit its forks, which have to be named on the allowlist themselves.
What the guard does not catch
For restrictions, a connector's identity is its own slug plus its declared fork lineage. The host it calls is deliberately not part of that identity. A connector built from scratch against the same API as a blocked connector is not caught by that block.
This is why connector:create is the only permission Elaichi flags as high trust. The role editor shows a "High trust" tag on it, and its description warns that connector governance binds the connector, not the host it calls. Elaichi checks a custom connector's config for shape, not for where it points. Among the system roles, only Org Owner and Org Admin hold connector:create.
So a restriction program is only as tight as the list of people who can author connectors. If that list is wide, a block on one Salesforce connector does not stop a new connector aimed at Salesforce.
When a change takes effect
A member's roles, teams, permissions and resolved restrictions are cached for 60 seconds. The cache keys include a per-organization epoch, and every role, membership, team, restriction and grant change writes a new epoch. A change reaches every surface within about two minutes in the worst case at a remote point of presence. That covers MCP, the console, the REST API and the in-app assistant. Write the rule, then wait, then test.
That is slower than two other things people confuse it with. Revoking a grant, removing or suspending a member, revoking a share and disconnecting an account all take effect on the caller's next call. Each MCP request re-reads the grant, and reads toolboxes, shares and connections fresh.
The resolver fails closed. If it gets an answer in a shape it does not recognize, it refuses the call rather than allowing it. That happens, for example, when an organization's data store is still running older code during a deploy. The refusal is not cached.
What the refused caller is told
A refused tool call tells the caller where the block comes from, their role or their own account. The wording is "This tool is restricted for your role by an organization policy", or "for your account". It adds that an admin can lift it through an access request. It does not name the rule, who wrote it, why, or what else it covers.
Filing that request needs no permission and is always for the caller themselves. From an AI client, a grant holding mcp:read or mcp:tools can file one; it does not need write access. A request for one tool on a connector that is blocked whole for the requester is refused. The message names the connector to ask for instead.
Approving is a person's decision in the console, under Governance, then Access requests. It needs member:manage plus a fresh identity check, and no AI surface can decide a request. Approving a connector or tool request creates an access grant for that one person: the role's rules are never edited, and nobody else's access changes. A grant only lifts role rules. It never lifts a rule written for the member personally.
When you do not need any of this
If your whole organization is three people who all get the same apps, restrictions buy you nothing. Everyone holds the same role, and no rule reaches anyone differently. When no restriction rule reaches a member, nothing is restricted for them: every connector and tool passes the check. The honest starting point is one role and no rules, then a rule the first time two people need different reach.
The second case is an app whose own permission model already does the work. A per-person OAuth connection reaches only what that person can reach in the app. If an app's roles already stop a support agent deleting an account, a restriction on top is a second place to maintain the same decision. Restrict one AI tool or the whole app? walks through which cases are worth a rule.
For the wider picture of who decides what across roles, shares and the audit trail, read MCP governance. For the connectors a rule can name, see the connector catalog.