Enable servers to send sampling messages to clients (#101)

This commit is contained in:
Christopher Hertel 2025-11-01 09:02:24 +01:00 • committed by GitHub
commit fb3c1e65a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -13,7 +13,9 @@ namespace Mcp\Capability\Registry;
use Mcp\Exception\InvalidArgumentException;
use Mcp\Exception\RegistryException;
use Mcp\Server\ClientAwareInterface;
use Mcp\Server\ClientGateway;
use Mcp\Server\Session\SessionInterface;
use Psr\Container\ContainerInterface;
/**
@ -31,12 +33,18 @@ final class ReferenceHandler implements ReferenceHandlerInterface
*/
public function handle(ElementReference $reference, array $arguments): mixed
{
$session = $arguments['_session'];
if (\is_string($reference->handler)) {
if (class_exists($reference->handler) && method_exists($reference->handler, '__invoke')) {
$reflection = new \ReflectionMethod($reference->handler, '__invoke');
$instance = $this->getClassInstance($reference->handler);
$arguments = $this->prepareArguments($reflection, $arguments);
if ($instance instanceof ClientAwareInterface) {
$instance->setClient(new ClientGateway($session));
}
return \call_user_func($instance, ...$arguments);
}
@ -49,7 +57,7 @@ final class ReferenceHandler implements ReferenceHandlerInterface
}
if (\is_callable($reference->handler)) {
$reflection = $this->getReflectionForCallable($reference->handler);
$reflection = $this->getReflectionForCallable($reference->handler, $session);
$arguments = $this->prepareArguments($reflection, $arguments);
return \call_user_func($reference->handler, ...$arguments);
@ -59,6 +67,11 @@ final class ReferenceHandler implements ReferenceHandlerInterface
[$className, $methodName] = $reference->handler;
$reflection = new \ReflectionMethod($className, $methodName);
$instance = $this->getClassInstance($className);
if ($instance instanceof ClientAwareInterface) {
$instance->setClient(new ClientGateway($session));
}
$arguments = $this->prepareArguments($reflection, $arguments);
return \call_user_func([$instance, $methodName], ...$arguments);
@ -130,7 +143,7 @@ final class ReferenceHandler implements ReferenceHandlerInterface
/**
* Gets a ReflectionMethod or ReflectionFunction for a callable.
*/
private function getReflectionForCallable(callable $handler): \ReflectionMethod|\ReflectionFunction
private function getReflectionForCallable(callable $handler, SessionInterface $session): \ReflectionMethod|\ReflectionFunction
{
if (\is_string($handler)) {
return new \ReflectionFunction($handler);
@ -143,6 +156,10 @@ final class ReferenceHandler implements ReferenceHandlerInterface
if (\is_array($handler) && 2 === \count($handler)) {
[$class, $method] = $handler;
if ($class instanceof ClientAwareInterface) {
$class->setClient(new ClientGateway($session));
}
return new \ReflectionMethod($class, $method);
}