Rework registry to combine provider and registry interface, move capabilities out and enable Registry injection in Builder (#150)

This commit is contained in:
Christopher Hertel 2025-11-20 19:36:57 +01:00 • committed by GitHub
commit 7cd281d0c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 567 additions and 736 deletions

View file

@ -18,6 +18,7 @@ use Mcp\Capability\Registry\Loader\ArrayLoader;
use Mcp\Capability\Registry\Loader\DiscoveryLoader;
use Mcp\Capability\Registry\Loader\LoaderInterface;
use Mcp\Capability\Registry\ReferenceHandler;
use Mcp\Capability\RegistryInterface;
use Mcp\JsonRpc\MessageFactory;
use Mcp\Schema\Annotations;
use Mcp\Schema\Enum\ProtocolVersion;
@ -47,6 +48,8 @@ final class Builder
{
private ?Implementation $serverInfo = null;
private RegistryInterface $registry;
private ?LoggerInterface $logger = null;
private ?CacheInterface $discoveryCache = null;
@ -248,6 +251,13 @@ final class Builder
return $this;
}
public function setRegistry(RegistryInterface $registry): self
{
$this->registry = $registry;
return $this;
}
/**
* Provides a PSR-3 logger instance. Defaults to NullLogger.
*/
@ -440,7 +450,7 @@ final class Builder
{
$logger = $this->logger ?? new NullLogger();
$container = $this->container ?? new Container();
$registry = new Registry($this->eventDispatcher, $logger);
$registry = $this->registry ?? new Registry($this->eventDispatcher, $logger);
$loaders = [
...$this->loaders,
@ -455,16 +465,22 @@ final class Builder
$loader->load($registry);
}
if ($this->serverCapabilities) {
$registry->setServerCapabilities($this->serverCapabilities);
}
$sessionTtl = $this->sessionTtl ?? 3600;
$sessionFactory = $this->sessionFactory ?? new SessionFactory();
$sessionStore = $this->sessionStore ?? new InMemorySessionStore($sessionTtl);
$messageFactory = MessageFactory::make();
$capabilities = $registry->getCapabilities();
$capabilities = $this->serverCapabilities ?? new ServerCapabilities(
tools: $registry->hasTools(),
toolsListChanged: $this->eventDispatcher instanceof EventDispatcherInterface,
resources: $registry->hasResources() || $registry->hasResourceTemplates(),
resourcesSubscribe: false,
resourcesListChanged: $this->eventDispatcher instanceof EventDispatcherInterface,
prompts: $registry->hasPrompts(),
promptsListChanged: $this->eventDispatcher instanceof EventDispatcherInterface,
logging: false,
completions: true,
);
$configuration = new Configuration($this->serverInfo, $capabilities, $this->paginationLimit, $this->instructions, $this->protocolVersion);
$referenceHandler = new ReferenceHandler($container);

View file

@ -12,7 +12,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceHandlerInterface;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\ToolCallException;
use Mcp\Exception\ToolNotFoundException;
use Mcp\Schema\Content\TextContent;
@ -34,7 +34,7 @@ use Psr\Log\NullLogger;
final class CallToolHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $referenceProvider,
private readonly RegistryInterface $registry,
private readonly ReferenceHandlerInterface $referenceHandler,
private readonly LoggerInterface $logger = new NullLogger(),
) {
@ -58,7 +58,7 @@ final class CallToolHandler implements RequestHandlerInterface
$this->logger->debug('Executing tool', ['name' => $toolName, 'arguments' => $arguments]);
try {
$reference = $this->referenceProvider->getTool($toolName);
$reference = $this->registry->getTool($toolName);
$arguments['_session'] = $session;

View file

@ -12,7 +12,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Completion\ProviderInterface;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\PromptNotFoundException;
use Mcp\Exception\ResourceNotFoundException;
use Mcp\Schema\JsonRpc\Error;
@ -35,7 +35,7 @@ use Psr\Container\ContainerInterface;
final class CompletionCompleteHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $referenceProvider,
private readonly RegistryInterface $registry,
private readonly ?ContainerInterface $container = null,
) {
}
@ -57,8 +57,8 @@ final class CompletionCompleteHandler implements RequestHandlerInterface
try {
$reference = match (true) {
$request->ref instanceof PromptReference => $this->referenceProvider->getPrompt($request->ref->name),
$request->ref instanceof ResourceReference => $this->referenceProvider->getResource($request->ref->uri),
$request->ref instanceof PromptReference => $this->registry->getPrompt($request->ref->name),
$request->ref instanceof ResourceReference => $this->registry->getResource($request->ref->uri),
};
$providers = $reference->completionProviders;

View file

@ -12,7 +12,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceHandlerInterface;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\PromptGetException;
use Mcp\Exception\PromptNotFoundException;
use Mcp\Schema\JsonRpc\Error;
@ -32,7 +32,7 @@ use Psr\Log\NullLogger;
final class GetPromptHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $referenceProvider,
private readonly RegistryInterface $registry,
private readonly ReferenceHandlerInterface $referenceHandler,
private readonly LoggerInterface $logger = new NullLogger(),
) {
@ -54,7 +54,7 @@ final class GetPromptHandler implements RequestHandlerInterface
$arguments = $request->arguments ?? [];
try {
$reference = $this->referenceProvider->getPrompt($promptName);
$reference = $this->registry->getPrompt($promptName);
$arguments['_session'] = $session;

View file

@ -11,7 +11,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\InvalidCursorException;
use Mcp\Schema\JsonRpc\Request;
use Mcp\Schema\JsonRpc\Response;
@ -27,7 +27,7 @@ use Mcp\Server\Session\SessionInterface;
final class ListPromptsHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $registry,
private readonly RegistryInterface $registry,
private readonly int $pageSize = 20,
) {
}

View file

@ -11,7 +11,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\InvalidCursorException;
use Mcp\Schema\JsonRpc\Request;
use Mcp\Schema\JsonRpc\Response;
@ -27,7 +27,7 @@ use Mcp\Server\Session\SessionInterface;
final class ListResourceTemplatesHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $registry,
private readonly RegistryInterface $registry,
private readonly int $pageSize = 20,
) {
}

View file

@ -11,7 +11,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\InvalidCursorException;
use Mcp\Schema\JsonRpc\Request;
use Mcp\Schema\JsonRpc\Response;
@ -27,7 +27,7 @@ use Mcp\Server\Session\SessionInterface;
final class ListResourcesHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $registry,
private readonly RegistryInterface $registry,
private readonly int $pageSize = 20,
) {
}

View file

@ -11,7 +11,7 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\InvalidCursorException;
use Mcp\Schema\JsonRpc\Request;
use Mcp\Schema\JsonRpc\Response;
@ -28,7 +28,7 @@ use Mcp\Server\Session\SessionInterface;
final class ListToolsHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $registry,
private readonly RegistryInterface $registry,
private readonly int $pageSize = 20,
) {
}

View file

@ -12,8 +12,8 @@
namespace Mcp\Server\Handler\Request;
use Mcp\Capability\Registry\ReferenceHandlerInterface;
use Mcp\Capability\Registry\ReferenceProviderInterface;
use Mcp\Capability\Registry\ResourceTemplateReference;
use Mcp\Capability\RegistryInterface;
use Mcp\Exception\ResourceNotFoundException;
use Mcp\Exception\ResourceReadException;
use Mcp\Schema\JsonRpc\Error;
@ -33,7 +33,7 @@ use Psr\Log\NullLogger;
final class ReadResourceHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReferenceProviderInterface $referenceProvider,
private readonly RegistryInterface $referenceProvider,
private readonly ReferenceHandlerInterface $referenceHandler,
private readonly LoggerInterface $logger = new NullLogger(),
) {