MCP permission rules: support argument matching (analogous to Bash(cmd *))
Summary
Claude Code's MCP permission grammar currently supports only server/tool granularity:
mcp__<server>mcp__<server>__*mcp__<server>__<tool>
There is no way to match on tool arguments, analogous to Bash(cmd *) or WebFetch(domain:...). Requesting something like:
mcp__gateway__gateway_invoke_tool(name:gmail_*)
mcp__gateway__gateway_invoke_tool(name:*_delete_*)
Motivation
Gateway / meta-tool patterns — including Claude Code's own internal deferred-tools/ToolSearch design — collapse many underlying tools into one permission name, destroying per-tool approval UX.
Our use case: we run an MCP gateway that lazy-loads ~300 tools behind three meta-tools (gateway_list_tools, gateway_describe_tool, gateway_invoke_tool). After this collapse, every tool call shows up as gateway_invoke_tool regardless of whether the inner tool is gmail_search_messages or gmail_delete_message — so users can't grant fine-grained approvals.
Workaround
We've shipped a PreToolUse hook that reads tool_input.name and returns allow/ask/deny per inner tool, with prompt text like "Allow gateway_invoke_tool to call gmail_delete_message?". It works, but hooks are heavier than declarative permission rules and require us to reimplement prompt UX.
Proposal
Extend MCP permission rule grammar to accept a parenthesized specifier that matches structured tool_input fields, at minimum name:<glob>. Ideally the syntax mirrors existing tools (Bash(cmd *)), so:
mcp__gateway__gateway_invoke_tool(name:gmail_*) # allow all gmail tools
mcp__gateway__gateway_invoke_tool(name:*_delete_*) # ask before any delete-like tool
Docs reference
Current MCP permission rule grammar: https://code.claude.com/docs/en/permissions#mcp
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗