You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+68Lines changed: 68 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1073,6 +1073,74 @@ $server = Server::make()
1073
1073
->build();
1074
1074
```
1075
1075
1076
+
### Middleware Support
1077
+
1078
+
Both `HttpServerTransport` and `StreamableHttpServerTransport` support PSR-7 compatible middleware for intercepting and modifying HTTP requests and responses. Middleware allows you to extract common functionality like authentication, logging, CORS handling, and request validation into reusable components.
1079
+
1080
+
Middleware must be a valid PHP callable that accepts a PSR-7 `ServerRequestInterface` as the first argument and a `callable` as the second argument.
1081
+
1082
+
```php
1083
+
use Psr\Http\Message\ServerRequestInterface;
1084
+
use Psr\Http\Message\ResponseInterface;
1085
+
use React\Promise\PromiseInterface;
1086
+
1087
+
class AuthMiddleware
1088
+
{
1089
+
public function __invoke(ServerRequestInterface $request, callable $next)
-**Response Handling**: Middleware must handle both synchronous `ResponseInterface` and asynchronous `PromiseInterface` returns from `$next($request)`, since ReactPHP operates asynchronously
1141
+
-**Invokable Pattern**: The recommended pattern is to use invokable classes with a separate `handle()` method to process responses, making the async logic reusable
1142
+
-**Execution Order**: Middleware executes in the order provided, with the last middleware being closest to your MCP handlers
1143
+
1076
1144
### SSL Context Configuration
1077
1145
1078
1146
For HTTPS deployments of `StreamableHttpServerTransport`, configure SSL context options:
* @param array<callable(\Psr\Http\Message\ServerRequestInterface, callable): (\Psr\Http\Message\ResponseInterface|\React\Promise\PromiseInterface)> $middlewares Middlewares to be applied to the HTTP server.
Copy file name to clipboardExpand all lines: src/Transports/StreamableHttpServerTransport.php
+13-2Lines changed: 13 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -67,6 +67,9 @@ class StreamableHttpServerTransport implements ServerTransportInterface, LoggerA
67
67
68
68
/**
69
69
* @param bool $enableJsonResponse If true, the server will return JSON responses instead of starting an SSE stream.
70
+
* @param bool $stateless If true, the server will not emit client_connected events.
71
+
* @param EventStoreInterface $eventStore If provided, the server will replay events to the client.
72
+
* @param array<callable(\Psr\Http\Message\ServerRequestInterface, callable): (\Psr\Http\Message\ResponseInterface|\React\Promise\PromiseInterface)> $middlewares Middlewares to be applied to the HTTP server.
70
73
* This can be useful for simple request/response scenarios without streaming.
71
74
*/
72
75
publicfunction__construct(
@@ -76,12 +79,19 @@ public function __construct(
76
79
private ?array$sslContext = null,
77
80
privatereadonlybool$enableJsonResponse = true,
78
81
privatereadonlybool$stateless = false,
79
-
?EventStoreInterface$eventStore = null
82
+
?EventStoreInterface$eventStore = null,
83
+
privatearray$middlewares = []
80
84
) {
81
85
$this->logger = newNullLogger();
82
86
$this->loop = Loop::get();
83
87
$this->mcpPath = '/' . trim($mcpPath, '/');
84
88
$this->eventStore = $eventStore;
89
+
90
+
foreach ($this->middlewaresas$mw) {
91
+
if (!is_callable($mw)) {
92
+
thrownew \InvalidArgumentException('All provided middlewares must be callable.');
93
+
}
94
+
}
85
95
}
86
96
87
97
protectedfunctiongenerateId(): string
@@ -119,7 +129,8 @@ public function listen(): void
0 commit comments