关于 xdebug
xdebug-mcp 是一个 MCP 服务,通过 Xdebug 的 DBGp 协议为 PHP 应用提供调试能力,使 AI 助手可以直接控制断点、单步执行和变量检查。它支持 TCP 与 Unix 域套接字两种连接方式,并可用于 Docker 容器中运行的 PHP 程序。
主要功能
- 01断点设置,包括条件断点与异常断点
- 02单步进入、单步跳过、单步跳出与继续执行
- 03变量查看、修改与 PHP 表达式求值
- 04调用栈查看与 Watch 表达式
- 05支持同时调试多个 PHP 会话
- 06支持 TCP 与 Unix 域套接字连接
适用场景
- 01让 AI 助手协助定位 PHP 应用中的运行时错误
- 02在 Docker 容器中调试 PHP 程序并通过路径映射对应主机源码
- 03通过 Logpoint 在不中断执行的情况下记录变量输出
MCP 相关
该项目是一个 MCP 服务,向 MCP 客户端(如 Claude)暴露约 41 个调试相关工具,包括会话管理、断点、执行控制、变量检查、性能分析和代码覆盖率等。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
46收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
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 build
MCP 服务配置
用于 Claude Code
将 xdebug-mcp 服务添加到 MCP 配置(.mcp.json 或 Claude 设置):
使用 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 为起点进行代理注册。
代理模式要求:
xdebug-mcp使用 TCP 侦听器模式(而非XDEBUG_SOCKET_PATH)- 为
XDEBUG_PORT设置唯一的回调端口,例如9006、9007或9008 - 设置
DBGP_PROXY_HOST、DBGP_PROXY_PORT和DBGP_IDEKEY
完整设置说明、多 Agent 示例以及 PHP/Xdebug 代理配置,请参阅 DBGp 代理注册指南。
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=mcp
Docker 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 Domain Socket
为了在本地系统上提升性能并简化设置,你可以使用 Unix Domain Socket 代替 TCP。Unix Socket 可消除网络协议栈开销,非常适合在同一台机器上调试。
优势:
- ⚡ 延迟更低(无 TCP/IP 协议栈开销)
- 🔒 安全性更高(使用文件权限,而非绑定端口)
- 📦 设置更简单(无需管理端口)
- 🚀 本地调试通信速度更快
MCP 配置(Unix Socket):
{
"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
Socket 文件权限:
Socket 文件会以默认权限创建。若要限制访问,你可以:
# 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 Socket 上监听,而非 TCP 端口
- 启动时自动清理过期的 Socket 文件(防止出现“地址已在使用”错误)
- 关闭时自动清理 Socket 文件
- 使用与 TCP 模式相同的调试工具和功能
何时使用 Unix Socket:
- ✅ 本地 PHP 开发(性能最佳)
- ✅ 在同一台机器上调试
- ✅ 高频命中断点
- ❌ 远程调试(请改用 TCP)
Unix Socket 支持由 @dkd-kaehm 在 Issue #1 中提出
可用的 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 | 日志级别:debug、info、warn、error |
连接模式:TCP 与 Unix 套接字
| 特性 | TCP | Unix 套接字 |
|---|---|---|
| 设置 | 简单(默认) | 简单(一个环境变量) |
| 性能 | 良好 | 出色(延迟更低) |
| 安全性 | 端口可通过网络访问 | 基于文件的权限控制 |
| 远程调试 | ✅ 支持 | ❌ 仅限本地 |
| Docker | ✅ 可与 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 <container-id> | grep xdebug
Unix 套接字问题
- “Address already in use”:套接字文件未被清理
- 手动删除:
rm -f /tmp/xdebug.sock - MCP 服务会在下次启动时自动清理
- 手动删除:
- “Permission denied”:检查套接字文件权限
- 列出套接字:
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:- 默认值:30000ms(30 秒)
- 对于较慢的系统,可尝试:
COMMAND_TIMEOUT=60000
- 对于 Unix 套接字,请确认套接字位于高速文件系统上(而非网络挂载)
- 检查系统负载:
top——过多的上下文切换会拖慢调试
服务无法启动
- 端口被占用(TCP):
- 查找进程:
lsof -i :9003 - 终止进程:
kill -9 <pid>
- 查找进程:
- 配置错误:
- 验证环境变量:
echo $XDEBUG_SOCKET_PATH - 检查路径名中是否有拼写错误
- 验证环境变量:
- Permission denied:
- 对于 Unix 套接字,请确保对父目录具有写入权限
- 示例:
mkdir -p ~/.xdebug && chmod 700 ~/.xdebug
贡献
欢迎贡献!欢迎提交 Pull Request。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。