[BUG] MCP stdio server process is restarted/recycled between tool calls in recent Claude Code versions, causing stateful MCP servers (like appium-mcp) to lose session state and fail with error -32000

Resolved 💬 3 comments Opened Apr 21, 2026 by amitabh2601 Closed May 27, 2026

Preflight Checklist

  • [x] I have searched existing issues 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?

Actual Behavior
MCP server process is killed and a new one spawned between tool calls or when sub-agents are involved
Stateful operations (like WebDriver sessions) are lost
Claude agent sees error -32000 or timeout errors
Remote resources (BrowserStack sessions) are leaked — created but never used

What Should Happen?

Expected Behavior
A single MCP server process should persist for the entire Claude Code conversation/session
All tool calls to that MCP server (from the main agent or sub-agents) should route to the same process
The MCP server process should only be shut down when the Claude Code conversation ends or the user explicitly resets it

Summary
Starting around Claude Code v2.1.107+, the MCP stdio server process is being killed and respawned between tool calls or when sub-agents are spawned. This breaks any MCP server that maintains in-process state (e.g., WebDriver sessions, database connections, open file handles).

The most visible symptom: create_session on a remote Appium/BrowserStack server takes 30-120s to provision a device. Claude Code kills the MCP server process before the response is returned or between subsequent tool calls, resulting in:

Error -32000 (MCP server error) reported to the Claude agent
The session IS created on BrowserStack (verified in BrowserStack dashboard) but the MCP server process that holds the session reference is dead
On retry, a NEW MCP server process starts, has no knowledge of the previous session, and tries to create another one
This burns through BrowserStack device sessions and wastes 2-4 minutes per failed attempt
Downgrading to Claude Code v2.1.104 immediately resolves the issue. The same MCP configuration, same appium-mcp version, same BrowserStack credentials — everything works flawlessly on 2.1.104.

The Root Cause (Our Analysis)
Claude Code appears to have changed how it manages MCP server process lifecycle in recent versions. The specific failure mode:

Impact
Severity: Critical — Complete breakage of stateful MCP workflows
Scope: Any MCP server that maintains in-process state between tool calls
Known affected: appium-mcp (Appium mobile automation)
Likely affected: Any MCP server managing persistent connections (databases, browsers, SSH, etc.)
Cost: Each failed create_session consumes a BrowserStack device session ($), wastes 2-4 minutes, and often the agent gives up after 2-3 retries

Error Messages/Logs

Environment
Claude Code version (broken): 2.1.116, also observed on 2.1.107+ (recent builds)
Claude Code version (working): 2.1.104 (downgraded — confirmed fix)
OS: macOS (Apple Silicon)
Node.js: v22.19.0
MCP Server: appium-mcp@latest (v1.61.0) via stdio transport
MCP SDK: @modelcontextprotocol/sdk (used by appium-mcp)
Transport: stdio (configured in ~/.claude.json under project-level mcpServers)


Detailed Evidence
MCP Server Process Lifecycle Logs
We instrumented the MCP server launch with a wrapper script that logs PID, PPID, timestamps, and signal traps. Here's what we observed:

Pattern on BROKEN versions (v2.1.116):
Log 1 — Process 67303 (started, killed in 30s, no tool calls ever made):

=== appium-mcp debug session started at 2026-04-21T07:57:50Z ===
PID: 67303
PPID: 67294          ← Claude Code parent process
...
Client connected: FastMCPSession { ... }
=== appium-mcp exited with code 0 at 2026-04-21T07:58:21Z ===
Duration: ~30 seconds. Connected, but ZERO tool calls. Exited cleanly (code 0) — Claude Code shut it down.

Log 2 — Process 68049 (same PPID, spawned after 67303 was killed):

=== appium-mcp debug session started at 2026-04-21T08:00:22Z ===
PID: 68049
PPID: 67294          ← Same Claude Code parent process
...
[TOOL START] create_session { ... }
Sending capabilities to remote server...
ERROR: The operation was aborted due to timeout (120013ms)
[TOOL ERROR] create_session (120016ms): Failed to create session: WebDriverError: timeout
Claude spawned a new process, sent create_session, but BrowserStack provisioning took >120s → timeout.

Log 3 — Process 81087 (v2.1.116, later attempt):

[TOOL START] create_session → timeout after 120013ms
[TOOL START] create_session (retry) → timeout after 120007ms
Two consecutive create_session attempts on the same MCP process, both timed out. The BrowserStack sessions WERE created (visible in dashboard) but the response arrived after the 120s MCP timeout.

Pattern on WORKING version (v2.1.104):
Log — Process 71005 (single process, entire test execution):

=== appium-mcp debug session started at 2026-04-21T08:16:53Z ===
CLAUDE_CODE: 2.1.104 (Claude Code)
...
[TOOL START] create_session → timeout (120016ms)  ← 1st attempt, BrowserStack was slow
[TOOL START] create_session → timeout (120007ms)  ← 2nd attempt
[TOOL START] create_session → SUCCESS (30426ms)   ← 3rd attempt worked!
  Session ID: 41fecabf0d4b0266d8d3a18c635ea1cc00f36e68

[TOOL START] appium_get_page_source (1966ms)      ← All subsequent calls work
[TOOL START] appium_screenshot (3595ms)            ← Same process, same session
[TOOL START] appium_find_element (1184ms)
[TOOL START] appium_gesture (1280ms)
... 15+ more tool calls, all successful ...
[TOOL START] delete_session (1931ms)               ← Clean shutdown
Key difference: On v2.1.104, the SAME MCP server process persists across ALL tool calls. Session state is maintained. Even after 2 timeouts, the 3rd create_session succeeds and all subsequent calls work perfectly.

Pattern on WORKING version (v2.1.107, April 14 — before the regression):
Log — Process 58607 (992 lines, full test execution):

CLAUDE_CODE: 2.1.107 (Claude Code)
[TOOL START] create_session → SUCCESS (73112ms)
[TOOL START] appium_get_page_source (1642ms)
[TOOL START] appium_screenshot (20083ms)
... hundreds of tool calls across the entire session ...
Single process, full test lifecycle. This was working on v2.1.107 on April 14.


When a sub-agent is spawned (e.g., via the Agent tool in Claude Code), the parent agent's MCP server process may be killed and a new one started for the sub-agent
Or: Claude Code has a new idle timeout or connection recycling mechanism that shuts down MCP server processes between tool calls if there's a gap (e.g., while the LLM is generating the next response)
Or: The MCP client connection management was refactored and now each "session" or "agent" gets its own MCP server instance, rather than sharing a single persistent process
This is a critical regression for any stateful MCP server. The MCP specification does not prohibit servers from maintaining state between tool calls — in fact, stateful operations (like Appium sessions, database transactions, etc.) are a primary MCP use case.

Steps to Reproduce

Reproduction Steps
Install Claude Code v2.1.116 (or any recent version after ~2.1.107)
Configure an MCP server via stdio that maintains state between calls (e.g., appium-mcp with a remote Appium server like BrowserStack)
Use a Claude Code custom command or prompt that: a. Spawns a sub-agent (via Agent tool) b. The sub-agent calls create_session on the MCP server c. The sub-agent then calls subsequent tools (screenshot, find element, etc.)
Observe: The MCP server process is killed/replaced between steps, and subsequent tool calls fail with -32000 or timeout errors
Verify on BrowserStack dashboard: Sessions ARE created on the remote server, but Claude never receives the response because the MCP process was recycled
To verify fix: Downgrade to Claude Code v2.1.104:

npm install -g @anthropic-ai/claude-code@2.1.104
Same configuration, same everything — works immediately.

MCP Server Configuration
// In ~/.claude.json → projects → /path/to/project → mcpServers
{
"appium-mcp": {
"disabled": false,
"timeout": 120000,
"type": "stdio",
"command": "npx",
"args": ["-y", "appium-mcp@latest"],
"env": {
"APPIUM_SERVER_URL": "http://hub-cloud.browserstack.com/wd/hub",
"BSTACK_USERNAME": "${BSTACK_USERNAME}",
"BSTACK_ACCESS_KEY": "${BSTACK_ACCESS_KEY}"
}
}
}

Claude Model

Not sure / Multiple models

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.104

Claude Code Version

2.1.116

Platform

AWS Bedrock

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

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