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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ All notable changes to `mcp/sdk` will be documented in this file.
0.9.0
-----

* [BC Break] `SchemaValidator` takes an optional `Opis\JsonSchema\Validator` as its first constructor argument, moving `$logger` to second. Pass `logger:` by name.
* Add `Builder::setSchemaValidator()` to configure the validator used for `tools/call` input, e.g. with a resolver for external `$ref` schemas.
* [BC Break] Remove the `providerClass` argument of `#[CompletionProvider]`. Use `provider:`, which takes the same class-string and is now the first positional argument.
* Add `HttpTransport::getSessionId()` to read the server-minted `Mcp-Session-Id`: a request-scoped caller can persist it and pass it back through the constructor's `$headers` on a later transport. Always `null` on `2026-07-28`, which removed protocol-level sessions.

Expand Down
3 changes: 1 addition & 2 deletions src/Capability/Discovery/SchemaValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@
*/
class SchemaValidator
{
private ?Validator $jsonSchemaValidator = null;

public function __construct(
private ?Validator $jsonSchemaValidator = null,
private LoggerInterface $logger = new NullLogger(),
) {
}
Expand Down
12 changes: 11 additions & 1 deletion src/Server/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Mcp\Capability\Discovery\Discoverer;
use Mcp\Capability\Discovery\DiscovererInterface;
use Mcp\Capability\Discovery\SchemaGeneratorInterface;
use Mcp\Capability\Discovery\SchemaValidator;
use Mcp\Capability\Registry;
use Mcp\Capability\Registry\Container;
use Mcp\Capability\Registry\ElementReference;
Expand Down Expand Up @@ -105,6 +106,8 @@ final class Builder

private ?SchemaGeneratorInterface $schemaGenerator = null;

private ?SchemaValidator $schemaValidator = null;

private ?ReferenceHandlerInterface $referenceHandler = null;

private ?DiscovererInterface $discoverer = null;
Expand Down Expand Up @@ -582,6 +585,13 @@ public function setSchemaGenerator(SchemaGeneratorInterface $schemaGenerator): s
return $this;
}

public function setSchemaValidator(SchemaValidator $schemaValidator): self
{
$this->schemaValidator = $schemaValidator;

return $this;
}

public function setReferenceHandler(ReferenceHandlerInterface $referenceHandler): self
{
$this->referenceHandler = $referenceHandler;
Expand Down Expand Up @@ -1084,7 +1094,7 @@ private function resolve(): array
$referenceHandler = $this->referenceHandler ?? new ReferenceHandler($container);

$requestHandlers = array_merge($this->requestHandlers, [
new Handler\Request\CallToolHandler($registry, $referenceHandler, $logger),
new Handler\Request\CallToolHandler($registry, $referenceHandler, $logger, $this->schemaValidator),
new Handler\Request\CompletionCompleteHandler($registry, $container, $logger),
new Handler\Request\GetPromptHandler($registry, $referenceHandler, $logger),
new Handler\Request\InitializeHandler($configuration),
Expand Down
2 changes: 1 addition & 1 deletion src/Server/Handler/Request/CallToolHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function __construct(
private readonly LoggerInterface $logger = new NullLogger(),
?SchemaValidator $schemaValidator = null,
) {
$this->schemaValidator = $schemaValidator ?? new SchemaValidator($logger);
$this->schemaValidator = $schemaValidator ?? new SchemaValidator(logger: $logger);
}

public function supports(Request $request): bool
Expand Down
17 changes: 17 additions & 0 deletions tests/Unit/Server/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ public function testCustomReferenceHandlerIsUsedForToolCalls(): void
$this->assertSame('intercepted', $result);
}

#[TestDox('Custom SchemaValidator is used when calling a tool')]
public function testCustomSchemaValidatorIsUsedForToolCalls(): void
{
$schemaValidator = $this->createMock(\Mcp\Capability\Discovery\SchemaValidator::class);
$schemaValidator->expects($this->once())
->method('validateAgainstJsonSchema')
->willReturn([]);

$server = Server::builder()
->setServerInfo('test', '1.0.0')
->setSchemaValidator($schemaValidator)
->addTool(static fn (): string => 'validated', name: 'test_tool', description: 'A test tool')
->build();

$this->assertSame('validated', $this->callTool($server, 'test_tool'));
}

#[TestDox('A pre-built instance handler with constructor dependencies is registered and invoked on that instance')]
public function testPreBuiltInstanceHandlerIsInvokedOnTheGivenInstance(): void
{
Expand Down