[BUG] Local stdio MCP server tools never registered as deferred tools despite successful connection (v2.1.81)

Resolved 💬 10 comments Opened Mar 21, 2026 by mmayasaurus Closed Mar 30, 2026

Description

Local stdio MCP servers connect successfully and are visible internally to Claude Code, but their tools are never registered as deferred tools and cannot be discovered or called by the model. Cloud MCP servers (claude.ai Gmail, Vercel, Notion, etc.) work perfectly in the same session.

This is not specific to any one MCP server — I've reproduced it with both @modelcontextprotocol/server-filesystem@0.6.2 and @modelcontextprotocol/server-memory. No local stdio MCP server registers tools.

Environment

  • Claude Code version: 2.1.81 (latest on npm as of 2026-03-20)
  • Platform: macOS (Darwin 25.3.0, Apple Silicon)
  • Shell: zsh
  • Node.js: v22.x (npx 11.12.0)
  • MCP server tested: @modelcontextprotocol/server-filesystem@0.6.2 (also @modelcontextprotocol/server-memory)

Steps to Reproduce

  1. Add a local stdio MCP server to .mcp.json in the project root:

``json
{
"mcpServers": {
"obsidian-full-vault": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem@0.6.2", "/path/to/directory"]
}
}
}
``

  1. Ensure .claude/settings.local.json has:

``json
{
"enableAllProjectMcpServers": true,
"enabledMcpjsonServers": ["obsidian-full-vault"]
}
``

  1. Start Claude Code (claude).
  1. Run claude mcp list — server shows ✓ Connected.
  1. In the session, use ToolSearch to look for mcp__obsidianreturns nothing.
  1. Try ListMcpResourcesTool(server: "obsidian-full-vault")succeeds, proving Claude Code sees the server internally.
  1. No mcp__obsidian-full-vault__* tools are available to the model.

Expected Behavior

The server's 9 tools should appear as deferred tools discoverable via ToolSearch, with names like mcp__obsidian-full-vault__read_file, mcp__obsidian-full-vault__list_allowed_directories, etc.

Actual Behavior

  • claude mcp list✓ Connected
  • claude mcp get obsidian-full-vault → shows correct config, scope "Project config (shared via .mcp.json)"
  • ListMcpResourcesTool(server: "obsidian-full-vault") → succeeds (returns empty resources, which is correct for filesystem server)
  • ToolSearch("mcp__obsidian")no results
  • The model cannot call any tool from the server

Key Evidence: This Affects ALL Local Stdio Servers

To rule out a server-specific issue, I added @modelcontextprotocol/server-memory as a second test server:

claude mcp add -s project test-memory -- npx -y @modelcontextprotocol/server-memory
  • claude mcp list✓ Connected
  • ToolSearch("mcp__test-memory")no results

Meanwhile, cloud MCP servers work fine in the same session:

  • ToolSearch("mcp__claude_ai_Gmail") → returns tools, can fetch schemas, can call them

Server Verification

Direct stdio test confirms the server returns all 9 tools correctly:

printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}\n{"jsonrpc":"2.0","method":"notifications/initialized"}\n{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}\n' | npx -y @modelcontextprotocol/server-filesystem@0.6.2 /path/to/directory

Returns: read_file, read_multiple_files, write_file, create_directory, list_directory, move_file, search_files, get_file_info, list_allowed_directories

What I've Tried (All Failed)

| Attempt | Result |
|---------|--------|
| Server in .mcp.json (project scope) + enableAllProjectMcpServers: true | Connected, tools NOT registered |
| Server added via claude mcp add -s user (user scope) | Connected, tools NOT registered |
| Server added via claude mcp add -s local (local scope) | Connected, tools NOT registered |
| enabledMcpjsonServers in both settings.local.json and ~/.claude.json project entry | No effect |
| hasTrustDialogAccepted: true in ~/.claude.json project entry | No effect |
| Pre-adding permissions (mcp__obsidian-full-vault__read_file, etc.) to allow list | No effect |
| additionalDirectories in settings | No effect |
| claude mcp reset-project-choices | Reset approval state, but tools still not registered after restart |
| Multiple session restarts | No effect |
| Testing with a completely different server (server-memory) | Same behavior — proves systemic |

Scope Behavior Difference

Interesting detail: ListMcpResourcesTool sees project-scope servers but NOT user-scope servers:

  • ListMcpResourcesTool(server: "obsidian-full-vault") (project scope) → succeeds
  • ListMcpResourcesTool(server: "obsidian-full-vault-user") (user scope) → "Server not found"

This suggests user-scope stdio servers may not even fully initialize in the session.

Related Issues

This appears to be the same underlying bug reported in many issues, all of which were closed as duplicates or "not planned" without a fix:

  • #24762 — MCP Tools Not Available to AI Despite Server Running (OPEN, canonical)
  • #16371 — Non-plugin MCP servers: tools not registered (closed as duplicate)
  • #27159 — MCP tool not available despite successful registration (closed as duplicate of #24762)
  • #25894 — MCP tools not loaded as deferred tools (closed as duplicate)
  • #12474 — MCP server tools not loaded into AI function set (closed as duplicate)
  • #5241 — MCP Tools Not Registering Despite Successful Connection
  • #3426 — Claude Code fails to expose MCP tools to AI sessions
  • #2682 — MCP Tools Not Available in Conversation Interface

I'm filing a new issue because:

  1. The existing canonical issue #24762 is about Claude Desktop, not Claude Code CLI
  2. I have more detailed diagnostic evidence than any existing report
  3. I can confirm this affects v2.1.81 (latest) on macOS with the CLI specifically
  4. I've isolated that the issue is systemic (all local stdio servers) not server-specific

Summary

Claude Code v2.1.81 can connect to local stdio MCP servers and sees them internally (via ListMcpResourcesTool), but never registers their tools as deferred tools for the model to use. Cloud MCP servers work fine. This makes all local/project MCP servers unusable.

View original on GitHub ↗

This issue has 10 comments on GitHub. Read the full discussion on GitHub ↗