-
Notifications
You must be signed in to change notification settings - Fork 487
Description
Summary
The ChatGPT MCP connector (openai-mcp/1.0.0) does not persist the mcp-session-id header between tool-call batches. Every batch sends mcp-session-id: null, triggering a fresh initialize → tools/list → tool-call cycle with a new OAuth token exchange. This causes:
- Unbounded server-side session accumulation — 78 orphaned sessions from a single user in one process lifetime
- Spurious re-authentication prompts — users are asked to "Continue" / re-authorize after every few tool calls despite valid tokens with
offline_accessscope - 7:1 auth-to-work ratio — 84 OIDC token verifications for 12 actual tool calls
Server-Side Evidence
Our MCP server emits structured JSON logs for every request. All data below is from production logs, not synthetic tests.
Capture 1: Session accumulation pattern
The connector sends mcp_session_id: null on every initialize, creating a new session each time:
{"event":"mcp_request_headers","headers":{"mcp_session_id":null,"has_authorization":true,"user_agent":"openai-mcp/1.0.0"},"method":"POST","is_initialize":true}
{"event":"session_created","session_id":"15a9bdc6-...","active_sessions":53}
Immediately after, it correctly uses the session ID for the tool call in that batch:
{"event":"mcp_request_headers","headers":{"mcp_session_id":"15a9bdc6-...","user_agent":"openai-mcp/1.0.0"},"is_initialize":false}
{"event":"mcp_tool_call","tool":"fetch","outcome":"ok","duration_ms":11}
Then it disconnects and starts over with mcp_session_id: null for the next batch:
{"event":"client_disconnected","session_id":"15a9bdc6-...","elapsed_ms":281}
// 4 seconds later:
{"event":"mcp_request_headers","headers":{"mcp_session_id":null},"is_initialize":true}
{"event":"session_created","session_id":"459e29da-...","active_sessions":54}Capture 2: Quantified impact (14.5-minute window)
┌─────────────────────────────────┬──────────────┐
│ Metric │ Value │
├─────────────────────────────────┼──────────────┤
│ Wall-clock duration │ 14.5 minutes │
├─────────────────────────────────┼──────────────┤
│ MCP sessions created │ 20 │
├─────────────────────────────────┼──────────────┤
│ Active sessions (start → end) │ 55 → 73 │
├─────────────────────────────────┼──────────────┤
│ Tool calls completed │ 12 │
├─────────────────────────────────┼──────────────┤
│ OIDC token verifications │ 84 │
├─────────────────────────────────┼──────────────┤
│ Session ID reuse across batches │ 0 │
├─────────────────────────────────┼──────────────┤
│ DELETE requests received │ 0 │
└─────────────────────────────────┴──────────────┘
Capture 3: Worst burst
Five new sessions spawned within 34 seconds, each with mcp_session_id: null:
22:46:12Z session_created active_sessions: 68
22:46:18Z session_created active_sessions: 69
22:46:25Z session_created active_sessions: 70
22:46:34Z session_created active_sessions: 71
22:46:46Z session_created active_sessions: 72
All five had the same OAuth subject (99daa1af-...) and client ID (chatgpt-mcp-connector).
Root Cause
The connector correctly receives and uses the mcp-session-id response header within a single batch (initialize → tools/list → tool call). But it discards the session ID between batches. Each new batch starts fresh with a null session ID, forcing a complete re-initialization cycle.
Expected Behavior
Per the MCP Streamable HTTP specification, the client MUST:
- Persist the mcp-session-id from the initialize response
- Include it in all subsequent requests to the same server
- Send a DELETE when the session is no longer needed
The connector does none of these across batch boundaries.
Impact
- Memory leak: Orphaned sessions accumulate until server TTL cleanup (24h) or restart
- Auth fatigue: Users see repeated "Continue" prompts that erode trust in the MCP integration
- OIDC pressure: 7x authentication overhead per tool call hits the identity provider unnecessarily
- Affects all MCP servers: This is client-side behavior, not server-specific. Any MCP server using OAuth with the ChatGPT connector will see this pattern.
Environment
- ChatGPT Plus (web, February 2026)
- User-Agent: openai-mcp/1.0.0
- OAuth client: chatgpt-mcp-connector
- Identity provider: Keycloak (OIDC-compliant)
- MCP protocol version: 2025-11-25
- Server: Custom Streamable HTTP (Node.js/Express)
Related
- Community thread with 6 independent reports (Nov 2025 – Feb 2026) - https://community.openai.com/t/bug-chatgpt-mcp-connector-prompts-for-reauthentication-despite-valid-tokens-with-offline-access-scope/1372031
- OpenAI SDK does not expose MCP session ID, making stateful streamable HTTP sessions impossible openai-agents-python#924 — related session management issue in the Agents SDK (open since June 2025)
Server-Side Mitigation (for other MCP server operators)
We implemented a subject-to-session replacement map that evicts the prior session when the same OAuth subject re-initializes, bounding leak to 1 session per subject. This is a workaround, not a fix — the client should persist session IDs.