#!/usr/bin/env php info('Starting MCP Custom Method Handlers (Stdio) Server...'); $toolDefinitions = [ 'say_hello' => new Tool( name: 'say_hello', inputSchema: [ 'type' => 'object', 'properties' => [ 'name' => ['type' => 'string', 'description' => 'Name to greet'], ], 'required' => ['name'], ], description: 'Greets a user by name.', annotations: null, ), 'sum' => new Tool( name: 'sum', inputSchema: [ 'type' => 'object', 'properties' => [ 'a' => ['type' => 'number'], 'b' => ['type' => 'number'], ], 'required' => ['a', 'b'], ], description: 'Returns a+b.', annotations: null, ), ]; $listToolsHandler = new class($toolDefinitions) implements MethodHandlerInterface { /** * @param array $toolDefinitions */ public function __construct(private array $toolDefinitions) { } public function supports(HasMethodInterface $message): bool { return $message instanceof ListToolsRequest; } public function handle(ListToolsRequest|HasMethodInterface $message, SessionInterface $session): Response { assert($message instanceof ListToolsRequest); return new Response($message->getId(), new ListToolsResult(array_values($this->toolDefinitions), null)); } }; $callToolHandler = new class($toolDefinitions) implements MethodHandlerInterface { /** * @param array $toolDefinitions */ public function __construct(private array $toolDefinitions) { } public function supports(HasMethodInterface $message): bool { return $message instanceof CallToolRequest; } public function handle(CallToolRequest|HasMethodInterface $message, SessionInterface $session): Response|Error { assert($message instanceof CallToolRequest); $name = $message->name; $args = $message->arguments ?? []; if (!isset($this->toolDefinitions[$name])) { return new Error($message->getId(), Error::METHOD_NOT_FOUND, sprintf('Tool not found: %s', $name)); } try { switch ($name) { case 'say_hello': $greetName = (string) ($args['name'] ?? 'world'); $result = [new TextContent(sprintf('Hello, %s!', $greetName))]; break; case 'sum': $a = (float) ($args['a'] ?? 0); $b = (float) ($args['b'] ?? 0); $result = [new TextContent((string) ($a + $b))]; break; default: $result = [new TextContent('Unknown tool')]; } return new Response($message->getId(), new CallToolResult($result)); } catch (Throwable $e) { return new Response($message->getId(), new CallToolResult([new TextContent('Tool execution failed')], true)); } } }; $capabilities = new ServerCapabilities(tools: true, resources: false, prompts: false); $server = Server::builder() ->setServerInfo('Custom Handlers Server', '1.0.0') ->setLogger(logger()) ->setContainer(container()) ->setCapabilities($capabilities) ->addMethodHandlers([$listToolsHandler, $callToolHandler]) ->build(); $transport = new StdioTransport(logger: logger()); $result = $server->run($transport); logger()->info('Server listener stopped gracefully.', ['result' => $result]); exit($result);