McpServer
Our own facade over the official mcp/sdk Server::builder() API: every Mcp\* symbol the app touches is confined to this class (plus ContainerAdapter), so an SDK breaking change (it is pre-1.0) touches one file, not the whole feature.
Builds an SDK server from McpCatalog’s registered tools/resources/ prompts, resolving each handler through Quiote’s own DI Container.
Synopsis
Section titled “Synopsis”final class McpServer
| Source | McpServer.php |
Constructor
Section titled “Constructor”__construct()
Section titled “__construct()”public function __construct(Container $container, string $contextName, ?ClientInterface $oauthHttpClient = null): mixed
$oauthHttpClient overrides the PSR-18 client OidcDiscovery/JwksProvider (see McpServer::buildHttpMiddleware()) would otherwise auto-discover via php-http/discovery.
Production code always omits it; tests use it to stub OIDC discovery/JWKS responses without a real network call.
| Parameter | Type | Description |
|---|---|---|
$container | Container | |
$contextName | string | |
$oauthHttpClient | ?ClientInterface |
Returns mixed
Methods
Section titled “Methods”| Method | Description |
|---|---|
build(McpConfig $config): Server | Assemble (and cache) the SDK server from the current McpCatalog contents. |
handleHttp(McpConfig $config, ServerRequestInterface $request): ResponseInterface | Drive one Streamable-HTTP request/response cycle. |
| [`runStdio(McpConfig $config, resource | null $input = null, resource |
build()
Section titled “build()”public function build(McpConfig $config): Server
Assemble (and cache) the SDK server from the current McpCatalog contents.
| Parameter | Type | Description |
|---|---|---|
$config | McpConfig |
Returns Server
handleHttp()
Section titled “handleHttp()”public function handleHttp(McpConfig $config, ServerRequestInterface $request): ResponseInterface
Drive one Streamable-HTTP request/response cycle.
The SDK server is stateless per PHP request either way (no shared state survives beyond this call other than what its session store persists) so it’s safe to reuse the cached McpServer::build() result across requests within a worker.
StreamableHttpTransport reads the JSON-RPC payload by re-reading the request’s raw body stream itself — but earlier in the real pipeline, PayloadParsingMiddleware already consumed that stream to populate getParsedBody() and does not rewind it, so by the time this runs the stream is at EOF. Rebuilding the body from the already-parsed data instead of re-parsing it avoids a spurious JSON parse error on every call.
| Parameter | Type | Description |
|---|---|---|
$config | McpConfig | |
$request | ServerRequestInterface |
Returns ResponseInterface
runStdio()
Section titled “runStdio()”public function runStdio(McpConfig $config, resource|null $input = null, resource|null $output = null): int
Run the stdio transport loop (blocks until the client disconnects or the process is signalled).
| Parameter | Type | Description |
|---|---|---|
$config | McpConfig | |
$input | `resource“ | “null` |
$output | `resource“ | “null` |
Returns int