Allow MCP servers to declare tools as read-only vs read-write for permission control
Problem
When configuring MCP server permissions, users currently have to allowlist every single read-only tool individually. For example, with Grafana, Linear, Jarvis, and other MCP servers, I end up with 80+ individual permission entries like:
"mcp__grafana__get_dashboard_by_uid",
"mcp__grafana__list_datasources",
"mcp__linear__get_issue",
"mcp__linear__list_issues",
"mcp__jarvis__*",
...
I want to give Claude Code universal permission to use read-only tools (queries, fetches, lists) while still requiring approval for write operations (create, update, delete, send). But there's no way to express this today.
Proposed Solution
Allow MCP servers to annotate tools with a readOnly: true/false property (or similar metadata like accessLevel: "read" | "write"). Then expose a permission rule that lets users auto-allow all read-only tools:
{
"permissions": {
"allow": [
"mcp__*[readOnly]"
]
}
}
Or alternatively, a top-level setting:
{
"permissions": {
"autoAllowReadOnlyMcpTools": true
}
}
Why This Matters
- Security: Users want a simple way to say "reads are fine, writes need approval" without maintaining a massive allowlist
- Usability: Every new read-only tool added by an MCP server requires manually updating the permission config
- Convention: The MCP spec could benefit from a standard way for servers to declare tool side-effects, and Claude Code could lead this convention
Alternatives Considered
- Wildcards like
mcp__grafana__get_*help but are fragile (not all read tools start withget_) and still require per-server rules mcp__*is too broad since it allows writes too
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗