[Examples] Demo pre-built instance handlers + inspector coverage (#390)

* [Tests] Bump MCP Inspector to 0.22.0 for 2025-11-25 protocol

The pinned inspector 0.17.2 predates the protocol version bump to
2025-11-25 (v0.6.0) and rejects the handshake with "Server's protocol
version is not supported", failing every inspector snapshot test. 0.22.0
negotiates the current protocol; the full inspector suite passes against
it (95 tests, 7 pre-existing skips).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [Examples] Demo pre-built instance handler in combined-registration

Extends the combined-registration example with a third handler style:
a pre-built object instance `[$instance, 'method']`, alongside the
existing discovered and manual class-string handlers. PreconfiguredGreeter
takes a scalar constructor argument neither the container-less
`new $className()` fallback nor the auto-wiring container can build, so it
can only be registered as an already-constructed instance — exercising the
resolver path added in the parent branch.

Adds an inspector snapshot case (tools/call instance_greeter) and updates
the tools/list snapshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christopher Hertel 2026-07-15 00:23:20 +02:00 • committed by GitHub
commit 1fed089d71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 99 additions and 7 deletions

View file

@ -0,0 +1,46 @@
<?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\Example\Server\CombinedRegistration;
use Psr\Log\LoggerInterface;
/**
* A handler whose constructor takes a scalar the container cannot auto-wire, so
* it can only be registered as a pre-built object instance:
* `->addTool([new PreconfiguredGreeter('...', ...), 'greet'], 'instance_greeter')`.
*
* Neither the container-less `new $className()` fallback nor the auto-wiring
* container can build this class, since the required `string $greeting` has no
* default and is not a resolvable service.
*/
final class PreconfiguredGreeter
{
public function __construct(
private readonly string $greeting,
private readonly LoggerInterface $logger,
) {
}
/**
* A tool registered as a pre-built object instance.
*
* @param string $name the name to greet
*
* @return string greeting
*/
public function greet(string $name): string
{
$this->logger->info("Instance tool 'instance_greeter' called for {$name}");
return "{$this->greeting}, {$name}!";
}
}

View file

@ -14,9 +14,15 @@ require_once dirname(__DIR__).'/bootstrap.php';
chdir(__DIR__);
use Mcp\Example\Server\CombinedRegistration\ManualHandlers;
use Mcp\Example\Server\CombinedRegistration\PreconfiguredGreeter;
use Mcp\Server;
use Mcp\Server\Session\FileSessionStore;
// Built here so its constructor dependencies (a scalar the container cannot
// auto-wire) are injected before registration; the SDK invokes this very
// instance instead of trying to construct one itself.
$preconfiguredGreeter = new PreconfiguredGreeter('Willkommen', logger());
$server = Server::builder()
->setServerInfo('Combined HTTP Server', '1.0.0')
->setLogger(logger())
@ -24,6 +30,7 @@ $server = Server::builder()
->setSession(new FileSessionStore(__DIR__.'/sessions'))
->setDiscovery(__DIR__)
->addTool([ManualHandlers::class, 'manualGreeter'])
->addTool([$preconfiguredGreeter, 'greet'], 'instance_greeter')
->addResource(
[ManualHandlers::class, 'getPriorityConfigManual'],
'config://priority',