php-mcp-server-generator
github/awesome-copilot
Scaffold a full PHP MCP server—tools, resources, prompts, and tests—in one go using the official PHP SDK.
What is php-mcp-server-generator?
This skill generates a complete, production-ready PHP Model Context Protocol (MCP) server project scaffold using the official PHP SDK, including tools, resources, prompts, and PHPUnit tests. Use it when you need to quickly bootstrap a new PHP-based MCP server with proper project structure, composer config, and example implementations.
- Asks clarifying questions about project name, description, transport type, tools, and PHP version
- Generates a full project directory structure including composer.json, server.php, src/, and tests/
- Produces example Tool classes using #[McpTool] attributes with schema validation
- Produces example Resource and ResourceTemplate classes for static and templated data
- Produces example Prompt classes with completion providers for parameter suggestions
- Generates a PHPUnit test file covering the example tools
How to install php-mcp-server-generator
npx skills add https://github.com/github/awesome-copilot --skill php-mcp-server-generator- PHP 8.2 or higher
- Composer
- mcp/sdk PHP package (installed via composer.json)
- Node.js/npx (only needed if using MCP Inspector for testing)
How to use php-mcp-server-generator
- 1.Invoke the skill in your coding agent (e.g., Copilot/Claude) to start the PHP MCP server generator.
- 2.Answer the prompts: project name, server description, transport type (stdio/http/both), list of tools to include, whether to include resources/prompts, and PHP version (8.2+).
- 3.Let the generator scaffold the project structure (composer.json, server.php, src/Tools, src/Resources, src/Prompts, tests).
- 4.Run `composer install` in the generated project directory.
- 5.Run `php server.php` to start the server with stdio transport.
- 6.Run `vendor/bin/phpunit` to execute the generated tests.
- 7.Optionally test interactively with `npx @modelcontextprotocol/inspector php server.php`.
- 8.Configure the server in Claude Desktop (or another MCP client) using the provided server.php path.
Use cases
- Bootstrapping a new PHP MCP server project from scratch for a specific use case (e.g., file management server)
- Quickly generating example MCP tools, resources, and prompts with proper PHP SDK attribute usage
- Creating a server configurable for stdio or HTTP transport to integrate with Claude Desktop
- Generating a starting PHPUnit test suite alongside the MCP tool implementations
- Learning the project structure and conventions for building PHP MCP servers with the official SDK
- PHP developers building MCP servers for the first time
- Developers integrating custom tools/resources/prompts with Claude Desktop or other MCP clients
- Teams wanting a standardized starting structure for PHP-based MCP server projects
php-mcp-server-generator FAQ
PHP 8.2 or higher.
It acts as a generator prompt: it asks you clarifying questions (project name, description, transport, tools, etc.) and then scaffolds the project files based on your answers.
The generated server can use stdio, http, or both, depending on what you choose during setup.
Yes, it generates a PHPUnit test file (tests/ToolsTest.php) with example tests for the generated tools.
Run it with `php server.php`, or use the MCP Inspector via `npx @modelcontextprotocol/inspector php server.php`.
Full instructions (SKILL.md)
Source of truth, from github/awesome-copilot.
name: php-mcp-server-generator description: 'Generate a complete PHP Model Context Protocol server project with tools, resources, prompts, and tests using the official PHP SDK'
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],#[McpPrompt]for clean code - Type Declarations: Use strict types (
declare(strict_types=1);) in all files - PSR-12 Coding Standard: Follow PHP-FIG standards
- Schema Validation: Use
#[Schema]attributes for parameter validation - 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!
Related skills
More from github/awesome-copilot and the wider catalog.
git-commit
Execute semantic git commits with conventional message analysis and intelligent staging.
excalidraw-diagram-generator
Generate Excalidraw diagrams from natural language descriptions.
documentation-writer
Create structured technical documentation using the Diátaxis framework for tutorials, how-to guides, references, and explanations.
gh-cli
GitHub CLI comprehensive reference for repositories, issues, PRs, Actions, projects, releases, and all GitHub operations from the command line.
prd
Generate comprehensive Product Requirements Documents with executive summaries, user stories, technical specs, and risk analysis.
refactor
Surgical code refactoring to improve maintainability without changing behavior.