内容
# PHP MCP服务器 示例
Claude可连接的MCP服务器(Streamable HTTP传输)的PHP示例。
无需composer等依赖库(PHP 8.1以上)。
## 构成
| 文件 | 角色 |
|---|---|
| `mcp-server.php` | MCP服务器本体。Claude将连接此处(端口8000) |
| `api.php` | 示例的后端API。GET返回JSON,POST接收JSON(端口8001) |
| `.mcp.json` | Claude Code的连接设置 |
| `data.json` | `api.php` 自动生成的简易数据存储 |
```
Claude ──(MCP / JSON-RPC over HTTP)──> mcp-server.php ──(HTTP GET/POST)──> api.php ──> data.json
```
## 提供工具
- **`get_data`** — 向后端API发送GET请求以获取JSON数据(`id` 指定获取单个数据)
- **`post_data`** — 向后端API发送POST请求以注册 `{name, value}` 并返回结果JSON
## 启动方法
### 一键启动脚本(推荐)
```sh
./mcp.sh start # 启动PHP服务器2个 + cloudflared隧道 + .mcp.json自动更新 + 连通性检查
./mcp.sh status # 显示运行状态和当前公开URL、.mcp.json同步状态
./mcp.sh stop # 停止所有
```
隧道URL每次启动都会变化,但 `start` 会自动更新 `.mcp.json`。
按照启动后显示的指南,常规使用时可以使用 `git push`,而在claude.ai连接器中使用时需要更新连接器设置的URL。
### 手动启动
使用两个终端,分别在不同端口启动:
```sh
# 终端1: MCP服务器
php -S localhost:8000
# 终端2: 后端API
php -S localhost:8001
```
> **注意:** PHP内置服务器是单线程的,如果将MCP服务器和后端API放在同一端口上,会导致死锁。如果希望使用单个命令,可以使用 `PHP_CLI_SERVER_WORKERS=4 php -S localhost:8000` 增加工作线程数,并将 `mcp-server.php` 中的 `BACKEND_URL` 恢复到8000端口。
> 如果使用Apache/nginx等常规Web服务器,则不会出现此问题。
## 从Claude连接
### Claude Code
此目录中包含 `.mcp.json`,启动 `claude` 时会自动识别。
手动添加:
```sh
claude mcp add --transport http php-sample http://localhost:8000/mcp-server.php
```
连接后,可以指示执行以下操作:“使用get_data获取数据”和“使用post_data注册name=xxx, value=yyy”。
### claude.ai / Claude Desktop(自定义连接器)
自定义连接器需要公开的HTTPS URL。在本地开发时,可以使用ngrok等工具创建隧道:
```sh
ngrok http 8000
# 将生成的 https://xxxx.ngrok.io/mcp-server.php 设置为连接器的URL
```
## 功能验证(curl)
```sh
# 初始化
curl -s -X POST http://localhost:8000/mcp-server.php \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}'
# 工具列表
curl -s -X POST http://localhost:8000/mcp-server.php \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 获取数据(GET)
curl -s -X POST http://localhost:8000/mcp-server.php \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_data","arguments":{}}}'
# 注册数据(POST)
curl -s -X POST http://localhost:8000/mcp-server.php \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"post_data","arguments":{"name":"pressure","value":"1013"}}}'
```
## 自定义要点
- 连接到实际API时,请修改 `mcp-server.php` 中的 `BACKEND_URL`,并根据实际数据调整 `handleToolsList()` 中的 `inputSchema` 和 `handleToolsCall()` 的处理逻辑。
- 增加工具时,请在 `tools/list` 中添加定义,并在 `handleToolsCall()` 的 `switch` 中添加分支。
- 本示例未包含身份验证。如果部署到公开环境,请在 `handlePost()` 开头添加Bearer令牌验证等机制。