Repository navigation
Mixing up Streaming HTTP protocol versions results in connection failures #5619
Description
What version of Codex is running?
codex-cli 0.47.0
What subscription do you have?
Plus
Which model were you using?
n/a
What platform is your computer?
Ubuntu WSL1
What issue are you seeing?
codex is not authenticating with some non-stdio MCP servers.
Take the rest with a grain of salt (Claude analysis of the server logs, and your github code):-
The Codex client is sending 2025-06-18 but appears to be expecting 2024-11-05 behavior (immediate close after endpoint event).
Based on the documentation from Context7 about the official rmcp SDK, and examining the Codex code:
🎯 Root Cause Analysis: Client Bug Confirmed
What I Found:
-
The Official
rmcpSDK Documentation shows that for Streamable HTTP transport, the server should:- Send SSE headers
- Send the
endpointevent - Then continue processing the initialize request synchronously and send the response via SSE
-
Your Server is Correct: The logs show you're doing exactly that:
18:58:39 Streaming HTTP response... (SSE headers + endpoint event) 18:58:39 Processing initial request for session... 18:58:39 JSONRPC Request... method=initialize 18:58:39 Session FIN detected: SSL client closed connection gracefully -
The Codex Client Bug: Looking at the client code structure:
auth_status.rsline 21 uses"2024-11-05"for OAuth discovery- But the logs show the client sent
"protocolVersion":"2025-06-18"in the initialize request - This is the problem! The client is mixing protocol versions and may be expecting immediate JSON response instead of SSE-based response
The Protocol Version Mismatch:
From the MCP spec documentation you showed me earlier and the Context7 docs:
2024-11-05: Original spec where initialize response could be synchronous2025-06-18: New spec where Streamable HTTP uses SSE for all messages including initialize response
The Codex client is sending 2025-06-18 but appears to be expecting 2024-11-05 behavior (immediate close after endpoint event).
✅ Conclusion: This is 100% a Client Bug
Your server implementation is completely correct. The Codex client (codex-mcp-client v0.47.0) has a bug where it:
- Sends protocol version
2025-06-18 - Receives the SSE
endpointevent - Immediately closes the connection without waiting for the
initializeresponse via SSE - This causes the "connection closed: initialize response" error
Recommended Action:
Report this as a bug to the Codex team at https://github.com/openai/codex/issues with:
- Your server logs
- The fact that your server works perfectly with Cursor IDE
- Reference to the MCP
2025-06-18spec requirement that responses come via SSE
Your OAuth implementation and server are working perfectly. ✅
Logs:-
Discovery:-
18:58:39 Connect from ('127.0.0.1', 63924)
18:58:39 Request from 127.0.0.1:63924 < {'Method': 'GET', 'Path': '/.well-known/oauth-authorization-server/sse', 'Headers': {'mcp-protocol-version': '2024-11-05', 'accept': '/', 'host': '127-0-0-1.local.aurafriday.com:31173'}, 'Body length': 0} Body:
18:58:39 RESponse to 127.0.0.1:63924 > 1174 bytes\nb'HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nCache-Control: public, max-age=3600\r\nContent-Length: 1045\r\nConnection: close\r\n\r\n{\n "issuer": "https://127-0-0-1.local.aurafriday.com:31173",\n "authorization_endpoint": "https://127-0-0-1.local.aurafriday.com:31173/oauth2/authorize",\n "token_endpoint": "https://127-0-0-1.local.aurafriday.com:31173/oauth2/token",\n "registration_endpoint": "https://127-0-0-1.local.aurafriday.com:31173/oauth2/register",\n "introspection_endpoint": "https://127-0-0-1.local.aurafriday.com:31173/oauth2/introspect",\n "revocation_endpoint": "https://127-0-0-1.local.aurafriday.com:31173/oauth2/revoke",\n "grant_types_supported": [\n "authorization_code",\n "refresh_token"\n ],\n "response_types_supported": [\n "code"\n ],\n "response_modes_supported": [\n "query",\n "form_post"\n ],\n "code_challenge_methods_supported": [\n "S256"\n ],\n "token_endpoint_auth_methods_supported": [\n "client_secret_basic",\n "client_secret_post",\n "none"\n ],\n "scopes_supported": [\n "offline_access"\n ],\n "claims_parameter_supported": false,\n "request_parameter_supported": false,\n "request_uri_parameter_supported": false\n}'
18:58:39 Session Initiated graceful socket shutdown (FIN sent)
18:58:39 Session Client socket closed
18:58:39 Connect from ('127.0.0.1', 63925)
Auth:-
18:58:39 Request from 127.0.0.1:63925 < {'Method': 'POST', 'Path': '/sse', 'Headers': {'accept': 'text/event-stream, application/json', 'authorization': 'Bearer ', 'content-type': 'application/json', 'host': '127-0-0-1.local.aurafriday.com:31173', 'content-length': '198'}, 'Body length': 198} Body: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{"elicitation":{}},"clientInfo":{"name":"codex-mcp-client","title":"Codex","version":"0.47.0"}}} 18:58:39 Auth Attempting Bearer OAuth for OAuth client: Codex from 127.0.0.1:63925 18:58:39 Auth Successful Bearer OAuth authentication for OAuth client: Codex from 127.0.0.1:63925 18:58:39 Streaming HTTP Parsed initial request: {'jsonrpc': '2.0', 'id': 0, 'method': 'initialize', 'params': {'protocolVersion': '2025-06-18', 'capabilities': {'elicitation': {}}, 'clientInfo': {'name': 'codex-mcp-client', 'title': 'Codex', 'version': '0.47.0'}}} 18:58:39 New streaming HTTP connection from 127.0.0.1:63925, session_id=f9c5483294394a9ca75e32ea1870f67d 18:58:39 Streaming HTTP response to 127.0.0.1:63925 > b'HTTP/1.1 200 OK\r\nContent-Type: text/event-stream; charset=utf-8\r\nConnection: keep-alive\r\nCache-Control: no-store\r\nX-Accel-Buffering: no\r\nAccess-Control-Allow-Origin: null\r\nAccess-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Max-Age: 86400\r\n\r\nevent: endpoint\r\ndata: /messages/?session_id=f9c5483294394a9ca75e32ea1870f67d\r\n\r\n' 18:58:39 Streaming HTTP Processing initial request for session f9c5483294394a9ca75e32ea1870f67d 18:58:39 JSONRPC Request session=f9c5483294394a9ca75e32ea1870f67d, method=initialize, id=0 18:58:39 Session FIN detected: SSL client 127.0.0.1:63925 closed connection gracefully 18:58:39 Session Disconnect detected for client 127.0.0.1:63925 before sending
What steps can reproduce the bug?
Maybe work out which protocol(s) you want to support, and check if the flow is correct?
Claude 4.5 (Above) is not always right.
What is the expected behavior?
OAuth should work.
Additional information
See also: 5588
Attempts OAuth even when the MCP SSE server does not support oauth
Activity
github-actions commentedon Oct 24, 2025
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
gpeal commentedon Nov 3, 2025
Is there a public MCP server I can test against? I don't totally trust the AI report attached but can take a look if there is a public repro.
eirenik0 commentedon Dec 23, 2025
@gpeal I see that it's a little bit different but might be related. You could test it with this server, for example, https://docs.z.ai/devpack/mcp/reader-mcp-server.
I see the error:
And feature
experimental_use_rmcp_client = trueis doesn't help.guyinwonder168 commentedon Mar 15, 2026
Confirming this with a fresh repro on 2026-03-15 against the Z.AI public MCP endpoints.
Setup:
web-search-prime:https://api.z.ai/api/mcp/web_search_prime/mcpweb-reader:https://api.z.ai/api/mcp/web_reader/mcpzread:https://api.z.ai/api/mcp/zread/mcpbearer_token_env_var = "ZAI_API_KEY"http_headers = { Accept = "application/json, text/event-stream" }Observed in Codex startup:
What I verified manually outside Codex:
initializesucceeds on all three endpoints when I send:Authorization: Bearer $ZAI_API_KEYAccept: application/json, text/event-streaminitialize200,content-type: text/event-stream, and anmcp-session-id.initializeresult advertisesprotocolVersion: "2024-11-05"even when the client asks for2025-03-26.notifications/initializedmanually with the returnedMcp-Session-Idsucceeds with200.tools/listmanually after that also succeeds.So this does not look like:
Accept: application/json, text/event-streamIt looks like a compatibility problem in the Codex streamable HTTP MCP client during/after the
initializedstep, likely related to protocol negotiation or how this older server implementation is handled.If useful, I can provide exact
curlrepro commands, but the short version is: the same session works manually and fails only in Codex withTransport channel closed, when send initialized notification.guyinwonder168 commentedon Mar 15, 2026
This looks closely related to #5208.
Why I think so:
Transport channel closed, when send initialized notificationThe difference is that this is still reproducible now with public Z.AI MCP servers, despite #5208 having been closed as fixed via the earlier rust-sdk work.
So this may be either:
initializebut advertiseprotocolVersion: "2024-11-05"while Codex is initiating with2025-03-26.If helpful, I can post exact
curlrepro commands for the full successful manual sequence (initialize->notifications/initialized->tools/list).guyinwonder168 commentedon Mar 15, 2026
Here is a minimal manual repro that succeeds outside Codex for
web_search_prime. The same pattern also works forweb_readerandzreadby swapping the URL.Expected successful manual behavior:
200,content-type: text/event-stream, and anmcp-session-id200200plus the tool listIn my environment, this full manual sequence succeeds, while Codex startup still fails earlier with:
caibirdme commentedon Mar 23, 2026
I find a workaround for this
use mcp-proxy, you should install it first
here's the example config.toml
Enable JSON responses on Streamable HTTP for Codex CLI compatibility (#…