Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Schema/Enum/ProtocolVersion.php
Original file line number Diff line number Diff line change
@@ -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';
}
4 changes: 3 additions & 1 deletion src/Schema/JsonRpc/MessageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

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.
*
Expand All @@ -19,5 +21,5 @@
interface MessageInterface extends \JsonSerializable
{
public const JSONRPC_VERSION = '2.0';
public const PROTOCOL_VERSION = '2025-06-18';
public const PROTOCOL_VERSION = ProtocolVersion::V2025_06_18;
}
8 changes: 6 additions & 2 deletions src/Schema/Result/InitializeResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Mcp\Schema\Result;

use Mcp\Exception\InvalidArgumentException;
use Mcp\Schema\Enum\ProtocolVersion;
use Mcp\Schema\Implementation;
use Mcp\Schema\JsonRpc\MessageInterface;
use Mcp\Schema\JsonRpc\Response;
Expand All @@ -38,6 +39,7 @@ public function __construct(
public readonly Implementation $serverInfo,
public readonly ?string $instructions = null,
public readonly ?array $_meta = null,
public readonly ?ProtocolVersion $protocolVersion = null,
) {
}

Expand Down Expand Up @@ -66,7 +68,8 @@ public static function fromArray(array $data): self
ServerCapabilities::fromArray($data['capabilities']),
Implementation::fromArray($data['serverInfo']),
$data['instructions'] ?? null,
$data['_meta'] ?? null
$data['_meta'] ?? null,
ProtocolVersion::tryFrom($data['protocolVersion']),
);
}

Expand All @@ -81,8 +84,9 @@ public static function fromArray(array $data): self
*/
public function jsonSerialize(): array
{
$protocolVersion = $this->protocolVersion ?? MessageInterface::PROTOCOL_VERSION;
$data = [
'protocolVersion' => MessageInterface::PROTOCOL_VERSION,
'protocolVersion' => $protocolVersion->value,
'capabilities' => $this->capabilities,
'serverInfo' => $this->serverInfo,
];
Expand Down
12 changes: 11 additions & 1 deletion src/Server/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -75,6 +76,8 @@ final class Builder

private ?string $instructions = null;

private ?ProtocolVersion $protocolVersion = null;

/**
* @var array<int, RequestHandlerInterface>
*/
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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, [
Expand Down
2 changes: 2 additions & 0 deletions src/Server/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Mcp\Server;

use Mcp\Schema\Enum\ProtocolVersion;
use Mcp\Schema\Implementation;
use Mcp\Schema\ServerCapabilities;

Expand All @@ -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,
) {
}
}
2 changes: 2 additions & 0 deletions src/Server/Handler/Request/InitializeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
);
}
Expand Down
76 changes: 76 additions & 0 deletions tests/Unit/Server/Handler/Request/InitializeHandlerTest.php
Original file line number Diff line number Diff line change
@@ -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']
);
}
}