From 2f577fee58f257b010dd58f53ae76ac8caff01a4 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Fri, 29 May 2026 13:16:38 -0400 Subject: [PATCH] fix(mcp): stateless HTTP transport so client reconnects after redeploy Stateful session manager strands Claude Code after a container redeploy: it reconnects with a now-unknown Mcp-Session-Id, the server 404s, and the client won't re-initialize on a 404 (claude-code #60949). Stateless makes each request self-contained (bearer-auth only) so post-deploy reconnect works without a manual /mcp retry. --- src/fabledassistant/mcp/server.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/fabledassistant/mcp/server.py b/src/fabledassistant/mcp/server.py index 69871e8..f321c78 100644 --- a/src/fabledassistant/mcp/server.py +++ b/src/fabledassistant/mcp/server.py @@ -74,9 +74,18 @@ def build_mcp_server() -> FastMCP: behind a reverse proxy with bearer-token auth as the real security boundary. """ + # stateless_http=True: don't hand the client a persistent Mcp-Session-Id. + # The stateful default strands Claude Code after a container redeploy — + # it reconnects with the now-unknown session id, the server returns 404, + # and the client won't re-initialize on a 404 (Claude Code issue #60949), + # so the connection stays dead until a manual /mcp retry. Stateless makes + # every request self-contained (bearer-auth only), so a post-deploy + # reconnect just works. Trade-off: no server-pushed list_changed stream, + # which we don't use — tools are re-fetched on reconnect anyway. mcp = FastMCP( "scribe", instructions=_INSTRUCTIONS.strip(), + stateless_http=True, transport_security=TransportSecuritySettings( enable_dns_rebinding_protection=False, ),