Skip to content

Commit b51fe79

Browse files
fix: allow controlling the error code for POST error responses
- Updated the Protocol class to set a 404 status code for invalid or expired sessions and improved logging for response sending and error handling. - Adjusted response status code handling to utilize the context's status code, ensuring more accurate HTTP responses.
1 parent 74575ca commit b51fe79

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/Protocol.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,16 @@ public function processMessage(Request|Notification|BatchRequest $message, strin
121121

122122
if ($session === null) {
123123
$error = Error::forInvalidRequest('Invalid or expired session. Please re-initialize the session.', $message->id);
124-
$this->transport->sendMessage($error, $sessionId, $context);
124+
$context['status_code'] = 404;
125+
126+
$this->transport->sendMessage($error, $sessionId, $context)
127+
->then(function () use ($sessionId, $error, $context) {
128+
$this->logger->debug('Response sent.', ['sessionId' => $sessionId, 'payload' => $error, 'context' => $context]);
129+
})
130+
->catch(function (Throwable $e) use ($sessionId, $error, $context) {
131+
$this->logger->error('Failed to send response.', ['sessionId' => $sessionId, 'error' => $e->getMessage()]);
132+
});
133+
125134
return;
126135
}
127136

src/Transports/StreamableHttpServerTransport.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,16 @@ class StreamableHttpServerTransport implements ServerTransportInterface, LoggerA
6868

6969
private ?ThroughStream $getStream = null;
7070

71+
/**
72+
* @param bool $enableJsonResponse If true, the server will return JSON responses instead of starting an SSE stream.
73+
* This can be useful for simple request/response scenarios without streaming.
74+
*/
7175
public function __construct(
7276
private readonly string $host = '127.0.0.1',
7377
private readonly int $port = 8080,
7478
private string $mcpPath = '/mcp',
7579
private ?array $sslContext = null,
76-
private readonly bool $preferDirectJsonResponse = true,
80+
private readonly bool $enableJsonResponse = true,
7781
?IdGeneratorInterface $idGenerator = null,
7882
?EventStoreInterface $eventStore = null
7983
) {
@@ -295,11 +299,7 @@ private function handlePostRequest(ServerRequestInterface $request): PromiseInte
295299
$deferred->resolve(new HttpResponse(202));
296300
$context['type'] = 'post_202_sent';
297301
} else {
298-
$clientPrefersSse = str_contains($acceptHeader, 'text/event-stream');
299-
$clientAcceptsJson = str_contains($acceptHeader, 'application/json');
300-
$useSse = $clientPrefersSse && !($this->preferDirectJsonResponse && $clientAcceptsJson);
301-
302-
if ($useSse) {
302+
if (!$this->enableJsonResponse) {
303303
$streamId = $this->idGenerator->generateId();
304304
$sseStream = new ThroughStream();
305305
$this->activeSseStreams[$streamId] = [
@@ -480,7 +480,8 @@ public function sendMessage(Message $message, string $sessionId, array $context
480480
$headers['Mcp-Session-Id'] = $sessionId;
481481
}
482482

483-
$deferred->resolve(new HttpResponse(200, $headers, $responseBody));
483+
$statusCode = $context['status_code'] ?? 200;
484+
$deferred->resolve(new HttpResponse($statusCode, $headers, $responseBody . "\n"));
484485
return resolve(null);
485486

486487
default:

0 commit comments

Comments
 (0)