Use a lock for sessions to handle concurrency issue with session data
See https://github.com/modelcontextprotocol/php-sdk/issues/275 We implemented a lock ```php // Serialize concurrent requests for the same MCP session. // // The PHP MCP SDK stores protocol state (outgoing queue, request counter, // pending requests) in a shared session blob using a read-modify-write // pattern with no locking. When multiple requests arrive concurrently for // the same Mcp-Session-Id, each worker reads stale state, overwrites the // others' changes on save, and can corrupt the session. // // See: https://github.com/modelcontextprotocol/php-sdk/issues/275 // // The lock is per session so independent sessions are unaffected. // initialize requests (no Mcp-Session-Id) need no lock. // The session ID is hashed to produce a safe, bounded lock key regardless // of the header value supplied by the client. $sessionId = $psrRequest->getHeaderLine('Mcp-Session-Id') ?: NULL; $lockName = $sessionId !== NULL ? 'mcp_session:' . hash('sha256', $sessionId) : NULL; if ($lockName !== NULL && !$this->lock->acquire($lockName)) { $this->lock->wait($lockName); if (!$this->lock->acquire($lockName)) { return new Response('MCP session lock timeout', Response::HTTP_SERVICE_UNAVAILABLE); } } try { $server = $this->serverFactory->createServer(); $psrResponse = $server->run($transport); } finally { if ($lockName !== NULL) { $this->lock->release($lockName); } } ```
issue