# Funplay Cocos MCP — AI Agent Skill > Use this skill when operating a Cocos Creator 3.8+ project through the Funplay Cocos MCP server. ## What This Is An MCP server embedded inside the Cocos Creator editor. It exposes tools, resources, and prompts that let you inspect and manipulate a live Cocos project — scene hierarchy, nodes, components, assets, prefabs, scripts, screenshots, runtime state, and more. - **Server URL**: `http://127.0.0.1:8765/` (default; may auto-shift if port is taken) - **MCP server name**: `funplay_cocos` - **Tool profiles**: `core` (38 tools, default), `full` (110 tools), `custom` - **Health check**: `GET /health` — verify the server is alive before doing anything ## Core Philosophy: execute_javascript First **`execute_javascript` is the primary tool.** It handles ~80% of all workflows in fewer, higher-leverage calls than chaining many narrow tools. **Decision rule**: Start with `execute_javascript`. Only switch to a specialist tool when it is *strictly better* for the task: | Task | Best tool | Why | |---|---|---| | Scene/node/component inspection & mutation | `execute_javascript` (scene) | One call can inspect, decide, and act | | Editor automation, file ops, asset-db | `execute_javascript` (editor) | Full access to `Editor`, `fs`, `path`, `helpers` | | TypeScript compile errors | `run_script_diagnostics` / `get_script_diagnostic_context` | Parsed diagnostics with source snippets | | Visual verification | `capture_scene_screenshot` / `capture_preview_screenshot` | Image proof of results | | Exact asset discovery | `list_assets` | Structured asset-db query with type filtering | | Opening a specific scene | `open_scene` | Direct scene switching | | Compact editor summary | `get_editor_state` | One-call snapshot of project + selection + windows | | Validate scene health | `validate_scene` | Combined scene + runtime + diagnostics + logs check | **Anti-pattern**: Calling `get_hierarchy` → `inspect_node` → `list_components` → `inspect_component` in 4 separate calls when one `execute_javascript` with `context="scene"` can do all of it and mutate in the same call. ## The Two Execution Contexts ### context="scene" — Live scene/runtime Runs inside the active Cocos scene via the scene bridge. **Injected variables:** - `cc` — Cocos engine (use `cc.Sprite`, `cc.Node`, `cc.Vec3`, `cc.UITransform`, etc.) - `scene` — Active scene root node (`cc.Node`, same as `director.getScene()`) - `director` — `cc.director` - `require` — Node.js require (with Cocos module paths) - `Editor` — Editor global (if running in editor) - `args` — User-passed args object **Return patterns (any one):** ```javascript // 1. Direct return return { sceneName: scene.name, childCount: scene.children.length }; // 2. run function (async supported) async function run(env) { return result; } // 3. module.exports module.exports = async (env) => result; ``` **Critical rules:** - Always use `cc.Sprite`, `cc.Node` — never bare `Sprite`, `Node` - Do NOT redeclare `scene`, `director`, `cc` — they are already in scope - `assetManager.loadAny` must use callback style — it returns `null` without a callback ### context="editor" — Editor/browser context Runs in the Cocos editor main process with full Node.js access. **Injected variables:** - `require`, `Editor`, `args`, `context`, `helpers`, `fs`, `path`, `os` **`helpers` object:** - `helpers.getStatus()` — server status - `helpers.listTools()` — all exposed MCP tools - `helpers.readResource(uri)` — read an MCP resource - `helpers.callTool(name, args)` — call another MCP tool - `helpers.configureClient(targetId)` — configure an MCP client **Common editor-context patterns:** ```javascript // Query asset-db const info = await Editor.Message.request("asset-db", "query-asset-info", "ASSET_UUID"); // Call a scene method const result = await Editor.Message.request( "scene", "execute-scene-script", { name: "funplay-cocos-mcp", method: "inspectNode", args: { uuid: "NODE_UUID" } } ); // Read project context via helper const ctx = await helpers.readResource("cocos://project/context"); // Call another tool from editor context const diag = await helpers.callTool("run_script_diagnostics", {}); ``` ## Safety Checks `execute_javascript` has safety checks **enabled by default**. The following patterns are blocked: - `fs.rm`, `fs.unlink`, `fs.truncate`, `fs.rmdir` and sync variants — **delete/truncate** - `fs.createWriteStream`, `fs.openSync` — **raw write streams** - `require("child_process")`, `exec`, `spawn`, etc. — **shell execution** - `~`, `$HOME`, `%USERPROFILE%` — **user-home path literals** - `../` — **path traversal** - Absolute paths outside the Cocos project root **To bypass** (only after reviewing the risk): pass `"safety_checks": false` in the tool args. File tools and `cocos://asset/path/...` resources are sandboxed to the project root. ## Common Workflows ### 1. Orient: Understand the current project state ```json // One call for a compact snapshot { "context": "editor", "code": "return await helpers.readResource('cocos://project/context');" } ``` Or use the specialist tool: ```json {} ``` → `get_editor_state` returns project info, runtime status, selection, scene summary, and windows. ### 2. Inspect scene hierarchy ```json { "context": "scene", "code": "function walk(n, d=0) { const r = { name: n.name, active: n.active, components: n.components.map(c=>c.constructor.name) }; if (d < 3 && n.children.length) r.children = n.children.map(c => walk(c, d+1)); return r; } return walk(scene);" } ``` Or use `get_hierarchy` with `{ "rootPath": "Canvas", "maxDepth": 3, "includeComponents": true }` for a structured snapshot. ### 3. Create UI (login page example) ```json { "context": "scene", "code": "const { Node, UITransform, Sprite, Label, Button, Color, Vec3, find } = cc; const canvas = find('Canvas'); const bg = new Node('LoginBG'); bg.layer = canvas.layer; bg.addComponent(UITransform).setContentSize(720, 1280); bg.addComponent(Sprite).color = new Color(40, 40, 50, 255); canvas.addChild(bg); const title = new Node('Title'); title.layer = canvas.layer; title.addComponent(UITransform).setContentSize(400, 60); const tLabel = title.addComponent(Label); tLabel.string = 'Login'; tLabel.fontSize = 48; tLabel.color = Color.WHITE; title.setPosition(0, 400, 0); bg.addChild(title); return { created: ['LoginBG', 'Title'], canvas: canvas.name };" } ``` After creation, verify: 1. `get_hierarchy` or `execute_javascript` to confirm structure 2. `capture_scene_screenshot` for visual proof ### 4. Set an asset reference (SpriteFrame, Texture, etc.) **Cannot use `set_component_property` for asset references.** Use `execute_javascript` with `loadAny`: ```json { "context": "scene", "code": "const { find, assetManager, SpriteFrame } = cc; const node = find('Canvas/Player/Sprite'); const sprite = node.getComponent('cc.Sprite'); const sf = await new Promise((resolve, reject) => { assetManager.loadAny({ uuid: 'SPRITEFRAME_UUID', type: SpriteFrame }, (err, asset) => { if (err) reject(err); else resolve(asset); }); }); sprite.spriteFrame = sf; return { node: node.name, spriteFrame: sf.name };" } ``` ### 5. Fix script errors 1. Run diagnostics: `run_script_diagnostics` → get error list 2. Get context: `get_script_diagnostic_context` → errors with source snippets 3. Fix the file: `execute_javascript` with `context="editor"` using `fs`/`path`, or use `replace_in_file` 4. Refresh assets: `refresh_assets` 5. Re-run diagnostics to confirm clean ### 6. Prefab workflow 1. Inspect: `inspect_prefab` with `{ "target": "db://assets/prefabs/Enemy.prefab" }` 2. Validate references: `validate_prefab_references` 3. Edit JSON directly: `edit_prefab_json` with `jsonPath` + `valueJson` or `search`/`replace` 4. Instantiate in scene: `create_prefab_instance` (linked) or `instantiate_prefab` (runtime) 5. After scene edits, apply back: `apply_prefab_instance` ### 7. Visual verification ```json // Scene panel screenshot { "fileName": "after-ui-creation" } ``` → `capture_scene_screenshot` ```json // Preview/game screenshot { "fileName": "gameplay-check" } ``` → `capture_preview_screenshot` ## MCP Resources Quick Reference | Resource URI | What it gives you | |---|---| | `cocos://project/context` | Full project + editor context (project path, version, selection, scene) | | `cocos://project/summary` | Project path, folder listing, script/prefab/scene counts | | `cocos://scene/active` | Active scene summary (depth 3) | | `cocos://selection/current` | Current node + asset selection | | `cocos://errors/scripts` | Latest TypeScript diagnostics | | `cocos://logs/editor` | Recent MCP runtime logs + tool interactions | | `cocos://logs/project` | Tails of common project log files | | `cocos://mcp/interactions` | Recent MCP tool call history | | `cocos://mcp/execute-context` | Full execute_javascript variable & pattern guide | **Resource templates:** - `cocos://scene/node/{path}` — inspect a node by hierarchy path - `cocos://asset/path/{relative_path}` — read a text/asset file by project-relative path - `cocos://asset/info/{uuid_or_path}` — asset info + metadata by uuid or path ## MCP Prompts Built-in workflow prompts (call via `prompts/get`): | Prompt | Use when | |---|---| | `fix_script_errors` | Diagnosing and repairing TypeScript compile errors | | `create_playable_prototype` | Building a gameplay prototype from scratch | | `scene_validation` | Validating scene health, references, and runtime state | | `auto_wire_scene` | Wiring up node references, event bindings, and component connections | All prompts reinforce the `execute_javascript`-first philosophy. ## Key Pitfalls 1. **`set_component_property` cannot set asset references** (SpriteFrame, Texture, Material, Font, AudioClip). Use `execute_javascript` with `cc.assetManager.loadAny({uuid, type}, cb)`. 2. **`assetManager.loadAny(uuid)` without callback returns `null`** in scene context. Always use callback style: ```javascript assetManager.loadAny({ uuid, type: SpriteFrame }, (err, asset) => { ... }); ``` 3. **Custom script components require compilation** before `add_component` or `find` can locate them. If a script was just created or modified, wait for Cocos to recompile or trigger a refresh first. 4. **Node hierarchy paths are slash-separated from scene root**, e.g. `"Canvas/Player/Sprite"`. Use `get_hierarchy` to verify paths before passing them to tools. 5. **`create_node` accepts `parentPath`, not `parentUuid`**. Resolve the path first with `get_hierarchy` or `find_nodes`. 6. **Always use `cc.` prefix** in scene context: `cc.Sprite`, `cc.Node`, `cc.UITransform`, `cc.Label`, `cc.Button`, etc. Bare names like `Sprite` or `Node` will fail. 7. **New nodes need `.layer` set** to match their parent, otherwise they won't render. Set `node.layer = parent.layer` before adding to hierarchy. 8. **Safety checks block absolute paths outside the project**. If you need to read an external file, use `execute_javascript` with `context="editor"` and pass `safety_checks: false` only after verifying the code is safe. ## Tool Profile Management - **`core`** (default): 38 high-signal tools. Start here. - **`full`**: All 110 tools including UI creation, node editing, components, animation, camera, input simulation, file I/O, runtime control, and more. - **`custom`**: Start from `core`, add categories/tools via `enabledToolCategories` / `enabledTools`, remove via `disabledToolCategories` / `disabledTools`. Check current exposure: `get_tool_catalog` → see every tool with profile, category, and enabled state. If you need a `full`-only tool (e.g. `create_node`, `add_component`, `write_file`), tell the user to switch to `full` profile in the MCP panel (`Funplay > MCP Server`). ## Quick Start Checklist for Agents 1. **Verify connection** — call `get_project_info` or `get_editor_state` 2. **Read context** — `cocos://project/context` resource or `get_editor_state` 3. **Do the work** — prefer `execute_javascript` (scene for runtime, editor for automation) 4. **Verify results** — `validate_scene`, `run_script_diagnostics`, or screenshot tools 5. **Report** — summarize what was done, what was verified, and any issues found