[BUG] Server-side MCP schema caching causes ghost tools for disconnected servers
[BUG] Server-side MCP schema caching causes ghost tools for disconnected servers
What's Wrong?
MCP tool definitions persist in assistant context after servers are disconnected/removed from .mcp.json. Tools appear in <functions> but fail when called with "No such tool available".
Critical finding: No local schema cache exists anywhere on disk. Only permissions.allow contains tool names (no schemas), yet full schemas appear in context. This indicates Anthropic API is caching and injecting schemas server-side based on permissions.allow entries.
What Should Happen?
Tool definitions should only appear for currently connected servers. Disconnected servers' tools should not inject into context regardless of permissions.allow.
Reproduction
- Connect MCP server (e.g., playwright) - tools load successfully
- Approve tool usage - added to
permissions.allow - Remove server from
.mcp.json- server disconnects - Start new session - Ghost tools still appear in
<functions> - Try to call tool - Fails:
"No such tool available"
Evidence
No local cache exists:
find ~/.claude -name "*schema*" -o -name "*cache*" # Nothing found
find ~/Library/Caches/claude-cli-nodejs/ -type f # Only connection logs
find ~/Library/Application\ Support/Claude/ -name "*.json" # No schemas
Only reference is tool names in permissions:
// .claude/settings.local.json
"permissions": {
"allow": ["mcp__playwright__browser_navigate"] // Just the name
}
Yet full schemas appear in assistant context:
// From <functions> section:
{
"name": "mcp__playwright__browser_navigate",
"description": "Navigate to URL", // Full schema present!
"parameters": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": { "url": { "type": "string" } }
}
}
Server status from logs:
{"debug": "Connection established with capabilities: {\"hasTools\":true,...}"}
{"debug": "Server is disabled, skipping automatic reconnection"}
// Yet schemas persist in next session
Debug log shows permission-based injection:
[DEBUG] Applying permission update: Adding 120 allow rule(s)
["mcp__playwright__browser_navigate","mcp__zen__clink",...]
Fix
Remove ghost tools from permissions.allow in .claude/settings.local.json. Schemas immediately disappear from context (~2,600 tokens freed in my case).
Impact
- Token waste: ~100 tokens per ghost tool × number of disconnected servers
- Confusing UX: Tools appear available but fail when called
- Related to: #6320, #6834, #7328 (same root cause: permission-based injection vs connection-based)
Environment
- Version: 2.0.19
- Platform: Anthropic API
- OS: macOS (Darwin 25.1.0)
- Terminal: Cursor
- Model: Sonnet 4.5 (claude-sonnet-4-5-20250929)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗