Skip to content

Commit 5f97f2b

Browse files
refactor: use a custom method handler registration system
1 parent 4b91567 commit 5f97f2b

23 files changed

+864
-2678
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/*
5+
* This file is part of the official PHP MCP SDK.
6+
*
7+
* A collaboration between Symfony and the PHP Foundation.
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
require_once dirname(__DIR__).'/bootstrap.php';
14+
chdir(__DIR__);
15+
16+
use Mcp\Schema\Content\TextContent;
17+
use Mcp\Schema\JsonRpc\Error;
18+
use Mcp\Schema\JsonRpc\HasMethodInterface;
19+
use Mcp\Schema\JsonRpc\Response;
20+
use Mcp\Schema\Request\CallToolRequest;
21+
use Mcp\Schema\Request\ListToolsRequest;
22+
use Mcp\Schema\Result\CallToolResult;
23+
use Mcp\Schema\Result\ListToolsResult;
24+
use Mcp\Schema\ServerCapabilities;
25+
use Mcp\Schema\Tool;
26+
use Mcp\Server;
27+
use Mcp\Server\Handler\MethodHandlerInterface;
28+
use Mcp\Server\Session\SessionInterface;
29+
use Mcp\Server\Transport\StdioTransport;
30+
31+
logger()->info('Starting MCP Custom Method Handlers (Stdio) Server...');
32+
33+
$toolDefinitions = [
34+
'say_hello' => new Tool(
35+
name: 'say_hello',
36+
inputSchema: [
37+
'type' => 'object',
38+
'properties' => [
39+
'name' => ['type' => 'string', 'description' => 'Name to greet'],
40+
],
41+
'required' => ['name'],
42+
],
43+
description: 'Greets a user by name.',
44+
annotations: null,
45+
),
46+
'sum' => new Tool(
47+
name: 'sum',
48+
inputSchema: [
49+
'type' => 'object',
50+
'properties' => [
51+
'a' => ['type' => 'number'],
52+
'b' => ['type' => 'number'],
53+
],
54+
'required' => ['a', 'b'],
55+
],
56+
description: 'Returns a+b.',
57+
annotations: null,
58+
),
59+
];
60+
61+
$listToolsHandler = new class($toolDefinitions) implements MethodHandlerInterface {
62+
/**
63+
* @param array<string, Tool> $toolDefinitions
64+
*/
65+
public function __construct(private array $toolDefinitions)
66+
{
67+
}
68+
69+
public function supports(HasMethodInterface $message): bool
70+
{
71+
return $message instanceof ListToolsRequest;
72+
}
73+
74+
public function handle(ListToolsRequest|HasMethodInterface $message, SessionInterface $session): Response
75+
{
76+
assert($message instanceof ListToolsRequest);
77+
78+
return new Response($message->getId(), new ListToolsResult(array_values($this->toolDefinitions), null));
79+
}
80+
};
81+
82+
$callToolHandler = new class($toolDefinitions) implements MethodHandlerInterface {
83+
/**
84+
* @param array<string, Tool> $toolDefinitions
85+
*/
86+
public function __construct(private array $toolDefinitions)
87+
{
88+
}
89+
90+
public function supports(HasMethodInterface $message): bool
91+
{
92+
return $message instanceof CallToolRequest;
93+
}
94+
95+
public function handle(CallToolRequest|HasMethodInterface $message, SessionInterface $session): Response|Error
96+
{
97+
assert($message instanceof CallToolRequest);
98+
99+
$name = $message->name;
100+
$args = $message->arguments ?? [];
101+
102+
if (!isset($this->toolDefinitions[$name])) {
103+
return new Error($message->getId(), Error::METHOD_NOT_FOUND, sprintf('Tool not found: %s', $name));
104+
}
105+
106+
try {
107+
switch ($name) {
108+
case 'say_hello':
109+
$greetName = (string) ($args['name'] ?? 'world');
110+
$result = [new TextContent(sprintf('Hello, %s!', $greetName))];
111+
break;
112+
case 'sum':
113+
$a = (float) ($args['a'] ?? 0);
114+
$b = (float) ($args['b'] ?? 0);
115+
$result = [new TextContent((string) ($a + $b))];
116+
break;
117+
default:
118+
$result = [new TextContent('Unknown tool')];
119+
}
120+
121+
return new Response($message->getId(), new CallToolResult($result));
122+
} catch (Throwable $e) {
123+
return new Response($message->getId(), new CallToolResult([new TextContent('Tool execution failed')], true));
124+
}
125+
}
126+
};
127+
128+
$capabilities = new ServerCapabilities(tools: true, resources: false, prompts: false);
129+
130+
$server = Server::builder()
131+
->setServerInfo('Custom Handlers Server', '1.0.0')
132+
->setLogger(logger())
133+
->setContainer(container())
134+
->setCapabilities($capabilities)
135+
->addMethodHandlers([$listToolsHandler, $callToolHandler])
136+
->build();
137+
138+
$transport = new StdioTransport(logger: logger());
139+
140+
$server->connect($transport);
141+
142+
$transport->listen();
143+
144+
logger()->info('Server listener stopped gracefully.');

src/Capability/Prompt/PromptGetter.php

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/Capability/Prompt/PromptGetterInterface.php

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/Capability/Resource/ResourceReader.php

Lines changed: 0 additions & 68 deletions
This file was deleted.

src/Capability/Resource/ResourceReaderInterface.php

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)