[Client] Expired HTTP sessions remain marked connected, including during cancellation
Mantenedores costumam responder em até 1 dia
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 25/100
Direção de pesquisa
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.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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.
- Linguagem predominante
- PHP
- Estrelas
- 1.6k
- Forks
- 177
- Merge médio
- 3d 1h
- PRs com merge (30d)
- 27
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Sem modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de modelcontextprotocol/php-sdk
-
[Server] Handler type uses bare Closure, hard to decorate RegistryInterface under strict PHPStanAbertaServer
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 78/100
modelcontextprotocol/php-sdk#468 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
Builder::build() silently skips configured file-based discovery when symfony/finder is missing — should fail loudlyTalvez já em andamento @ousamabenyounes assumiu há 52 dias. Abertaneeds confirmation needs maintainer action Server
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
modelcontextprotocol/php-sdk#398 · 1 reação ·
Mantenedores costumam responder em até 1 dia
-
enhancement
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
modelcontextprotocol/php-sdk#370 ·
Mantenedores costumam responder em até 1 dia
-
[Server][Streamable HTTP] Concurrent SSE streams on one session can consume each other's client responsesTalvez já em andamento @mglaman assumiu há 1 dia. Abertabug P2 Server
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 25/100
modelcontextprotocol/php-sdk#544 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Server
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 32/100
modelcontextprotocol/php-sdk#529 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
Todas as issues de modelcontextprotocol/php-sdk
Issues semelhantes
-
魚類詳細頁基本 tab 移除重複的地方知識Abertaspec:debating
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
blackie0424/tao_among#93 ·
Mantenedores costumam responder em até 1 dia
-
📚 Documentation: Placeholder link `link-to-realtime-docs` in Flutter SDK changelogTalvez já em andamento @ShyneChikwapulo assumiu hoje. Abertaapi / realtime product / auth product / messaging product / vcs
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 82/100
appwrite/appwrite#14272 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 75/100
Boavizta/boaviztapi#580 · 1 comentário ·
-
Add PrestashopAbertarequest
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
endoflife-date/endoflife.date#11303 ·
Mantenedores costumam responder em até 1 dia