-
Notifications
You must be signed in to change notification settings - Fork 10.2k
MCP tool calls fail permanently after server-side session expiry (rmcp does not re-initialize on HTTP 404) #13969
Description
What version of the Codex App are you using (From “About Codex” dialog)?
0.108.0-alpha.12
What subscription do you have?
Pro
What platform is your computer?
Darwin arm64 24.6.0 arm
What issue are you seeing?
When a remote MCP server's session expires (TTL cleanup), all subsequent MCP tool calls fail permanently with:
tool call error: tool call failed for `xxxxx-mcp/search`
Caused by:
tools/call failed: Transport send error: Transport [rmcp::transport::worker::WorkerTransport
<rmcp::transport::streamable_http_client::StreamableHttpClientWorker
<reqwest::async_impl::client::Client>>] error: Client error: error decoding response body
CodeX never recovers until manually restarted or the MCP server is re-added.
Root cause: CodeX bundles rmcp 0.15.0. When the MCP server returns HTTP 404 for an expired session, rmcp does not re-initialize the session as required by the MCP spec. Instead, it keeps sending requests with the stale session ID indefinitely.
Per MCP Spec 2025-03-26, Session Management, rule 4:
When a client receives HTTP 404 in response to a request containing an
Mcp-Session-Id, it MUST start a new session by sending a newInitializeRequestwithout a session ID attached.
This is not implemented in rmcp (confirmed in all versions up to latest 1.1.0). The worker's main event loop simply forwards the error without any re-initialization attempt.
What steps can reproduce the bug?
- Configure a remote MCP server (Streamable HTTP) with session TTL (e.g. 10 minutes)
- Connect CodeX to this MCP server, use it for tool calls (works fine)
- Wait for the session to expire (idle longer than the TTL)
- Try to use the MCP tool again
- All tool calls fail with
error decoding response body - No recovery occurs. CodeX keeps using the stale session ID.
MCP server logs confirm the behavior:
12:45:09 Session expired {"sessionId":"e52ece66-..."}
12:46:37 tools/call e52ece66 → 404 Session not found
12:46:37 tools/call e52ece66 → 404 Session not found (same stale ID)
12:46:37 tools/call e52ece66 → 404 Session not found
12:46:49 tools/call e52ece66 → 404 Session not found
12:47:01 resources/list e52ece66 → 404 Session not found
12:47:28 tools/call e52ece66 → 404 Session not found (no re-initialize ever sent)
What is the expected behavior?
When CodeX receives HTTP 404 for an expired MCP session, it should automatically start a new session by sending a new InitializeRequest without a session ID, as required by the MCP specification. The tool call should then be retried transparently.
Additional information
rmcp version in CodeX: 0.15.0 (confirmed via strings /Applications/Codex.app/Contents/Resources/codex | grep rmcp)
Two separate bugs in rmcp:
- rmcp 0.15.0 does not check HTTP status before parsing the response body, causing the misleading
error decoding response bodymessage. This was partially fixed in rmcp 1.1.0 (env variable not found in windows terminal #709) which now returnsUnexpectedServerResponse("HTTP 404: ..."). - rmcp (all versions) does not implement session re-initialization on 404. The worker layer has no code path for this.
CodeX-specific option: codex-rs/rmcp-client/ wrapper could implement session recovery independently of upstream rmcp fix by detecting the session error and re-creating the MCP client connection.