1414use Http \Discovery \Psr17FactoryDiscovery ;
1515use Mcp \Exception \InvalidArgumentException ;
1616use Mcp \Schema \JsonRpc \Error ;
17+ use Mcp \Server \Transport \Http \Middleware \CorsMiddleware ;
1718use Mcp \Server \Transport \Http \MiddlewareRequestHandler ;
1819use Psr \Http \Message \ResponseFactoryInterface ;
1920use Psr \Http \Message \ResponseInterface ;
@@ -32,50 +33,32 @@ class StreamableHttpTransport extends BaseTransport
3233{
3334 private const SESSION_HEADER = 'Mcp-Session-Id ' ;
3435
35- private const ALLOWED_HEADER = [
36- 'Accept ' ,
37- 'Authorization ' ,
38- 'Content-Type ' ,
39- 'Last-Event-ID ' ,
40- 'Mcp-Protocol-Version ' ,
41- self ::SESSION_HEADER ,
42- ];
43-
4436 private ResponseFactoryInterface $ responseFactory ;
4537 private StreamFactoryInterface $ streamFactory ;
4638
4739 private ?string $ immediateResponse = null ;
4840 private ?int $ immediateStatusCode = null ;
4941
50- /** @var array<string, string> */
51- private array $ corsHeaders ;
52-
5342 /** @var list<MiddlewareInterface> */
5443 private array $ middleware = [];
5544
5645 /**
57- * @param array<string, string> $corsHeaders
5846 * @param iterable<MiddlewareInterface> $middleware
5947 */
6048 public function __construct (
6149 private ServerRequestInterface $ request ,
6250 ?ResponseFactoryInterface $ responseFactory = null ,
6351 ?StreamFactoryInterface $ streamFactory = null ,
64- array $ corsHeaders = [],
6552 ?LoggerInterface $ logger = null ,
6653 iterable $ middleware = [],
54+ ?CorsMiddleware $ corsMiddleware = null ,
6755 ) {
6856 parent ::__construct ($ logger );
6957
7058 $ this ->responseFactory = $ responseFactory ?? Psr17FactoryDiscovery::findResponseFactory ();
7159 $ this ->streamFactory = $ streamFactory ?? Psr17FactoryDiscovery::findStreamFactory ();
7260
73- $ this ->corsHeaders = array_merge ([
74- 'Access-Control-Allow-Origin ' => '* ' ,
75- 'Access-Control-Allow-Methods ' => 'GET, POST, DELETE, OPTIONS ' ,
76- 'Access-Control-Allow-Headers ' => implode (', ' , self ::ALLOWED_HEADER ),
77- 'Access-Control-Expose-Headers ' => self ::SESSION_HEADER ,
78- ], $ corsHeaders );
61+ $ this ->middleware [] = $ corsMiddleware ?? new CorsMiddleware ();
7962
8063 foreach ($ middleware as $ m ) {
8164 if (!$ m instanceof MiddlewareInterface) {
@@ -98,12 +81,7 @@ public function listen(): ResponseInterface
9881 \Closure::fromCallable ([$ this , 'handleRequest ' ]),
9982 );
10083
101- return $ this ->withCorsHeaders ($ handler ->handle ($ this ->request ));
102- }
103-
104- protected function handleOptionsRequest (): ResponseInterface
105- {
106- return $ this ->responseFactory ->createResponse (204 );
84+ return $ handler ->handle ($ this ->request );
10785 }
10886
10987 protected function handlePostRequest (): ResponseInterface
@@ -273,25 +251,13 @@ protected function createErrorResponse(Error $jsonRpcError, int $statusCode): Re
273251 return $ response ;
274252 }
275253
276- protected function withCorsHeaders (ResponseInterface $ response ): ResponseInterface
277- {
278- foreach ($ this ->corsHeaders as $ name => $ value ) {
279- if (!$ response ->hasHeader ($ name )) {
280- $ response = $ response ->withHeader ($ name , $ value );
281- }
282- }
283-
284- return $ response ;
285- }
286-
287254 private function handleRequest (ServerRequestInterface $ request ): ResponseInterface
288255 {
289256 $ this ->request = $ request ;
290257 $ sessionIdString = $ request ->getHeaderLine (self ::SESSION_HEADER );
291258 $ this ->sessionId = $ sessionIdString ? Uuid::fromString ($ sessionIdString ) : null ;
292259
293260 return match ($ request ->getMethod ()) {
294- 'OPTIONS ' => $ this ->handleOptionsRequest (),
295261 'POST ' => $ this ->handlePostRequest (),
296262 'DELETE ' => $ this ->handleDeleteRequest (),
297263 default => $ this ->createErrorResponse (Error::forInvalidRequest ('Method Not Allowed ' ), 405 ),
0 commit comments