Skip to content

Commit e01cb29

Browse files
committed
feat(docs): add annotation-based registration section to Hyperf integration guide
1 parent c4fe4d1 commit e01cb29

File tree

2 files changed

+644
-0
lines changed

2 files changed

+644
-0
lines changed

docs/cn/server/hyperf-integration.md

Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)