Control MCP Tool Access
Narrow an Access Binding from whole servers down to individual tools, add conditions on tool arguments and responses, and switch a server to a default-deny posture. For the model behind these controls, see Team Access.
Grant specific tools
- Go to Setup → Settings → Access Bindings and edit the binding (or create one — see Create a Team Access Binding).
Under Tools, add one or more rows. Each row names servers and tools:
To express Servers Tools Two tools on one server github-mcpget_issue, list_pull_requestsEvery read-style tool on every server *read_*A whole server (same as no tool rows) github-mcp*Tool names are the per-server names shown in the tool inventory. Simple globs use
*as the only wildcard.- Optionally add subjects beyond teams under Additional subjects — an individual user, an agent ID (a trailing wildcard like
ci-runner-*is allowed), or an agent label likeenv=prod. Save. The right-hand Compiled policies pane shows the exact CEL policies the binding now enforces — the same names appear in Security Events on every decision they make.
Set the binding's decision mode to Audit first and watch Security Events; flip it to its intended mode once the matches look right.
Deny specific tools
Create a binding with decision mode Deny and tool rows naming what to block (e.g. delete_repository, transfer_*). A deny always wins — even if another binding grants the same tool to the same caller.
Add input and output conditions
In the binding editor:
-
Input conditions run on the request, before the tool executes — typically over
object.tool.arguments:string(object.tool.arguments.path).startsWith("/workspace/") -
Output conditions run on the tool's response, before the agent sees it — over
object.mcp.response.*:!object.mcp.response.hasPII
A failed condition always denies, whatever the binding's decision mode. See Policy Context for the available fields in each phase.
Set a default-deny posture per server
With the posture set to deny, a caller can only reach tools that an enabled binding grants to them specifically — one binding's grant never opens that tool to another binding's subjects, even if both bindings cover the same server.
In the UI: Inventory → MCP Servers → Details → Access, and switch Unlisted tools on this server to Deny. The same drawer's Tools tab shows the server's full declared inventory with drift states and per-tool grants, and its Governance tab holds the drift response mode and the scheduled re-scan interval.
Via the API:
curl -X PATCH "$YOUR_WORKSPACE_URL/api/v1/mcp-servers/github-mcp/tool-default" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"action": "deny"}'
Set "action": "allow" to return to the default posture. The change takes effect on the next policy refresh — no restart.
Before enabling deny posture on a busy server, review the tool inventory (below) for tools in active use that no binding grants — those calls start failing the moment the posture applies.
See one identity's access across every server
The views above are server-centric — pick a server, see who can reach it. Setup → Settings → Access Bindings → Access Matrix is the identity-centric complement: pick a team, user, agent, or agent label and see its effective allow/deny across every (server, tool) pair fleet-wide, with the binding (or the server's default posture) that decided each one. Use it to answer "what can this identity actually do" without checking every server one at a time.
Review the tool inventory
The tool inventory lists every tool each connected MCP server declares — including tools that have never been called, which usage views can't show. In the UI, it's on the Tools tab of a server's details drawer — reachable from Inventory → MCP Servers → Registration → Details (as above) or, for any role, from Inventory → MCP Servers → Observed → (click a server). Via the API:
curl "$YOUR_WORKSPACE_URL/api/v1/tools?server=github-mcp" \
-H "Authorization: Bearer $ADMIN_TOKEN"
Each entry shows the tool's drift state, call count, last-called time, and which binding subjects are granted it. Filters: ?status=never_called, ?status=drifted, ?status=new, and ?q=<substring>.
Verify
- As a granted caller, invoke a selected tool — it succeeds; the Security Events entry records the binding.
- Invoke a tool outside the grant on a deny-posture server — it fails with "tool not granted by any access binding", policy
mcptooldefault:<server>. - Violate an input condition (e.g. a path outside the allowed root) — the call is denied with the condition's message, policy
mcpaccessbinding:<binding>:input.
See also
- Team Access — the model, compiled-policy names, and precedence
- Rate-limit MCP tools
- MCP Governance — tool pinning and drift response