Skip to content

Latest commit

 

History

History
675 lines (526 loc) · 18.1 KB

File metadata and controls

675 lines (526 loc) · 18.1 KB

WaveForge MCP 故障排除指南

本文档记录了 WaveForge MCP 服务器开发过程中遇到的问题和解决方案。

🚨 已知问题与解决方案

1. connect_project 与 project_bind 共享底层实现导致的问题

问题描述

  • 原始的 project_bind 工具无法在 Kiro IDE 中正常工作
  • 创建 connect_project 作为替代后,问题依然存在
  • 两个工具都表现出相同的故障模式

根本原因分析(2025-09-30 更新):

经过深入代码分析发现,问题不是工具名称冲突,而是 connect_projectproject_bind 共享了相同的底层实现:

  1. 共享的调用链

    • connect_projectConnectProjectTool.connectByRoot()ProjectManager.bindProject()
    • project_bindProjectBindTool.handle()ProjectManager.bindProject()
    • 两者最终都调用相同的 ProjectManager.bindProject() 方法
  2. 共享的底层代码

    • ProjectManager.bindProject() 使用 ProjectRegistry.validateProjectPath()
    • ProjectManager.bindProject() 使用 ProjectRegistry.initializeProject()
    • 这些都是 project_bind 时代的旧代码
  3. 设计违背

    • 按照设计文档(current-task-outcome-sync.md),connect_project 应该是握手流程的核心工具
    • 但当前实现中,它只是 project_bind 的一个薄包装层
    • 任何 project_bind 的底层问题都会直接传递给 connect_project

解决方案(任务 7.1):

  • connect_project 创建完全独立的实现
  • 使用 EnhancedProjectRegistry 的现代化 API
  • 按设计文档实现 root/slug/repo 三种连接方式
  • 完全移除 project_bind 工具及其所有相关代码
  • 确保 connect_project 不再依赖任何 project_bind 时代的代码路径

经验教训

  • MCP 工具名称选择需要避免可能的保留字(已证实不是名称问题)
  • 当替换工具不work时,需要检查是否共享了有问题的底层实现
  • 新工具应该有独立的实现,而不是简单地包装旧代码
  • 代码重构时要彻底清理旧代码,避免间接依赖
  • Git 历史分析很重要:connect_project 的诞生是因为 project_bind 问题,但没有解决根本原因

2. JSON Schema anyOf/oneOf 兼容性问题(Cursor/Kiro 无法使用工具)

问题描述

  • connect_project 工具在 Cursor 和 Kiro IDE 中报错 "An unexpected error occurred"
  • 同样的工具在 Codex 中正常工作
  • MCP 服务器成功连接,但工具调用失败
  • 本地测试和单元测试全部通过

根本原因(2025-09-30 发现):

在提交 156b697 中,工具的 JSON Schema 定义使用了 anyOfoneOf 语法:

问题 1: connect_project 使用了 anyOf

inputSchema: {
  type: 'object',
  properties: { /* ... */ },
  additionalProperties: false,
  anyOf: [                          // ⚠️ Cursor/Kiro 不支持
    { required: ['root'] },
    { required: ['project_path'] },
    { required: ['slug'] },
    { required: ['repo'] },
  ],
}

问题 2: current_task_modify 使用了 oneOf

content: {
  oneOf: [                          // ⚠️ Cursor/Kiro 不支持
    { type: 'string' },
    { type: 'array', items: { type: 'string' } },
  ],
}

不同 MCP 客户端对 JSON Schema 的支持不同

  • ✗ Cursor/Kiro:严格的 schema 验证,不支持 anyOf/oneOf/allOf
  • ✓ Codex:更宽容的 schema 验证,忽略复杂约束

解决方案

移除所有高级 schema 特性,使用最简单的 JSON Schema 语法:

// connect_project 修复
inputSchema: {
  type: 'object',
  properties: {
    root: { type: 'string', description: '...' },
    project_path: { type: 'string', description: '...' },
    slug: { type: 'string', description: '...' },
    repo: { type: 'string', description: '...' },
  },
  additionalProperties: false,
  // 不使用 anyOf - 在 description 中说明
  // 参数验证在代码逻辑中进行
}

// current_task_modify 修复
content: {
  // 移除 oneOf - 可以是 string 或 string[]
  description: '修改内容(字符串或字符串数组)',
  // 类型验证在代码中进行
}

MCP 配置修复

如果 MCP 服务器启动失败("Connection closed"),检查配置:

{
  "mcpServers": {
    "waveforge": {
      "command": "node",
      "args": ["/absolute/path/to/waveforge/dist/esm/server.js"],
      "env": {
        "WF_LOG_LEVEL": "SILENT",
        "WF_DEBUG": "false"
      },
      "disabled": false,
      "autoApprove": [
        "connect_project",
        "project_info",
        "current_task_init",
        "current_task_read",
        "current_task_update",
        "current_task_modify",
        "current_task_complete",
        "current_task_log"
      ],
      "disabledTools": ["health", "ping"]
    }
  }
}

重启步骤

  1. 保存配置文件
  2. 在 IDE 中完全重启 MCP 服务器(断开并重新连接)
  3. Cursor 用户可能需要重启整个 IDE

经验教训

  • MCP 工具的 JSON Schema 应该使用最保守、最基本的语法
  • 避免使用所有高级 schema 特性anyOfoneOfallOfnot、条件验证等
  • 复杂的参数验证应该在工具实现的代码中进行,而不是依赖 JSON Schema
  • 不同 MCP 客户端对 JSON Schema 的支持程度差异很大
  • 单元测试通过不代表在所有 MCP 客户端中能用,需要在实际客户端中测试
  • 配置文件中必须使用绝对路径,不要使用命令别名

3. MCP 服务器日志输出干扰问题

问题描述

  • MCP 服务器启动时输出大量结构化日志
  • 这些日志干扰了 MCP 协议的正常通信
  • 导致客户端无法正确解析工具响应

解决方案

  1. 添加 SILENT 日志级别支持
  2. 在 MCP 配置中设置 WF_LOG_LEVEL=SILENT
  3. 修改日志系统以支持完全静默模式

代码变更

// 在 LogLevel 枚举中添加
Silent = 'SILENT',

// 在 shouldLog 方法中添加检查
if (this.config.level === LogLevel.Silent) {
  return false;
}

3. ESLint 未使用变量错误

问题描述

  • Git pre-commit hooks 中的 ESLint 检查失败
  • 多个测试文件中存在未使用的变量和导入

解决方案

  • 移除未使用的导入(如 vi, ProjectBindParams 等)
  • 将未使用但需要的变量重命名为 _variableName 格式
  • 跳过不再适用的测试用例

🛠️ 当前工具状态

可用工具

工具名称 状态 描述
connect_project ✅ 可用 连接项目到当前 MCP 会话
project_info ✅ 可用 获取当前连接项目的信息
current_task_init ✅ 可用 初始化新的开发任务
current_task_read ✅ 可用 读取当前任务完整状态
current_task_update ✅ 可用 更新任务状态和进度
current_task_modify ✅ 可用 修改任务结构
current_task_complete ✅ 可用 完成任务并生成文档
current_task_log ✅ 可用 记录重要事件
health 🚫 禁用 服务器健康检查
ping 🚫 禁用 服务器连接测试

工具使用示例

connect_project

{
  "project_path": "/path/to/your/project"
}

响应:

{
  "success": true,
  "message": "项目连接成功",
  "data": {
    "project": {
      "id": "project-1758555879023",
      "root": "/path/to/your/project",
      "slug": "waveforge"
    }
  }
}

project_info

{}

响应:

{
  "success": true,
  "message": "获取项目信息成功",
  "data": {
    "project": {
      "id": "project-1758555879023",
      "root": "/path/to/your/project",
      "slug": "waveforge"
    }
  }
}

🔒 安全检查和验证

connect_project 工具安全性

重要提醒connect_project 工具现在包含完整的安全检查机制,确保项目连接的安全性和可靠性。

路径验证检查

工具会自动执行以下验证:

  1. 路径存在性检查:验证提供的路径是否存在
  2. 目录类型验证:确认路径指向的是目录而非文件
  3. 读写权限检查:验证当前用户对目录的读写权限
  4. 路径规范化:处理相对路径、符号链接等边界情况

安全防护机制

系统会阻止连接到以下危险目录:

macOS/Linux 系统关键目录:

  • / (根目录)
  • /bin, /sbin, /usr/bin, /usr/sbin (系统二进制文件)
  • /etc (系统配置)
  • /var, /tmp (系统变量和临时文件)
  • /boot (启动文件)
  • /dev, /proc, /sys (设备和系统信息)

Windows 系统关键目录:

  • C:\Windows (系统目录)
  • C:\Program Files, C:\Program Files (x86) (程序文件)
  • C:\System Volume Information (系统卷信息)

用户敏感目录:

  • 用户主目录的根级别 (~C:\Users\username)
  • .ssh, .aws, .config 等配置目录

项目结构检测

工具会智能检测项目类型和结构:

  1. 项目类型识别

    • Node.js 项目 (package.json)
    • Python 项目 (requirements.txt, pyproject.toml, setup.py)
    • Rust 项目 (Cargo.toml)
    • Java 项目 (pom.xml, build.gradle)
    • Git 仓库 (.git 目录)
  2. 项目根目录检测

    • 自动向上查找项目标识文件
    • 智能确定真正的项目根目录
    • 避免在子目录中错误初始化
  3. 项目健康检查

    • 验证 .wave 目录结构完整性
    • 检查必要文件的权限状态
    • 自动修复损坏的配置文件

错误处理和用户反馈

当遇到安全问题时,工具会提供详细的错误信息:

{
  "success": false,
  "error": "SECURITY_VIOLATION",
  "message": "拒绝连接到系统关键目录",
  "details": {
    "path": "/etc",
    "reason": "系统配置目录,存在安全风险",
    "suggestion": "请选择一个开发项目目录"
  }
}
{
  "success": false,
  "error": "PERMISSION_DENIED",
  "message": "目录权限不足",
  "details": {
    "path": "/some/protected/dir",
    "missing_permissions": ["write"],
    "suggestion": "请检查目录权限或选择其他目录"
  }
}

使用建议

  1. 选择合适的项目目录

    • 使用专门的开发目录 (如 ~/Development, ~/Projects)
    • 确保目录具有完整的读写权限
    • 避免在系统目录或敏感位置创建项目
  2. 项目结构最佳实践

    • 在项目根目录运行 connect_project
    • 让工具自动检测和设置项目结构
    • 定期使用 project_info 检查项目状态
  3. 安全注意事项

    • 不要尝试绕过安全检查
    • 如果遇到权限问题,检查文件系统权限而不是修改安全规则
    • 定期备份 .wave 目录中的重要数据

🔧 配置建议

MCP 配置 (.kiro/settings/mcp.json)

{
  "mcpServers": {
    "waveforge": {
      "command": "node",
      "args": ["/path/to/waveforge/dist/esm/server.js"],
      "env": {
        "WF_LOG_LEVEL": "SILENT",
        "WF_DEBUG": "false"
      },
      "disabled": false,
      "autoApprove": [
        "connect_project",
        "project_info",
        "current_task_init",
        "current_task_update",
        "current_task_read",
        "current_task_modify",
        "current_task_complete",
        "current_task_log"
      ],
      "disabledTools": ["health", "ping"]
    }
  }
}

安全配置说明

推荐的安全设置:

  1. 日志级别设置

    • WF_LOG_LEVEL: "SILENT" - 防止日志输出干扰 MCP 通信
    • 在调试时可临时改为 "INFO""DEBUG"
  2. 自动批准工具

    • 只批准经过验证的核心工具
    • connect_projectproject_info 包含完整的安全检查
    • 任务管理工具 (current_task_*) 只操作项目内的 .wave 目录
  3. 禁用工具

    • healthping 工具默认禁用,减少攻击面
    • 如需调试可临时启用
  4. 环境变量安全

    • 不要在配置中暴露敏感信息
    • 使用环境变量文件 (.env) 管理敏感配置
    • 确保 .env 文件不被提交到版本控制

高安全环境配置:

{
  "mcpServers": {
    "waveforge": {
      "command": "node",
      "args": ["/path/to/waveforge/dist/esm/server.js"],
      "env": {
        "WF_LOG_LEVEL": "SILENT",
        "WF_DEBUG": "false",
        "WF_SECURITY_MODE": "strict"
      },
      "disabled": false,
      "autoApprove": [],
      "disabledTools": ["health", "ping"]
    }
  }
}

在高安全模式下:

  • 所有工具调用都需要手动确认
  • 启用额外的路径验证检查
  • 记录所有文件系统操作的审计日志

环境变量

变量名 可选值 描述
WF_LOG_LEVEL INFO, WARNING, ERROR, SILENT 日志级别
WF_DEBUG true, false 调试模式

🧪 测试状态

通过的测试

  • ✅ 基本项目连接功能
  • ✅ 参数验证
  • ✅ 错误处理(简化版)

跳过的测试

  • ⏭️ 复杂的项目状态管理测试
  • ⏭️ 文件系统集成测试
  • ⏭️ 多项目并发测试

这些测试被跳过是因为当前使用的是简化实现,专注于核心功能的稳定性。

🏥 项目健康检查指南

使用 project_info 进行健康检查

project_info 工具不仅提供项目基本信息,还会执行全面的健康检查:

基本健康检查

# 调用 project_info 工具
{
  "tool": "project_info"
}

健康检查项目:

  1. 项目结构完整性

    • 验证 .wave 目录结构
    • 检查必要的索引文件 (index.json, _latest.json)
    • 确认模板文件存在
  2. 文件权限状态

    • 检查读写权限
    • 验证目录访问权限
    • 识别权限问题
  3. 数据一致性

    • 验证 JSON 文件格式
    • 检查任务数据完整性
    • 识别损坏的文件

健康状态响应示例

健康状态良好:

{
  "success": true,
  "message": "获取项目信息成功",
  "data": {
    "project": {
      "id": "project-1758555879023",
      "root": "/path/to/project",
      "slug": "my-project"
    },
    "health": {
      "status": "healthy",
      "checks": {
        "directory_structure": "ok",
        "file_permissions": "ok",
        "data_integrity": "ok"
      }
    }
  }
}

发现问题时:

{
  "success": true,
  "message": "获取项目信息成功(发现问题)",
  "data": {
    "project": {
      "id": "project-1758555879023",
      "root": "/path/to/project",
      "slug": "my-project"
    },
    "health": {
      "status": "warning",
      "checks": {
        "directory_structure": "missing_directories",
        "file_permissions": "ok",
        "data_integrity": "corrupted_index"
      },
      "issues": [
        {
          "type": "missing_directory",
          "path": ".wave/templates",
          "severity": "warning",
          "auto_fix": true
        },
        {
          "type": "corrupted_file",
          "path": ".wave/tasks/index.json",
          "severity": "error",
          "auto_fix": true
        }
      ],
      "recommendations": [
        "运行自动修复以解决发现的问题",
        "建议备份当前数据后重新初始化"
      ]
    }
  }
}

自动修复机制

系统具备自动修复常见问题的能力:

可自动修复的问题

  1. 缺失目录:自动创建必要的目录结构
  2. 损坏的 JSON 文件:重建为有效的空结构
  3. 缺失的模板文件:从默认模板复制
  4. 权限问题:提供修复建议

手动修复步骤

对于无法自动修复的问题:

  1. 备份数据

    cp -r .wave .wave.backup.$(date +%Y%m%d_%H%M%S)
  2. 重新连接项目

    {
      "tool": "connect_project",
      "project_path": "/path/to/your/project"
    }
  3. 验证修复结果

    {
      "tool": "project_info"
    }

定期健康检查建议

  1. 每日检查:在开始工作前运行 project_info
  2. 问题排查:遇到异常时首先检查项目健康状态
  3. 数据备份:定期备份 .wave 目录
  4. 版本控制:将 .wave 目录纳入 Git 管理(除了 current-task.md)

常见健康问题和解决方案

问题类型 症状 解决方案
目录结构损坏 工具调用失败,找不到文件 重新连接项目,自动重建结构
JSON 文件损坏 解析错误,数据丢失 自动修复或从备份恢复
权限不足 无法写入文件 检查并修复目录权限
模板缺失 无法生成文档 自动复制默认模板
索引不一致 任务列表显示异常 重建索引文件

📝 开发注意事项

  1. 工具命名:避免使用可能与 IDE 冲突的通用名称
  2. 日志管理:在 MCP 环境中,过多的日志输出会干扰协议通信
  3. 简化优先:在功能稳定之前,优先使用简化实现
  4. 测试适配:测试应该与实际实现保持一致
  5. 安全第一:始终验证用户输入,特别是文件路径
  6. 健康监控:定期检查项目健康状态,及时发现和解决问题

🔄 未来改进计划

  1. 恢复完整的项目管理功能

    • 实现真正的项目状态持久化
    • 支持多项目管理
    • 添加项目验证和清理功能
  2. 增强错误处理

    • 更详细的错误信息
    • 自动恢复机制
    • 更好的用户反馈
  3. 性能优化

    • 减少文件系统操作
    • 添加缓存机制
    • 优化启动时间

📞 获取帮助

如果遇到问题:

  1. 检查 MCP 配置是否正确
  2. 确认日志级别设置为 SILENT
  3. 验证工具名称没有冲突
  4. 查看本文档的已知问题部分

如果问题仍然存在,请提交 Issue 并包含:

  • MCP 配置文件
  • 错误日志
  • 复现步骤