Skip to content

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.

final class McpServer

SourceMcpServer.php

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.

ParameterTypeDescription
$containerContainer
$contextNamestring
$oauthHttpClient?ClientInterface

Returns mixed

MethodDescription
build(McpConfig $config): ServerAssemble (and cache) the SDK server from the current McpCatalog contents.
handleHttp(McpConfig $config, ServerRequestInterface $request): ResponseInterfaceDrive one Streamable-HTTP request/response cycle.
[`runStdio(McpConfig $config, resourcenull $input = null, resource

public function build(McpConfig $config): Server

Assemble (and cache) the SDK server from the current McpCatalog contents.

ParameterTypeDescription
$configMcpConfig

Returns Server

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.

ParameterTypeDescription
$configMcpConfig
$requestServerRequestInterface

Returns ResponseInterface

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).

ParameterTypeDescription
$configMcpConfig
$input`resource““null`
$output`resource““null`

Returns int