# MCP Bridge 插件开发流程文档 本文档记录了 MCP Bridge 插件的完整开发流程,包括核心架构设计、功能实现、测试与调试等各个阶段。 ## 0. 项目开发规范 (Project Rules) > [!IMPORTANT] > 所有贡献者必须严格遵守以下规则: 1. **语言与沟通**: 所有注释、文档、计划、任务及 AI 回复必须使用 **简体中文 (Simplified Chinese)**。 2. **技术栈**: 新脚本必须使用 **TypeScript** (`.ts`)。禁止创建新的 `.js` 文件 (除非是构建脚本或测试配置)。 3. **文档**: 所有修改或创建的脚本必须包含详细的 JSDoc 格式注释。 4. **架构**: 严禁引入新的架构模式或重型外部库。必须复用现有的 Cocos Creator 管理器和工具类。 5. **隔离原则**: 保持 `main.js` (主进程) 与 `scene-script.js` (渲染进程) 的严格职责分离。即便是在主进程中,也应通过 IPC 与场景脚本交互。 6. **主体校验规则 (Subject Validation Rule)**: 在对节点、组件或属性进行任何“写”操作之前,AI 必须先验证主体的存在性与类型正确性。严禁基于假设进行操作。 ## 1. 项目初始化 ### 1.1 目录结构搭建 ``` mcp-bridge/ ├── main.js # 插件主入口 ├── scene-script.js # 场景脚本 ├── mcp-proxy.js # MCP 代理 ├── README.md # 项目说明 ├── DEVELOPMENT.md # 开发流程文档 ├── package.json # 插件配置 └── panel/ # 面板目录 ├── index.html # 面板界面 └── index.js # 面板逻辑 ``` ### 1.2 插件配置 在 `package.json` 中配置插件信息: ```json { "name": "mcp-bridge", "version": "1.0.0", "description": "MCP Bridge for Cocos Creator", "main": "main.js", "panel": { "main": "panel/index.html", "type": "dockable", "title": "MCP Bridge", "width": 800, "height": 600 }, "contributions": { "menu": [ { "path": "Packages/MCP Bridge", "label": "Open Test Panel", "message": "open-test-panel" } ] } } ``` ## 2. 核心架构设计 ### 2.1 系统架构 ``` ┌────────────────────┐ HTTP ┌────────────────────┐ IPC ┌────────────────────┐ │ 外部 AI 工具 │ ──────────> │ main.js (HTTP服务) │ ─────────> │ scene-script.js │ │ (Cursor/VS Code) │ <──────── │ (MCP 协议处理) │ <──────── │ (场景操作执行) │ └────────────────────┘ JSON └────────────────────┘ JSON └────────────────────┘ ``` ### 2.2 核心模块 1. **HTTP 服务模块**:处理外部请求,解析 MCP 协议 2. **MCP 工具模块**:实现各种操作工具 3. **场景操作模块**:执行场景相关操作 4. **资源管理模块**:处理脚本和资源文件 5. **面板界面模块**:提供用户交互界面 ## 3. 功能模块实现 ### 3.1 HTTP 服务实现 在 `main.js` 中实现 HTTP 服务: ```javascript startServer(port) { try { const http = require('http'); mcpServer = http.createServer((req, res) => { // 处理请求... }); mcpServer.listen(port, () => { addLog("success", `MCP Server running at http://127.0.0.1:${port}`); }); } catch (e) { addLog("error", `Failed to start server: ${e.message}`); } } ``` ## 4. 开发历程与里程碑 ### 2026-02-10: Undo 系统深度修复与规范化 - **问题分析**: 修复了 `TypeError: Cannot read property '_name' of null`。该错误是由于直接修改节点属性(绕过 Undo 系统)与分组事务混用导致的。 - **重构要点**: 将 `update-node-transform` 中所有的直接赋值替换为 `scene:set-property` IPC 调用,确保所有变换修改均受撤销系统监控。 - **缺陷修正**: 修复了 `manage_undo` 在 `begin_group` 时传递错误参数导致 "Unknown object to record" 的问题。 - **全量汉化与文档同步**: 完成了 `main.js` 和 `scene-script.js` 的 100% 简体中文翻译。同步更新了 `README.md`、`DEVELOPMENT.md` 及 `注意事项.md`。 ### 2026-02-13: 新增 `open_prefab` 功能与消息协议修正 - **需求实现**: 新增 `open_prefab` 工具,允许 AI 直接打开预制体进入编辑模式。 - **协议修正**: 经过测试对比,最终确认使用 `scene:enter-prefab-edit-mode` 消息并配合 `Editor.Ipc.sendToAll` 是进入预制体编辑模式的最佳方案,解决了 `scene:open-by-uuid` 无法触发编辑状态的问题。 - **文档深度补全**: 遵循全局开发规范,同步更新了所有技术文档,确保 100% 简体中文覆盖及详尽的 JSDoc 注释。 ### 2026-02-25: 修复 manage_script 路径引用错误与强制生成 Meta - **缺陷修正**: 修复了 `main.js` 中 `manageScript` 处理 `create` 动作时由于变量名解构导致 `path.dirname` 找不到 `path` 引用的问题。现已改为使用预设的 `pathModule` 模块。 - **规范强化**: 将 `manage_script` 的工具提示(Prompt)更新为强制要求调用 `refresh_editor` 生成脚本的 `.meta` 文件,以确保新创建的脚本能够被正确挂载为组件,同时不增加整体 Token 消耗。 ### 3.2 MCP 工具注册 在 `/list-tools` 接口中注册工具: ```javascript const tools = [ { name: "get_selected_node", description: "获取当前选中的节点", parameters: [], }, // 其他工具... ]; ``` ### 3.3 场景操作实现 在 `scene-script.js` 中实现场景相关操作: ```javascript const sceneScript = { "create-node"(params, callback) { // 创建节点逻辑... }, "set-property"(params, callback) { // 设置属性逻辑... }, // 其他操作... }; ``` ### 3.4 脚本管理实现 在 `main.js` 中实现脚本管理功能: ```javascript manageScript(args, callback) { const { action, path, content } = args; switch (action) { case "create": // 确保父目录存在 const fs = require('fs'); const pathModule = require('path'); const absolutePath = Editor.assetdb.urlToFspath(path); const dirPath = pathModule.dirname(absolutePath); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } // 创建 TypeScript 脚本 Editor.assetdb.create(path, content || `const { ccclass, property } = cc._decorator; @ccclass export default class NewScript extends cc.Component { // LIFE-CYCLE CALLBACKS: onLoad () {} start () {} update (dt) {} }`, (err) => { callback(err, err ? null : `Script created at ${path}`); }); break; // 其他操作... } } ``` ### 3.5 批处理执行实现 在 `main.js` 中实现批处理功能: ```javascript batchExecute(args, callback) { const { operations } = args; const results = []; let completed = 0; if (!operations || operations.length === 0) { return callback("No operations provided"); } operations.forEach((operation, index) => { this.handleMcpCall(operation.tool, operation.params, (err, result) => { results[index] = { tool: operation.tool, error: err, result: result }; completed++; if (completed === operations.length) { callback(null, results); } }); }); } ``` ### 3.6 资产管理实现 在 `main.js` 中实现资产管理功能: ```javascript manageAsset(args, callback) { const { action, path, targetPath, content } = args; switch (action) { case "create": // 确保父目录存在 const fs = require('fs'); const pathModule = require('path'); const absolutePath = Editor.assetdb.urlToFspath(path); const dirPath = pathModule.dirname(absolutePath); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } Editor.assetdb.create(path, content || '', (err) => { callback(err, err ? null : `Asset created at ${path}`); }); break; // 其他操作... } } ``` ### 3.7 面板界面实现 在 `panel/index.html` 中实现标签页界面: ```html