Xdebug MCP服务器
](https://www.npmjs.com/package/xdebug-mcp) 
一个MCP(模型上下文协议)服务器,通过Xdebug的DBGp协议提供PHP调试功能。这允许像Claude这样的AI助手直接调试PHP应用程序。
特性
核心调试
- 完全调试控制:踏入、跨过、走出、继续、停止
- 断点:行断点、条件断点、异常断点、函数调用断点
- 计量检验:查看所有变量,获取特定变量,设置变量值
- 表达式求值:在当前上下文中计算PHP表达式
- 堆栈跟踪:查看完整的调用堆栈
- 多个会话:同时调试多个PHP脚本
- Docker支持:适用于在Docker容器中运行的PHP
高级功能
- 观察表情:具有变化检测功能的持久手表,可在每次中断时自动评估
- 日志点:使用日志消息而不停止执行
{$var}占位符 - 内存剖析:跟踪断点之间的内存使用情况和执行时间
- 代码覆盖率:跟踪调试期间执行了哪些行
- 请求上下文:捕获
$_GET,$_POST,$_SESSION,$_COOKIE,自动标头 - 步骤筛选器:在步进过程中跳过供应商/库代码
- 调试配置文件:保存和还原断点配置
- 会话导出:将调试会话导出为JSON或HTML报告
安装
来自npm(推荐)
npm install -g xdebug-mcp来自源头
git clone https://github.com/kpanuragh/xdebug-mcp.git
cd xdebug-mcp
npm install
npm run buildMCP服务器配置
克劳德代码
将xdebug mcp服务器添加到mcp配置中(.mcp.json 或克劳德设置):
使用npm全局安装:
{
"mcpServers": {
"xdebug": {
"command": "xdebug-mcp",
"env": {
"XDEBUG_PORT": "9003",
"LOG_LEVEL": "info"
}
}
}
}使用npx:
{
"mcpServers": {
"xdebug": {
"command": "npx",
"args": ["-y", "xdebug-mcp"],
"env": {
"XDEBUG_PORT": "9003",
"LOG_LEVEL": "info"
}
}
}
}使用路径映射(适用于Docker)
在Docker容器中调试PHP时,需要路径映射将容器路径转换为主机路径:
{
"mcpServers": {
"xdebug": {
"command": "xdebug-mcp",
"env": {
"XDEBUG_PORT": "9003",
"PATH_MAPPINGS": "{\"/var/www/html\": \"/home/user/projects/myapp\"}",
"LOG_LEVEL": "info"
}
}
}
}使用DBGp代理注册
如果您已经使用了DBGp代理,请保留 mcp-config.example.json 作为默认的直接监听器示例,并从 mcp-config.proxy.example.json 用于代理注册。
代理模式要求:
- TCP侦听器模式
xdebug-mcp(不是XDEBUG_SOCKET_PATH) - 一个唯一的回调端口,例如
9006,9007,或9008为了XDEBUG_PORT DBGP_PROXY_HOST,DBGP_PROXY_PORT,以及DBGP_IDEKEY
请参阅 DBGp代理注册指南 了解完整设置、多代理示例和PHP/Xdebug代理配置。
PHP/Xdebug配置
php.ini(或 xdebug.ini)
[xdebug]
zend_extension=xdebug
; Enable step debugging
xdebug.mode=debug
; Start debugging on every request
xdebug.start_with_request=yes
; Host where MCP server is running
; For Docker: use host.docker.internal
; For local PHP: use 127.0.0.1
xdebug.client_host=host.docker.internal
; Port where MCP server listens
xdebug.client_port=9003
; IDE key (optional, for filtering)
xdebug.idekey=mcpDocker Compose
version: '3.8'
services:
php:
image: php:8.2-apache
volumes:
- ./src:/var/www/html
- ./xdebug.ini:/usr/local/etc/php/conf.d/99-xdebug.ini
extra_hosts:
- "host.docker.internal:host-gateway" # Required for Linux
environment:
- XDEBUG_MODE=debug
- XDEBUG_CONFIG=client_host=host.docker.internal client_port=9003使用Unix域套接字
为了提高性能和简化本地系统上的设置,您可以使用Unix域套接字而不是TCP。Unix套接字消除了网络堆栈开销,非常适合在同一台机器上进行调试。
优点:
- ⚡ 更低的延迟(无TCP/IP堆栈开销)
- 🔒 更好的安全性(文件权限而不是端口绑定)
- 📦 更简单的设置(无端口管理)
- 🚀 更快的本地调试通信
MCP配置(Unix套接字):
{
"mcpServers": {
"xdebug": {
"command": "xdebug-mcp",
"env": {
"XDEBUG_SOCKET_PATH": "/tmp/xdebug.sock",
"LOG_LEVEL": "info"
}
}
}
}PHP/Xdebug配置:
[xdebug]
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=unix:///tmp/xdebug.sock套接字文件权限:
套接字文件是使用默认权限创建的。要限制访问,您可以:
# After MCP server starts
chmod 600 /tmp/xdebug.sock
# Or use a secure directory
mkdir -p ~/.xdebug && chmod 700 ~/.xdebug
# Then set XDEBUG_SOCKET_PATH=$HOME/.xdebug/xdebug.sock自动清理:
当 XDEBUG_SOCKET_PATH 设置后,服务器将:
- 在指定的Unix套接字而不是TCP端口上侦听
- 启动时自动清理过时的套接字文件(防止“地址正在使用”错误)
- 关机时自动清理套接字文件
- 使用与TCP模式相同的调试工具和功能
何时使用Unix套接字:
- ✅ 本地PHP开发(最佳性能)
- ✅ 同机调试
- ✅ 高频断点点击
- ❌ 远程调试(改用TCP)
可用MCP工具(共41个)
会话管理
| 工具 | 说明 |
|---|---|
list_sessions | 列出所有活动的调试会话 |
get_session_state | 获取会话的详细状态 |
set_active_session | 设置哪个会话处于活动状态 |
close_session | 关闭调试会话 |
断点
| 工具 | 说明 |
|---|---|
set_breakpoint | 设置行断点或条件断点(支持挂起断点) |
set_exception_breakpoint | 异常中断(支持挂起的断点) |
set_call_breakpoint | 函数调用中断(支持挂起的断点) |
remove_breakpoint | 删除断点(适用于挂起的断点) |
update_breakpoint | 启用/禁用或修改断点 |
list_breakpoints | 列出所有断点,包括待定断点 |
待定断点:您可以在调试会话开始之前设置断点。这些被存储为“挂起的断点”,并在PHP脚本与Xdebug连接时自动应用。这对于在触发页面加载或脚本执行之前设置断点非常有用。
执行控制
| 工具 | 说明 |
|---|---|
continue | 继续到下一个断点 |
step_into | 进入函数调用 |
step_over | 跳过(跳过函数内部) |
step_out | 退出当前功能 |
stop | 停止调试 |
detach | 分离并让脚本继续 |
检查
| 工具 | 说明 |
|---|---|
get_stack_trace | 获取调用堆栈 |
get_contexts | 获取可用的变量上下文 |
get_variables | 获取作用域中的所有变量 |
get_variable | 获取特定变量 |
set_variable | 设置变量的值 |
evaluate | 计算PHP表达式 |
get_source | 获取源代码 |
观察表情
| 工具 | 说明 |
|---|---|
add_watch | 添加持久监视表达式 |
remove_watch | 删除手表表情 |
evaluate_watches | 评估所有手表并检测变化 |
list_watches | 列出所有活动手表 |
日志点
| 工具 | 说明 |
|---|---|
add_logpoint | 添加带有消息模板的日志点 |
remove_logpoint | 删除日志点 |
get_logpoint_history | 查看日志输出和点击统计 |
分析
| 工具 | 说明 |
|---|---|
start_profiling | 启动内存/时间分析 |
stop_profiling | 停止分析并获取结果 |
get_profile_stats | 获取当前分析统计信息 |
get_memory_timeline | 查看随时间变化的内存使用情况 |
代码覆盖率
| 工具 | 说明 |
|---|---|
start_coverage | 开始跟踪代码覆盖率 |
stop_coverage | 停下来获取报道 |
get_coverage_report | 查看覆盖率统计 |
调试配置文件
| 工具 | 说明 |
|---|---|
save_debug_profile | 将当前配置另存为配置文件 |
load_debug_profile | 加载已保存的调试配置文件 |
list_debug_profiles | 列出所有已保存的配置文件 |
附加工具
| 工具 | 说明 |
|---|---|
capture_request_context | 捕获HTTP请求上下文 |
add_step_filter | 添加过滤器以在步进过程中跳过文件 |
list_step_filters | 列出步骤筛选规则 |
get_function_history | 查看函数调用历史记录 |
export_session | 将会话导出为JSON/HTML报告 |
capture_snapshot | 捕获调试状态快照 |
用法示例
设置断点
Use set_breakpoint with file="/var/www/html/index.php" and line=25条件断点
Use set_breakpoint with file="/var/www/html/api.php", line=42, condition="$userId > 100"监视表达式
Use add_watch with expression="$user->email"
Use add_watch with expression="count($items)"日志点
Use add_logpoint with file="/var/www/html/api.php", line=50, message="User {$userId} accessed {$endpoint}"检查变量
Use get_variables to see all local variables
Use get_variable with name="$user" to inspect a specific variable
Use evaluate with expression="count($items)" to evaluate an expression捕获请求上下文
Use capture_request_context to see $_GET, $_POST, $_SESSION, cookies, and headers环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
XDEBUG_PORT | 9003 | 用于监听Xdebug连接的端口(TCP模式) |
XDEBUG_HOST | 0.0.0.0 | 要绑定的主机(TCP模式) |
XDEBUG_SOCKET_PATH | - | Unix域套接字路径(例如。, /tmp/xdebug.sock).设置时,使用Unix套接字而不是TCP |
COMMAND_TIMEOUT | 30000 | 命令超时(毫秒) |
PATH_MAPPINGS | - | JSON对象映射容器到主机路径 |
MAX_DEPTH | 3 | 可变检查的最大深度 |
MAX_CHILDREN | 128 | 数组/对象返回的最大子对象数 |
MAX_DATA | 2048 | 每个变量的最大数据大小 |
LOG_LEVEL | info | 日志级别:调试、信息、警告、错误 |
连接模式:TCP与Unix套接字
| 特性 | TCP | Unix套接字 |
|---|---|---|
| 设置 | 简单(默认) | 简单(一个环境变量) |
| 演出 | 良好 | 优秀(延迟较低) |
| 安全 | 网络可访问的端口 | 基于文件的权限 |
| 远程调试 | ✅ 支持 | ❌ 仅限本地 |
| 码头工人 | ✅ 与host.docker.internal配合使用 | ❌ 需要卷装载 |
| 陈旧插座 | 手动端口清理 | 自动清理 |
| 默认 | XDEBUG_PORT=9003 | 已禁用(使用TCP) |
快速决策指南:
- 🏠 地方发展? → 使用Unix套接字以获得最佳性能
- 🐳 Docker在同一台机器上? → 使用带卷挂载的Unix套接字
- 🌐 远程服务器? → 使用TCP
- 🚀 最大速度? → 使用Unix套接字
- 📝 不知道? → 从TCP(默认)开始,如果需要,切换到Unix套接字
运作原理
- MCP服务器启动 并监听Xdebug连接(TCP端口9003或Unix套接字)
- PHP脚本运行 启用Xdebug
- Xdebug连接 通过DBGp协议连接到MCP服务器
- AI使用MCP工具 控制调试(设置断点、步骤、检查)
- DBGp命令 发送到Xdebug,解析并返回响应
┌─────────────┐ MCP/stdio ┌─────────────┐ DBGp/TCP or ┌─────────────┐
│ Claude │ ◄────────────────► │ xdebug-mcp │ ◄─ Unix Socket ──► │ Xdebug │
│ (AI Agent) │ │ Server │ │ (in PHP) │
└─────────────┘ └─────────────┘ └─────────────┘连接选项:
- TCP(默认):
xdebug.client_host=127.0.0.1+XDEBUG_PORT=9003 - Unix套接字:
xdebug.client_host=unix:///tmp/xdebug.sock+XDEBUG_SOCKET_PATH=/tmp/xdebug.sock
故障排除
没有出现调试会话
- 检查是否安装了Xdebug:
php -v应显示Xdebug - 验证Xdebug配置:
php -i | grep xdebug - 确保
xdebug.client_host指向MCP服务器 - 对于TCP: 检查防火墙是否允许端口9003上的连接
- 对于Unix套接字: 验证套接字路径是否存在以及是否具有正确的权限:
ls -la /tmp/xdebug.sock - 检查MCP服务器日志:
LOG_LEVEL=debug用于详细输出
Docker连接问题
- 对于Linux,添加
extra_hosts: ["host.docker.internal:host-gateway"] - 验证容器是否可以访问主机:
curl host.docker.internal:9003 - 检查容器中的xdebug日志:
docker logs | grep xdebug
Unix套接字问题
- “地址已在使用中”:套接字文件未清理
- 手动删除: rm -f /tmp/xdebug.sock - MCP服务器将在下次启动时自动清理
- “权限被拒绝”:检查套接字文件权限
- 列表套接字: ls -la /tmp/xdebug.sock - 以与PHP相同的用户身份运行: ps aux | grep php
- php.ini中的套接字路径:
- 对的: xdebug.client_host=unix:///tmp/xdebug.sock - 错误: xdebug.client_host=unix:/tmp/xdebug.sock (少了一个 /)
断点未命中
- 确保文件路径完全匹配(Docker使用容器路径)
- 检查断点是否已解决:
list_breakpoints - 验证脚本执行是否达到该行
- 检查一下
xdebug.start_with_request=yes已设置 - 尝试一个简单的文件来验证基本设置是否有效
性能问题
- 如果步进缓慢,请增加
COMMAND_TIMEOUT:
- 默认值:30000毫秒(30秒) - 尝试: COMMAND_TIMEOUT=60000 对于较慢的系统
- 对于Unix套接字,验证套接字是否位于快速文件系统上(而不是网络挂载)
- 检查系统负载:
top-过度的上下文切换会减慢调试速度
服务器无法启动
- 正在使用的端口(TCP):
- 查找过程: lsof -i :9003 - 杀死它: kill -9
- 配置错误:
- 验证环境变量: echo $XDEBUG_SOCKET_PATH - 检查路径名中的拼写错误
- 权限被拒绝:
- 对于Unix套接字,确保对父目录的写权限 - 例子: mkdir -p ~/.xdebug && chmod 700 ~/.xdebug
贡献
欢迎投稿!请随时提交拉取请求。
许可证
麻省理工学院
