{"kind":"Skill","metadata":{"namespace":"community","name":"php-mcp-server-generator","version":"0.1.0"},"spec":{"description":"Generate a complete PHP Model Context Protocol server project with tools, resources, prompts, and tests using the official PHP SDK","files":{"SKILL.md":"---\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}/\n├── composer.json\n├── .gitignore\n├── README.md\n├── server.php\n├── src/\n│   ├── Tools/\n│   │   └── {ToolClass}.php\n│   ├── Resources/\n│   │   └── {ResourceClass}.php\n│   ├── Prompts/\n│   │   └── {PromptClass}.php\n│   └── Providers/\n│       └── {CompletionProvider}.php\n└── tests/\n    └── ToolsTest.php\n```\n\n## File Templates\n\n### composer.json\n\n```json\n{\n    \"name\": \"your-org/{project-name}\",\n    \"description\": \"{Server description}\",\n    \"type\": \"project\",\n    \"require\": {\n        \"php\": \"^8.2\",\n        \"mcp/sdk\": \"^0.1\"\n    },\n    \"require-dev\": {\n        \"phpunit/phpunit\": \"^10.0\",\n        \"symfony/cache\": \"^6.4\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"App\\\\\\\\\": \"src/\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Tests\\\\\\\\\": \"tests/\"\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/vendor\n/cache\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\": [\"/absolute/path/to/server.php\"]\n    }\n  }\n}\n```\n\n## Testing\n\n```bash\nvendor/bin/phpunit\n```\n\n## Tools\n\n- **{tool_name}**: {Tool description}\n\n## Development\n\nTest with MCP Inspector:\n\n```bash\nnpx @modelcontextprotocol/inspector php server.php\n```\n```\n\n### server.php\n\n```php\n#!/usr/bin/env php\n\u003c?php\n\ndeclare(strict_types=1);\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse Mcp\\Server;\nuse Mcp\\Server\\Transport\\StdioTransport;\nuse Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\nuse Symfony\\Component\\Cache\\Psr16Cache;\n\n// Setup cache for discovery\n$cache = new Psr16Cache(new FilesystemAdapter('mcp-discovery', 3600, __DIR__ . '/cache'));\n\n// Build server with discovery\n$server = Server::builder()\n    -\u003esetServerInfo('{Project Name}', '1.0.0')\n    -\u003esetDiscovery(\n        basePath: __DIR__,\n        scanDirs: ['src'],\n        excludeDirs: ['vendor', 'tests', 'cache'],\n        cache: $cache\n    )\n    -\u003ebuild();\n\n// Run with stdio transport\n$transport = new StdioTransport();\n\n$server-\u003erun($transport);\n```\n\n### src/Tools/ExampleTool.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    /**\n     * Performs a greeting with the provided name.\n     * \n     * @param string $name The name to greet\n     * @return string A greeting message\n     */\n    #[McpTool]\n    public function greet(string $name): string\n    {\n        return \"Hello, {$name}!\";\n    }\n    \n    /**\n     * Performs arithmetic calculations.\n     */\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' =\u003e $a + $b,\n            'subtract' =\u003e $a - $b,\n            'multiply' =\u003e $a * $b,\n            'divide' =\u003e $b != 0 ? $a / $b : \n                throw new \\InvalidArgumentException('Division by zero'),\n            default =\u003e throw new \\InvalidArgumentException('Invalid operation')\n        };\n    }\n}\n```\n\n### src/Resources/ConfigResource.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    /**\n     * Provides application configuration.\n     */\n    #[McpResource(\n        uri: 'config://app/settings',\n        name: 'app_config',\n        mimeType: 'application/json'\n    )]\n    public function getConfiguration(): array\n    {\n        return [\n            'version' =\u003e '1.0.0',\n            'environment' =\u003e 'production',\n            'features' =\u003e [\n                'logging' =\u003e true,\n                'caching' =\u003e true\n            ]\n        ];\n    }\n}\n```\n\n### src/Resources/DataProvider.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    /**\n     * Provides data by category and ID.\n     */\n    #[McpResourceTemplate(\n        uriTemplate: 'data://{category}/{id}',\n        name: 'data_resource',\n        mimeType: 'application/json'\n    )]\n    public function getData(string $category, string $id): array\n    {\n        // Example data retrieval\n        return [\n            'category' =\u003e $category,\n            'id' =\u003e $id,\n            'data' =\u003e \"Sample data for {$category}/{$id}\"\n        ];\n    }\n}\n```\n\n### src/Prompts/PromptGenerator.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    /**\n     * Generates a code review prompt.\n     */\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' =\u003e 'assistant',\n                'content' =\u003e 'You are an expert code reviewer specializing in best practices and optimization.'\n            ],\n            [\n                'role' =\u003e 'user',\n                'content' =\u003e \"Review this {$language} code with focus on {$focus}:\\n\\n```{$language}\\n{$code}\\n```\"\n            ]\n        ];\n    }\n    \n    /**\n     * Generates documentation prompt.\n     */\n    #[McpPrompt]\n    public function generateDocs(string $code, string $style = 'detailed'): array\n    {\n        return [\n            [\n                'role' =\u003e 'user',\n                'content' =\u003e \"Generate {$style} documentation for:\\n\\n```\\n{$code}\\n```\"\n            ]\n        ];\n    }\n}\n```\n\n### tests/ToolsTest.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-\u003etool = new ExampleTool();\n    }\n    \n    public function testGreet(): void\n    {\n        $result = $this-\u003etool-\u003egreet('World');\n        $this-\u003eassertSame('Hello, World!', $result);\n    }\n    \n    public function testCalculateAdd(): void\n    {\n        $result = $this-\u003etool-\u003eperformCalculation(5, 3, 'add');\n        $this-\u003eassertSame(8.0, $result);\n    }\n    \n    public function testCalculateDivide(): void\n    {\n        $result = $this-\u003etool-\u003eperformCalculation(10, 2, 'divide');\n        $this-\u003eassertSame(5.0, $result);\n    }\n    \n    public function testCalculateDivideByZero(): void\n    {\n        $this-\u003eexpectException(\\InvalidArgumentException::class);\n        $this-\u003eexpectExceptionMessage('Division by zero');\n        \n        $this-\u003etool-\u003eperformCalculation(10, 0, 'divide');\n    }\n    \n    public function testCalculateInvalidOperation(): void\n    {\n        $this-\u003eexpectException(\\InvalidArgumentException::class);\n        $this-\u003eexpectExceptionMessage('Invalid operation');\n        \n        $this-\u003etool-\u003eperformCalculation(5, 3, 'modulo');\n    }\n}\n```\n\n### phpunit.xml.dist\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cphpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"vendor/phpunit/phpunit/phpunit.xsd\"\n         bootstrap=\"vendor/autoload.php\"\n         colors=\"true\"\u003e\n    \u003ctestsuites\u003e\n        \u003ctestsuite name=\"Test Suite\"\u003e\n            \u003cdirectory\u003etests\u003c/directory\u003e\n        \u003c/testsuite\u003e\n    \u003c/testsuites\u003e\n    \u003ccoverage\u003e\n        \u003cinclude\u003e\n            \u003cdirectory suffix=\".php\"\u003esrc\u003c/directory\u003e\n        \u003c/include\u003e\n    \u003c/coverage\u003e\n\u003c/phpunit\u003e\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' =\u003e $id, 'status' =\u003e $status-\u003evalue];\n}\n```\n\n## Resource Patterns\n\n### Static Resource\n```php\n#[McpResource(uri: 'config://settings', mimeType: 'application/json')]\npublic function getSettings(): array\n{\n    return ['key' =\u003e 'value'];\n}\n```\n\n### Dynamic Resource\n```php\n#[McpResourceTemplate(uriTemplate: 'user://{id}')]\npublic function getUser(string $id): array\n{\n    return $this-\u003eusers[$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/bin/phpunit\n\n# Start server\nphp server.php\n\n# Test with inspector\nnpx @modelcontextprotocol/inspector php server.php\n```\n\n## Claude Desktop Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"{project-name}\": {\n      \"command\": \"php\",\n      \"args\": [\"/absolute/path/to/server.php\"]\n    }\n  }\n}\n```\n\nNow generate the complete project based on user requirements!\n"},"import":{"commit_sha":"541b7819d8c3545c6df122491af4fa1eae415779","imported_at":"2026-05-18T20:05:35Z","license_text":"MIT License\n\nCopyright GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","owner":"github","repo":"github/awesome-copilot","source_url":"https://github.com/github/awesome-copilot/tree/541b7819d8c3545c6df122491af4fa1eae415779/plugins/php-mcp-development/skills/php-mcp-server-generator"}},"content_hash":[122,7,130,231,6,129,248,103,40,87,209,175,133,86,186,194,201,247,192,89,221,138,137,182,20,161,39,219,7,199,223,229],"trust_level":"unsigned","yanked":false}
