anthropics / anthropics/claude-code
[BUG] `claude mcp list` ignores allowedMcpServers/deniedMcpServers — empty allowlist still returns every server connected
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
`claude mcp list` doesn't do a MCP policy check. Passing an empty allowlist which should admit no servers returns the full server list, health-checked and connected. Non-empty `deniedMcpServers` does the same thing, the denied servers are still listed and contacted.
I understand that both keys are honored from managed settings only. The problem is that the listing gives no indication of it. It looks the same whether a policy is in effect, inert, or missing. If I run `claude mcp list` to confirm my MCP policy as applied I get a fully-connected list either way, and incorrectly conclude the policy is not working or, worse, that it is.
For a security control an empty allowlist showing a fully-connected list is bad and wrong.
### What Should Happen?
Either:
1. `claude mcp list` applies the same allow/deny policy as the session does and omits or marks servers the policy blocks; or
2. the listing reports explicitly which settings source is in effect and which servers are policy-blocked so the output distinguishes "policy applied" from "policy ignored".
At minimum an empty `allowedMcpServers` should produce a different output than having no policy.
### Error Messages/Logs
```shell
No error is produced — that is the issue. Abbreviated output of the repro command
below (all servers listed and contacted despite the empty allowlist):
claude.ai Claude Docs: https://api.anthropic.com/v1/pages/mcp - Connected
claude.ai Google Drive: https://drivemcp.googleapis.com/mcp/v1 - Connected
claude.ai Google Calendar: https://calendarmcp.googleapis.com/mcp/v1 - Connected
claude.ai Gmail: https://gmailmcp.googleapis.com/mcp/v1 - Connected
plugin:engineering:linear: https://mcp.linear.app/mcp (HTTP) - Needs authentication
plugin:engineering:atlassian: https://mcp.atlassian.com/v1/mcp (HTTP) - Needs authentication
plugin:engineering:notion: https://mcp.notion.com/mcp (HTTP) - Needs authentication
[...]
```
### Steps to Reproduce
1. Have at least one MCP server configured (any claude.ai connector, or a plugin that declares servers in .mcp.json).
2. Run:
claude --settings '{"allowedMcpServers": []}' mcp list
Expected: no servers admitted.
Actual: every server is listed and health-checked, exactly as with no policy.
3. Run the same with a denylist naming servers you can see in step 2:
claude --settings '{"deniedMcpServers": [""]}' mcp list
Actual: the named servers are still listed and still contacted.
4. Repeat with the settings placed in a managed-settings.json directory pointed at by CLAUDE_CODE_MANAGED_SETTINGS_PATH — same result.
### Claude Model
None
### Is this a regression?
I don't know
### Last Working Version
_No response_
### Claude Code Version
2.1.274
### Platform
Anthropic API
### Operating System
macOS
### Terminal/Shell
iTerm2
### Additional Information
Found while trying to stop a synced plugin from contacting third-party MCP endpoints. The plugin "engineering" (marketplace "knowledge-work-plugins") declares ten remote servers in .mcp.json, eight with live URLs, and Claude Code health-checks all of them at startup and on /mcp before any has been connected or authenticated. `claude mcp list` was how I tried to verify whether a denylist had taken effect, which is how I hit this.
Filing that startup-connection behavior separately as a feature request, since this template is for a single bug.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing `claude --settings '{"allowedMcpServers": []}' mcp list` and the equivalent `deniedMcpServers` command, then compare them with no policy and with managed-settings.json via CLAUDE_CODE_MANAGED_SETTINGS_PATH. Trace the `claude mcp list` entry point and MCP policy handling. Done means blocked servers are omitted or clearly marked, the active settings source is distinguishable, and blocked servers are not contacted.
Written by the indexing model from the issue text.
Assessment
- Domain
- authorization, cli, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100