Content
# PHP MCP Server
[English Version](README.en.md)
This is a PHP-based MCP (Model Control Protocol) server framework that supports elegant MCP service definition through annotations.
## Project Overview
This project provides a complete MCP server implementation with the following features:
- Annotation-based MCP service definition
- Supports Tool, Prompt, and Resource processors
- Supports Stdio and Sse transport methods
- Supports [Swow](https://github.com/swow/swow) and [Swoole](https://github.com/swoole/swoole-src) environments
- Complete logging system
- Docker support
## System Requirements
- PHP >= 8.1
- Composer
- Swow extension > 1.5 or Swoole > 5.1
- Docker (optional)
## Quick Start
### Installation
```bash
# 1. Clone the project
git clone https://github.com/he426100/php-mcp-server
cd php-mcp-server
# 2. Install dependencies
composer install
# 3. Optional, install the Swow extension (if not already installed)
./vendor/bin/swow-builder --install
```
> For detailed installation instructions for the Swow extension, please refer to the [Swow official documentation](https://github.com/swow/swow)
### Run the Example Server
```bash
php bin/console mcp:test-server
```
#### Common Command Parameters
| Parameter | Description | Default Value | Options |
|-----------|-------------|---------------|---------|
| --transport | Transport type | stdio | stdio, sse |
| --port | Port to listen on for SSE | 8000 | |
## Annotation Usage Guide
This framework provides three core annotations for defining MCP services:
### 1. Tool Annotation
Used to define tool class processors:
```php
use Mcp\Annotation\Tool;
class MyService {
#[Tool(
name: 'calculate-sum',
description: 'Calculates the sum of two numbers',
parameters: [
'num1' => [
'type' => 'number',
'description' => 'The first number',
'required' => true
],
'num2' => [
'type' => 'number',
'description' => 'The second number',
'required' => true
]
]
)]
public function sum(int $num1, int $num2): int
{
return $num1 + $num2;
}
}
```
### 2. Prompt Annotation
Used to define prompt template processors:
```php
use Mcp\Annotation\Prompt;
class MyService {
#[Prompt(
name: 'greeting',
description: 'Generates a greeting',
arguments: [
'name' => [
'description' => 'The name of the person to greet',
'required' => true
]
]
)]
public function greeting(string $name): string
{
return "Hello, {$name}!";
}
}
```
### 3. Resource Annotation
Used to define resource processors:
```php
use Mcp\Annotation\Resource;
class MyService {
#[Resource(
uri: 'example://greeting',
name: 'Greeting Text',
description: 'Greeting resource',
mimeType: 'text/plain'
)]
public function getGreeting(): string
{
return "Hello from MCP server!";
}
}
```
## Creating Custom Services
1. Create a service class:
```php
namespace Your\Namespace;
use Mcp\Annotation\Tool;
use Mcp\Annotation\Prompt;
use Mcp\Annotation\Resource;
class CustomService
{
#[Tool(name: 'custom-tool', description: 'Custom tool')]
public function customTool(): string
{
return "Custom tool result";
}
}
```
2. Create a command class:
```php
namespace Your\Namespace\Command;
use He426100\McpServer\Command\AbstractMcpServerCommand;
use Your\Namespace\CustomService;
class CustomServerCommand extends AbstractMcpServerCommand
{
protected string $serverName = 'custom-server';
protected string $serviceClass = CustomService::class;
protected function configure(): void
{
parent::configure();
$this->setName('custom:server')
->setDescription('Run a custom MCP server');
}
}
```
## Annotation Parameter Descriptions
### Tool Annotation Parameters
| Parameter | Type | Description | Required |
|------|------|------|------|
| name | string | Tool name | Yes |
| description | string | Tool description | Yes |
| parameters | array | Parameter definitions | No |
### Prompt Annotation Parameters
| Parameter | Type | Description | Required |
|------|------|------|------|
| name | string | Prompt template name | Yes |
| description | string | Prompt template description | Yes |
| arguments | array | Parameter definitions | No |
### Resource Annotation Parameters
| Parameter | Type | Description | Required |
|------|------|------|------|
| uri | string | Resource URI | Yes |
| name | string | Resource name | Yes |
| description | string | Resource description | Yes |
| mimeType | string | MIME type | No |
## Annotation Function Return Type Descriptions
### Tool Annotation Function Supported Return Types
| Return Type | Description | Conversion Result |
|---------|------|---------|
| TextContent/ImageContent/EmbeddedResource | Directly return content object | Preserved as is |
| TextContent/ImageContent/EmbeddedResource Array | Array of content objects | Preserved as is |
| ResourceContents | Resource content object | Converted to EmbeddedResource |
| String or scalar type | e.g., string, int, float, bool | Converted to TextContent |
| null | Null value | Converted to TextContent with an empty string |
| Array or object | Complex data structure | Converted to JSON-formatted TextContent |
### Prompt Annotation Function Supported Return Types
| Return Type | Description | Conversion Result |
|---------|------|---------|
| PromptMessage | Message object | Preserved as is |
| PromptMessage Array | Array of message objects | Preserved as is |
| Content object | TextContent/ImageContent, etc. | Converted to a user-role PromptMessage |
| String or scalar type | e.g., string, int, float, bool | Converted to a user message with TextContent |
| null | Null value | Converted to a user message with empty content |
| Array or object | Complex data structure | Converted to a JSON-formatted user message |
### Resource Annotation Function Supported Return Types
| Return Type | Description | Conversion Result |
|---------|------|---------|
| TextResourceContents/BlobResourceContents | Resource content object | Preserved as is |
| ResourceContents Array | Array of resource content objects | Preserved as is |
| String or stringable object | Text content | Converted to the corresponding resource content based on MIME type |
| null | Null value | Converted to empty TextResourceContents |
| Array or object | Complex data structure | Converted to JSON-formatted resource content |
Notes:
- Large file content exceeding 2MB will be automatically truncated
- Text-based (text/*) MIME types will use TextResourceContents
- Other MIME types will use BlobResourceContents
## Log Configuration
Server logs are saved by default in `runtime/server_log.txt`. You can modify this by inheriting `AbstractMcpServerCommand`:
```php
protected string $logFilePath = '/custom/path/to/log.txt';
```
## Docker Support
Build and run the container:
```bash
docker build -t php-mcp-server .
docker run --name=php-mcp-server -p 8000:8000 -itd php-mcp-server mcp:test-server --transport sse
```
sse address: http://127.0.0.1:8000/sse
## Using with CPX
You can run this project directly using [CPX (Composer Package Executor)](https://github.com/imliam/cpx) without prior installation:
### Prerequisites
1. Install CPX globally:
```bash
composer global require cpx/cpx
```
2. Ensure that Composer's global bin directory is in your PATH
### Usage
```bash
# Run the test server
cpx he426100/php-mcp-server mcp:test-server
# Use SSE transport mode
cpx he426100/php-mcp-server mcp:test-server --transport=sse
# View available commands
cpx he426100/php-mcp-server list
```
## License
[MIT License](LICENSE)
## Contribution
Welcome to submit Issues and Pull Requests.
## Author
[he426100](https://github.com/he426100/)
[logiscape](https://github.com/logiscape/mcp-sdk-php)
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.