From de7c0874725a64b6ab8f4dacc83bec04abbbb336 Mon Sep 17 00:00:00 2001 From: Pascual Munoz Galian Date: Sat, 21 Feb 2026 00:57:37 +0100 Subject: [PATCH] fix: mark client initialized after initialize handshake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many real-world MCP clients (Claude Code, Gemini/Antigravity) complete the initialize handshake and immediately call tools/list or tools/call without sending the notifications/initialized notification. Currently, initialized is only set to true in handleNotificationInitialized(), so these clients get permanently locked out with "Client session not initialized" errors. This change marks the session as initialized right after a successful initialize response. If a client still sends notifications/initialized, handleNotificationInitialized() sets the flag again — a harmless no-op. Discovered while running a production MCP server (Cohete blog) that serves Claude Code and other MCP clients over SSE transport. --- src/Dispatcher.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Dispatcher.php b/src/Dispatcher.php index c9069df..9816ef9 100644 --- a/src/Dispatcher.php +++ b/src/Dispatcher.php @@ -128,6 +128,12 @@ public function handleInitialize(InitializeRequest $request, SessionInterface $s $session->set('client_info', $request->clientInfo->toArray()); $session->set('protocol_version', $protocolVersion); + // Mark client as initialized immediately after successful handshake. + // Many real-world MCP clients (Claude Code, Gemini) skip + // the notifications/initialized step, causing "Client session not + // initialized" errors on all subsequent requests. + $session->set('initialized', true); + $serverInfo = $this->configuration->serverInfo; $capabilities = $this->configuration->capabilities; $instructions = $this->configuration->instructions;