[Server] Refactor protocol pipeline to separate request and notification handling (#106)

This commit is contained in:
Kyrian Obikwelu 2025-10-12 13:53:41 +01:00 • committed by GitHub
commit 54a5d1495c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -36,8 +36,8 @@ use Mcp\Schema\ServerCapabilities;
use Mcp\Schema\Tool;
use Mcp\Schema\ToolAnnotations;
use Mcp\Server;
use Mcp\Server\Handler\JsonRpcHandler;
use Mcp\Server\Handler\MethodHandlerInterface;
use Mcp\Server\Handler\Notification\NotificationHandlerInterface;
use Mcp\Server\Handler\Request\RequestHandlerInterface;
use Mcp\Server\Session\InMemorySessionStore;
use Mcp\Server\Session\SessionFactory;
use Mcp\Server\Session\SessionFactoryInterface;
@ -76,9 +76,14 @@ final class Builder
private ?string $instructions = null;
/**
* @var array<int, MethodHandlerInterface>
* @var array<int, RequestHandlerInterface>
*/
private array $customMethodHandlers = [];
private array $requestHandlers = [];
/**
* @var array<int, NotificationHandlerInterface>
*/
private array $notificationHandlers = [];
/**
* @var array{
@ -185,9 +190,9 @@ final class Builder
/**
* Register a single custom method handler.
*/
public function addMethodHandler(MethodHandlerInterface $handler): self
public function addRequestHandler(RequestHandlerInterface $handler): self
{
$this->customMethodHandlers[] = $handler;
$this->requestHandlers[] = $handler;
return $this;
}
@ -195,12 +200,36 @@ final class Builder
/**
* Register multiple custom method handlers.
*
* @param iterable<int, MethodHandlerInterface> $handlers
* @param iterable<int, RequestHandlerInterface> $handlers
*/
public function addMethodHandlers(iterable $handlers): self
public function addRequestHandlers(iterable $handlers): self
{
foreach ($handlers as $handler) {
$this->customMethodHandlers[] = $handler;
$this->requestHandlers[] = $handler;
}
return $this;
}
/**
* Register a single custom notification handler.
*/
public function addNotificationHandler(NotificationHandlerInterface $handler): self
{
$this->notificationHandlers[] = $handler;
return $this;
}
/**
* Register multiple custom notification handlers.
*
* @param iterable<int, NotificationHandlerInterface> $handlers
*/
public function addNotificationHandlers(iterable $handlers): self
{
foreach ($handlers as $handler) {
$this->notificationHandlers[] = $handler;
}
return $this;
@ -365,7 +394,7 @@ final class Builder
$configuration = new Configuration($this->serverInfo, $capabilities, $this->paginationLimit, $this->instructions);
$referenceHandler = new ReferenceHandler($container);
$methodHandlers = array_merge($this->customMethodHandlers, [
$requestHandlers = array_merge($this->requestHandlers, [
new Handler\Request\PingHandler(),
new Handler\Request\InitializeHandler($configuration),
new Handler\Request\ListToolsHandler($registry, $this->paginationLimit),
@ -375,19 +404,22 @@ final class Builder
new Handler\Request\ReadResourceHandler($registry, $referenceHandler, $logger),
new Handler\Request\ListPromptsHandler($registry, $this->paginationLimit),
new Handler\Request\GetPromptHandler($registry, $referenceHandler, $logger),
]);
$notificationHandlers = array_merge($this->notificationHandlers, [
new Handler\Notification\InitializedHandler(),
]);
$jsonRpcHandler = new JsonRpcHandler(
methodHandlers: $methodHandlers,
$protocol = new Protocol(
requestHandlers: $requestHandlers,
notificationHandlers: $notificationHandlers,
messageFactory: $messageFactory,
sessionFactory: $sessionFactory,
sessionStore: $sessionStore,
logger: $logger,
);
return new Server($jsonRpcHandler, $logger);
return new Server($protocol, $logger);
}
private function performDiscovery(