# Feature Absorption Plan: From cocos-mcp-server to funplay-cocos-mcp This document identifies features in `cocos-mcp-server` that are missing from `funplay-cocos-mcp`, evaluates which ones are worth porting as dedicated tools, and provides concrete implementation guidance for each. ## Design Principles Follow the existing funplay tool-design philosophy (`CONTRIBUTING.md`): - **`execute_javascript` can already handle it → skip.** No dedicated tool needed. - **High-frequency, complex parameters, or benefits from structured schema → dedicated tool.** - **Multiple narrow tools → consolidate into 1-2 tools with an `action` parameter.** - New tools default to `full` profile; only high-signal tools enter `core`. ## Priority Tiers | Tier | Rationale | Tool count | |---|---|---:| | P1 — Fill real gaps | Capabilities funplay completely lacks and cannot trivially do via `execute_javascript` | 5 new tools | | P2 — Enhance existing | Strengthen tools funplay already has, or add consolidated versions of cocos-mcp-server's fragmented tools | 3 enhancements | | P3 — Optional | Useful but lower frequency; implement on demand | 6 items | --- ## P1 — Fill Real Gaps ### 1. `create_scene` — Scene creation **Gap**: funplay has `open_scene` and `list_scenes` but cannot create a new scene. **cocos-mcp-server source**: `source/tools/scene-tools.ts:205` — constructs a full `cc.Scene` JSON template (~400 lines) and writes it to disk, then imports via asset-db. **Implementation**: - **File**: `lib/tools/scene-management.js` (new) - **Dependencies**: `sceneBridge` (add `createScene` method to `scene.js`) + `Editor.Message.request('asset-db', 'create-asset', ...)` - **Schema**: ```json { "sceneName": { "type": "string", "description": "Name of the new scene" }, "savePath": { "type": "string", "description": "Asset path, e.g. db://assets/scenes/NewScene.scene" } } ``` - **Required**: `["sceneName", "savePath"]` - **Profile**: `full` - **Notes**: Do NOT port the 400-line JSON template. Instead, use `Editor.Message.request('scene', 'create-scene', ...)` if available in the target Cocos version, or call `director.runScene(new Scene())` in the scene script then `Editor.Message.request('scene', 'save-scene')`. The hand-written JSON approach in cocos-mcp-server is fragile across Cocos versions. ### 2. `copy_paste_node` — Node clipboard **Gap**: funplay has `create_node`, `delete_node`, `set_node_transform` but no copy/paste/cut. **cocos-mcp-server source**: `source/tools/scene-advanced-tools.ts:463` — `Editor.Message.request('scene', 'copy-node', uuids)`, `paste-node`, `cut-node`. **Implementation**: - **File**: `lib/tools/scene-management.js` (same file as above) - **Dependencies**: `Editor.Message.request('scene', ...)` — these are editor-side IPC, no scene script needed. - **Schema** (consolidated with `action`): ```json { "action": { "type": "string", "enum": ["copy", "paste", "cut"] }, "uuids": { "type": "array", "items": { "type": "string" }, "description": "Node UUIDs to copy or cut" }, "target": { "type": "string", "description": "Target parent node UUID (paste only)" }, "keepWorldTransform": { "type": "boolean", "default": false } } ``` - **Required**: `["action"]` - **Profile**: `full` - **IPC mapping**: - `copy` → `Editor.Message.request('scene', 'copy-node', uuids)` - `paste` → `Editor.Message.request('scene', 'paste-node', { target, uuids, keepWorldTransform })` - `cut` → `Editor.Message.request('scene', 'cut-node', uuids)` ### 3. `batch_asset_ops` — Batch asset import/delete **Gap**: funplay has `delete_asset` (single) but no batch import or batch delete. **cocos-mcp-server source**: `source/tools/asset-advanced-tools.ts:61` — `batch_import_assets` (source dir → target dir + filter + recursive + overwrite), `batch_delete_assets` (URL array). **Implementation**: - **File**: `lib/tools/assets-advanced.js` (existing, append) - **Dependencies**: `Editor.Message.request('asset-db', ...)` - **Schema** (consolidated with `action`): ```json { "action": { "type": "string", "enum": ["import", "delete"] }, "sourceDirectory": { "type": "string", "description": "Local filesystem source (import only)" }, "targetDirectory": { "type": "string", "description": "Asset-db target URL, e.g. db://assets/textures (import only)" }, "urls": { "type": "array", "items": { "type": "string" }, "description": "Asset URLs to delete (delete only)" }, "fileFilter": { "type": "array", "items": { "type": "string" }, "description": "File extensions, e.g. [\".png\", \".jpg\"]" }, "recursive": { "type": "boolean", "default": false }, "overwrite": { "type": "boolean", "default": false } } ``` - **Required**: `["action"]` - **Profile**: `full` - **IPC mapping**: - `import` → `Editor.Message.request('asset-db', 'import', targetDirectory, sourceDirectory, { ... })` - `delete` → `Editor.Message.request('asset-db', 'delete-assets', urls)` ### 4. `query_scene_state` — Scene state queries **Gap**: funplay cannot check if the scene has unsaved changes, check scene readiness, or soft-reload. **cocos-mcp-server source**: `source/tools/scene-advanced-tools.ts:283-305` — `query_scene_dirty`, `soft_reload_scene`, `query_scene_ready`. **Implementation**: - **File**: `lib/tools/scene-management.js` - **Dependencies**: `Editor.Message.request('scene', ...)` - **Schema** (consolidated with `action`): ```json { "action": { "type": "string", "enum": ["is_dirty", "is_ready", "soft_reload"] } } ``` - **Required**: `["action"]` - **Profile**: `core` — `is_dirty` is a critical signal for AI to decide whether to save before making changes. - **IPC mapping**: - `is_dirty` → `Editor.Message.request('scene', 'query-is-dirty')` - `is_ready` → `Editor.Message.request('scene', 'query-ready')` - `soft_reload` → `Editor.Message.request('scene', 'soft-reload')` ### 5. `find_unused_assets` — Find unused assets **Gap**: funplay has `inspect_asset_dependencies` and `validate_asset_dependencies` for individual assets, but no project-wide unused-asset scan. **cocos-mcp-server source**: `source/tools/asset-advanced-tools.ts:144` — scans a directory, cross-references the dependency graph. **Implementation**: - **File**: `lib/tools/assets-advanced.js` (append) - **Dependencies**: `Editor.Message.request('asset-db', 'query-assets', ...)` + dependency analysis - **Schema**: ```json { "directory": { "type": "string", "default": "db://assets" }, "excludeDirectories": { "type": "array", "items": { "type": "string" }, "default": [] } } ``` - **Required**: `[]` - **Profile**: `full` - **Notes**: Implementation requires querying all assets, building a reverse dependency map, then filtering. Medium complexity. --- ## P2 — Enhance Existing Capabilities ### 6. Enhance `inspect_asset_dependencies` — Add reverse direction **Gap**: funplay only supports forward dependencies. cocos-mcp-server supports `dependents` (reverse) and `both`. **cocos-mcp-server source**: `source/tools/asset-advanced-tools.ts:124` — `direction` parameter with enum `["dependents", "dependencies", "both"]`. **Implementation**: - **File**: `lib/tools/assets-advanced.js` (modify existing tool) - **Change**: Add `direction` parameter to the existing `inspect_asset_dependencies` tool schema. - **IPC**: `Editor.Message.request('asset-db', 'query-dependency', ...)` + reverse traversal for `dependents`. ### 7. `manage_scene_view` — Scene view / Gizmo control (consolidate 20 → 3) **Gap**: funplay has zero scene-view control tools. cocos-mcp-server has 20 separate tools. **cocos-mcp-server source**: `source/tools/scene-view-tools.ts` — gizmo tool/pivot/coordinate, 2D/3D mode, grid, icon gizmo, focus camera, align camera/view, get/reset status. **Implementation**: - **File**: `lib/tools/scene-view.js` (new) - **Dependencies**: `Editor.Message.request('scene', ...)` - **Consolidate into 3 tools**: **`set_scene_view`**: ```json { "action": { "type": "string", "enum": ["gizmo_tool", "gizmo_pivot", "gizmo_coordinate", "view_mode", "grid", "icon_gizmo_3d", "icon_gizmo_size", "reset"] }, "value": { "description": "Value depends on action: gizmo_tool→\"position\"|\"rotation\"|\"scale\"|\"rect\", gizmo_pivot→\"pivot\"|\"center\", gizmo_coordinate→\"local\"|\"global\", view_mode→boolean(is2D), grid→boolean, icon_gizmo_3d→boolean, icon_gizmo_size→number" } } ``` **`get_scene_view`**: ```json { "action": { "type": "string", "enum": ["gizmo_tool", "gizmo_pivot", "gizmo_coordinate", "view_mode", "grid", "icon_gizmo_3d", "icon_gizmo_size", "full_status"] } } ``` **`focus_on_nodes`**: ```json { "uuids": { "type": "array", "items": { "type": "string" }, "description": "Node UUIDs to focus on (null/empty for all)" } } ``` - **Profile**: `full` - **IPC mapping** (all `Editor.Message.request('scene', ...)`): - `change-gizmo-tool`, `change-gizmo-pivot`, `change-gizmo-coordinate` - `change-view-mode`, `set-grid-visible`, `set-icon-gizmo-3d`, `set-icon-gizmo-size` - `focus-camera-on-nodes`, `align-camera-with-view`, `align-view-with-node` - `query-gizmo-tool-name`, `query-gizmo-pivot`, `query-gizmo-coordinate`, etc. ### 8. `manage_reference_image` — Reference images (consolidate 12 → 2) **Gap**: funplay has zero reference-image tools. cocos-mcp-server has 12. **cocos-mcp-server source**: `source/tools/reference-image-tools.ts` — add/remove/switch/clear/refresh, set position/scale/opacity/data, query config/current, list. **Implementation**: - **File**: `lib/tools/reference-image.js` (new) - **Dependencies**: `Editor.Message.request('reference-image', ...)` - **Consolidate into 2 tools**: **`manage_reference_image`**: ```json { "action": { "type": "string", "enum": ["add", "remove", "switch", "clear_all", "refresh", "list", "query_current", "query_config"] }, "paths": { "type": "array", "items": { "type": "string" }, "description": "Image paths (add/remove)" }, "path": { "type": "string", "description": "Single image path (switch)" }, "sceneUUID": { "type": "string", "description": "Optional scene UUID (switch)" } } ``` **`set_reference_image_property`**: ```json { "action": { "type": "string", "enum": ["position", "scale", "opacity", "data"] }, "x": { "type": "number" }, "y": { "type": "number" }, "sx": { "type": "number" }, "sy": { "type": "number" }, "opacity": { "type": "number", "minimum": 0, "maximum": 1 }, "key": { "type": "string", "enum": ["path", "x", "y", "sx", "sy", "opacity"] }, "value": { "description": "Value for the given key (data action)" } } ``` - **Profile**: `full` - **IPC mapping**: `Editor.Message.request('reference-image', 'add-image'|'remove-image'|'switch-image'|'set-image-data'|'query-config'|'query-current-image'|'refresh'|'clear-all', ...)` --- ## P3 — Optional Enhancements Implement on demand. All are `full` profile. | # | Tool name | Source | Consolidation | Key IPC | |---|---|---|---|---| | 9 | `manage_undo` | `scene-advanced-tools.ts:241` | `begin`/`end`/`cancel` → 1 tool + action | `scene: begin-undo-recording` etc. | | 10 | `manage_asset_crud` | `project-tools.ts:178` | `create`/`copy`/`move`/`save`/`reimport` → 1 tool + action | `asset-db: create-asset` etc. | | 11 | `manage_preview_server` | `project-tools.ts:156` | `start`/`stop` → 1 tool + action | `preview-server: start`/`stop` | | 12 | `get_project_settings` | `project-tools.ts:52` | Single tool, category param | `project: query-settings` | | 13 | `validate_asset_references` | `asset-advanced-tools.ts:110` | Directory-wide scan | `asset-db: query-assets` + analysis | | 14 | `build_project` | `project-tools.ts:24` | Platform enum param | `builder: build` | --- ## Not Recommended for Absorption These cocos-mcp-server features are adequately covered by `execute_javascript` and do not warrant dedicated tools: | Feature | Reason to skip | |---|---| | Broadcast message listening (`listen_broadcast`, `stop_listening`) | Low frequency; `execute_javascript` with `Editor.Message.broadcast` is sufficient | | Preferences panel opening (`open_preferences_settings`) | One-liner: `Editor.Panel.open('preferences')` | | Console log capture (`get_console_logs`, `clear_console`) | funplay's `get_recent_logs` + `clear_logs` already cover this | | Texture compression (`compress_textures`) | Very low frequency; better as a project build setting | | Asset manifest export (`export_asset_manifest`) | Low frequency; `execute_javascript` can iterate asset-db | | Array element manipulation (`move_array_element`, `remove_array_element`) | `execute_javascript` in scene context is more flexible | | Node property reset (`reset_node_property`) | `execute_javascript` one-liner via `Editor.Message.request('scene', 'reset-property', ...)` | | Scene snapshot (`scene_snapshot`) | Advanced internal feature; AI rarely needs it directly | | `validate_json_params` / `safe_string_value` / `format_mcp_request` | Workarounds for cocos-mcp-server's own JSON parsing bugs; funplay's server handles JSON correctly | --- ## Implementation Steps ### Step 1: Create `lib/tools/scene-management.js` New file with `createSceneManagementTools({ createSchema, sceneBridge })` exporting: - `create_scene` - `copy_paste_node` - `query_scene_state` ### Step 2: Extend `lib/tools/assets-advanced.js` Append to existing `createAssetsAdvancedTools`: - `batch_asset_ops` - `find_unused_assets` - Add `direction` parameter to existing `inspect_asset_dependencies` ### Step 3: Create `lib/tools/scene-view.js` New file with `createSceneViewTools({ createSchema })` exporting: - `set_scene_view` - `get_scene_view` - `focus_on_nodes` ### Step 4: Create `lib/tools/reference-image.js` New file with `createReferenceImageTools({ createSchema })` exporting: - `manage_reference_image` - `set_reference_image_property` ### Step 5: Register in `lib/tool-registry.js` ```javascript const { createSceneManagementTools } = require('./tools/scene-management'); const { createSceneViewTools } = require('./tools/scene-view'); const { createReferenceImageTools } = require('./tools/reference-image'); // Inside createToolRegistry, in the tools array: ...createSceneManagementTools({ createSchema, sceneBridge }), ...createSceneViewTools({ createSchema }), ...createReferenceImageTools({ createSchema }), ``` ### Step 6: Add scene-side methods to `scene.js` Add `createScene` method to the scene script's `methods` export for scene creation support. ### Step 7: Run verification chain ```bash npm run check # syntax check all files npm test # run unit tests npm run docs:generate # regenerate docs/TOOLS.md npm run docs:check # verify docs in sync npm run release:check # release metadata ``` ### Step 8: Update documentation - `README.md` — add new tool categories to the Built-in Tools table - `README_CN.md` — mirror changes - `CHANGELOG.md` — add entry under next version --- ## Expected Outcome | Metric | Before | After | |---|---|---| | `full` profile tools | 101 | ~115 (net +14 after consolidation) | | `core` profile tools | 37 | 38 (+`query_scene_state`) | | Blank areas | Scene creation, view control, reference images, clipboard, batch assets | All filled | | New files | — | `lib/tools/scene-management.js`, `lib/tools/scene-view.js`, `lib/tools/reference-image.js` | | Modified files | — | `lib/tools/assets-advanced.js`, `lib/tool-registry.js`, `scene.js` |