[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ADYCFXMEDRETGERE77J0TP":3,"skill-same:01M6ADYCFXMEDRETGERE77J0TP":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":57,"ownerHtmlUrl":58,"ownerBlogUrl":59,"ownerDescription":60,"updatedAt":61,"install":62,"resources":75},"01M6ADYCFXMEDRETGERE77J0TP","php-mcp-server-generator",null,"Generate a complete PHP Model Context Protocol server project with tools, resources, prompts, and tests using the official PHP SDK","github\u002Fawesome-copilot","github","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9919?v=4","01M6AC83DS133TPXFSP1DHNCC6","GitHub","01M6AD3PBDYPK7NVFJNJ66Y8RS",41046,"MIT","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fphp-mcp-server-generator\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"MCP","mcp server","generator","server","php mcp server generator","php","with tools","with","resources","complete","tests","project","context","model","Tools","protocol","generate","official","model context protocol","sdk","2026-11-10 10:12:30",false,"---\nname: php-mcp-server-generator\ndescription: 'Generate a complete PHP Model Context Protocol server project with tools, resources, prompts, and tests using the official PHP SDK'\n---\n\n# PHP MCP Server Generator\n\nYou are a PHP MCP server generator. Create a complete, production-ready PHP MCP server project using the official PHP SDK.\n\n## Project Requirements\n\nAsk the user for:\n1. **Project name** (e.g., \"my-mcp-server\")\n2. **Server description** (e.g., \"A file management MCP server\")\n3. **Transport type** (stdio, http, or both)\n4. **Tools to include** (e.g., \"file read\", \"file write\", \"list directory\")\n5. **Whether to include resources and prompts**\n6. **PHP version** (8.2+ required)\n\n## Project Structure\n\n```\n{project-name}\u002F\n├── composer.json\n├── .gitignore\n├── README.md\n├── server.php\n├── src\u002F\n│   ├── Tools\u002F\n│   │   └── {ToolClass}.php\n│   ├── Resources\u002F\n│   │   └── {ResourceClass}.php\n│   ├── Prompts\u002F\n│   │   └── {PromptClass}.php\n│   └── Providers\u002F\n│       └── {CompletionProvider}.php\n└── tests\u002F\n    └── ToolsTest.php\n```\n\n## File Templates\n\n### composer.json\n\n```json\n{\n    \"name\": \"your-org\u002F{project-name}\",\n    \"description\": \"{Server description}\",\n    \"type\": \"project\",\n    \"require\": {\n        \"php\": \"^8.2\",\n        \"mcp\u002Fsdk\": \"^0.1\"\n    },\n    \"require-dev\": {\n        \"phpunit\u002Fphpunit\": \"^10.0\",\n        \"symfony\u002Fcache\": \"^6.4\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"App\\\\\\\\\": \"src\u002F\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Tests\\\\\\\\\": \"tests\u002F\"\n        }\n    },\n    \"config\": {\n        \"optimize-autoloader\": true,\n        \"preferred-install\": \"dist\",\n        \"sort-packages\": true\n    }\n}\n```\n\n### .gitignore\n\n```\n\u002Fvendor\n\u002Fcache\ncomposer.lock\n.phpunit.cache\nphpstan.neon\n```\n\n### README.md\n\n```markdown\n# {Project Name}\n\n{Server description}\n\n## Requirements\n\n- PHP 8.2 or higher\n- Composer\n\n## Installation\n\n```bash\ncomposer install\n```\n\n## Usage\n\n### Start Server (Stdio)\n\n```bash\nphp server.php\n```\n\n### Configure in Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"{project-name}\": {\n      \"command\": \"php\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fserver.php\"]\n    }\n  }\n}\n```\n\n## Testing\n\n```bash\nvendor\u002Fbin\u002Fphpunit\n```\n\n## Tools\n\n- **{tool_name}**: {Tool description}\n\n## Development\n\nTest with MCP Inspector:\n\n```bash\nnpx @modelcontextprotocol\u002Finspector php server.php\n```\n```\n\n### server.php\n\n```php\n#!\u002Fusr\u002Fbin\u002Fenv php\n\u003C?php\n\ndeclare(strict_types=1);\n\nrequire_once __DIR__ . '\u002Fvendor\u002Fautoload.php';\n\nuse Mcp\\Server;\nuse Mcp\\Server\\Transport\\StdioTransport;\nuse Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\nuse Symfony\\Component\\Cache\\Psr16Cache;\n\n\u002F\u002F Setup cache for discovery\n$cache = new Psr16Cache(new FilesystemAdapter('mcp-discovery', 3600, __DIR__ . '\u002Fcache'));\n\n\u002F\u002F Build server with discovery\n$server = Server::builder()\n    ->setServerInfo('{Project Name}', '1.0.0')\n    ->setDiscovery(\n        basePath: __DIR__,\n        scanDirs: ['src'],\n        excludeDirs: ['vendor', 'tests', 'cache'],\n        cache: $cache\n    )\n    ->build();\n\n\u002F\u002F Run with stdio transport\n$transport = new StdioTransport();\n\n$server->run($transport);\n```\n\n### src\u002FTools\u002FExampleTool.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Tools;\n\nuse Mcp\\Capability\\Attribute\\McpTool;\nuse Mcp\\Capability\\Attribute\\Schema;\n\nclass ExampleTool\n{\n    \u002F**\n     * Performs a greeting with the provided name.\n     * \n     * @param string $name The name to greet\n     * @return string A greeting message\n     *\u002F\n    #[McpTool]\n    public function greet(string $name): string\n    {\n        return \"Hello, {$name}!\";\n    }\n    \n    \u002F**\n     * Performs arithmetic calculations.\n     *\u002F\n    #[McpTool(name: 'calculate')]\n    public function performCalculation(\n        float $a,\n        float $b,\n        #[Schema(pattern: '^(add|subtract|multiply|divide)$')]\n        string $operation\n    ): float {\n        return match($operation) {\n            'add' => $a + $b,\n            'subtract' => $a - $b,\n            'multiply' => $a * $b,\n            'divide' => $b != 0 ? $a \u002F $b : \n                throw new \\InvalidArgumentException('Division by zero'),\n            default => throw new \\InvalidArgumentException('Invalid operation')\n        };\n    }\n}\n```\n\n### src\u002FResources\u002FConfigResource.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Resources;\n\nuse Mcp\\Capability\\Attribute\\McpResource;\n\nclass ConfigResource\n{\n    \u002F**\n     * Provides application configuration.\n     *\u002F\n    #[McpResource(\n        uri: 'config:\u002F\u002Fapp\u002Fsettings',\n        name: 'app_config',\n        mimeType: 'application\u002Fjson'\n    )]\n    public function getConfiguration(): array\n    {\n        return [\n            'version' => '1.0.0',\n            'environment' => 'production',\n            'features' => [\n                'logging' => true,\n                'caching' => true\n            ]\n        ];\n    }\n}\n```\n\n### src\u002FResources\u002FDataProvider.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Resources;\n\nuse Mcp\\Capability\\Attribute\\McpResourceTemplate;\n\nclass DataProvider\n{\n    \u002F**\n     * Provides data by category and ID.\n     *\u002F\n    #[McpResourceTemplate(\n        uriTemplate: 'data:\u002F\u002F{category}\u002F{id}',\n        name: 'data_resource',\n        mimeType: 'application\u002Fjson'\n    )]\n    public function getData(string $category, string $id): array\n    {\n        \u002F\u002F Example data retrieval\n        return [\n            'category' => $category,\n            'id' => $id,\n            'data' => \"Sample data for {$category}\u002F{$id}\"\n        ];\n    }\n}\n```\n\n### src\u002FPrompts\u002FPromptGenerator.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Prompts;\n\nuse Mcp\\Capability\\Attribute\\McpPrompt;\nuse Mcp\\Capability\\Attribute\\CompletionProvider;\n\nclass PromptGenerator\n{\n    \u002F**\n     * Generates a code review prompt.\n     *\u002F\n    #[McpPrompt(name: 'code_review')]\n    public function reviewCode(\n        #[CompletionProvider(values: ['php', 'javascript', 'python', 'go', 'rust'])]\n        string $language,\n        string $code,\n        #[CompletionProvider(values: ['performance', 'security', 'style', 'general'])]\n        string $focus = 'general'\n    ): array {\n        return [\n            [\n                'role' => 'assistant',\n                'content' => 'You are an expert code reviewer specializing in best practices and optimization.'\n            ],\n            [\n                'role' => 'user',\n                'content' => \"Review this {$language} code with focus on {$focus}:\\n\\n```{$language}\\n{$code}\\n```\"\n            ]\n        ];\n    }\n    \n    \u002F**\n     * Generates documentation prompt.\n     *\u002F\n    #[McpPrompt]\n    public function generateDocs(string $code, string $style = 'detailed'): array\n    {\n        return [\n            [\n                'role' => 'user',\n                'content' => \"Generate {$style} documentation for:\\n\\n```\\n{$code}\\n```\"\n            ]\n        ];\n    }\n}\n```\n\n### tests\u002FToolsTest.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse App\\Tools\\ExampleTool;\n\nclass ToolsTest extends TestCase\n{\n    private ExampleTool $tool;\n    \n    protected function setUp(): void\n    {\n        $this->tool = new ExampleTool();\n    }\n    \n    public function testGreet(): void\n    {\n        $result = $this->tool->greet('World');\n        $this->assertSame('Hello, World!', $result);\n    }\n    \n    public function testCalculateAdd(): void\n    {\n        $result = $this->tool->performCalculation(5, 3, 'add');\n        $this->assertSame(8.0, $result);\n    }\n    \n    public function testCalculateDivide(): void\n    {\n        $result = $this->tool->performCalculation(10, 2, 'divide');\n        $this->assertSame(5.0, $result);\n    }\n    \n    public function testCalculateDivideByZero(): void\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Division by zero');\n        \n        $this->tool->performCalculation(10, 0, 'divide');\n    }\n    \n    public function testCalculateInvalidOperation(): void\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid operation');\n        \n        $this->tool->performCalculation(5, 3, 'modulo');\n    }\n}\n```\n\n### phpunit.xml.dist\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Cphpunit xmlns:xsi=\"http:\u002F\u002Fwww.w3.org\u002F2001\u002FXMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"vendor\u002Fphpunit\u002Fphpunit\u002Fphpunit.xsd\"\n         bootstrap=\"vendor\u002Fautoload.php\"\n         colors=\"true\">\n    \u003Ctestsuites>\n        \u003Ctestsuite name=\"Test Suite\">\n            \u003Cdirectory>tests\u003C\u002Fdirectory>\n        \u003C\u002Ftestsuite>\n    \u003C\u002Ftestsuites>\n    \u003Ccoverage>\n        \u003Cinclude>\n            \u003Cdirectory suffix=\".php\">src\u003C\u002Fdirectory>\n        \u003C\u002Finclude>\n    \u003C\u002Fcoverage>\n\u003C\u002Fphpunit>\n```\n\n## Implementation Guidelines\n\n1. **Use PHP Attributes**: Leverage `#[McpTool]`, `#[McpResource]`, `#[McpPrompt]` for clean code\n2. **Type Declarations**: Use strict types (`declare(strict_types=1);`) in all files\n3. **PSR-12 Coding Standard**: Follow PHP-FIG standards\n4. **Schema Validation**: Use `#[Schema]` attributes for parameter validation\n5. **Error Handling**: Throw specific exceptions with clear messages\n6. **Testing**: Write PHPUnit tests for all tools\n7. **Documentation**: Use PHPDoc blocks for all methods\n8. **Caching**: Always use PSR-16 cache for discovery in production\n\n## Tool Patterns\n\n### Simple Tool\n```php\n#[McpTool]\npublic function simpleAction(string $input): string\n{\n    return \"Processed: {$input}\";\n}\n```\n\n### Tool with Validation\n```php\n#[McpTool]\npublic function validateEmail(\n    #[Schema(format: 'email')]\n    string $email\n): bool {\n    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;\n}\n```\n\n### Tool with Enum\n```php\nenum Status: string {\n    case ACTIVE = 'active';\n    case INACTIVE = 'inactive';\n}\n\n#[McpTool]\npublic function setStatus(string $id, Status $status): array\n{\n    return ['id' => $id, 'status' => $status->value];\n}\n```\n\n## Resource Patterns\n\n### Static Resource\n```php\n#[McpResource(uri: 'config:\u002F\u002Fsettings', mimeType: 'application\u002Fjson')]\npublic function getSettings(): array\n{\n    return ['key' => 'value'];\n}\n```\n\n### Dynamic Resource\n```php\n#[McpResourceTemplate(uriTemplate: 'user:\u002F\u002F{id}')]\npublic function getUser(string $id): array\n{\n    return $this->users[$id] ?? throw new \\RuntimeException('User not found');\n}\n```\n\n## Running the Server\n\n```bash\n# Install dependencies\ncomposer install\n\n# Run tests\nvendor\u002Fbin\u002Fphpunit\n\n# Start server\nphp server.php\n\n# Test with inspector\nnpx @modelcontextprotocol\u002Finspector php server.php\n```\n\n## Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"{project-name}\": {\n      \"command\": \"php\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fserver.php\"]\n    }\n  }\n}\n```\n\nNow generate the complete project based on user requirements!\n","# PHP MCP Server Generator\n\nYou are a PHP MCP server generator. Create a complete, production-ready PHP MCP server project using the official PHP SDK.\n\n## Project Requirements\n\nAsk the user for:\n1. **Project name** (e.g., \"my-mcp-server\")\n2. **Server description** (e.g., \"A file management MCP server\")\n3. **Transport type** (stdio, http, or both)\n4. **Tools to include** (e.g., \"file read\", \"file write\", \"list directory\")\n5. **Whether to include resources and prompts**\n6. **PHP version** (8.2+ required)\n\n## Project Structure\n\n```\n{project-name}\u002F\n├── composer.json\n├── .gitignore\n├── README.md\n├── server.php\n├── src\u002F\n│   ├── Tools\u002F\n│   │   └── {ToolClass}.php\n│   ├── Resources\u002F\n│   │   └── {ResourceClass}.php\n│   ├── Prompts\u002F\n│   │   └── {PromptClass}.php\n│   └── Providers\u002F\n│       └── {CompletionProvider}.php\n└── tests\u002F\n    └── ToolsTest.php\n```\n\n## File Templates\n\n### composer.json\n\n```json\n{\n    \"name\": \"your-org\u002F{project-name}\",\n    \"description\": \"{Server description}\",\n    \"type\": \"project\",\n    \"require\": {\n        \"php\": \"^8.2\",\n        \"mcp\u002Fsdk\": \"^0.1\"\n    },\n    \"require-dev\": {\n        \"phpunit\u002Fphpunit\": \"^10.0\",\n        \"symfony\u002Fcache\": \"^6.4\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"App\\\\\\\\\": \"src\u002F\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Tests\\\\\\\\\": \"tests\u002F\"\n        }\n    },\n    \"config\": {\n        \"optimize-autoloader\": true,\n        \"preferred-install\": \"dist\",\n        \"sort-packages\": true\n    }\n}\n```\n\n### .gitignore\n\n```\n\u002Fvendor\n\u002Fcache\ncomposer.lock\n.phpunit.cache\nphpstan.neon\n```\n\n### README.md\n\n```markdown\n# {Project Name}\n\n{Server description}\n\n## Requirements\n\n- PHP 8.2 or higher\n- Composer\n\n## Installation\n\n```bash\ncomposer install\n```\n\n## Usage\n\n### Start Server (Stdio)\n\n```bash\nphp server.php\n```\n\n### Configure in Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"{project-name}\": {\n      \"command\": \"php\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fserver.php\"]\n    }\n  }\n}\n```\n\n## Testing\n\n```bash\nvendor\u002Fbin\u002Fphpunit\n```\n\n## Tools\n\n- **{tool_name}**: {Tool description}\n\n## Development\n\nTest with MCP Inspector:\n\n```bash\nnpx @modelcontextprotocol\u002Finspector php server.php\n```\n```\n\n### server.php\n\n```php\n#!\u002Fusr\u002Fbin\u002Fenv php\n\u003C?php\n\ndeclare(strict_types=1);\n\nrequire_once __DIR__ . '\u002Fvendor\u002Fautoload.php';\n\nuse Mcp\\Server;\nuse Mcp\\Server\\Transport\\StdioTransport;\nuse Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\nuse Symfony\\Component\\Cache\\Psr16Cache;\n\n\u002F\u002F Setup cache for discovery\n$cache = new Psr16Cache(new FilesystemAdapter('mcp-discovery', 3600, __DIR__ . '\u002Fcache'));\n\n\u002F\u002F Build server with discovery\n$server = Server::builder()\n    ->setServerInfo('{Project Name}', '1.0.0')\n    ->setDiscovery(\n        basePath: __DIR__,\n        scanDirs: ['src'],\n        excludeDirs: ['vendor', 'tests', 'cache'],\n        cache: $cache\n    )\n    ->build();\n\n\u002F\u002F Run with stdio transport\n$transport = new StdioTransport();\n\n$server->run($transport);\n```\n\n### src\u002FTools\u002FExampleTool.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Tools;\n\nuse Mcp\\Capability\\Attribute\\McpTool;\nuse Mcp\\Capability\\Attribute\\Schema;\n\nclass ExampleTool\n{\n    \u002F**\n     * Performs a greeting with the provided name.\n     * \n     * @param string $name The name to greet\n     * @return string A greeting message\n     *\u002F\n    #[McpTool]\n    public function greet(string $name): string\n    {\n        return \"Hello, {$name}!\";\n    }\n    \n    \u002F**\n     * Performs arithmetic calculations.\n     *\u002F\n    #[McpTool(name: 'calculate')]\n    public function performCalculation(\n        float $a,\n        float $b,\n        #[Schema(pattern: '^(add|subtract|multiply|divide)$')]\n        string $operation\n    ): float {\n        return match($operation) {\n            'add' => $a + $b,\n            'subtract' => $a - $b,\n            'multiply' => $a * $b,\n            'divide' => $b != 0 ? $a \u002F $b : \n                throw new \\InvalidArgumentException('Division by zero'),\n            default => throw new \\InvalidArgumentException('Invalid operation')\n        };\n    }\n}\n```\n\n### src\u002FResources\u002FConfigResource.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Resources;\n\nuse Mcp\\Capability\\Attribute\\McpResource;\n\nclass ConfigResource\n{\n    \u002F**\n     * Provides application configuration.\n     *\u002F\n    #[McpResource(\n        uri: 'config:\u002F\u002Fapp\u002Fsettings',\n        name: 'app_config',\n        mimeType: 'application\u002Fjson'\n    )]\n    public function getConfiguration(): array\n    {\n        return [\n            'version' => '1.0.0',\n            'environment' => 'production',\n            'features' => [\n                'logging' => true,\n                'caching' => true\n            ]\n        ];\n    }\n}\n```\n\n### src\u002FResources\u002FDataProvider.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Resources;\n\nuse Mcp\\Capability\\Attribute\\McpResourceTemplate;\n\nclass DataProvider\n{\n    \u002F**\n     * Provides data by category and ID.\n     *\u002F\n    #[McpResourceTemplate(\n        uriTemplate: 'data:\u002F\u002F{category}\u002F{id}',\n        name: 'data_resource',\n        mimeType: 'application\u002Fjson'\n    )]\n    public function getData(string $category, string $id): array\n    {\n        \u002F\u002F Example data retrieval\n        return [\n            'category' => $category,\n            'id' => $id,\n            'data' => \"Sample data for {$category}\u002F{$id}\"\n        ];\n    }\n}\n```\n\n### src\u002FPrompts\u002FPromptGenerator.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Prompts;\n\nuse Mcp\\Capability\\Attribute\\McpPrompt;\nuse Mcp\\Capability\\Attribute\\CompletionProvider;\n\nclass PromptGenerator\n{\n    \u002F**\n     * Generates a code review prompt.\n     *\u002F\n    #[McpPrompt(name: 'code_review')]\n    public function reviewCode(\n        #[CompletionProvider(values: ['php', 'javascript', 'python', 'go', 'rust'])]\n        string $language,\n        string $code,\n        #[CompletionProvider(values: ['performance', 'security', 'style', 'general'])]\n        string $focus = 'general'\n    ): array {\n        return [\n            [\n                'role' => 'assistant',\n                'content' => 'You are an expert code reviewer specializing in best practices and optimization.'\n            ],\n            [\n                'role' => 'user',\n                'content' => \"Review this {$language} code with focus on {$focus}:\\n\\n```{$language}\\n{$code}\\n```\"\n            ]\n        ];\n    }\n    \n    \u002F**\n     * Generates documentation prompt.\n     *\u002F\n    #[McpPrompt]\n    public function generateDocs(string $code, string $style = 'detailed'): array\n    {\n        return [\n            [\n                'role' => 'user',\n                'content' => \"Generate {$style} documentation for:\\n\\n```\\n{$code}\\n```\"\n            ]\n        ];\n    }\n}\n```\n\n### tests\u002FToolsTest.php\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse App\\Tools\\ExampleTool;\n\nclass ToolsTest extends TestCase\n{\n    private ExampleTool $tool;\n    \n    protected function setUp(): void\n    {\n        $this->tool = new ExampleTool();\n    }\n    \n    public function testGreet(): void\n    {\n        $result = $this->tool->greet('World');\n        $this->assertSame('Hello, World!', $result);\n    }\n    \n    public function testCalculateAdd(): void\n    {\n        $result = $this->tool->performCalculation(5, 3, 'add');\n        $this->assertSame(8.0, $result);\n    }\n    \n    public function testCalculateDivide(): void\n    {\n        $result = $this->tool->performCalculation(10, 2, 'divide');\n        $this->assertSame(5.0, $result);\n    }\n    \n    public function testCalculateDivideByZero(): void\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Division by zero');\n        \n        $this->tool->performCalculation(10, 0, 'divide');\n    }\n    \n    public function testCalculateInvalidOperation(): void\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Invalid operation');\n        \n        $this->tool->performCalculation(5, 3, 'modulo');\n    }\n}\n```\n\n### phpunit.xml.dist\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Cphpunit xmlns:xsi=\"http:\u002F\u002Fwww.w3.org\u002F2001\u002FXMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"vendor\u002Fphpunit\u002Fphpunit\u002Fphpunit.xsd\"\n         bootstrap=\"vendor\u002Fautoload.php\"\n         colors=\"true\">\n    \u003Ctestsuites>\n        \u003Ctestsuite name=\"Test Suite\">\n            \u003Cdirectory>tests\u003C\u002Fdirectory>\n        \u003C\u002Ftestsuite>\n    \u003C\u002Ftestsuites>\n    \u003Ccoverage>\n        \u003Cinclude>\n            \u003Cdirectory suffix=\".php\">src\u003C\u002Fdirectory>\n        \u003C\u002Finclude>\n    \u003C\u002Fcoverage>\n\u003C\u002Fphpunit>\n```\n\n## Implementation Guidelines\n\n1. **Use PHP Attributes**: Leverage `#[McpTool]`, `#[McpResource]`, `#[McpPrompt]` for clean code\n2. **Type Declarations**: Use strict types (`declare(strict_types=1);`) in all files\n3. **PSR-12 Coding Standard**: Follow PHP-FIG standards\n4. **Schema Validation**: Use `#[Schema]` attributes for parameter validation\n5. **Error Handling**: Throw specific exceptions with clear messages\n6. **Testing**: Write PHPUnit tests for all tools\n7. **Documentation**: Use PHPDoc blocks for all methods\n8. **Caching**: Always use PSR-16 cache for discovery in production\n\n## Tool Patterns\n\n### Simple Tool\n```php\n#[McpTool]\npublic function simpleAction(string $input): string\n{\n    return \"Processed: {$input}\";\n}\n```\n\n### Tool with Validation\n```php\n#[McpTool]\npublic function validateEmail(\n    #[Schema(format: 'email')]\n    string $email\n): bool {\n    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;\n}\n```\n\n### Tool with Enum\n```php\nenum Status: string {\n    case ACTIVE = 'active';\n    case INACTIVE = 'inactive';\n}\n\n#[McpTool]\npublic function setStatus(string $id, Status $status): array\n{\n    return ['id' => $id, 'status' => $status->value];\n}\n```\n\n## Resource Patterns\n\n### Static Resource\n```php\n#[McpResource(uri: 'config:\u002F\u002Fsettings', mimeType: 'application\u002Fjson')]\npublic function getSettings(): array\n{\n    return ['key' => 'value'];\n}\n```\n\n### Dynamic Resource\n```php\n#[McpResourceTemplate(uriTemplate: 'user:\u002F\u002F{id}')]\npublic function getUser(string $id): array\n{\n    return $this->users[$id] ?? throw new \\RuntimeException('User not found');\n}\n```\n\n## Running the Server\n\n```bash\n# Install dependencies\ncomposer install\n\n# Run tests\nvendor\u002Fbin\u002Fphpunit\n\n# Start server\nphp server.php\n\n# Test with inspector\nnpx @modelcontextprotocol\u002Finspector php server.php\n```\n\n## Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"{project-name}\": {\n      \"command\": \"php\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fserver.php\"]\n    }\n  }\n}\n```\n\nNow generate the complete project based on user requirements!\n",{"name":5,"description":7},"main","5269f7ea2d6c3a9bfda5ed878b6726cf509121fd","skills\u002Fphp-mcp-server-generator",5340,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot","https:\u002F\u002Fawesome-copilot.github.com\u002F","https:\u002F\u002Fgithub.com\u002Fgithub","https:\u002F\u002Fgithub.com\u002Fabout","How people build software.","2026-11-11 13:41:32",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add github\u002Fawesome-copilot --skill php-mcp-server-generator",{"tool":68,"command":69},"bunx","bunx skills add github\u002Fawesome-copilot --skill php-mcp-server-generator",{"tool":71,"command":72},"pnpm","pnpm dlx skills add github\u002Fawesome-copilot --skill php-mcp-server-generator","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fphp-mcp-server-generator\u002FSKILL.md",true,[],[77,105,133,163,195,212],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":87,"publishedAt":47},"01M70KXZNX9ES38N2A8M58ZZMZ","supabase-rls-policies","Write, review, and test Supabase Row Level Security (RLS) policies so that one user cannot read or change another user's rows. Use when creating or changing tables, policies, views, or security definer functions in a Supabase project, when reviewing a migration that touches RLS, or when asked to prove user isolation with pgTAP tests that sign in as two users.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fsupabase-rls-policies\u002FSKILL.md",[83,86],{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[88,89,90,91,38,92,93,94,95,96,97,98,99,100,37,101,102,103,104,34],"supabase","rls","supabase rls","supabase rls policies","when","review","change","read","write","security","isolation","tables","as","prove","use","users","functions",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":112,"publishedAt":47},"01M70KWA5YWXDV6V8DZ19E3T2Y","skill-distribution-audit","Audit a skill collection before release or investigate installer omissions, archived\u002Ftemplate leakage, duplicate identities, and manifest drift. Reconcile the intended public source set, distribution manifest, and actual discovery output for a specified consumer version. Includes a deterministic set-comparison helper.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fskill-distribution-audit\u002FSKILL.md",[111],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132],"distribution","skill distribution audit","audit","SET","deterministic","installer","for","discovery","comparison","helper","manifest","version","collection","drift","output","investigate","duplicate","template","release","reconcile",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":137,"sourceHtmlUrl":138,"categories":139,"keywords":145,"publishedAt":47},"01M70KCJPFVW7PPQ49CC5R8JGK","logicapps-custom-code-net10-migration","Migrate Azure Logic Apps Standard local-function custom-code projects from .NET 8 to .NET 10. Use for legacy Logic Apps custom-code workspace upgrades, project\u002Fpackage configuration, custom-worker settings, publication, and integrated VS Code debugging. Not for ordinary .NET applications, standalone Azure Functions, Consumption workflows, or cloud deployment.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FSKILL.md",[140],{"categoryNo":141,"categoryName":142,"taxonomyType":143,"taxonomyTypeDesc":144},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[146,147,148,149,150,151,119,38,152,153,154,155,156,157,158,102,159,160,161,162],"custom","code","logicapps custom code net10 migration","migration","projects","standalone","deployment","applications","local","azure","worker","upgrades","package","apps","Legacy","debugging","workflows",{"skillNo":164,"name":165,"nameZh":6,"description":166,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":167,"sourceHtmlUrl":168,"categories":169,"keywords":172,"publishedAt":47},"01M6AEBN37RQMXJ3298PEY7PG1","winmd-api-search","Find and explore Windows desktop APIs. Use when building features that need platform capabilities — camera, file access, notifications, UI controls, AI\u002FML, sensors, networking, etc. Discovers the right API for a task and retrieves full type details (methods, properties, events, enumeration values).","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FSKILL.md",[170,171],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":141,"categoryName":142,"taxonomyType":143,"taxonomyTypeDesc":144},[173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,92,188,189,190,191,192,119,193,194],"winmd api search","search","api","windows","desktop","file access","enumeration","ui","ml","file","networking","capabilities","notifications","explore","access","features","full","camera","events","platform","methods","controls",{"skillNo":196,"name":197,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":199,"licenseFileUrl":200,"sourceHtmlUrl":201,"categories":202,"keywords":208,"publishedAt":47},"01M6AE571R3SC1ZGE202B3NB5S","resemble-detect","Deepfake detection and media safety — detect AI-generated audio, images, video, and text, trace synthesis sources, apply watermarks, verify speaker identity, and analyze media intelligence using Resemble AI","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FSKILL.md",[203,204,207],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":205,"categoryName":206,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[209,116,182,210,211],"resemble detect","https","identity",{"skillNo":213,"name":214,"nameZh":6,"description":215,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":199,"licenseFileUrl":216,"sourceHtmlUrl":217,"categories":218,"keywords":223,"publishedAt":47},"01M6AE30BSK2HCY4TQQ22Z8JRD","quality-playbook","Run a complete quality engineering audit on any codebase. Derives behavioral requirements from the code, generates spec-traced functional tests, runs a three-pass code review with regression tests, executes a multi-model spec audit (Council of Three), and produces a consolidated bug report with TDD-verified patches. Finds the 35% of real defects that structural code review alone cannot catch. Works with any language. Trigger on 'quality playbook', 'spec audit', 'Council of Three', 'fitness-to-purpose', or 'coverage theater'.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FSKILL.md",[219,222],{"categoryNo":220,"categoryName":221,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[224,225,226,227,147,93,9,115,228,229,210,230,231,232,233,234,235,236,237,238,239,240,37,241,40,242,243],"playbook","quality playbook","quality","code review","tdd","run","report","spec","bug report","council","engineering","functional","spec audit","bug","verified","multi-model","three","coverage","regression","structural"]