# Debug MCP
<div align="center">
**[English](README.md)** | **简体中文**
</div>
一个基于模型上下文协议(MCP)的智能调试助手,通过分析Bug、注入HTTP调试日志、基于实时反馈迭代修复问题来自动化调试过程。
## 核心特性
- 🔍 **自动化Bug分析**: 分析Bug描述并建议可能的原因
- 🌐 **多环境支持**: 自动检测并适配不同的运行环境
- 📝 **基于HTTP的日志记录**: 通过HTTP POST将调试日志发送到集中式服务器(**不是** console.log)
- 🔄 **迭代式调试**: 根据用户反馈持续调试,直到问题解决
- 🧹 **自动清理**: Bug修复后自动移除所有调试代码
- 📊 **项目范围日志**: 每个项目的日志存储在 `{projectPath}/.debug/debug.log`
- 🌍 **跨设备调试**: 支持局域网内多设备调试
## 工作原理
**⚠️ 重要提示**: 此MCP服务器 **不使用** `console.log()`。相反,它注入通过HTTP POST将日志发送到本地调试服务器的代码。日志随后存储在项目目录的 `{projectPath}/.debug/debug.log` 中。
### 为什么使用基于HTTP的日志记录?
1. **集中收集**: 应用程序不同部分的所有日志都收集在一个地方
2. **结构化数据**: 日志以JSON格式存储,包含时间戳、级别和上下文
3. **AI友好**: AI可以通过 `read_debug_logs` 工具轻松读取和分析日志
4. **项目范围**: 日志存储在项目目录中,而不是分散在控制台输出中
## 支持的环境
| 环境 | 描述 |
|------------|-------------|
| **Browser** | 使用fetch API的Web应用程序 |
| **Node.js** | 带原生fetch的服务端Node.js (18+) |
| **Node.js Legacy** | 使用http模块的旧版Node.js |
| **React Native** | 使用React Native的移动应用 |
| **Electron (Main)**** | Electron主进程(直接文件写入) |
| **Electron (Renderer)**** | Electron渲染器进程(IPC) |
| **WeChat Mini Program** | 微信/支付宝小程序(wx.request) |
| **PHP** | 服务端PHP(curl) |
| **Python** | 服务端Python(requests库) |
| **Java** | 服务端Java,使用DebugHttpClient工具类 |
| **Android** | Android应用,支持线程安全的网络请求 |
| **Kotlin** | Kotlin应用,支持协程 |
| **Objective-C** | iOS/macOS应用,使用NSURLSession |
## 安装
```bash
# 克隆仓库
git clone https://gitee.com/UPUP0326/debug-mcp.git
cd debug-mcp
# 安装依赖
npm install
# 构建项目
npm run build
# 启动服务器
npm start
```
## 配置
### 端口配置(可选)
**重要**: HTTP服务器端口现在由系统自动分配,无需手动配置。每个MCP实例会自动获得一个可用端口,避免端口冲突。
如果需要使用固定端口(不推荐),可以在环境变量中设置:
```env
# HTTP服务器端口(可选,默认自动分配)
# 如果设置,将使用此端口;如果不设置,系统自动分配可用端口
DEBUG_PORT=37373
# HTTP服务器主机(默认:localhost)
# 使用 '0.0.0.0' 接受网络上任何设备的连接
# 使用你的局域网IP(例如 '192.168.1.100')允许其他设备发送日志
DEBUG_HOST=localhost
# 示例:
# DEBUG_HOST=0.0.0.0 # 接受任何设备的连接
# DEBUG_HOST=192.168.1.100 # 你的计算机的局域网IP
# DEBUG_HOST=localhost # 仅本地连接(默认)
# 日志文件路径(相对于项目目录)
LOG_FILE=.debug/debug.log
```
**获取实际端口**: 使用 `get_server_port` MCP工具可以查询当前分配的端口和URL。
## 快速入门指南
### 步骤 1:启动MCP服务器
```bash
npm start
```
服务器将启动:
- **MCP服务器**: 监听stdio以进行AI通信
- **HTTP API服务器**: 自动分配可用端口以接收调试日志(端口信息可通过 `get_server_port` 工具查询)
### 步骤 2:配置MCP客户端
#### Cursor IDE 配置
在Cursor中,MCP服务器配置位于设置中。打开Cursor设置,找到MCP配置部分,添加:
```json
{
"mcpServers": {
"debug-mcp": {
"command": "node",
"args": ["E:/work/debug-mcp/dist/index.js"],
"env": {
"DEBUG_HOST": "localhost"
}
}
}
}
```
**注意**:
- 将 `E:/work/debug-mcp/dist/index.js` 替换为你的实际路径
- 端口会自动分配,无需配置 `DEBUG_PORT`
- 如果需要跨设备调试,将 `DEBUG_HOST` 设置为 `0.0.0.0` 或你的局域网IP
#### Claude Desktop 配置
在Claude Desktop中,配置文件位置:
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Mac**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
添加以下配置:
```json
{
"mcpServers": {
"debug-mcp": {
"command": "node",
"args": ["E:/work/debug-mcp/dist/index.js"],
"env": {
"DEBUG_HOST": "localhost"
}
}
}
}
```
**注意**:
- 将 `E:/work/debug-mcp/dist/index.js` 替换为你的实际路径
- 端口会自动分配,无需配置 `DEBUG_PORT`
- 如果需要跨设备调试,将 `DEBUG_HOST` 设置为 `0.0.0.0` 或你的局域网IP
**跨设备调试设置**:
要启用从移动设备或网络上的其他计算机进行调试:
1. **查找你的局域网IP**:
- Windows: `ipconfig` → 查找 "IPv4 地址"(例如 192.168.1.100)
- Mac/Linux: `ifconfig` 或 `ip addr` → 查找 "inet"(例如 192.168.1.100)
2. **更新MCP配置**:
```json
{
"env": {
"DEBUG_HOST": "192.168.1.100" // 你的局域网IP
// 注意:端口会自动分配,无需配置 DEBUG_PORT
}
}
```
3. **获取实际端口**: 启动MCP服务器后,使用 `get_server_port` 工具查询实际分配的端口
4. **确保防火墙允许该端口**(端口号通过 `get_server_port` 查询)
4. **获取实际端口**: 使用 `get_server_port` 工具查询实际分配的端口
5. **设备现在可以发送日志到** `http://192.168.1.100:PORT/api/log`(PORT为实际端口)
### 步骤 3:与AI一起使用
调试时,只需向AI描述Bug。AI将会:
1. **分析Bug** - 使用 `analyze_bug` 工具
2. **检测环境** - 使用 `detect_environment` 工具检测文件环境
3. **获取调试模板** - 使用 `get_debug_template` 工具获取调试代码
4. **手动插入调试代码** - 将代码插入到文件中
**AI的重要提示**:
- ⚠️ **不要** 使用 `console.log()` - 使用通过HTTP POST发送日志的模板代码
- ⚠️ **必须** 提供 `projectPath` 作为项目目录的绝对路径
- 调试代码将日志发送到动态分配的服务器URL(使用 `get_server_port` 工具获取实际URL)
- 对于跨设备调试,URL将使用配置的 `DEBUG_HOST` 和自动分配的端口
- 日志存储在 `{projectPath}/.debug/debug.log`
### 工作流程示例
```
用户: "我的登录按钮点击后没有反应"
AI流程:
1. analyze_bug("登录按钮点击后没有反应")
→ 返回: 可能原因(事件监听器、API错误、验证)
2. detect_environment("src/components/Login.js")
→ 返回: "browser"
3. get_debug_template(
environment="browser",
logMessage="登录按钮被点击",
variables=["username", "password"],
projectPath="/path/to/project"
)
→ 返回: 基于HTTP的调试代码(不是console.log)
4. AI将调试代码手动插入Login.js
⚠️ 关键步骤 - AI告知用户:
💭 我的假设:按钮的点击事件监听器可能没有正确附加。
📋 测试步骤:
1. 重启你的应用程序
2. 导航到登录页面
3. 点击登录按钮
4. 检查是否有任何反应
✅ 预期结果:如果监听器正常工作,你应该看到调试系统中记录的按钮点击
📢 请报告结果:点击后有反应吗?控制台中有错误消息吗?
5. 用户测试并报告:"点击后没有任何反应"
6. read_debug_logs(projectPath="/path/to/project")
→ 返回: 没有按钮点击的日志条目
7. AI分析: "由于我们没有看到按钮点击日志,事件监听器
根本没有触发。让我添加更多日志来检查组件是否挂载..."
8. [重复调试循环,使用针对性的假设]
9. 用户报告: "现在我看到日志了!但出现401错误"
10. AI分析日志并建议: "401错误表示认证失败。
让我检查API请求格式..."
11. [继续直到Bug修复]
```
## AI行为准则
使用此MCP服务器时,AI应遵循以下模式:
### ✅ 应该做
1. **始终提供projectPath** 作为项目目录的绝对路径
2. **使用 get_debug_template** 获取基于HTTP的日志记录代码(不是console.log)
3. **手动插入** 调试代码到适当位置
4. **解释你的假设** - 你认为可能有什么问题
5. **提供清晰的测试步骤** - 用户应该采取的具体操作
6. **说明预期结果** - 如果你的假设正确,应该发生什么
7. **请求反馈** - 特别要求用户报告结果
8. **使用 read_debug_logs** 在用户测试后分析实际运行时数据
9. **处理意外结果** - 当结果与预期不同时,提出后续问题
10. **迭代** - 基于数据继续调试,直到问题解决
11. **成功时自动清理** - 当用户说"It works!"、"Fixed!"、"Success!"等时,立即:
- 使用 `clear_debug_logs` 清除日志文件
- 删除所有调试代码块(搜索 `DEBUG CODE START/END` 标记)
- 恢复所有临时视觉/测试标记(搜索 `TEMPORARY DEBUG MARKER` 注释)
- 恢复原始代码(按钮标签、图片、样式、颜色等)
- **不要问** "Should I clean up?" - 直接清理
12. **跟踪所有修改** - 保留每个修改的列表:
- 调试代码块(HTTP POST日志)
- 视觉标记(测试图片、按钮文本更改、颜色高亮)
- 样式修改(用于测试的CSS更改)
- 任何其他临时修改
### ❌ 不应该做
1. ❌ 使用 console.log() - 始终使用提供的HTTP POST模板
2. ❌ 省略 projectPath - 日志将进入错误的目录
3. ❌ 跳过解释推理 - 用户需要理解你的假设
4. ❌ 忘记测试步骤 - 用户需要清晰的说明
5. ❌ 忽略意外结果 - 当事情没有按计划进行时进行调查
6. ❌ 当用户确认成功时询问 "Should I clean up?" - 直接清理
7. ❌ 忘记临时视觉标记 - 所有测试更改都必须恢复
## 可用的MCP工具
### get_server_info
获取调试MCP服务器配置、HTTP端点和支持的环境。
```json
{}
```
### get_server_port
获取当前HTTP服务器的端口和URL信息。端口由系统自动分配,使用此工具可以查询实际分配的端口号和完整的服务器URL。
```json
{}
```
**返回信息**:
- `port`: 当前分配的端口号
- `host`: 服务器主机地址
- `url`: 完整的日志端点URL
- `baseUrl`: 服务器基础URL
- `endpoints`: 所有可用的API端点
**使用场景**:
- 当需要知道实际端口号时
- 跨设备调试时,需要将URL告知其他设备
- 验证服务器是否正常启动
### analyze_bug
分析Bug描述并提供关于可能原因的智能建议。
```json
{
"bugDescription": "登录按钮点击后无响应",
"files": ["login.js", "auth.js"]
}
```
### detect_environment
自动检测文件的运行环境。
```json
{
"filePath": "src/components/Login.js"
}
```
**返回**: 环境类型(browser、node、python等)和置信度
### get_debug_template
获取特定环境的调试代码模板。**这是添加调试日志的主要工具。**
```json
{
"environment": "browser",
"logMessage": "登录按钮被点击",
"variables": ["username", "password"],
"projectPath": "/Users/username/my-project",
"level": "info"
}
```
**⚠️ 重要提示**:
- 返回的代码使用 **HTTP POST**,而不是 `console.log()`
- `projectPath` **是必需的** - 使用项目目录的绝对路径
- 不要将生成的代码修改为使用 `console.log()`
- 手动将代码插入到文件的适当位置
**示例返回代码**:
```javascript
// ==================== DEBUG CODE START ====================
// ⚠️ DO NOT REPLACE WITH console.log()
// This code sends logs via HTTP POST to the debug server
// ==================== DEBUG CODE START ====================
fetch('http://localhost:PORT/api/log', { // PORT为自动分配的端口,使用get_server_port工具查询
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
projectPath: '/Users/username/my-project',
timestamp: new Date().toISOString(),
level: 'info',
message: '登录按钮被点击',
data: { username, password }
})
}).catch(err => console.error('[Debug Log Failed]', err));
// ==================== DEBUG CODE END ====================
```
### read_debug_logs
从项目读取调试日志。
```json
{
"projectPath": "/Users/username/my-project",
"lastLines": 100
}
```
**返回**: 包含时间戳、级别、消息和数据的日志条目数组
### list_debug_blocks
列出项目中所有调试块(debug-start和debug-end标记之间的代码)。
```json
{
"projectPath": "/Users/username/my-project"
}
```
### clear_debug_logs
清除项目日志文件中的所有调试日志。
```json
{
"projectPath": "/Users/username/my-project"
}
```
## 完整的调试会话示例
这是一个完整的调试流程示例:
### 初始问题报告
**用户**: "我的React应用的登录表单无法提交。当我点击提交按钮时,没有任何反应。"
### 步骤 1:分析阶段
**AI**: 让我分析这个问题并检查你的环境。
*使用: `analyze_bug` 和 `detect_environment`*
"根据你的描述,可能的原因是:
1. 提交按钮未附加事件监听器
2. 表单验证阻止提交
3. 提交处理函数有错误
我检测到你正在使用浏览器环境的React。"
### 步骤 2:首次调试代码注入
**AI**: 我将添加一个日志来检查按钮点击事件是否触发。
*使用 `get_debug_template` 配合 projectPath 并插入代码*
```javascript
// AI将此插入到 handleSubmit 函数中
fetch('http://localhost:PORT/api/log', { // PORT为自动分配的端口,使用get_server_port工具查询
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
projectPath: '/Users/john/my-app',
timestamp: new Date().toISOString(),
level: 'info',
message: '提交按钮被点击',
data: { formData, isValid }
})
}).catch(err => console.error('[Debug Log Failed]', err));
```
### 步骤 3:AI提供测试说明
**AI**:
💭 **我的假设**: 提交按钮的点击处理程序可能没有附加,或者有提前返回阻止处理程序执行。
📋 **测试步骤**:
1. 重启React开发服务器
2. 在浏览器中打开登录页面
3. 填写所有必填字段
4. 点击提交按钮
5. 检查浏览器控制台是否有错误
✅ **预期结果**: 如果处理程序正常工作,你应该看到指示按钮被点击的调试日志条目。
📢 **请报告结果**: 点击后发生了什么?你看到控制台错误了吗?
### 步骤 4:用户报告
**用户**: "我点击了按钮但没有任何反应。控制台中也没有错误。"
### 步骤 5:AI分析日志
**AI**: 让我检查调试日志以捕获的内容。
*使用 `read_debug_logs(projectPath="/Users/john/my-app")`*
"我没有看到任何按钮点击的日志条目。这证实了点击处理程序根本没有被调用。"
### 步骤 6:第二次迭代
**AI**: 事件监听器没有触发。让我添加一个日志来检查组件是否正确挂载,并验证事件处理程序是否附加。
*再次使用 `get_debug_template` 并插入更多调试日志*
**AI**:
💭 **新假设**: 组件可能没有挂载,或者JSX在事件处理程序绑定中有错误。
📋 **测试步骤**:
1. 刷新页面
2. 检查是否看到 "Login component mounted" 日志
3. 再次尝试点击提交
✅ **预期结果**: 你应该看到组件挂载日志,这将告诉我们组件是否已加载。
### 步骤 7:用户提供意外结果
**用户**: "我看到挂载日志了!但点击提交时,控制台显示 'handleSubmit is not defined'。"
### 步骤 8:AI调查意外结果
**AI**: 啊!这非常有帮助。"handleSubmit is not defined" 错误意味着函数没有被正确绑定或导入。让我检查你的组件代码...
[AI读取文件并识别问题]
"我发现了问题!你有 `onClick={handleSubmit}`,但函数定义为 `const handleLoginSubmit = (...)`。名称不匹配。让我修复它。"
### 步骤 9:解决方案
**AI**: 我将更正JSX中的函数名。
[AI修复代码]
💡 **根本原因**: 函数名不匹配 - JSX引用 `handleSubmit`,但实际函数名为 `handleLoginSubmit`
📋 **最终测试步骤**:
1. 重启服务器
2. 再次尝试提交表单
3. 验证其正常工作
✅ **预期结果**: 表单现在应该成功提交!
### 步骤 10:自动清理(包括视觉标记)
**用户**: "太好了!谢谢!"
**AI**: [检测到成功确认并审查所有修改]
太好了!让我立即清理所有调试代码和临时更改。
*使用 `clear_debug_logs` 并搜索所有调试标记*
"✅ 所有调试日志已清除
✅ 调试代码已从以下位置移除:
- src/components/Login.js (第15-25行) - HTTP POST日志
- src/api/auth.js (第42-50行) - HTTP POST日志
✅ 临时视觉标记已恢复:
- src/components/Login.js - 按钮标签从 'TEST-LOGIN' 改回 'Login'
- src/styles/button.css - 背景颜色从 'red' 改回 'blue'
- src/assets/test-image.png - 移除测试图片引用
你的应用现在干净并准备就绪!"
---
### 本示例的关键改进:
1. ✅ **AI始终解释其假设** 然后添加代码
2. ✅ **AI提供清晰的编号测试步骤**
3. ✅ **AI清楚地说明了预期结果**
4. ✅ **AI询问具体反馈** 来自用户
5. ✅ **AI使用 read_debug_logs** 验证实际发生的情况
6. ✅ **AI调查意外结果**(函数名错误)
7. ✅ **AI基于数据迭代** 直到找到根本原因
8. ✅ **AI在用户确认成功后立即自动清理** - 不询问"Should I clean up?"
### 成功检测触发词
当用户说以下内容时,AI应自动清理:
- ✅ "It works!" / "太好了!" / "成功了!"
- ✅ "Fixed!" / "修复了!"
- ✅ "Success!" / "成功!"
- ✅ "Great!" / "太棒了!"
- ✅ "Thanks!" / "谢谢!"
- ✅ "Perfect!" / "完美!"
- ✅ "That solved it" / "解决了"
- ✅ "Working now" / "现在可以工作了"
AI应该继续调试当用户说:
- ❌ "Still not working" / "还是不工作"
- ❌ "Same error" / "同样的错误"
- ❌ "Didn't help" / "没有帮助"
- ❌ "Nothing changed" / "没有变化"
- ❌ "Getting a different error" / "出现不同的错误"
## 临时修改标记
对调试目的进行任何临时更改时,你必须清楚地标记它们以便清理:
### 临时更改的类型
#### 1. 调试代码(自动)
已包装在 `DEBUG CODE START/END` 标记中:
```javascript
// ==================== DEBUG CODE START ====================
fetch('http://localhost:PORT/api/log', { // PORT为自动分配的端口,使用get_server_port工具查询 ... });
// ==================== DEBUG CODE END ====================
```
#### 2. 视觉/测试标记(手动 - 必须添加)
**按钮文本更改**:
```javascript
// TEMPORARY DEBUG MARKER - WILL BE REVERTED
<button>TEST-LOGIN</button> // 从 "Login" 改的
// END TEMPORARY DEBUG MARKER
```
**测试图片**:
```jsx
// TEMPORARY DEBUG MARKER - WILL BE REVERTED
<img src="/test-debug-image.png" alt="Testing visibility" />
// END TEMPORARY DEBUG MARKER
```
**颜色高亮**:
```css
/* TEMPORARY DEBUG MARKER - WILL BE REVERTED */
.button { background-color: red; } /* 从 blue 改的 */
/* END TEMPORARY DEBUG MARKER */
```
**占位符文本**:
```javascript
// TEMPORARY DEBUG MARKER - WILL BE REVERTED
const label = "DEBUG MODE - Button at top"; // 从 "Submit" 改的
// END TEMPORARY DEBUG MARKER
```
**测试标志**:
```javascript
// TEMPORARY DEBUG MARKER - WILL BE REVERTED
const isDebugging = true; // 将被移除
// END TEMPORARY DEBUG MARKER
```
### 清理检查清单
当用户确认成功时,检查并恢复:
✅ **调试代码**:
- [ ] 搜索 `DEBUG CODE START` 并移除所有块
- [ ] 使用 `clear_debug_logs` 清除调试日志
✅ **视觉标记**:
- [ ] 搜索 `TEMPORARY DEBUG MARKER` 注释
- [ ] 将按钮标签恢复为原始状态
- [ ] 删除测试图片
- [ ] 恢复原始颜色/样式
- [ ] 删除占位符文本
- [ ] 删除测试标志/变量
✅ **验证**:
- [ ] 应用外观和行为与调试前完全相同
- [ ] 没有遗留的调试相关注释
- [ ] 没有引用测试资源
## 跨设备调试
通过配置服务器主机,调试网络上的移动设备和其他设备。
### 何时使用跨设备调试
- 📱 **移动Web应用**: 从开发机器调试移动浏览器
- 📲 **React Native应用**: 在物理设备上测试的同时捕获日志
- 🌐 **多设备**: 在手机、平板和电脑上同时测试你的Web应用
- 🏠 **本地网络测试**: 在设备上测试,无需部署到生产环境
### 设置指南
#### 1. 查找你计算机的局域网IP
**Windows**:
```cmd
ipconfig
```
查找 "IPv4 地址" → 例如 `192.168.1.100`
**Mac/Linux**:
```bash
ifconfig | grep "inet " | grep -v 127.0.0.1
# 或
ip addr show | grep "inet " | grep -v 127.0.0.1
```
查找 "inet" → 例如 `192.168.1.100`
#### 2. 配置MCP服务器
更新你的MCP客户端配置:
```json
{
"mcpServers": {
"debug-mcp": {
"command": "node",
"args": ["D:/work/debug-mcp/dist/index.js"],
"env": {
"DEBUG_HOST": "192.168.1.100" // 你的局域网IP
// 注意:端口会自动分配,无需配置 DEBUG_PORT
}
}
}
}
```
或使用 `0.0.0.0` 接受来自任何设备的连接:
```json
{
"env": {
"DEBUG_HOST": "0.0.0.0"
// 注意:端口会自动分配,无需配置 DEBUG_PORT
}
}
```
#### 3. 配置防火墙(如果需要)
**Windows**:
```cmd
# 使用get_server_port工具获取实际端口,然后替换PORT
netsh advfirewall firewall add rule name="Debug MCP" dir=in action=allow protocol=TCP localport=PORT
```
**Mac/Linux**:
```bash
# 通常不需要,但如果你有防火墙:
# 使用get_server_port工具获取实际端口,然后替换PORT
sudo ufw allow PORT/tcp
```
#### 4. 测试连接
从网络上的另一个设备:
```bash
# 使用get_server_port工具获取实际端口,然后替换PORT
curl http://192.168.1.100:PORT/health
```
应该返回: `{"status":"ok"}`
### 使用示例
**场景**: 调试移动Web应用
1. **配置服务器** 使用局域网IP: `DEBUG_HOST=192.168.1.100`
2. **AI生成调试代码** 使用正确的URL:
```javascript
// 使用get_server_port工具获取实际端口,然后替换PORT
fetch('http://192.168.1.100:PORT/api/log', {
method: 'POST',
body: JSON.stringify({ message: '按钮被点击' })
});
```
3. **在移动设备上打开你的Web应用** 使用: `http://192.168.1.100:3000`
4. **在手机上测试应用** - 日志被发送到你的计算机
5. **AI读取日志** 从你的计算机: `read_debug_logs(projectPath="/path/to/project")`
### 主机配置选项
| DEBUG_HOST 值 | 描述 | 使用场景 |
|-----------------|-------------|----------|
| `localhost` | 仅本地连接 | 默认,本地调试 |
| `0.0.0.0` | 接受来自任何设备的连接 | 灵活测试 |
| `192.168.1.100` | 你的特定局域网IP | 明确,推荐用于移动设备 |
| `127.0.0.1` | 仅本地主机 | 与localhost相同 |
### 故障排除
**无法从移动设备连接**:
1. 验证设备在同一网络上
2. 使用 `get_server_port` 工具查询实际端口
3. 检查该端口的防火墙设置
4. 确认MCP服务器正在运行
5. 使用curl测试: `curl http://YOUR_IP:PORT/health`(PORT为实际端口)
**日志没有出现**:
1. 检查生成的代码使用正确的URL
2. 验证projectPath设置正确
3. 检查浏览器控制台的网络错误
4. 确保设备可以到达你的计算机
## HTTP API端点
调试服务器在自动分配的端口上运行HTTP API服务器。使用 `get_server_port` MCP工具可以查询实际端口和URL。
### POST /api/log
从运行的应用程序接收调试日志条目。
**示例**:
```bash
# 使用get_server_port工具查询实际端口,然后替换PORT
curl -X POST http://localhost:PORT/api/log \
-H "Content-Type: application/json" \
-d '{
"projectPath": "/path/to/project",
"timestamp": "2025-01-03T10:30:00Z",
"level": "info",
"message": "登录按钮被点击",
"data": { "username": "test", "isLoggedIn": false }
}'
```
### GET /api/log
检索调试日志。
```bash
# 使用get_server_port工具查询实际端口,然后替换PORT
curl http://localhost:PORT/api/log?last=100&projectPath=/path/to/project
```
### DELETE /api/log
清除所有调试日志。
```bash
# 使用get_server_port工具查询实际端口,然后替换PORT
curl -X DELETE http://localhost:PORT/api/log?projectPath=/path/to/project
```
### GET /api/stats
获取日志统计信息。
```bash
# 使用get_server_port工具查询实际端口,然后替换PORT
curl http://localhost:PORT/api/stats?projectPath=/path/to/project
```
### GET /health
健康检查端点。
```bash
# 使用get_server_port工具查询实际端口,然后替换PORT
curl http://localhost:PORT/health
```
## 环境特定示例
### Browser / Node.js (18+)
```javascript
// 使用fetch API
fetch('http://localhost:PORT/api/log', { // PORT为自动分配的端口,使用get_server_port工具查询
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
projectPath: '/path/to/project',
timestamp: new Date().toISOString(),
level: 'info',
message: 'Debug message',
data: { variable1, variable2 }
})
}).catch(err => console.error('[Debug Log Failed]', err));
```
### Node.js Legacy (v14-17)
```javascript
// 使用http模块
const http = require('http');
const data = JSON.stringify({
projectPath: '/path/to/project',
timestamp: new Date().toISOString(),
level: 'info',
message: 'Debug message',
data: { variable1, variable2 }
});
// 使用get_server_port工具获取实际端口,然后替换PORT
const req = http.request('http://localhost:PORT/api/log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
req.write(data);
req.end();
```
### Python
```python
import requests
from datetime import datetime
try:
requests.post(
'http://localhost:PORT/api/log', # PORT为自动分配,使用get_server_port工具查询
json={
'projectPath': '/path/to/project',
'timestamp': datetime.now().isoformat(),
'level': 'info',
'message': 'Debug message',
'data': {'variable1': variable1, 'variable2': variable2}
},
timeout=0.1
)
except Exception:
pass # 静默失败,不破坏主要逻辑
```
### PHP
```php
$logData = json_encode([
'projectPath' => '/path/to/project',
'timestamp' => date('c'),
'level' => 'info',
'message' => 'Debug message',
'data' => ['variable1' => $variable1, 'variable2' => $variable2]
]);
// 使用get_server_port工具获取实际端口,然后替换PORT
$ch = curl_init('http://localhost:PORT/api/log');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $logData);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100);
curl_exec($ch);
curl_close($ch);
```
### WeChat Mini Program
```javascript
wx.request({
url: 'http://localhost:PORT/api/log', // PORT为自动分配,使用get_server_port工具查询
method: 'POST',
data: {
projectPath: '/path/to/project',
timestamp: new Date().toISOString(),
level: 'info',
message: 'Debug message',
data: { variable1, variable2 }
},
fail: (err) => console.error('[Debug Log Failed]', err)
});
```
### Java
```java
// 需要 DebugHttpClient.java 工具类
// 工具会自动检测工具类是否存在,并引导您添加它
try {
DebugHttpClient.sendLog(
"http://localhost:PORT/api/log", // PORT为自动分配,使用get_server_port工具查询
"Debug message",
new java.util.HashMap<String, Object>() {{
put("variable1", variable1);
put("variable2", variable2);
}},
"info"
);
} catch (Exception e) {
// 静默失败 - 不中断主逻辑
}
```
### Android
```java
// Android: 网络请求必须在后台线程中执行
if (android.os.Looper.getMainLooper().getThread() == Thread.currentThread()) {
// 我们在主线程中,在后台线程中执行
new Thread(() -> {
try {
DebugHttpClient.sendLog(
"http://localhost:PORT/api/log", // PORT为自动分配,使用get_server_port工具查询
"Debug message",
new java.util.HashMap<String, Object>() {{
put("variable1", variable1);
put("variable2", variable2);
}},
"info"
);
} catch (Exception e) {
// 静默失败
}
}).start();
} else {
// 已在后台线程,直接执行
try {
DebugHttpClient.sendLog(
"http://localhost:PORT/api/log", // PORT为自动分配,使用get_server_port工具查询
"Debug message",
new java.util.HashMap<String, Object>() {{
put("variable1", variable1);
put("variable2", variable2);
}},
"info"
);
} catch (Exception e) {
// 静默失败
}
}
```
### Kotlin
```kotlin
// Kotlin: 使用协程进行异步网络请求(Android)或直接调用(Java)
try {
// 对于 Android: 使用协程作用域
// CoroutineScope(Dispatchers.IO).launch {
// DebugHttpClient.sendLog(...)
// }
// 对于标准 Java: 直接调用
DebugHttpClient.sendLog(
"http://localhost:PORT/api/log", // PORT为自动分配,使用get_server_port工具查询
"Debug message",
mapOf("variable1" to variable1, "variable2" to variable2),
"info"
)
} catch (e: Exception) {
// 静默失败 - 不中断主逻辑
}
```
### Objective-C (iOS/macOS)
```objective-c
// 使用get_server_port工具获取实际端口,然后替换PORT
NSURL *url = [NSURL URLWithString:@"http://localhost:PORT/api/log"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setTimeoutInterval:0.1];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSString *timestamp = [formatter stringFromDate:[NSDate date]];
NSDictionary *logData = @{
@"timestamp": timestamp,
@"level": @"info",
@"message": @"Debug message",
@"data": @{@"variable1": variable1, @"variable2": variable2}
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:logData options:0 error:&error];
if (jsonData) {
[request setHTTPBody:jsonData];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 静默失败 - 不中断主逻辑
}];
[task resume];
}
```
## 备份文件
修改任何文件之前,工具会创建备份:
```
original.js.backup.1704288000000
```
这些备份可用于在需要时恢复文件。
## 贡献
欢迎贡献!请随时提交issue或拉取请求。
## 许可证
MIT