[Client] Expired HTTP sessions remain marked connected, including during cancellation
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 25/100
Línea de trabajo
Start with src/Client/Transport/HttpTransport.php at send() and trace how HTTP responses are handled, then read src/Client/Protocol.php at notifyCancellation() to understand why notification failures are caught. Done means a session-bound 404 invalidates the session even during cancellation, preserves the original cancellation or deadline exception, and allows a fresh connection without replaying the interrupted call.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Describe the bug
Stateful Streamable HTTP session expiry is not correctly reflected in the PHP SDK’s connection state.
In the affected HttpTransport::send() implementation, HTTP status codes are not checked before processing or discarding the response body.
Consequently:
- A session-bound HTTP 404 with an empty or plain-text body leaves the tool request waiting until timeout.
Client::isConnected()remainstrue, and subsequent requests continue using the expired session.- A 404 returned for
notifications/cancelledis also discarded without invalidating the connection.
This concerns protocol revisions using Mcp-Session-Id, such as 2025-11-25.
To Reproduce
Ordinary tool request
- Initialize a connection to a stateful HTTP server and receive session ID
S. - Invalidate
Son the server. - Call a tool. The server returns HTTP 404 with an empty or plain-text body.
- Observe that the request waits until timeout and the client still reports itself connected.
- Make another call: it sends the same expired session ID.
Cancellation or deadline expiry
- Start a tool call using session
Sand leave its response pending. - Invalidate the session, then cancel the call or let its deadline expire.
- The SDK sends
notifications/cancelledwithS; the server returns HTTP 404. - The original call is interrupted, but the client remains marked connected despite its expired session.
Simply adding a ConnectionException for HTTP 404 is insufficient for the second case: Protocol::notifyCancellation() catches notification failures. Connection invalidation must persist independently of whether that exception reaches the caller.
Expected behavior
- Recognize a 404 on a request carrying
Mcp-Session-Idas session expiry. - Close the response body, clear the session ID, and mark the client uninitialized so
isConnected()returnsfalse. - Surface an ordinary request’s session expiry promptly as a connection failure.
- Preserve the original cancellation/deadline exception when expiry is detected during the cancellation POST.
- Allow a subsequent reconnect to initialize without the expired session ID.
- Keep healthy connections reusable after cancellation or deadline expiry.
The 2025-11-25 specification, Session Management points 3–4, requires fresh initialization after a session-bound 404. It does not require automatically replaying the interrupted tool call.
Additional context
- Related HTTP status-handling PR: #425.
- Similar reports: TypeScript SDK #1708, Python SDK #1676.
- Lenguaje dominante
- PHP
- Estrellas
- 1.6k
- Forks
- 177
- Merge medio
- 3 d 1 h
- PR fusionados (30 d)
- 27
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de modelcontextprotocol/php-sdk
-
[Server] Handler type uses bare Closure, hard to decorate RegistryInterface under strict PHPStanAbiertoServer
Dificultad 1/5 Menos de una hora Aptitud para principiantes 78/100
modelcontextprotocol/php-sdk#468 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Builder::build() silently skips configured file-based discovery when symfony/finder is missing — should fail loudlyPosiblemente ocupada @ousamabenyounes la tomó hace 52 días. Abiertoneeds confirmation needs maintainer action Server
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
modelcontextprotocol/php-sdk#398 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
modelcontextprotocol/php-sdk#370 ·
Los mantenedores suelen responder en 1 día
-
[Server][Streamable HTTP] Concurrent SSE streams on one session can consume each other's client responsesPosiblemente ocupada @mglaman la tomó hace 1 día. Abiertobug P2 Server
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
modelcontextprotocol/php-sdk#544 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Server
Dificultad 4/5 3-5 días Aptitud para principiantes 32/100
modelcontextprotocol/php-sdk#529 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de modelcontextprotocol/php-sdk
Issues similares
-
📚 Documentation: Placeholder link `link-to-realtime-docs` in Flutter SDK changelogPosiblemente ocupada @ShyneChikwapulo la tomó hoy. Abiertoapi / realtime product / auth product / messaging product / vcs
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
appwrite/appwrite#14272 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
Boavizta/boaviztapi#580 · 1 comentario ·
-
Add PrestashopAbiertorequest
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
endoflife-date/endoflife.date#11303 ·
Los mantenedores suelen responder en 1 día
-
0. to triage enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día