Skip to main content
Glama
nguyennt02

cocos-mcp-v3-ui

by nguyennt02

cocos-mcp-v3-ui

MCP server (UI-design tools) for Cocos Creator 3.8.x, built as an editor package. It lets an MCP client (Claude Code) drive the editor to build UI — ideal for translating a Figma design into a Cocos scene: read the design with the Figma MCP, then create nodes/components/sprites/prefabs here.

Ported (not mechanically) from a 2.x cocos-mcp-v2-ui. 3.x differs fundamentally: the scene bridge is the Promise-based Editor.Message.request('scene','execute-scene-script'), node size/anchor/opacity/color live on components (cc.UITransform / cc.UIOpacity / the render component — not on the node as in 2.x), and the package is plain CommonJS.

Architecture

Claude Code ──stdio(MCP)──▶ bridge/  ──HTTP /rpc──▶ editor package (main proc)
                          (system Node,            core/server + registry + tools
                           @modelcontextprotocol)        │
                                                          ▼  Editor.Message.request
                                                             ('scene','execute-scene-script')
                                                   scene.js (scene proc, cc.* live)
  • Editor package (main.js, core/, tools/, scene.js, scene/) runs inside Cocos Creator. main.js starts an HTTP server (core/server.js) exposing GET /health, POST /rpc {tool,args}, GET /tools, and a stateless POST /mcp. The server is loopback-only and rejects browser-originated requests (no Origin header, loopback Host only) so a web page cannot drive the editor (see isLocalRequest).

  • Bridge (bridge/) is a separate Node process Claude spawns. It speaks the MCP protocol over stdio (via the official SDK) and proxies tools/list+tools/call to the editor's HTTP /tools+/rpc. Keeping MCP-spec compliance out of the editor process.

  • Single-responsibility / DRY: tool modules are thin (schema + delegate). Everything crossing into the scene goes through one core/scene-bridge.js#callScene; one core/response.js shape; scene-side has one resolveNode, one serialize, one applyTransform. Each mutating tool records an editor snapshot (undo + dirty flag).

Related MCP server: cocos-mcp-server

Install

  1. Symlink (or copy) this folder into the project's extensions/ (or packages/):

    ln -s /Users/nguyennt/Documents/MCP/cocos-mcp-v3-ui \
          <your-cocos-3.x-project>/extensions/cocos-mcp-v3-ui
  2. Install the bridge deps once: cd bridge && npm install.

  3. Open the project in Cocos Creator 3.8.x. The package auto-starts the server on port 8585 (autoStart: true). Panel: menu Extension → Cocos MCP v3 UI → Open Panel.

Connect to Claude Code

claude mcp add cocos-ui --transport stdio -- \
  node /Users/nguyennt/Documents/MCP/cocos-mcp-v3-ui/bridge/bin/cocos-ui-bridge.js --port 8585

Verify: /mcp in Claude lists cocos-ui connected and the 36 tools. The editor must be running with a scene open for scene tools to work (otherwise they return No active scene).

Tools (36)

Category

Tools

ping (1)

ping

scene (5)

get_current_scene, get_scene_hierarchy, open_scene, save_scene, capture_node

node (10)

create_node, get_node_info, find_nodes, set_node_transform, set_node_property, set_node_properties_batch, create_node_tree, set_sibling_index, delete_node, duplicate_node

component (13)

add_component, set_component_property, get_components, remove_component, set_component_reference, add_click_event, add_components_batch, set_component_references_batch, add_click_events_batch, set_label_style, apply_widget, draw_rounded_rect, apply_gradient

asset (2)

import_asset, query_asset_uuid

prefab (2)

create_prefab, instantiate_prefab

referenceImage (3)

add_reference_image, set_reference_image_data, remove_reference_image

MCP tool name = <category>_<method> (e.g. node_create_node, referenceImage_add_reference_image). A category must not contain an underscore — dispatch splits on the FIRST underscore.

Highlights (added per build-experience feedback)

  • color is forgiving: set_component_property/set_node_property/tree specs accept {r,g,b,a}, [r,g,b,a], or a hex string ("#161718").

  • create_node_tree: build an entire node + component + property subtree in ONE call (returns uuids).

  • draw_rounded_rect: native rounded backgrounds/borders via cc.Graphics — no texture hacks.

  • apply_gradient: bakes a rounded gradient PNG and binds it as a spriteFrame — real gradient buttons/badges (cc.Graphics fill is solid-only).

  • set_component_reference + add_click_event: wire ScrollView.content, Widget.target, button handlers, etc.

  • Enum names: enum props accept names (type:"VERTICAL", sizeMode:"CUSTOM") as well as numbers.

  • import_asset auto-creates the destination folder, auto-rasterizes SVG-content files, and fails loudly instead of silently importing nothing. spriteFrame assignment preserves node size.

Figma → Cocos workflow

  1. Read the design with the Figma MCP (positions, sizes, colors, text).

  2. scene_get_scene_hierarchy → find the Canvas uuid.

  3. (optional) export a screenshot from Figma → asset_import_assetreferenceImage_add_reference_image { spriteFrameUuid } to trace it.

  4. node_create_node per element → component_add_component (cc.Sprite/cc.Label/ cc.Button/cc.Widget/cc.Layout) → component_set_component_property (string, fontSize, color, spriteFrame) → node_set_node_transform to place/size.

  5. For images: asset_import_asset returns spriteFrameUuid — pass that to set_component_property property:"spriteFrame" (it persists; the texture uuid does not).

  6. Reusable bits: prefab_create_prefabprefab_instantiate_prefab.

  7. scene_save_scene.

Notes & limitations (3.x specifics)

  • capture_node (edit-mode) — 3.x has no immediate-mode camera.render(node), so we render through a temporary off-screen cc.Camera + cc.RenderTexture framed on the node's world bounds, force a frame, then readPixels() (falls back to borrowing the scene camera). The scene side returns base64 RGBA (bottom-up); the main side flips + PNG-encodes to disk and returns the path. Works in edit mode at the node's own aspect; maxSize caps the longest side (default 720). You can also verify by DATA with get_scene_hierarchy / get_components.

  • One render component per node (3.8.x)cc.Sprite, cc.Graphics, cc.Label, cc.RichText all derive from cc.UIRenderer and remain mutually exclusive on a node (verified: adding cc.Sprite next to cc.Graphics throws a conflict error). So a node can't have both draw_rounded_rect (Graphics) and apply_gradient/spriteFrame (Sprite) — apply_gradient auto-routes to a child gradient_bg node when the target already has a render component, and add_component surfaces the engine's conflict message.

  • Reference image is simulated — Cocos has a native reference-image gizmo, but to keep the workflow we add a low-opacity Sprite node __ReferenceImage__ behind the UI. Remove it before shipping (remove_reference_image); it is a real scene node.

  • Editor Hierarchy/Inspector refresh on the next reselect/reload after raw-runtime mutations. Each mutating tool records a snapshot (so undo works and the scene is marked dirty); the live scene/canvas updates immediately.

  • No main-process hot-reload: editing main.js/core//tools//scene/ during development requires a full editor restart (Developer → Reload Extensions/Editor). At runtime this is irrelevant — the server starts on project open.

  • spriteFrame: importing a PNG yields a texture and a sprite-frame sub-asset. Bind the sub-asset uuid (returned as spriteFrameUuid). In 3.x these sub-assets have stable uuid suffixes (<uuid>@f9941 spriteFrame, <uuid>@6c48a texture); assetdb.importFiles verifies them via asset-db:query-url before returning.

  • Verified editor messages (3.8.x): scene execute-scene-script / save-scene / open-scene / snapshot; asset-db:query-uuid / query-url / import-asset / create-asset / refresh-asset. Prefab create uses the scene create-prefab message where available, with a manual drag-to-Assets fallback.

Security

The HTTP server binds 127.0.0.1 and only serves loopback requests that carry no Origin header (i.e. the Node bridge, not a browser). This prevents a malicious web page from POSTing to http://127.0.0.1:8585/rpc to drive the editor or write files, and the loopback Host check blocks DNS-rebinding. Do not expose the port beyond localhost.

Tests

  • Unit (pure logic — colors, enums, PNG encoder, gradient, SVG sniff; no editor needed):

    node test/unit.test.js
  • Integration (error/edge paths for the scene & component tools; needs the editor running with a scene open — creates a temp container node and deletes it afterwards):

    node test/integration.test.js --port 8585
  • See test/manual-checklist.md for the per-tool manual verification steps.

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    C
    maintenance
    A comprehensive MCP server that enables Claude to read, create, edit, and generate code from Figma designs. Supports design tokens, code generation to multiple frameworks, and accessibility checks.
    100
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive MCP server plugin for Cocos Creator 3.8+ that enables AI assistants to control the editor via standardized protocol, offering 50 tools for scene, node, component, prefab, asset, project, and debugging operations.
    15 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive MCP server for Cocos Creator 3.8+ that enables AI assistants to interact with the editor via 50+ tools for scene, node, component, prefab, asset, and project management.
    15 npm
    MIT