[FEATURE] permissions.deny rules do not apply to MCP tools, allowing file access bypass
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Severity: Security - Access Control Bypass
Description:
When a file path is denied via settings.local.json permissions.deny (e.g., "Read(./application.yml)"), the built-in Read tool is correctly
blocked. However, MCP server tools that perform equivalent file access operations (e.g., Serena's read_file, search_for_pattern) are not subject
to the same deny rules, allowing the denied file to be read through an alternative tool path.
Steps to Reproduce:
- Add "Read(./application.yml)" to permissions.deny in .claude/settings.local.json
- Attempt to read application.yml using the built-in Read tool → Blocked (expected)
- Attempt to read the same file using an MCP tool (e.g., mcp__plugin_serena_serena__read_file with relative_path: "application.yml") → Allowed
(unexpected)
Expected Behavior:
Deny rules should enforce file-path-level access control regardless of which tool (built-in or MCP) is used to access the file. When
Read(./application.yml) is denied, any tool that reads that file path should be blocked.
Actual Behavior:
Only the built-in Read tool respects the deny rule. MCP tools with file read capabilities bypass the restriction entirely.
Impact:
Users relying on permissions.deny to protect sensitive files (database credentials in application.yml, API keys in *.properties, .env files,
etc.) have a false sense of security. Any enabled MCP server with file access tools can read these files without restriction.
Suggested Fix:
Implement file-path-level deny enforcement at the permission layer, intercepting all tool calls (including MCP) that resolve to a denied file
path. Alternatively, provide a dedicated deny syntax for MCP tools (e.g., mcp__*__read_file(./application.yml)) so users can explicitly block
MCP access to sensitive paths.
Workaround:
Configure file exclusions at the MCP server level independently (e.g., Serena's ignored_paths in project.yml, .gitignore with
ignore_all_files_in_gitignore: true). This requires manual synchronization with the Claude Code deny list and is error-prone.
Proposed Solution
Suggested Fix:
Implement file-path-level deny enforcement at the permission layer, intercepting all tool calls (including MCP) that resolve to a denied file
path. Alternatively, provide a dedicated deny syntax for MCP tools (e.g., mcp__*__read_file(./application.yml)) so users can explicitly block
MCP access to sensitive paths
Alternative Solutions
_No response_
Priority
High - Significant impact on productivity
Feature Category
CLI commands and flags
Use Case Example
_No response_
Additional Context
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗