Skip to content

Latest commit

 

History

History
47 lines (38 loc) · 2.21 KB

index.md

File metadata and controls

47 lines (38 loc) · 2.21 KB

Inside your handler

The methods you register are ordinary PHP methods, but they are not cut off from the protocol. Type-hint a Mcp\Server\RequestContext argument anywhere in the signature and the SDK passes it in — that object is the way back to the client mid-request.

use Mcp\Capability\Attribute\McpTool;
use Mcp\Schema\Elicitation\ElicitationSchema;
use Mcp\Schema\Elicitation\StringSchemaDefinition;
use Mcp\Server\RequestContext;

#[McpTool]
public function bookTable(string $restaurant, RequestContext $context): string
{
    $context->getClientLogger()->info(\sprintf('Booking a table at %s', $restaurant));

    $schema = new ElicitationSchema(['name' => new StringSchemaDefinition('Name for the booking')], ['name']);
    $answer = $context->getClientGateway()->elicit('Who is the booking for?', $schema);

    if (!$answer->isAccepted()) {
        return 'No table booked.';
    }

    return \sprintf('Table at %s booked for %s.', $restaurant, $answer->content['name']);
}

Two caveats on this example. The ClientLogger drops messages below warning until the client asks for a lower level (see Logging), so the info() message is not sent by default. On protocol version 2026-07-28, it sends no log messages at all unless the request asks for them. And elicit() works on both protocol versions, but your handler may run more than once for one call. Asking for input explains how to write it for that.

  • Talking back to the client — the ClientGateway: asking the client's model for a completion (sampling), reporting progress on a long call, and sending notifications.
  • Logging — structured PSR-3 log messages that surface in the client, not in your server's log file.
  • Asking for input — ClientGateway::elicit(), or returning an InputRequiredResult when a handler needs several answers at once. Either way, one handler serves both protocol eras.

Handlers that need application services (a database connection, an API client) get them from the container instead; see Service dependencies.