@@ -26,6 +26,328 @@ Router::post('/mcp', function () {
2626
2727> ** 注意** : ConfigProvider 会由 Hyperf 自动加载,无需手动注册到 ` config/config.php ` 。
2828
29+ ## 📝 基于注解的注册
30+
31+ 注册 MCP 工具、提示和资源的最简单方法是使用注解。这种方法会自动从方法签名生成 schema 并处理注册。
32+
33+ ### 可用注解
34+
35+ #### ` #[McpTool] ` - 注册工具
36+
37+ 使用 ` #[McpTool] ` 注解将方法注册为 MCP 工具:
38+
39+ ``` php
40+ <?php
41+ declare(strict_types=1);
42+
43+ namespace App\Service;
44+
45+ use Dtyq\PhpMcp\Server\Framework\Hyperf\Collector\Annotations\McpTool;
46+
47+ class CalculatorService
48+ {
49+ #[McpTool]
50+ public function calculate(string $operation, int $a, int $b): array
51+ {
52+ $result = match ($operation) {
53+ 'add' => $a + $b,
54+ 'subtract' => $a - $b,
55+ 'multiply' => $a * $b,
56+ 'divide' => $a / $b,
57+ default => null,
58+ };
59+
60+ return [
61+ 'operation' => $operation,
62+ 'operands' => [$a, $b],
63+ 'result' => $result,
64+ ];
65+ }
66+
67+ #[McpTool(
68+ name: 'advanced_calc',
69+ description: '高级数学计算',
70+ group: 'math'
71+ )]
72+ public function advancedCalculate(string $formula, array $variables = []): float
73+ {
74+ // 复杂计算逻辑
75+ return 42.0;
76+ }
77+ }
78+ ```
79+
80+ ** 注解参数:**
81+ - ` name ` : 工具名称(默认为方法名)
82+ - ` description ` : 工具描述
83+ - ` inputSchema ` : 自定义输入 schema(为空时自动生成)
84+ - ` group ` : 工具分组,用于组织
85+ - ` enabled ` : 是否启用工具(默认:true)
86+
87+ #### ` #[McpPrompt] ` - 注册提示
88+
89+ 使用 ` #[McpPrompt] ` 注解将方法注册为提示模板:
90+
91+ ``` php
92+ <?php
93+ declare(strict_types=1);
94+
95+ namespace App\Service;
96+
97+ use Dtyq\PhpMcp\Server\Framework\Hyperf\Collector\Annotations\McpPrompt;
98+ use Dtyq\PhpMcp\Types\Prompts\GetPromptResult;
99+ use Dtyq\PhpMcp\Types\Prompts\PromptMessage;
100+ use Dtyq\PhpMcp\Types\Content\TextContent;
101+ use Dtyq\PhpMcp\Types\Core\ProtocolConstants;
102+
103+ class PromptService
104+ {
105+ #[McpPrompt]
106+ public function greeting(string $name, string $language = 'chinese'): GetPromptResult
107+ {
108+ $greetings = [
109+ 'english' => "Hello, {$name}! Welcome to the Streamable HTTP MCP server!",
110+ 'spanish' => "¡Hola, {$name}! ¡Bienvenido al servidor MCP Streamable HTTP!",
111+ 'french' => "Bonjour, {$name}! Bienvenue sur le serveur MCP Streamable HTTP!",
112+ 'chinese' => "你好,{$name}!欢迎使用 Streamable HTTP MCP 服务器!",
113+ ];
114+
115+ $message = new PromptMessage(
116+ ProtocolConstants::ROLE_USER,
117+ new TextContent($greetings[$language] ?? $greetings['chinese'])
118+ );
119+
120+ return new GetPromptResult('问候提示', [$message]);
121+ }
122+
123+ #[McpPrompt(
124+ name: 'code_review',
125+ description: '生成代码审查提示',
126+ group: 'development'
127+ )]
128+ public function codeReview(string $code, string $language = 'php'): GetPromptResult
129+ {
130+ $prompt = "请审查以下 {$language} 代码:\n\n```{$language}\n{$code}\n```\n\n请提供以下方面的反馈:\n- 代码质量\n- 最佳实践\n- 潜在改进";
131+
132+ $message = new PromptMessage(
133+ ProtocolConstants::ROLE_USER,
134+ new TextContent($prompt)
135+ );
136+
137+ return new GetPromptResult('代码审查提示', [$message]);
138+ }
139+ }
140+ ```
141+
142+ ** 注解参数:**
143+ - ` name ` : 提示名称(默认为方法名)
144+ - ` description ` : 提示描述
145+ - ` arguments ` : 自定义参数 schema(为空时自动生成)
146+ - ` group ` : 提示分组,用于组织
147+ - ` enabled ` : 是否启用提示(默认:true)
148+
149+ #### ` #[McpResource] ` - 注册资源
150+
151+ 使用 ` #[McpResource] ` 注解将方法注册为资源提供者:
152+
153+ ``` php
154+ <?php
155+ declare(strict_types=1);
156+
157+ namespace App\Service;
158+
159+ use Dtyq\PhpMcp\Server\Framework\Hyperf\Collector\Annotations\McpResource;
160+ use Dtyq\PhpMcp\Types\Resources\TextResourceContents;
161+
162+ class SystemService
163+ {
164+ #[McpResource]
165+ public function systemInfo(): TextResourceContents
166+ {
167+ $info = [
168+ 'php_version' => PHP_VERSION,
169+ 'os' => PHP_OS,
170+ 'memory_usage' => memory_get_usage(true),
171+ 'timestamp' => date('c'),
172+ 'pid' => getmypid(),
173+ ];
174+
175+ return new TextResourceContents(
176+ 'mcp://system/info',
177+ json_encode($info, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
178+ 'application/json'
179+ );
180+ }
181+
182+ #[McpResource(
183+ name: 'server_config',
184+ uri: 'mcp://system/config',
185+ description: '服务器配置数据',
186+ mimeType: 'application/json'
187+ )]
188+ public function serverConfig(): TextResourceContents
189+ {
190+ $config = [
191+ 'environment' => env('APP_ENV', 'production'),
192+ 'debug' => env('APP_DEBUG', false),
193+ 'timezone' => date_default_timezone_get(),
194+ ];
195+
196+ return new TextResourceContents(
197+ 'mcp://system/config',
198+ json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
199+ 'application/json'
200+ );
201+ }
202+ }
203+ ```
204+
205+ ** 注解参数:**
206+ - ` name ` : 资源名称(默认为方法名)
207+ - ` uri ` : 资源 URI(为空时自动生成)
208+ - ` description ` : 资源描述
209+ - ` mimeType ` : 资源 MIME 类型
210+ - ` size ` : 资源大小(字节)
211+ - ` group ` : 资源分组,用于组织
212+ - ` enabled ` : 是否启用资源(默认:true)
213+ - ` isTemplate ` : 是否为模板资源
214+ - ` uriTemplate ` : URI 模板参数
215+
216+ ### Schema 自动生成
217+
218+ 注解系统会自动从方法签名生成 JSON schema:
219+
220+ ``` php
221+ #[McpTool]
222+ public function processUser(
223+ string $userId, // 必需的字符串参数
224+ int $age = 18, // 可选的整数参数,有默认值
225+ bool $active = true, // 可选的布尔参数,有默认值
226+ array $tags = [] // 可选的数组参数,默认为空数组
227+ ): array {
228+ // 实现代码
229+ }
230+ ```
231+
232+ 这会生成以下 schema:
233+ ``` json
234+ {
235+ "type" : " object" ,
236+ "properties" : {
237+ "userId" : {
238+ "type" : " string" ,
239+ "description" : " Parameter: userId"
240+ },
241+ "age" : {
242+ "type" : " integer" ,
243+ "description" : " Parameter: age" ,
244+ "default" : 18
245+ },
246+ "active" : {
247+ "type" : " boolean" ,
248+ "description" : " Parameter: active" ,
249+ "default" : true
250+ },
251+ "tags" : {
252+ "type" : " array" ,
253+ "description" : " Parameter: tags" ,
254+ "items" : {"type" : " string" },
255+ "default" : []
256+ }
257+ },
258+ "required" : [" userId" ]
259+ }
260+ ```
261+
262+ ** 支持的类型:**
263+ - ` string ` → ` "type": "string" `
264+ - ` int ` , ` integer ` → ` "type": "integer" `
265+ - ` float ` , ` double ` → ` "type": "number" `
266+ - ` bool ` , ` boolean ` → ` "type": "boolean" `
267+ - ` array ` → ` "type": "array" `
268+
269+ > ** 注意** : 不支持复杂类型(类、接口、联合类型)。自动 schema 生成只允许基本 PHP 类型。
270+
271+ ### 基于分组的注册
272+
273+ 您可以使用分组来组织注解并加载特定分组:
274+
275+ ``` php
276+ // 只注册数学相关工具
277+ Router::post('/mcp/math', function () {
278+ return di(HyperfMcpServer::class)->handler('math');
279+ });
280+
281+ // 注册开发工具
282+ Router::post('/mcp/dev', function () {
283+ return di(HyperfMcpServer::class)->handler('development');
284+ });
285+
286+ // 注册所有工具(默认分组)
287+ Router::post('/mcp', function () {
288+ return di(HyperfMcpServer::class)->handler();
289+ });
290+ ```
291+
292+ ### 完整注解示例
293+
294+ 这是一个使用所有三种注解类型的完整服务类:
295+
296+ ``` php
297+ <?php
298+ declare(strict_types=1);
299+
300+ namespace App\Service;
301+
302+ use Dtyq\PhpMcp\Server\Framework\Hyperf\Collector\Annotations\McpTool;
303+ use Dtyq\PhpMcp\Server\Framework\Hyperf\Collector\Annotations\McpPrompt;
304+ use Dtyq\PhpMcp\Server\Framework\Hyperf\Collector\Annotations\McpResource;
305+ use Dtyq\PhpMcp\Types\Prompts\GetPromptResult;
306+ use Dtyq\PhpMcp\Types\Prompts\PromptMessage;
307+ use Dtyq\PhpMcp\Types\Content\TextContent;
308+ use Dtyq\PhpMcp\Types\Core\ProtocolConstants;
309+ use Dtyq\PhpMcp\Types\Resources\TextResourceContents;
310+
311+ class McpDemoService
312+ {
313+ #[McpTool(description: '回显消息')]
314+ public function echo(string $message): array
315+ {
316+ return [
317+ 'echo' => $message,
318+ 'timestamp' => time(),
319+ ];
320+ }
321+
322+ #[McpPrompt(description: '生成欢迎消息')]
323+ public function welcome(string $username): GetPromptResult
324+ {
325+ $message = new PromptMessage(
326+ ProtocolConstants::ROLE_USER,
327+ new TextContent("欢迎 {$username} 来到我们的 MCP 服务器!")
328+ );
329+
330+ return new GetPromptResult('欢迎消息', [$message]);
331+ }
332+
333+ #[McpResource(description: '当前服务器状态')]
334+ public function status(): TextResourceContents
335+ {
336+ $status = [
337+ 'status' => 'healthy',
338+ 'uptime' => time() - $_SERVER['REQUEST_TIME'],
339+ 'memory' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB',
340+ ];
341+
342+ return new TextResourceContents(
343+ 'mcp://server/status',
344+ json_encode($status, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
345+ 'application/json'
346+ );
347+ }
348+ }
349+ ```
350+
29351## 🔧 高级配置
30352
31353### 自定义认证
0 commit comments