Files
funplay-cocos-mcp/SKILL.md
T
2026-06-30 22:01:37 +08:00

261 lines
12 KiB
Markdown

# 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