chore: import zh skill php-mcp-server-generator
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# WeHub 来源说明
|
||||
|
||||
- Skill 名称:`php-mcp-server-generator`
|
||||
- 中文类目:MCP server 项目脚手架(其他语言栈)
|
||||
- 上游仓库:`github__awesome-copilot`
|
||||
- 上游路径:`plugins/php-mcp-development/skills/php-mcp-server-generator/SKILL.md`
|
||||
- 上游链接:https://github.com/github/awesome-copilot/blob/HEAD/plugins/php-mcp-development/skills/php-mcp-server-generator/SKILL.md
|
||||
- 本仓库为 WeHub 中文 Skill 汉化包,基于 skill 市场筛选 Top200 清单整理
|
||||
- 原作者、版权和许可证信息以上游仓库为准
|
||||
@@ -0,0 +1,522 @@
|
||||
---
|
||||
name: php-mcp-server-generator
|
||||
description: '使用官方 PHP SDK 生成一个完整的 PHP Model Context Protocol 服务端项目,包含工具、资源、提示词和测试'
|
||||
---
|
||||
|
||||
# PHP MCP 服务端生成器
|
||||
|
||||
你是一个 PHP MCP 服务端生成器。使用官方 PHP SDK 创建一个完整的、可用于生产环境的 PHP MCP 服务端项目。
|
||||
|
||||
## 项目要求
|
||||
|
||||
向用户询问以下内容:
|
||||
1. **项目名称**(例如:"my-mcp-server")
|
||||
2. **服务端描述**(例如:"一个文件管理 MCP 服务端")
|
||||
3. **传输类型**(stdio、http 或两者都支持)
|
||||
4. **要包含的工具**(例如:"文件读取"、"文件写入"、"列出目录")
|
||||
5. **是否包含资源和提示词**
|
||||
6. **PHP 版本**(要求 8.2 或以上)
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
{project-name}/
|
||||
├── composer.json
|
||||
├── .gitignore
|
||||
├── README.md
|
||||
├── server.php
|
||||
├── src/
|
||||
│ ├── Tools/
|
||||
│ │ └── {ToolClass}.php
|
||||
│ ├── Resources/
|
||||
│ │ └── {ResourceClass}.php
|
||||
│ ├── Prompts/
|
||||
│ │ └── {PromptClass}.php
|
||||
│ └── Providers/
|
||||
│ └── {CompletionProvider}.php
|
||||
└── tests/
|
||||
└── ToolsTest.php
|
||||
```
|
||||
|
||||
## 文件模板
|
||||
|
||||
### composer.json
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "your-org/{project-name}",
|
||||
"description": "{Server description}",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"mcp/sdk": "^0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"symfony/cache": "^6.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### .gitignore
|
||||
|
||||
```
|
||||
/vendor
|
||||
/cache
|
||||
composer.lock
|
||||
.phpunit.cache
|
||||
phpstan.neon
|
||||
```
|
||||
|
||||
### README.md
|
||||
|
||||
```markdown
|
||||
# {Project Name}
|
||||
|
||||
{Server description}
|
||||
|
||||
## 环境要求
|
||||
|
||||
- PHP 8.2 或更高版本
|
||||
- Composer
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
### 启动服务端(Stdio)
|
||||
|
||||
```bash
|
||||
php server.php
|
||||
```
|
||||
|
||||
### 在 Claude Desktop 中配置
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"{project-name}": {
|
||||
"command": "php",
|
||||
"args": ["/absolute/path/to/server.php"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
vendor/bin/phpunit
|
||||
```
|
||||
|
||||
## 工具
|
||||
|
||||
- **{tool_name}**:{Tool description}
|
||||
|
||||
## 开发
|
||||
|
||||
使用 MCP Inspector 进行测试:
|
||||
|
||||
```bash
|
||||
npx @modelcontextprotocol/inspector php server.php
|
||||
```
|
||||
```
|
||||
|
||||
### server.php
|
||||
|
||||
```php
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use Mcp\Server;
|
||||
use Mcp\Server\Transport\StdioTransport;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Psr16Cache;
|
||||
|
||||
// Setup cache for discovery
|
||||
$cache = new Psr16Cache(new FilesystemAdapter('mcp-discovery', 3600, __DIR__ . '/cache'));
|
||||
|
||||
// Build server with discovery
|
||||
$server = Server::builder()
|
||||
->setServerInfo('{Project Name}', '1.0.0')
|
||||
->setDiscovery(
|
||||
basePath: __DIR__,
|
||||
scanDirs: ['src'],
|
||||
excludeDirs: ['vendor', 'tests', 'cache'],
|
||||
cache: $cache
|
||||
)
|
||||
->build();
|
||||
|
||||
// Run with stdio transport
|
||||
$transport = new StdioTransport();
|
||||
|
||||
$server->run($transport);
|
||||
```
|
||||
|
||||
### src/Tools/ExampleTool.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tools;
|
||||
|
||||
use Mcp\Capability\Attribute\McpTool;
|
||||
use Mcp\Capability\Attribute\Schema;
|
||||
|
||||
class ExampleTool
|
||||
{
|
||||
/**
|
||||
* Performs a greeting with the provided name.
|
||||
*
|
||||
* @param string $name The name to greet
|
||||
* @return string A greeting message
|
||||
*/
|
||||
#[McpTool]
|
||||
public function greet(string $name): string
|
||||
{
|
||||
return "Hello, {$name}!";
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs arithmetic calculations.
|
||||
*/
|
||||
#[McpTool(name: 'calculate')]
|
||||
public function performCalculation(
|
||||
float $a,
|
||||
float $b,
|
||||
#[Schema(pattern: '^(add|subtract|multiply|divide)$')]
|
||||
string $operation
|
||||
): float {
|
||||
return match($operation) {
|
||||
'add' => $a + $b,
|
||||
'subtract' => $a - $b,
|
||||
'multiply' => $a * $b,
|
||||
'divide' => $b != 0 ? $a / $b :
|
||||
throw new \InvalidArgumentException('Division by zero'),
|
||||
default => throw new \InvalidArgumentException('Invalid operation')
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### src/Resources/ConfigResource.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Resources;
|
||||
|
||||
use Mcp\Capability\Attribute\McpResource;
|
||||
|
||||
class ConfigResource
|
||||
{
|
||||
/**
|
||||
* Provides application configuration.
|
||||
*/
|
||||
#[McpResource(
|
||||
uri: 'config://app/settings',
|
||||
name: 'app_config',
|
||||
mimeType: 'application/json'
|
||||
)]
|
||||
public function getConfiguration(): array
|
||||
{
|
||||
return [
|
||||
'version' => '1.0.0',
|
||||
'environment' => 'production',
|
||||
'features' => [
|
||||
'logging' => true,
|
||||
'caching' => true
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### src/Resources/DataProvider.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Resources;
|
||||
|
||||
use Mcp\Capability\Attribute\McpResourceTemplate;
|
||||
|
||||
class DataProvider
|
||||
{
|
||||
/**
|
||||
* Provides data by category and ID.
|
||||
*/
|
||||
#[McpResourceTemplate(
|
||||
uriTemplate: 'data://{category}/{id}',
|
||||
name: 'data_resource',
|
||||
mimeType: 'application/json'
|
||||
)]
|
||||
public function getData(string $category, string $id): array
|
||||
{
|
||||
// Example data retrieval
|
||||
return [
|
||||
'category' => $category,
|
||||
'id' => $id,
|
||||
'data' => "Sample data for {$category}/{$id}"
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### src/Prompts/PromptGenerator.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Prompts;
|
||||
|
||||
use Mcp\Capability\Attribute\McpPrompt;
|
||||
use Mcp\Capability\Attribute\CompletionProvider;
|
||||
|
||||
class PromptGenerator
|
||||
{
|
||||
/**
|
||||
* Generates a code review prompt.
|
||||
*/
|
||||
#[McpPrompt(name: 'code_review')]
|
||||
public function reviewCode(
|
||||
#[CompletionProvider(values: ['php', 'javascript', 'python', 'go', 'rust'])]
|
||||
string $language,
|
||||
string $code,
|
||||
#[CompletionProvider(values: ['performance', 'security', 'style', 'general'])]
|
||||
string $focus = 'general'
|
||||
): array {
|
||||
return [
|
||||
[
|
||||
'role' => 'assistant',
|
||||
'content' => 'You are an expert code reviewer specializing in best practices and optimization.'
|
||||
],
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => "Review this {$language} code with focus on {$focus}:\n\n```{$language}\n{$code}\n```"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates documentation prompt.
|
||||
*/
|
||||
#[McpPrompt]
|
||||
public function generateDocs(string $code, string $style = 'detailed'): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => "Generate {$style} documentation for:\n\n```\n{$code}\n```"
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tests/ToolsTest.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use App\Tools\ExampleTool;
|
||||
|
||||
class ToolsTest extends TestCase
|
||||
{
|
||||
private ExampleTool $tool;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->tool = new ExampleTool();
|
||||
}
|
||||
|
||||
public function testGreet(): void
|
||||
{
|
||||
$result = $this->tool->greet('World');
|
||||
$this->assertSame('Hello, World!', $result);
|
||||
}
|
||||
|
||||
public function testCalculateAdd(): void
|
||||
{
|
||||
$result = $this->tool->performCalculation(5, 3, 'add');
|
||||
$this->assertSame(8.0, $result);
|
||||
}
|
||||
|
||||
public function testCalculateDivide(): void
|
||||
{
|
||||
$result = $this->tool->performCalculation(10, 2, 'divide');
|
||||
$this->assertSame(5.0, $result);
|
||||
}
|
||||
|
||||
public function testCalculateDivideByZero(): void
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Division by zero');
|
||||
|
||||
$this->tool->performCalculation(10, 0, 'divide');
|
||||
}
|
||||
|
||||
public function testCalculateInvalidOperation(): void
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Invalid operation');
|
||||
|
||||
$this->tool->performCalculation(5, 3, 'modulo');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### phpunit.xml.dist
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
</phpunit>
|
||||
```
|
||||
|
||||
## 实现指南
|
||||
|
||||
1. **使用 PHP 属性(Attributes)**:利用 `#[McpTool]`、`#[McpResource]`、`#[McpPrompt]` 实现简洁代码
|
||||
2. **类型声明**:所有文件使用严格类型(`declare(strict_types=1);`)
|
||||
3. **PSR-12 编码规范**:遵循 PHP-FIG 标准
|
||||
4. **Schema 校验**:使用 `#[Schema]` 属性进行参数校验
|
||||
5. **错误处理**:抛出具体异常,附带清晰的消息
|
||||
6. **测试**:为所有工具编写 PHPUnit 测试
|
||||
7. **文档**:所有方法使用 PHPDoc 块
|
||||
8. **缓存**:生产环境中始终使用 PSR-16 缓存进行发现(discovery)
|
||||
|
||||
## 工具模式
|
||||
|
||||
### 简单工具
|
||||
```php
|
||||
#[McpTool]
|
||||
public function simpleAction(string $input): string
|
||||
{
|
||||
return "Processed: {$input}";
|
||||
}
|
||||
```
|
||||
|
||||
### 带校验的工具
|
||||
```php
|
||||
#[McpTool]
|
||||
public function validateEmail(
|
||||
#[Schema(format: 'email')]
|
||||
string $email
|
||||
): bool {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
|
||||
}
|
||||
```
|
||||
|
||||
### 带枚举的工具
|
||||
```php
|
||||
enum Status: string {
|
||||
case ACTIVE = 'active';
|
||||
case INACTIVE = 'inactive';
|
||||
}
|
||||
|
||||
#[McpTool]
|
||||
public function setStatus(string $id, Status $status): array
|
||||
{
|
||||
return ['id' => $id, 'status' => $status->value];
|
||||
}
|
||||
```
|
||||
|
||||
## 资源模式
|
||||
|
||||
### 静态资源
|
||||
```php
|
||||
#[McpResource(uri: 'config://settings', mimeType: 'application/json')]
|
||||
public function getSettings(): array
|
||||
{
|
||||
return ['key' => 'value'];
|
||||
}
|
||||
```
|
||||
|
||||
### 动态资源
|
||||
```php
|
||||
#[McpResourceTemplate(uriTemplate: 'user://{id}')]
|
||||
public function getUser(string $id): array
|
||||
{
|
||||
return $this->users[$id] ?? throw new \RuntimeException('User not found');
|
||||
}
|
||||
```
|
||||
|
||||
## 运行服务端
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
composer install
|
||||
|
||||
# 运行测试
|
||||
vendor/bin/phpunit
|
||||
|
||||
# 启动服务端
|
||||
php server.php
|
||||
|
||||
# 使用 inspector 测试
|
||||
npx @modelcontextprotocol/inspector php server.php
|
||||
```
|
||||
|
||||
## Claude Desktop 配置
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"{project-name}": {
|
||||
"command": "php",
|
||||
"args": ["/absolute/path/to/server.php"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
现在,根据用户需求生成完整的项目吧!
|
||||
Reference in New Issue
Block a user