diff --git a/src/Schema/Enum/ProtocolVersion.php b/src/Schema/Enum/ProtocolVersion.php new file mode 100644 index 00000000..d2d44436 --- /dev/null +++ b/src/Schema/Enum/ProtocolVersion.php @@ -0,0 +1,24 @@ +protocolVersion ?? MessageInterface::PROTOCOL_VERSION; $data = [ - 'protocolVersion' => MessageInterface::PROTOCOL_VERSION, + 'protocolVersion' => $protocolVersion->value, 'capabilities' => $this->capabilities, 'serverInfo' => $this->serverInfo, ]; diff --git a/src/Server/Builder.php b/src/Server/Builder.php index 95ab9ea1..a08086d6 100644 --- a/src/Server/Builder.php +++ b/src/Server/Builder.php @@ -27,6 +27,7 @@ use Mcp\Exception\ConfigurationException; use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Annotations; +use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Implementation; use Mcp\Schema\Prompt; use Mcp\Schema\PromptArgument; @@ -75,6 +76,8 @@ final class Builder private ?string $instructions = null; + private ?ProtocolVersion $protocolVersion = null; + /** * @var array */ @@ -293,6 +296,13 @@ public function setDiscovery( return $this; } + public function setProtocolVersion(?ProtocolVersion $protocolVersion): self + { + $this->protocolVersion = $protocolVersion; + + return $this; + } + /** * Manually registers a tool handler. * @@ -391,7 +401,7 @@ public function build(): Server $messageFactory = MessageFactory::make(); $capabilities = $registry->getCapabilities(); - $configuration = new Configuration($this->serverInfo, $capabilities, $this->paginationLimit, $this->instructions); + $configuration = new Configuration($this->serverInfo, $capabilities, $this->paginationLimit, $this->instructions, $this->protocolVersion); $referenceHandler = new ReferenceHandler($container); $requestHandlers = array_merge($this->requestHandlers, [ diff --git a/src/Server/Configuration.php b/src/Server/Configuration.php index ab629b58..2f0bd7f0 100644 --- a/src/Server/Configuration.php +++ b/src/Server/Configuration.php @@ -11,6 +11,7 @@ namespace Mcp\Server; +use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Implementation; use Mcp\Schema\ServerCapabilities; @@ -34,6 +35,7 @@ public function __construct( public readonly ServerCapabilities $capabilities, public readonly int $paginationLimit = 50, public readonly ?string $instructions = null, + public readonly ?ProtocolVersion $protocolVersion = null, ) { } } diff --git a/src/Server/Handler/Request/InitializeHandler.php b/src/Server/Handler/Request/InitializeHandler.php index 28bf109f..7e9c216d 100644 --- a/src/Server/Handler/Request/InitializeHandler.php +++ b/src/Server/Handler/Request/InitializeHandler.php @@ -47,6 +47,8 @@ public function handle(Request $request, SessionInterface $session): Response $this->configuration->capabilities ?? new ServerCapabilities(), $this->configuration->serverInfo ?? new Implementation(), $this->configuration?->instructions, + null, + $this->configuration?->protocolVersion, ), ); } diff --git a/tests/Unit/Server/Handler/Request/InitializeHandlerTest.php b/tests/Unit/Server/Handler/Request/InitializeHandlerTest.php new file mode 100644 index 00000000..36c36f14 --- /dev/null +++ b/tests/Unit/Server/Handler/Request/InitializeHandlerTest.php @@ -0,0 +1,76 @@ +createMock(SessionInterface::class); + $session->expects($this->once()) + ->method('set') + ->with('client_info', [ + 'name' => 'client-app', + 'version' => '1.0.0', + ]); + + $request = InitializeRequest::fromArray([ + 'jsonrpc' => MessageInterface::JSONRPC_VERSION, + 'id' => 'request-1', + 'method' => InitializeRequest::getMethod(), + 'params' => [ + 'protocolVersion' => ProtocolVersion::V2024_11_05->value, + 'capabilities' => [], + 'clientInfo' => [ + 'name' => 'client-app', + 'version' => '1.0.0', + ], + ], + ]); + + $response = $handler->handle($request, $session); + + $this->assertInstanceOf(InitializeResult::class, $response->result); + + /** @var InitializeResult $result */ + $result = $response->result; + + $this->assertSame($customProtocolVersion, $result->protocolVersion); + $this->assertSame( + $customProtocolVersion->value, + $result->jsonSerialize()['protocolVersion'] + ); + } +}