Awesome-copilot php-mcp-server-generator
Generate a complete PHP Model Context Protocol server project with tools, resources, prompts, and tests using the official PHP SDK
install
source · Clone the upstream repo
git clone https://github.com/github/awesome-copilot
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/github/awesome-copilot "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/php-mcp-server-generator" ~/.claude/skills/github-awesome-copilot-php-mcp-server-generator-e4ac56 && rm -rf "$T"
manifest:
skills/php-mcp-server-generator/SKILL.mdsource content
PHP MCP Server Generator
You are a PHP MCP server generator. Create a complete, production-ready PHP MCP server project using the official PHP SDK.
Project Requirements
Ask the user for:
- Project name (e.g., "my-mcp-server")
- Server description (e.g., "A file management MCP server")
- Transport type (stdio, http, or both)
- Tools to include (e.g., "file read", "file write", "list directory")
- Whether to include resources and prompts
- PHP version (8.2+ required)
Project Structure
{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
File Templates
composer.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
# {Project Name} {Server description} ## Requirements - PHP 8.2 or higher - Composer ## Installation ```bash composer install
Usage
Start Server (Stdio)
php server.php
Configure in Claude Desktop
{ "mcpServers": { "{project-name}": { "command": "php", "args": ["/absolute/path/to/server.php"] } } }
Testing
vendor/bin/phpunit
Tools
- {tool_name}: {Tool description}
Development
Test with MCP Inspector:
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 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 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 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 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 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 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>
Implementation Guidelines
- Use PHP Attributes: Leverage
,#[McpTool]
,#[McpResource]
for clean code#[McpPrompt] - Type Declarations: Use strict types (
) in all filesdeclare(strict_types=1); - PSR-12 Coding Standard: Follow PHP-FIG standards
- Schema Validation: Use
attributes for parameter validation#[Schema] - Error Handling: Throw specific exceptions with clear messages
- Testing: Write PHPUnit tests for all tools
- Documentation: Use PHPDoc blocks for all methods
- Caching: Always use PSR-16 cache for discovery in production
Tool Patterns
Simple Tool
#[McpTool] public function simpleAction(string $input): string { return "Processed: {$input}"; }
Tool with Validation
#[McpTool] public function validateEmail( #[Schema(format: 'email')] string $email ): bool { return filter_var($email, FILTER_VALIDATE_EMAIL) !== false; }
Tool with Enum
enum Status: string { case ACTIVE = 'active'; case INACTIVE = 'inactive'; } #[McpTool] public function setStatus(string $id, Status $status): array { return ['id' => $id, 'status' => $status->value]; }
Resource Patterns
Static Resource
#[McpResource(uri: 'config://settings', mimeType: 'application/json')] public function getSettings(): array { return ['key' => 'value']; }
Dynamic Resource
#[McpResourceTemplate(uriTemplate: 'user://{id}')] public function getUser(string $id): array { return $this->users[$id] ?? throw new \RuntimeException('User not found'); }
Running the Server
# Install dependencies composer install # Run tests vendor/bin/phpunit # Start server php server.php # Test with inspector npx @modelcontextprotocol/inspector php server.php
Claude Desktop Configuration
{ "mcpServers": { "{project-name}": { "command": "php", "args": ["/absolute/path/to/server.php"] } } }
Now generate the complete project based on user requirements!