Ability to set custom protocol version (#117)
This commit is contained in:
parent
85549cb835
commit
09596c0382
7 changed files with 124 additions and 4 deletions
24
src/Schema/Enum/ProtocolVersion.php
Normal file
24
src/Schema/Enum/ProtocolVersion.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the official PHP MCP SDK.
|
||||||
|
*
|
||||||
|
* A collaboration between Symfony and the PHP Foundation.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Mcp\Schema\Enum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available protocol versions for MCP.
|
||||||
|
*/
|
||||||
|
enum ProtocolVersion: string
|
||||||
|
{
|
||||||
|
case V2024_11_05 = '2024-11-05';
|
||||||
|
|
||||||
|
case V2025_03_26 = '2025-03-26';
|
||||||
|
|
||||||
|
case V2025_06_18 = '2025-06-18';
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace Mcp\Schema\JsonRpc;
|
namespace Mcp\Schema\JsonRpc;
|
||||||
|
|
||||||
|
use Mcp\Schema\Enum\ProtocolVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refers to any valid JSON-RPC object that can be decoded off the wire, or encoded to be sent.
|
* Refers to any valid JSON-RPC object that can be decoded off the wire, or encoded to be sent.
|
||||||
*
|
*
|
||||||
|
|
@ -19,5 +21,5 @@ namespace Mcp\Schema\JsonRpc;
|
||||||
interface MessageInterface extends \JsonSerializable
|
interface MessageInterface extends \JsonSerializable
|
||||||
{
|
{
|
||||||
public const JSONRPC_VERSION = '2.0';
|
public const JSONRPC_VERSION = '2.0';
|
||||||
public const PROTOCOL_VERSION = '2025-06-18';
|
public const PROTOCOL_VERSION = ProtocolVersion::V2025_06_18;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Mcp\Schema\Result;
|
namespace Mcp\Schema\Result;
|
||||||
|
|
||||||
use Mcp\Exception\InvalidArgumentException;
|
use Mcp\Exception\InvalidArgumentException;
|
||||||
|
use Mcp\Schema\Enum\ProtocolVersion;
|
||||||
use Mcp\Schema\Implementation;
|
use Mcp\Schema\Implementation;
|
||||||
use Mcp\Schema\JsonRpc\MessageInterface;
|
use Mcp\Schema\JsonRpc\MessageInterface;
|
||||||
use Mcp\Schema\JsonRpc\Response;
|
use Mcp\Schema\JsonRpc\Response;
|
||||||
|
|
@ -38,6 +39,7 @@ class InitializeResult implements ResultInterface
|
||||||
public readonly Implementation $serverInfo,
|
public readonly Implementation $serverInfo,
|
||||||
public readonly ?string $instructions = null,
|
public readonly ?string $instructions = null,
|
||||||
public readonly ?array $_meta = null,
|
public readonly ?array $_meta = null,
|
||||||
|
public readonly ?ProtocolVersion $protocolVersion = null,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +68,8 @@ class InitializeResult implements ResultInterface
|
||||||
ServerCapabilities::fromArray($data['capabilities']),
|
ServerCapabilities::fromArray($data['capabilities']),
|
||||||
Implementation::fromArray($data['serverInfo']),
|
Implementation::fromArray($data['serverInfo']),
|
||||||
$data['instructions'] ?? null,
|
$data['instructions'] ?? null,
|
||||||
$data['_meta'] ?? null
|
$data['_meta'] ?? null,
|
||||||
|
ProtocolVersion::tryFrom($data['protocolVersion']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,8 +84,9 @@ class InitializeResult implements ResultInterface
|
||||||
*/
|
*/
|
||||||
public function jsonSerialize(): array
|
public function jsonSerialize(): array
|
||||||
{
|
{
|
||||||
|
$protocolVersion = $this->protocolVersion ?? MessageInterface::PROTOCOL_VERSION;
|
||||||
$data = [
|
$data = [
|
||||||
'protocolVersion' => MessageInterface::PROTOCOL_VERSION,
|
'protocolVersion' => $protocolVersion->value,
|
||||||
'capabilities' => $this->capabilities,
|
'capabilities' => $this->capabilities,
|
||||||
'serverInfo' => $this->serverInfo,
|
'serverInfo' => $this->serverInfo,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ use Mcp\Capability\Registry\Loader\LoaderInterface;
|
||||||
use Mcp\Capability\Registry\ReferenceHandler;
|
use Mcp\Capability\Registry\ReferenceHandler;
|
||||||
use Mcp\JsonRpc\MessageFactory;
|
use Mcp\JsonRpc\MessageFactory;
|
||||||
use Mcp\Schema\Annotations;
|
use Mcp\Schema\Annotations;
|
||||||
|
use Mcp\Schema\Enum\ProtocolVersion;
|
||||||
use Mcp\Schema\Implementation;
|
use Mcp\Schema\Implementation;
|
||||||
use Mcp\Schema\ServerCapabilities;
|
use Mcp\Schema\ServerCapabilities;
|
||||||
use Mcp\Schema\ToolAnnotations;
|
use Mcp\Schema\ToolAnnotations;
|
||||||
|
|
@ -63,6 +64,8 @@ final class Builder
|
||||||
|
|
||||||
private ?string $instructions = null;
|
private ?string $instructions = null;
|
||||||
|
|
||||||
|
private ?ProtocolVersion $protocolVersion = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<int, RequestHandlerInterface<mixed>>
|
* @var array<int, RequestHandlerInterface<mixed>>
|
||||||
*/
|
*/
|
||||||
|
|
@ -288,6 +291,13 @@ final class Builder
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setProtocolVersion(?ProtocolVersion $protocolVersion): self
|
||||||
|
{
|
||||||
|
$this->protocolVersion = $protocolVersion;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually registers a tool handler.
|
* Manually registers a tool handler.
|
||||||
*
|
*
|
||||||
|
|
@ -404,7 +414,7 @@ final class Builder
|
||||||
$messageFactory = MessageFactory::make();
|
$messageFactory = MessageFactory::make();
|
||||||
|
|
||||||
$capabilities = $registry->getCapabilities();
|
$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);
|
$referenceHandler = new ReferenceHandler($container);
|
||||||
|
|
||||||
$requestHandlers = array_merge($this->requestHandlers, [
|
$requestHandlers = array_merge($this->requestHandlers, [
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Mcp\Server;
|
namespace Mcp\Server;
|
||||||
|
|
||||||
|
use Mcp\Schema\Enum\ProtocolVersion;
|
||||||
use Mcp\Schema\Implementation;
|
use Mcp\Schema\Implementation;
|
||||||
use Mcp\Schema\ServerCapabilities;
|
use Mcp\Schema\ServerCapabilities;
|
||||||
|
|
||||||
|
|
@ -34,6 +35,7 @@ class Configuration
|
||||||
public readonly ServerCapabilities $capabilities,
|
public readonly ServerCapabilities $capabilities,
|
||||||
public readonly int $paginationLimit = 50,
|
public readonly int $paginationLimit = 50,
|
||||||
public readonly ?string $instructions = null,
|
public readonly ?string $instructions = null,
|
||||||
|
public readonly ?ProtocolVersion $protocolVersion = null,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ final class InitializeHandler implements RequestHandlerInterface
|
||||||
$this->configuration->capabilities ?? new ServerCapabilities(),
|
$this->configuration->capabilities ?? new ServerCapabilities(),
|
||||||
$this->configuration->serverInfo ?? new Implementation(),
|
$this->configuration->serverInfo ?? new Implementation(),
|
||||||
$this->configuration?->instructions,
|
$this->configuration?->instructions,
|
||||||
|
null,
|
||||||
|
$this->configuration?->protocolVersion,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
76
tests/Unit/Server/Handler/Request/InitializeHandlerTest.php
Normal file
76
tests/Unit/Server/Handler/Request/InitializeHandlerTest.php
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the official PHP MCP SDK.
|
||||||
|
*
|
||||||
|
* A collaboration between Symfony and the PHP Foundation.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Mcp\Tests\Unit\Server\Handler\Request;
|
||||||
|
|
||||||
|
use Mcp\Schema\Enum\ProtocolVersion;
|
||||||
|
use Mcp\Schema\Implementation;
|
||||||
|
use Mcp\Schema\JsonRpc\MessageInterface;
|
||||||
|
use Mcp\Schema\Request\InitializeRequest;
|
||||||
|
use Mcp\Schema\Result\InitializeResult;
|
||||||
|
use Mcp\Schema\ServerCapabilities;
|
||||||
|
use Mcp\Server\Configuration;
|
||||||
|
use Mcp\Server\Handler\Request\InitializeHandler;
|
||||||
|
use Mcp\Server\Session\SessionInterface;
|
||||||
|
use PHPUnit\Framework\Attributes\TestDox;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class InitializeHandlerTest extends TestCase
|
||||||
|
{
|
||||||
|
#[TestDox('uses configuration protocol version when provided')]
|
||||||
|
public function testHandleUsesConfigurationProtocolVersion(): void
|
||||||
|
{
|
||||||
|
$customProtocolVersion = ProtocolVersion::V2024_11_05;
|
||||||
|
|
||||||
|
$configuration = new Configuration(
|
||||||
|
serverInfo: new Implementation('server', '1.2.3'),
|
||||||
|
capabilities: new ServerCapabilities(),
|
||||||
|
protocolVersion: $customProtocolVersion,
|
||||||
|
);
|
||||||
|
|
||||||
|
$handler = new InitializeHandler($configuration);
|
||||||
|
|
||||||
|
$session = $this->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']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue