Skip to content

Chat backend (SDK createQuery) never surfaces tools from slow-connecting plugin MCP servers, despite /mcp reporting them connected #5605

Open

Description

@orchidautomation

Summary

A plugin MCP server with a large tool count (95 tools) shows as connected in the native /mcp status view (run via an interactive claude CLI terminal), but its tools are never callable from a chat session driven by t3code's GUI backend. ToolSearch/the deferred-tool index never contains any of that server's tools for the life of the session, even after the server is confirmed connected. Smaller plugin servers on the same account (2, 13, 32, 47 tools) work fine from the same GUI session.

Environment

  • t3code desktop, chat session backed by apps/server/src/provider/Layers/ClaudeAdapter.ts
  • @anthropic-ai/claude-agent-sdk pinned at 0.3.170 in pnpm-lock.yaml (current upstream is 0.3.224)
  • Comparison terminal: native claude CLI v2.1.224, run interactively, same machine, same ~/.claude.json config

Steps to reproduce

  1. Configure a plugin MCP server with a large tool surface (in my case ~95 tools) alongside several smaller plugin servers (2/13/32/47 tools).
  2. Open the native claude CLI in a terminal and run /mcp. All servers, including the large one, show ✓ connected · N tools. Calling the large server's tools works (e.g. a skill built on top of it resolves and executes correctly).
  3. Open a chat session through the t3code GUI (same config, same working directory) and ask the agent to use a tool from the large server.
  4. The agent can invoke the skill associated with that server (skill instructions load fine), but cannot find or call any of the server's underlying MCP tools — ToolSearch with the exact tool name, exact composite server name (plugin:<name>:<name>), and broad keyword queries all return "No matching deferred tools found."
  5. Meanwhile the GUI's own /mcp panel (apparently rendered by a separate native CLI/terminal path, not the chat backend) correctly shows the server as connected · 95 tools.
  6. The smaller plugin servers' tools are discoverable via ToolSearch in the same chat session throughout.

Root cause (from reading apps/server/src/provider/Layers/ClaudeAdapter.ts)

The chat backend calls the SDK's createQuery() once per session (around the queryOptions construction near line 4093). Per the SDK changelog:

Breaking: MCP servers now connect in the background by default; sessions start immediately and slow servers report status: "pending" in init until ready. Set MCP_CONNECTION_NONBLOCKING=0 to restore the old behavior of waiting up to 5s before the first query, or mark a server alwaysLoad: true to require it in turn 1.

ClaudeAdapter.ts does not set MCP_CONNECTION_NONBLOCKING anywhere in the environment it builds (claudeEnvironment), and does not mark any server alwaysLoad: true. So the SDK's default non-blocking-connect behavior applies: the session's initial tool manifest is built from whatever's ready at that instant, and a slower-to-connect server (plausibly correlated with a much larger tool count / heavier handshake) can miss the window and get excluded.

Compounding this: apps/server/src never calls the SDK's reloadPlugins(), toggleMcpServer(), or mcpServerStatus() methods anywhere (confirmed via repo-wide grep). So even after the slow server finishes connecting, nothing re-syncs the session's tool manifest — the omission is permanent for the life of the session, not just a startup race that resolves itself.

This would explain the exact symptom: the server is genuinely connected (hence /mcp reporting it correctly, and the interactive CLI terminal working fine since it doesn't have this turn-1 manifest freeze), but the chat backend's one-shot createQuery() session never learns about tools that weren't ready in time.

Suggested fix

In apps/server/src/provider/Layers/ClaudeAdapter.ts:

  1. Set MCP_CONNECTION_NONBLOCKING=0 in the claudeEnvironment passed to createQuery() so the SDK waits (up to 5s) for MCP servers to connect before turn 1, and/or mark heavier plugin servers alwaysLoad: true if that's exposed per-server.
  2. After session start, call reloadPlugins() (or equivalent) once outstanding servers finish connecting, so long-running sessions pick up tools from servers that missed the initial window instead of never seeing them.
  3. Consider bumping the pinned @anthropic-ai/claude-agent-sdk dependency from 0.3.170 to latest (0.3.224) — several MCP-related fixes have landed since (e.g. server-added-at-runtime tool injection, background-plugin-install disconnect handling) that may be relevant even if not a direct fix for this issue.

Impact

Any user with a plugin MCP server large/slow enough to miss the initial connect window loses access to that server's tools for the entire chat session in the GUI, with no visible error — the server just silently never gets referenced in tool discovery, while the status UI reports it as healthy. This is confusing to debug because every visible signal (/mcp, skill loading) says the server is fine.

Activity

  1. maria-rcks commented on Oct 9, 2026

    @maria-rcks
    Collaborator

    Note

    This is an automated response from a bot acting on maria's behalf.
    This issue has had no activity since 2026-08-07.
    Is it still relevant on the current version? If so, your version and OS would help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions