Subagents (Agent tool) cannot reach the LSP tool, contradicting documented MCP/tool inheritance

Status Open
Maintainer reply ✓ Yes — bcherny
Activity 4 comments · opened Jul 9, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Description

The LSP tool (provided via the official LSP plugins, e.g. pyright-lsp@claude-plugins-official, rust-analyzer-lsp@claude-plugins-official, clangd-lsp@claude-plugins-official) is available and fully functional in the main conversation thread, but is completely unreachable from any subagent spawned via the Agent tool — built-in or custom, regardless of tools/disallowedTools configuration.

This contradicts the sub-agents documentation, which states:

Subagents inherit the internal tools and MCP tools available in the main conversation by default.

Repro

  1. Enable an LSP plugin (e.g. pyright-lsp) in settings.json enabledPlugins, in a project with a supported language file.
  2. In the main thread, confirm the tool is reachable:

``
ToolSearch({query: "select:LSP", max_results: 5})
`
→ returns the full
LSP function schema, and calling it (e.g. operation: "documentSymbol"`) works correctly.

  1. Spawn a plain, unmodified subagent via the Agent tool (e.g. subagent_type: "general-purpose", no custom .claude/agents/*.md override, no tools/disallowedTools restriction) and have it run the identical call:

``
ToolSearch({query: "select:LSP", max_results: 5})
`
→ returns
"No matching deferred tools found"`.

Also reproduced with a custom subagent definition at .claude/agents/Explore.md (overriding the built-in Explore agent by name) using a disallowedTools denylist that does not mention LSP — same result, LSP is absent from that subagent's ToolSearch results.

Expected

Per the documented default, a subagent with no explicit tool restriction on LSP should be able to find and call it via ToolSearch, the same as the main thread.

Actual

LSP is never present in a subagent's deferred-tool registry, in any subagent context tested (built-in general-purpose, built-in Explore override, no restriction present in tools/disallowedTools).

Impact

This blocks any workflow that wants subagents (e.g. a read-only "Explore"/code-search subagent) to prefer LSP-based code navigation (documentSymbol, hover, goToDefinition, etc.) over grep/text search — the tool is architecturally unavailable to them, so prompt-level instructions to "try LSP first" cannot succeed no matter how the subagent is configured.

Environment

  • Platform: Linux
  • LSP plugins: pyright-lsp@claude-plugins-official, rust-analyzer-lsp@claude-plugins-official, clangd-lsp@claude-plugins-official (all enabled in settings.json)
  • Reproduced via both the top-level Agent tool with subagent_type: "general-purpose" (default config, no overrides) and a custom .claude/agents/Explore.md override

View original on GitHub ↗

4 Comments

ChrisKlug · 1 month ago

Reproduced on macOS with csharp-lsp@claude-plugins-official, with one refinement that may narrow this down: for us the failure is specific to background subagents (run_in_background: true). Foreground subagents load and use LSP without issue.

Evidence matrix (Claude Code 2.1.205; also reproduced on 2.1.202/2.1.203)

| Context | ToolSearch("select:LSP") | MCP-server tools via ToolSearch |
|---|---|---|
| Main thread | ✅ schema returned, tool works end-to-end | ✅ |
| Foreground subagent (run_in_background: false) | ✅ schema returned first try, verified working (documentSymbol, workspaceSymbol, findReferences return real results) | n/a (agent had explicit tools: list) |
| Background subagent (run_in_background: true) | ❌ "No matching deferred tools found" | ✅ all 16 tools of a project-local stdio MCP server discoverable and loadable |

Details:

  • The background failure is 100% reproducible: 9+ attempts across multiple background agents and three agent types — a custom agent with an explicit tools: list that includes LSP, built-in general-purpose, and an unrestricted (tools: *) custom agent. Not a startup race: it still fails when retried well after LSP was warmed up elsewhere in the same session.
  • Foreground vs. background was tested in the same session with the identical diagnostic prompt on the same agent type: foreground succeeds, background fails.
  • ENABLE_LSP_TOOL=1 in settings.json env makes no difference (tested across a full restart).
  • The MCP column is the interesting contrast: deferred-tool discovery itself works in background subagents — a stdio MCP server's tools are all present and loadable there. Only the native/plugin LSP tool is missing from the background deferred-tool registry.

So at least on macOS the inheritance break appears scoped to the plugin-provided LSP tool × background execution, rather than subagents generally. (If the original report's subagents were foreground, Linux may behave differently — worth confirming which mode was used.)

Environment: macOS 26.5.2 (Darwin 25.5.0), Claude Code 2.1.205, csharp-lsp plugin 1.0.0, csharp-ls 0.24.0.

sean-abbott · 1 month ago

They were background

bbias · 1 month ago

Reproduced on macOS with a clangd plugin (not just csharp-ls), confirming the bug isn't language-server-specific.

  • Claude Code: 2.1.207 · macOS (Darwin 25.5.0) · Homebrew clangd 22.1.8 via a local .lsp.json plugin
  • Main loop: LSP hover/goToDefinition work end-to-end ✅
  • Background subagent (run_in_background: true, the Agent tool default) — ToolSearch("select:LSP")"No matching deferred tools found"; fails across a full restart, on a custom agent whose frontmatter tools: explicitly lists LSP, on general-purpose, and on an unrestricted tools: * agent ❌
  • Foreground subagent (run_in_background: false), same agent type / same session — LSP hover succeeds on the first call, no ToolSearch needed ✅

So the foreground/background split reported above reproduces exactly with a second, unrelated language server on 2.1.207. The run_in_background: false workaround is reliable.

bcherny collaborator · 14 days ago

Reproduced on 2.1.233 (Linux, pyright-lsp@claude-plugins-official): the LSP tool works in the main conversation (hover returns results), but a subagent spawned via the Agent tool reports no LSP tool available, even via ToolSearch.

This is intended behavior from two changes rather than broken inheritance: subagents now run in the background by default (since ~2.1.198, about when you filed this), and background subagents keep every MCP tool but only a fixed set of built-in tools — LSP isn't in that set, and listing it in a subagent's tools field doesn't add it back. In interactive sessions, regular subagent spawns now always run in the background, so LSP is effectively main-conversation-only there. In headless claude -p, a foreground subagent still gets the LSP tool — verified hover works on 2.1.233.

You were right that the docs contradicted this at the time. They've since been updated: sub-agents → Available tools now documents both tool filters, including the exact background tool list.

We agree the result is confusing — we're considering whether the read-only LSP tool should stay available to background subagents, and adding a note to the LSP plugin docs. Leaving this open to track that.

🤖 Generated with Claude Code