MCP tool calls fail permanently after server-side session expiry (rmcp does not re-initialize on HTTP 404)
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.
<img width="798" height="431" alt="Image" src="https://github.com/user-attachments/assets/920b5d36-9402-4888-a6dc-89a0339382d5" />
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 anMcp-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 (#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.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗