Skip to main content
Glama

cocos-mcp

无头 Cocos Creator 3.8 MCP 服务器 —— 让 AI 不打开编辑器、不写一行 .ts 代码,30 分钟内交付一个能跑能玩的完整 2D / 基础 3D 小游戏。

🇺🇸 English

Python MCP Platforms Cocos Creator Tools Tests License

🔐 商业授权项目 · 源码闭源 需要试用 / 合作 / 定制:📧 2282059276@qq.com 旧版本(≤v1.1.0)以 MIT 开源,现版本起转闭源。


✨ 核心能力

  • 🎮 完全 Headless —— 直接读写 .scene / .prefab / .meta JSON,不依赖编辑器 GUI;业界唯一

  • ⚡ 一句话交付游戏 —— "做一个 Flappy Bird" / "做 2048" / "做一个带物理的平台跳跃",AI 自动调 184 工具完成全流程

  • 🔁 Playwright 闭环反馈 —— AI 能点击 / 按键 / 读状态 / 视觉 diff,"自己玩自己做的游戏"

  • 🎯 9 个游戏逻辑脚手架 —— player / enemy / spawner / game_loop / input / score / audio / camera_follow / ui_screen,canonical TypeScript 模板直接挂节点

  • 🎨 5 内置 UI 主题 + 6 UI 模式预设 —— dark_game / neon_arcade / pastel_cozy / ...;add_dialog_modal / add_main_menu / add_hud_bar 一次搭完整 UI 块

  • 🏭 一键多端发布 —— iOS / Android 原生包 + Asset Bundle + 微信小游戏分包 + 构建后补丁

Related MCP server: cocos-mcp-server

📋 Requirements

🚀 Quick Start

仓库为私有仓库。先联系作者获取访问权限(邮箱:2282059276@qq.com)。

# 1. 克隆(用你的访问凭证)
git clone https://gitee.com/csbcsb/cocos-mcp.git ~/.claude/mcp-servers/cocos-mcp

# 2. 装依赖
cd ~/.claude/mcp-servers/cocos-mcp
uv venv .venv --python 3.12
source .venv/bin/activate
uv pip install .

# 3. 注册到你的 MCP 客户端(见下方 Client Configuration)

然后重启客户端,直接说:

"做一个贪吃蛇游戏" "做一个带物理碰撞的平台跳跃" "把这个角色 prefab 在场景里实例化 10 个" "打包成微信小游戏,levels/ 走分包"

⚙️ Client Configuration

一行命令注册:

claude mcp add -s user cocos-mcp -- bash ~/.claude/mcp-servers/cocos-mcp/run.sh

重启 Claude Code 生效。

编辑配置文件(macOS:~/Library/Application Support/Claude/claude_desktop_config.json;Windows:%APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "cocos-mcp": {
      "command": "bash",
      "args": ["/Users/YOU/.claude/mcp-servers/cocos-mcp/run.sh"]
    }
  }
}

编辑 ~/.cursor/mcp.json:

{
  "mcpServers": {
    "cocos-mcp": {
      "command": "bash",
      "args": ["/Users/YOU/.claude/mcp-servers/cocos-mcp/run.sh"]
    }
  }
}

编辑 ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "cocos-mcp": {
      "command": "bash",
      "args": ["/Users/YOU/.claude/mcp-servers/cocos-mcp/run.sh"]
    }
  }
}

在项目根或 ~/.vscode/settings.json 里:

{
  "mcp": {
    "servers": {
      "cocos-mcp": {
        "type": "stdio",
        "command": "bash",
        "args": ["/Users/YOU/.claude/mcp-servers/cocos-mcp/run.sh"]
      }
    }
  }
}

Windows 用户:把 bash /path/to/run.sh 换成 cmd /c /path/to/run.bat,或直接用 python server.py 启动(需先激活 venv)。

🔄 升级

已经装过的用户拉新版本(以默认安装路径 ~/.claude/mcp-servers/cocos-mcp 为例):

cd ~/.claude/mcp-servers/cocos-mcp
git pull
uv pip install --python .venv/bin/python .   # 同步依赖(pyproject 可能新增包)

然后 完整重启 MCP 客户端(Claude Code / Desktop / Cursor / ...)。 理由:MCP server 是常驻子进程,Python 代码已加载进内存;不重启客户端就还在跑旧版本。

快速校验本地安装没坏:

~/.claude/mcp-servers/cocos-mcp/.venv/bin/python -c "import cocos, server; print('import OK')"

Windows 用户:把 .venv/bin/python 换成 .\.venv\Scripts\python.exe。

🧰 Tools (184 total)

启动时 stderr 会打印实际注册数量:cocos-mcp: N tools registered…

  • UUID:new_uuid / compress_uuid(生成 23 字符短形式)/ decompress_uuid

  • 项目:list_creator_installs / init_project / get_project_info / list_assets

  • 资源:add_script / add_image / add_audio_file / add_resource_file / upgrade_image_meta / set_sprite_frame_border(9-slice)/ get_sprite_frame_uuid / constants

  • 节点:create_scene / create_node / move_node / delete_node / duplicate_node / set_node_position/scale/rotation/active/layer / find_node_by_name / list_scene_nodes

  • 基础组件:add_uitransform / add_sprite / add_label / add_graphics / add_widget / add_component(通用)

  • add_rigidbody2d + 3 种 Collider(Box / Circle / Polygon)

  • 全套 8 种 Joint2D:Distance / Fixed / Hinge / Spring / Mouse / Slider / Wheel / Relative

  • set_physics_2d_config(重力 / 睡眠阈值 / 子步数)

  • 3D 物理:add_rigidbody_3d + 8 种 Collider(Box / Sphere / Capsule / Cylinder / Cone / Plane / Mesh / Terrain)+ 2 种 CharacterController + set_physics_3d_config + create_physics_material

  • 3D 渲染:add_directional_light / add_sphere_light / add_spot_light / add_mesh_renderer / add_skinned_mesh_renderer

  • 所有字段默认值逐一对齐 cocos-engine v3.8.6 源码,ERigidBodyType.DYNAMIC=1 / STATIC=2 / KINEMATIC=4 这类 bitmask 都有 regression test

  • 经典组件(13):Button / Layout / ProgressBar / ScrollView / Toggle / EditBox / Slider / PageView / ToggleContainer / MotionStreak / ScrollBar / PageViewIndicator / WebView

  • UI 模式预设(6):add_dialog_modal / add_main_menu / add_hud_bar / add_card_grid / add_toast / add_loading_spinner —— AI 一次搭完整 UI 块

  • 响应式助手(5):make_fullscreen / anchor_to_edge / center_in_parent / stack_vertically / stack_horizontally —— 告别 Widget bitmask

  • 文本合成(1):add_styled_text_block —— 标题 + 副标题 + 分割线 + 正文

  • 渲染扩展(4):Camera / Mask / RichText / 9-slice Sprite / Tiled Sprite / Filled Sprite

  • 入场动画(6):add_fade_in / add_slide_in / add_scale_in / add_bounce_in / add_pulse / add_shake

  • UI 主题(4):set_ui_theme(5 内置:dark_game / light_minimal / neon_arcade / pastel_cozy / corporate)/ get_ui_tokens / list_builtin_themes / hex_to_rgba

  • UI 质量 lint(1):cocos_lint_ui —— 8 条规则(touch target / 长文本剪字 / UI layer / WCAG 对比度 / 按钮重叠 / 字号框 / 按钮多无 Layout / 嵌套 Mask)

让 AI 真正能"玩"自己做的游戏:

  • cocos_click_preview / cocos_press_key_preview / cocos_drag_preview

  • cocos_fill_preview(文字输入)

  • cocos_read_state_preview(读任意 JS 表达式,如 window.game.score)

  • cocos_wait_preview / cocos_run_preview_sequence(序列批执行)

  • cocos_screenshot_preview_diff(纯 Pillow 视觉回归,不依赖 Playwright)

Playwright 是可选依赖(~200 MB chromium),没装时工具返回明确的 install hint。

生成 canonical .ts 模板,返回压缩 UUID 直接挂节点:

  • scaffold_input_abstraction —— WASD + 方向键 + 触屏统一成 InputManager 单例

  • scaffold_score_system —— 当前/最高分 + localStorage + Label 自动渲染

  • scaffold_player_controller —— 4 kinds:platformer / topdown / flappy / click_only

  • scaffold_enemy_ai —— 3 kinds:patrol / chase / shoot

  • scaffold_spawner —— 2 kinds:time 定时 / proximity 靠近触发

  • scaffold_game_loop —— menu / play / over 状态机

  • scaffold_audio_controller / scaffold_camera_follow / scaffold_ui_screen

所有模板字段都走 @property 让 Inspector 可调;numeric 字段带 { tooltip } 注解。

  • 媒体:AudioSource / Animation / ParticleSystem2D / VideoPlayer

  • 骨骼动画:Spine + 资源导入 / DragonBones + 资源导入

  • TiledMap:TiledMap / TiledLayer / TMX 资源导入

  • AI 素材生成:generate_asset(CogView-3-Flash / Pollinations,SHA-256 缓存)/ create_sprite_atlas

  • AnimationClip 关键帧生成器

  • Prefab:create_prefab / instantiate_prefab(带 fileId 唯一化)/ save_subtree_as_prefab

  • 场景:validate_scene / audit_scene_modules(组件 vs 引擎模块一致性)/ get_object / get_object_count / list_scene_nodes

  • batch_scene_ops:一次 read/write 跑多个 op;27 种 op 类型;实测 200 工具调用 4293ms → 33ms(130x)

  • 场景全局:set_ambient / set_skybox / set_shadows / set_fog(LINEAR / EXP / EXP² / LAYERED)

  • cocos_build:headless 构建 web-mobile / wechatgame / ios / android,带 source_maps / md5_cache / skip_compress_texture / inline_enum / mangle_properties

  • cocos_start_preview / stop_preview / preview_status

  • 构建后补丁(4):register_post_build_patch / list / remove / apply —— 声明式 json_set / regex_sub / copy_from,cocos_build 成功后自动应用,跟着 git 走

  • 项目设置:set_native_build_config(iOS/Android 包名/签名/朝向/icon)/ set_bundle_config / set_wechat_subpackages(4 MB 主包分包)

  • 引擎模块:get_engine_modules / set_engine_module(开关 physics-2d-box2d / spine / video 等)

💡 Examples

仓库自带 3 个一键运行的演示项目:

.venv/bin/python examples/flappy-bird/build_flappy.py /tmp/flappy --port 8080
.venv/bin/python examples/click-counter/build_click_counter.py /tmp/click --port 8081
.venv/bin/python examples/breakout/build_breakout.py

运行后打开 http://localhost:8080 即可玩。

# 1. 初始化 + 开启 3D 物理(默认 gravity = -10 m/s² 不是 -320 像素)
cocos_init_project("/tmp/roll3d")
cocos_set_physics_3d_config("/tmp/roll3d", gravity_y=-9.8)

# 2. 造个有摩擦系数的物理材质
ice = cocos_create_physics_material("/tmp/roll3d", "ice", friction=0.02, restitution=0.3)

# 3. 场景:Ball + Ground + 方向光
scene = cocos_create_scene("/tmp/roll3d/assets/scenes/game.scene")
canvas = scene["canvas_node_id"]

sun = cocos_create_node(scene_path, canvas, "Sun")
cocos_add_directional_light(scene_path, sun, illuminance=65000, shadow_enabled=True)

ball = cocos_create_node(scene_path, canvas, "Ball", lpos=[0, 5, 0])
cocos_add_rigidbody_3d(scene_path, ball, body_type=1)      # DYNAMIC=1(bitmask)
col = cocos_add_sphere_collider_3d(scene_path, ball, radius=0.5)
cocos_set_uuid_property(scene_path, col, "_material", ice["uuid"])

# 4. 雾 + release 构建
cocos_set_fog(scene_path, enabled=True, fog_type=1, density=0.05)  # EXP
cocos_build("/tmp/roll3d", debug=False, md5_cache=True)

🏭 商业化发布

cocos_set_native_build_config(
    project, "android",
    package_name="com.foo.game",
    orientation="landscape",
    android_min_api=21, android_target_api=33,
    android_use_debug_keystore=False,
    android_keystore_path="/keys/release.jks",
    android_keystore_password="…",
    android_keystore_alias="prod",
    android_keystore_alias_password="…",
    android_app_bundle=True,   # 出 .aab
)
# 把 assets/levels/ 标记成 Bundle,运行时 cc.assetManager.loadBundle('levels')
cocos_set_bundle_config(project, "assets/levels",
    compression_type={"web-mobile": "merge_dep", "wechatgame": "subpackage"})
cocos_set_wechat_subpackages(project, [
    {"name": "level1", "root": "assets/levels/world1"},
    {"name": "audio", "root": "assets/audio"},
])

Cocos 每次构建都会重新生成 build/<platform>/,手动改的 style.css / project.config.json 全被刷掉。通过声明式补丁登记一次,之后每次构建自动应用:

cocos_register_post_build_patch(project, patches=[
    # ① JSON 精准 key 覆盖(解决 WeChat appid 被重置)
    {"platform": "wechatgame", "file": "project.config.json",
     "kind": "json_set", "path": "appid", "value": "wx000000000000demo"},

    # ② 正则替换
    {"platform": "web-mobile", "file": "style.css",
     "kind": "regex_sub",
     "find": r"background:\s*#[0-9a-fA-F]{3,6}",
     "replace": "background: #1c2833"},

    # ③ 整文件覆盖
    {"platform": "web-mobile", "file": "index.html",
     "kind": "copy_from", "source": "custom/index.html"},
])

安全阀:regex 编译预检 + 路径注入防御(拒绝 .. / 绝对路径)+ drift 保护(正则不匹配报错而非静默跳过)+ dry_run=True 预检。

⚡ 性能调优

旋钮

默认

效果

cocos_batch_scene_ops

—

一次 read/write 跑多个 op;200 工具调用 4293ms → 33ms(130x)

场景读缓存

on

按绝对路径 + st_mtime_ns LRU(8) 缓存;外部写盘自动失效

Creator 安装缓存

on

list_creator_installs 走 functools.lru_cache,session 内不重复扫

COCOS_CREATOR_PATH

—

指定 Creator 版本目录,优先级最高(CI / Docker)

COCOS_CREATOR_EXTRA_ROOTS

—

追加扫描路径(POSIX : / Windows ; 分隔)

COCOS_MCP_SCENE_COMPACT=1

off

scene 写盘 compact JSON(500 对象 -41% 大小)

Pillow lazy-import

—

不触发图片操作的工具不需要 Pillow

🎯 AI 友好度 / 可靠性护栏

  • 结构化错误 —— cocos_build 失败返回 {error_code, hint},9 种类型(BUILD_TYPESCRIPT_ERROR / BUILD_MISSING_MODULE / BUILD_ASSET_NOT_FOUND / BUILD_TIMEOUT / ...)

  • TS 错误结构化 —— BuildResult 带 ts_errors: [{file, line, col, code, message}],AI 直接 Read+Edit

  • 场景预检 —— audit_scene_modules 扫组件 vs engine.json,返回可复制的 cocos_set_engine_module 命令链

  • 引擎模块映射表 —— 内置 COMPONENT_REQUIRES_MODULE(30+ 条)

  • 脚本 UUID 幂等 —— add_script 接受 23 / 36 字符 UUID,re-add 保持 UUID 不变

  • 构建后补丁 —— drift 保护 + 首个失败止损

  • TypedDict 契约 —— BuildResult / ValidationResult / BatchOpsResult 8 个 TypedDict,改字段忘同步自动失败

🐛 Troubleshooting

默认扫描 /Applications/Cocos/Creator (macOS) 或 %LOCALAPPDATA%\Programs\CocosDashboard\resources\.editors (Windows)。如果路径非标:

export COCOS_CREATOR_PATH=/custom/path/to/CocosCreator.app
# 或追加扫描目录
export COCOS_CREATOR_EXTRA_ROOTS=/opt/cocos:/shared/editors

首次构建 Creator 要 import 所有资源,可能超过默认 5 分钟。显式传 timeout:

cocos_build(project, timeout_sec=900)

多半是组件需要的引擎模块没启用。跑:

cocos_audit_scene_modules(scene_path)
# → { ok: false, disabled: ["physics-2d"], actions: [...] }

把 actions 里的命令复制粘贴跑一遍即可。

Creator 每次重写 project.config.json。用构建后补丁:

cocos_register_post_build_patch(project, patches=[
    {"platform": "wechatgame", "file": "project.config.json",
     "kind": "json_set", "path": "appid", "value": "wx000000000000demo"},
])

跟着 git 走,换机器 / 队友不会丢。

📊 质量保障

  • 741 pytest 单元测试,本地 < 15s 跑完

  • GitHub Actions CI 矩阵:Ubuntu / macOS / Windows × Python 3.11 / 3.12

  • mypy cocos/ 0 errors

  • ruff check 0 errors

  • 所有 3D 组件字段默认值逐一对齐 cocos-engine v3.8.6 源码(含 regression 测试锁定)

  • 跨平台:所有外部进程调用走 sys.executable / socket / tempfile.gettempdir()

🔐 Security & Privacy

  • 所有操作本地文件 I/O,不上传项目代码

  • generate_asset 默认走 CogView-3-Flash 国内免费 API;可切 Pollinations 或本地模型

  • Playwright 闭环反馈仅访问本地 preview server

  • 无任何遥测 / 埋点

📂 项目结构(简)

cocos-mcp/
├── server.py                 # MCP 入口(60 行 FastMCP + tools.register_all)
├── run.sh / run.bat
├── cocos/
│   ├── tools/                # MCP 工具薄包装,10 模块
│   ├── scene_builder/        # 场景 JSON 构造(physics / ui / ui_patterns / prefab ...)
│   ├── project/              # 资源导入 / UI token / 构建后补丁
│   ├── scaffolds/            # 9 个游戏逻辑 .ts 模板
│   ├── build.py              # CLI 构建 + 跨平台预览
│   ├── interact.py           # Playwright 闭环反馈
│   ├── gen_asset.py          # AI 生图(CogView / Pollinations + 缓存)
│   ├── errors.py / types.py / uuid_util.py / meta_util.py
├── examples/                 # 3 个一键 demo
├── tests/                    # 741 pytest
└── .github/workflows/test.yml

📄 License

Proprietary · All Rights Reserved · Copyright © heitugongzuoshi

未经书面授权,不得复制、修改、分发、二次发布或将本项目用于任何商业用途。 仅授权给已被邀请的协作者用于内部评估、试用与开发。

旧版本(≤v1.1.0)以 MIT 协议发布,相关分发已停止。本仓库当前版本(1.2-dev)起转为闭源。


商业授权 / 合作 / 定制

📧 2282059276@qq.com

服务内容:

  • 商用授权(团队 / 公司)

  • 定制开发(专属工具 / 特殊平台适配)

  • 技术咨询(Cocos 3.8 AI 工作流 / headless CI 集成)

  • 企业培训(AI + 游戏开发工作流)

Available Tools

184 tools
cocos_add_and_attach_scriptA

Write a TS script file + attach it as a component in ONE call.

Replaces the 3-call sequence agents ran dozens of times per session::

r = cocos_add_script(project, "Bird", source)       # file + meta
short = cocos_compress_uuid(r["uuid"])               # UUID form
cid = cocos_add_script(scene, node_id, short, props) # attach

The two same-named cocos_add_script tools (the project- level writer vs. the scene-level attacher) were the main friction — agents accidentally passed the standard UUID to the attacher, or skipped the compress step entirely and got a silently-broken component.

Arguments:

  • project_path / rel_path / source — where the .ts lives. rel_path follows cocos_add_script's prefix rules (bare name → assets/scripts/<name>.ts).

  • scene_path / node_id — target scene (or .prefab) and the node's array index.

  • props — component @property values, forwarded verbatim. Use {"__id__": N} for node/component refs, {"__uuid__": "..."} for asset refs.

  • uuid — optional override for the .ts.meta UUID. Omit to let the underlying add_script preserve an existing UUID on overwrite (idempotent mode) or mint a fresh one on first write.

Returns::

{
  "script_path":    "/abs/path/Foo.ts",
  "rel_path":       "assets/scripts/Foo.ts",
  "uuid_standard":  "5372d6f5-...",       # 36-char form
  "uuid_compressed":"5372db1cH...",       # what scenes use
  "component_id":   <int>,                # attached comp's id
  "created":        <bool>,               # False if meta preserved
}

Inputs: project_path (required), rel_path (required), source (required), scene_path (required), +3 more.

cocos_add_animationC

Attach cc.Animation. clip_uuids is a list of AnimationClip asset UUIDs.

Inputs: scene_path (required), node_id (required), default_clip_uuid, play_on_load, +1 more. Returns: result

cocos_add_audio_fileC

Copy an audio file (mp3/wav/ogg) into assets/resources/ + write meta.

The file is placed under resources/ so it can be loaded at runtime via resources.load(). Returns {path, rel_path, uuid}.

Inputs: project_path (required), src_path (required), rel_path, uuid.

cocos_add_audio_sourceC

Attach cc.AudioSource. clip_uuid references an audio-clip asset.

Inputs: scene_path (required), node_id (required), clip_uuid, play_on_awake, +2 more. Returns: result

cocos_add_block_input_eventsC

Attach cc.BlockInputEvents. Blocks touch/mouse from passing through this node.

Inputs: scene_path (required), node_id (required). Returns: result

cocos_add_bounce_inA

Entrance with a spring-like overshoot: 0 → overshoot → 1.0.

Tune overshoot 1.05-1.3 — below that the bounce is invisible, above it reads as jittery. 0.5s duration is a good default for most UI; halve for faster games.

Returns {clip_uuid, clip_path, anim_component_id}.

Inputs: scene_path (required), node_id (required), overshoot, duration, +2 more.

cocos_add_box_character_controllerA

Attach cc.BoxCharacterController — AABB-shaped kinematic character.

Use this INSTEAD of RigidBody + Collider for player movement. It handles ground snapping, slope limits, step-up automatically.

Inputs: scene_path (required), node_id (required), half_height, half_side_extent, +9 more. Returns: result

cocos_add_box_collider2dC

Attach cc.BoxCollider2D with given size, offset, and physics material.

Inputs: scene_path (required), node_id (required), width, height, +7 more. Returns: result

cocos_add_box_collider_3dC

Attach cc.BoxCollider (3D AABB shape).

Inputs: scene_path (required), node_id (required), size_x, size_y, +5 more. Returns: result

cocos_add_buttonA

Attach cc.Button. transition: 0=NONE, 1=COLOR, 2=SCALE, 3=SPRITE.

color_preset (e.g. "primary", "secondary", "danger") sets normal_color from the project's UI theme AND auto-derives matching hover / pressed / disabled shades — pass explicit RGBA args only when you want to override those derived values.

click_events: list of dicts from cocos_make_click_event(). Each binds a button press to a script method. Example: evt = cocos_make_click_event(scene, gm_node, 'GameManager', 'onRestart') cocos_add_button(scene, btn_node, click_events=[evt])

Inputs: scene_path (required), node_id (required), transition, zoom_scale, +18 more. Returns: result

cocos_add_button_with_labelA

Create a button node with a child Label in one call.

The most common UI primitive — menus typically have 2-4 buttons, each requiring:

btn_node = cocos_create_node(scene, parent, name, ...)
cocos_add_uitransform(scene, btn_node, W, H)
cocos_add_sprite(scene, btn_node, sprite_frame_uuid, ...)  # optional
btn = cocos_add_button(scene, btn_node, ...)
lbl_node = cocos_create_node(scene, btn_node, "Label")
cocos_add_uitransform(scene, lbl_node, W, H)
lbl = cocos_add_label(scene, lbl_node, text, font_size, ...)

Folds all seven calls into one. Structure produced::

Btn (Node + UITransform + optional Sprite + Button)
 └── Label (Node + UITransform + Label)

Design-token presets (label_color_preset / label_size_preset / bg_color_preset) resolve through the project's UI theme. Forward click_events from cocos_make_click_event verbatim.

Returns {button_node_id, label_node_id, button_component_id, label_component_id, sprite_component_id}.

Inputs: scene_path (required), parent_id (required), label_text (required), width, +12 more.

cocos_add_cameraB

Attach cc.Camera. projection: 0=ORTHO, 1=PERSPECTIVE. For minimap/split-screen.

Inputs: scene_path (required), node_id (required), projection, priority, +7 more. Returns: result

cocos_add_capsule_character_controllerA

Attach cc.CapsuleCharacterController — capsule-shaped kinematic character.

More common than box for humanoid characters; smoother wall sliding. height is the distance between the two sphere centers (NOT total capsule height, which is height + 2*radius).

Inputs: scene_path (required), node_id (required), radius, height, +8 more. Returns: result

cocos_add_capsule_collider_3dC

Attach cc.CapsuleCollider. direction: 0=X, 1=Y (default), 2=Z.

Inputs: scene_path (required), node_id (required), radius, cylinder_height, +5 more. Returns: result

cocos_add_card_gridA

Grid of tappable cards — level select, shop, character picker.

Each cards[i] is::

{"title": str,
 "subtitle": str | None,
 "icon_sprite_frame_uuid": str | None,
 "variant": "primary" | "surface",    # bg color, default "surface"
 "click_events": [...] | None}

Whole card is the button (tap anywhere). Title + subtitle auto- pick contrasting text colors for the chosen variant ("primary" variant gets bg-colored text; "surface" gets text-colored). Extras wrap to new rows when count > columns.

Returns {grid_node_id, cards: [{node_id, title_node_id, subtitle_node_id, icon_node_id, button_component_id}, ...]}. Wire per-card click by passing click_events in each spec.

Inputs: scene_path (required), parent_node_id (required), cards (required), columns, +3 more.

cocos_add_circle_collider2dC

Attach cc.CircleCollider2D with given radius and physics material.

Inputs: scene_path (required), node_id (required), radius, offset_x, +6 more. Returns: result

cocos_add_componentB

Attach any cc component by its full type name (e.g. 'cc.RigidBody2D').

props values are auto-wrapped: list[3]->Vec3, int->id ref, etc. For resource refs pass {"uuid": ""}.

Inputs: scene_path (required), node_id (required), type_name (required), props. Returns: result

cocos_add_cone_collider_3dD

Attach cc.ConeCollider.

Inputs: scene_path (required), node_id (required), radius, height, +5 more. Returns: result

cocos_add_cylinder_collider_3dD

Attach cc.CylinderCollider.

Inputs: scene_path (required), node_id (required), radius, height, +5 more. Returns: result

cocos_add_dialog_modalA

Build a centered modal dialog: backdrop + panel + title + body + buttons.

One call replaces 15+ primitive calls. Inherits colors from the project's UI theme (set via cocos_set_ui_theme).

buttons: list of {"text": str, "variant": ..., "click_events": [...]?} where variant is "primary" / "secondary" / "danger" / "ghost" (surface-colored for cancel). Defaults to one primary "OK" button.

Returns all created node + component IDs so the caller can wire click handlers or modify individual parts later.

Inputs: scene_path (required), parent_node_id (required), title (required), body, +4 more.

cocos_add_directional_lightA

Attach cc.DirectionalLight — sun/moon parallel light.

illuminance is in lux (default 65000 ≈ midday sun). shadow_pcf: 0=HARD, 1=SOFT, 2=SOFT_2X, 3=SOFT_4X. A scene typically has exactly one directional light.

Inputs: scene_path (required), node_id (required), color_r, color_g, +9 more. Returns: result

cocos_add_distance_joint2dC

Attach cc.DistanceJoint2D — keeps two bodies a fixed distance apart.

Inputs: scene_path (required), node_id (required), connected_body_id, anchor_x, +8 more. Returns: result

cocos_add_dragonbonesB

Attach dragonBones.ArmatureDisplay. Use cocos_add_dragonbones_data first.

Inputs: scene_path (required), node_id (required), dragon_asset_uuid, dragon_atlas_asset_uuid, +4 more. Returns: result

cocos_add_dragonbones_dataC

Import DragonBones assets (_ske.json + _tex.json + _tex.png).

Returns {dragon_asset_uuid, dragon_atlas_uuid, textures, dir}.

Inputs: project_path (required), db_json_path (required), atlas_json_path (required), texture_paths, +1 more.

cocos_add_editboxC

Attach cc.EditBox. input_mode: 0=ANY, 6=SINGLE_LINE. -1=unlimited length.

Inputs: scene_path (required), node_id (required), placeholder, max_length, +2 more. Returns: result

cocos_add_fade_inA

Fade a node from transparent → opaque at scene start.

Generates a .anim clip in assets/animations/ (override with rel_dir), attaches cc.UIOpacity (initial 0 so the first frame doesn't flash), and attaches cc.Animation with play_on_load=True. delay holds at 0 opacity before the ramp — useful for staggering sibling fades.

Returns {clip_uuid, clip_path, anim_component_id, opacity_component_id}.

Inputs: scene_path (required), node_id (required), duration, delay, +1 more.

cocos_add_filled_spriteB

Attach cc.Sprite with type=FILLED (cooldown timer, radial progress).

fill_type: 0=HORIZONTAL, 1=VERTICAL, 2=RADIAL. fill_range: 0~1 controls how much is filled (e.g. 0.3 = 30% filled).

Inputs: scene_path (required), node_id (required), sprite_frame_uuid, fill_type, +8 more. Returns: result

cocos_add_fixed_joint_2dC

Attach cc.FixedJoint2D — rigidly fuses two bodies (breakable structures).

Named "weld" in Box2D; replaces the prior cocos_add_weld_joint2d which emitted cc.WeldJoint2D (not a real 3.8 class).

Inputs: scene_path (required), node_id (required), connected_body_id, anchor_x, +7 more. Returns: result

cocos_add_graphicsC

Attach a cc.Graphics to a node (for runtime vector drawing).

Inputs: scene_path (required), node_id (required). Returns: result

cocos_add_hinge_joint2dC

Attach cc.HingeJoint2D — pivots around a shared anchor (door, wheel, pendulum).

Inputs: scene_path (required), node_id (required), connected_body_id, anchor_x, +10 more. Returns: result

cocos_add_hud_barA

Build a horizontal HUD bar pinned to the top (or bottom).

items is a list of:

  • {"kind": "label", "text": str, "size_preset": str, "color_preset": str, "width": int, "align": str} — text cell

  • {"kind": "spacer", "width": int} — blank gap

Default is a Score label + spacer + Lv label, good for endless- runner style games. side: "top" (default) or "bottom".

Inputs: scene_path (required), parent_node_id (required), items, height, +1 more.

cocos_add_imageA

Copy a PNG into the project and write a complete sprite-frame meta.

Default: assets/textures/. Set as_resource=True to put it under assets/resources/ (needed for runtime loading via resources.load()).

Returns {path, rel_path, main_uuid, sprite_frame_uuid, texture_uuid}.

Inputs: project_path (required), src_png (required), rel_path, as_resource.

cocos_add_labelA

Attach cc.Label. overflow: 0=NONE 1=CLAMP 2=SHRINK 3=RESIZE_HEIGHT. cache_mode: 0=NONE 1=BITMAP 2=CHAR. CLAMP truncates, SHRINK auto-shrinks font.

Design-token presets (override the equivalent explicit arg):

  • color_preset: e.g. "text", "primary", "danger"

  • size_preset: "title" | "heading" | "body" | "caption"

  • outline_color_preset: e.g. "bg" for dark outline on light Set the theme once via cocos_set_ui_theme; un-themed projects fall back to dark_game defaults so presets always resolve.

Inputs: scene_path (required), node_id (required), text (required), font_size, +15 more. Returns: result

cocos_add_layoutC

Attach cc.Layout. layout_type: 0=NONE, 1=HORIZONTAL, 2=VERTICAL, 3=GRID.

Inputs: scene_path (required), node_id (required), layout_type, spacing_x, +8 more. Returns: result

cocos_add_loading_spinnerA

Centered rotating icon + optional caption.

Pass sprite_frame_uuid to get the rotation animation; pass None for a text-only indicator. rotation_period is one full 360° revolution — 1.0s is the iOS/Material default cadence.

Tip: generate a spinner sprite via cocos_generate_asset(prompt='loading spinner icon, radial', style='icon') then pass the returned sprite_frame_uuid here.

Returns {spinner_node_id, icon_node_id, label_node_id, rotation_component_id}.

Inputs: scene_path (required), parent_node_id (required), sprite_frame_uuid, text, +2 more.

cocos_add_main_menuA

Build a full-screen vertical main menu: bg + title + stacked buttons.

Buttons use same shape as cocos_add_dialog_modal. Default is a "Start" (primary) + "Settings" (ghost) pair.

Typical flow::

scene = cocos_create_scene(...) cocos_set_ui_theme(project, theme="dark_game") cocos_add_main_menu(scene, scene["canvas_node_id"], "Flappy Bird", buttons=[{"text": "Start", "variant": "primary", "click_events": [click_evt]}])

Inputs: scene_path (required), parent_node_id (required), title (required), buttons, +2 more.

cocos_add_maskC

Attach cc.Mask. mask_type: 0=RECT, 1=ELLIPSE, 2=GRAPHICS_STENCIL, 3=SPRITE_STENCIL.

Inputs: scene_path (required), node_id (required), mask_type, inverted, +1 more. Returns: result

cocos_add_mesh_collider_3dA

Attach cc.MeshCollider.

IMPORTANT: convex=True is required when the rigid body is DYNAMIC — physics backends (PhysX/Bullet) only support convex meshes on non-static bodies. For static ground geometry, triangle (concave) meshes are fine with convex=False.

Inputs: scene_path (required), node_id (required), mesh_uuid, convex, +4 more. Returns: result

cocos_add_mesh_rendererB

Attach cc.MeshRenderer — renders a 3D mesh.

material_uuids: one per submesh; order matters. Pass None to wire later via cocos_set_uuid_property(id, "_mesh", uuid). shadow_casting: 0=OFF (default), 1=ON. shadow_receiving: 0=OFF, 1=ON (default). reflection_probe_type: 0=NONE, 1=BAKED_CUBEMAP, 2=PLANAR, 3=BLEND.

Inputs: scene_path (required), node_id (required), mesh_uuid, material_uuids, +4 more. Returns: result

cocos_add_motion_streakC

Attach cc.MotionStreak (trail effect). For sword trails, shooting stars.

Inputs: scene_path (required), node_id (required), fade_time, stroke, +4 more. Returns: result

cocos_add_mouse_joint2dC

Attach cc.MouseJoint2D — drag-to-target constraint, used to pick up bodies with the mouse.

Inputs: scene_path (required), node_id (required), max_force, frequency, +3 more. Returns: result

cocos_add_page_viewC

Attach cc.PageView (swipeable pages). direction: 0=H, 1=V.

Inputs: scene_path (required), node_id (required), content_id, direction, +2 more. Returns: result

cocos_add_page_view_indicatorA

Attach cc.PageViewIndicator — dots row that tracks PageView position.

Attach to a child of the PageView node. Engine auto-spawns one indicator sprite per page using sprite_frame_uuid as template. direction: 0=HORIZONTAL (default), 1=VERTICAL.

Inputs: scene_path (required), node_id (required), sprite_frame_uuid, direction, +3 more. Returns: result

cocos_add_particle_system_2dC

Attach cc.ParticleSystem2D with configurable emission, color, physics.

Inputs: scene_path (required), node_id (required), duration, emission_rate, +22 more. Returns: result

cocos_add_physics_body2dA

Attach cc.RigidBody2D + a shape collider in one call.

Replaces the 2-call pattern every Bird / Pipe / Enemy needed:

rb = cocos_add_rigidbody2d(scene, node, body_type=2, ...)
col = cocos_add_box_collider2d(scene, node, width=W, ...)

shape picks the collider: "box" / "circle" / "polygon". The relevant shape knobs (width×height / radius / points) are read based on the choice; the others are ignored. Raises ValueError on unknown shape rather than silently attaching a default.

body_type: 0=Static, 1=Kinematic, 2=Dynamic (default).

Returns {rigidbody_id, collider_id, shape}.

Inputs: scene_path (required), node_id (required), shape, body_type, +17 more.

cocos_add_plane_collider_3dC

Attach cc.PlaneCollider — infinite plane, typically used for the ground.

Default normal (0, 1, 0) + constant 0 means the XZ plane at y=0.

Inputs: scene_path (required), node_id (required), normal_x, normal_y, +6 more. Returns: result

cocos_add_polygon_collider2dC

Attach cc.PolygonCollider2D. points is [[x,y],...] vertex list.

Inputs: scene_path (required), node_id (required), points, density, +4 more. Returns: result

cocos_add_progress_barB

Attach cc.ProgressBar. mode: 0=HORIZONTAL, 1=VERTICAL, 2=FILLED.

Inputs: scene_path (required), node_id (required), bar_sprite_id, mode, +3 more. Returns: result

cocos_add_pulseA

Looping subtle scale pulse — attention-grabber for idle UI.

strength: how much bigger at peak (0.08 = 8%). Keep subtle; above ~0.15 looks anxious. period: one cycle in seconds. 1.0-1.5 reads as a relaxed heartbeat; below 0.5 feels panicked.

Clip loops forever — attach and forget.

Returns {clip_uuid, clip_path, anim_component_id}.

Inputs: scene_path (required), node_id (required), strength, period, +1 more.

cocos_add_relative_joint2dC

Attach cc.RelativeJoint2D — keeps relative position+angle ('attach to' effect).

Also covers the follow-target use case that the old cocos_add_motor_joint2d tried to solve; cc.MotorJoint2D does not exist in Cocos 3.8.

Inputs: scene_path (required), node_id (required), connected_body_id, max_force, +7 more. Returns: result

cocos_add_resource_fileC

Copy any file into assets/resources/ + write a minimal meta.

Suitable for JSON data, text assets, or custom resources. Returns {path, rel_path, uuid}.

Inputs: project_path (required), src_path (required), rel_path, uuid.

cocos_add_richtextC

Attach cc.RichText. Supports , , <color=#FF0000>, <size=24>, tags.

size_preset ("title"/"heading"/"body"/"caption") overrides font_size from the project's UI theme and sets line_height to ~1.25× of it.

Inputs: scene_path (required), node_id (required), text, font_size, +4 more. Returns: result

cocos_add_rigidbody2dC

Attach cc.RigidBody2D. body_type: 0=Static, 1=Kinematic, 2=Dynamic.

Inputs: scene_path (required), node_id (required), body_type, gravity_scale, +5 more. Returns: result

cocos_add_rigidbody_3dB

Attach cc.RigidBody (3D).

body_type: 1=DYNAMIC (default), 2=STATIC, 4=KINEMATIC. Values are engine's ERigidBodyType bitmask, NOT contiguous 0/1/2 like the 2D API. linear_factor / angular_factor lock motion on a per-axis basis (set component to 0 to freeze that axis, 1 for free movement).

Inputs: scene_path (required), node_id (required), body_type, mass, +11 more. Returns: result

cocos_add_safe_areaC

Attach cc.SafeArea. Auto-fits node to device safe area (notch/cutout).

Inputs: scene_path (required), node_id (required). Returns: result

cocos_add_scale_inB

Pop a node in from from_scale to 1.0 at scene start.

from_scale=0 → pop-in from nothing; from_scale=0.5 → grow from half-size.

Returns {clip_uuid, clip_path, anim_component_id}.

Inputs: scene_path (required), node_id (required), from_scale, duration, +2 more.

cocos_add_scene_to_buildB

Add a scene to the includedScenes list in project settings.

Idempotent -- skips if the UUID is already included.

Inputs: project_path (required), scene_uuid (required).

cocos_add_scriptA

Write a TypeScript script + its meta into the project.

rel_path can be either:

  • bare name like 'GameManager' -> writes assets/scripts/GameManager.ts

  • full path like 'assets/scripts/sub/Foo.ts'

Returns {path, rel_path, uuid}. The uuid is the standard 36-char form; use cocos_compress_uuid to get the 23-char form needed in scene files.

Inputs: project_path (required), rel_path (required), source (required).

cocos_add_scroll_barB

Attach cc.ScrollBar — companion scroll indicator for a ScrollView.

direction: 0=HORIZONTAL (default), 1=VERTICAL. Pass scroll_view_id + handle_sprite_id to wire both references at attach time; otherwise set later via link_property.

Inputs: scene_path (required), node_id (required), handle_sprite_id, scroll_view_id, +3 more. Returns: result

cocos_add_scroll_viewC

Attach cc.ScrollView. content_id points to the scrollable content node.

Inputs: scene_path (required), node_id (required), content_id, horizontal, +5 more. Returns: result

cocos_add_shakeA

One-shot position wobble — for damage / error / impact feedback.

axis: "x" (horizontal hit / invalid-input), "y" (stomp), "both" (explosion / big impact). intensity is the peak amplitude in logical pixels; oscillation decays linearly to 0 over duration.

Animates around the node's CURRENT _lpos — position the node first, then attach.

Returns {clip_uuid, clip_path, anim_component_id}.

Inputs: scene_path (required), node_id (required), intensity, duration, +2 more.

cocos_add_skinned_mesh_rendererB

Attach cc.SkinnedMeshRenderer — MeshRenderer driven by a skeleton.

Use this for humanoid/animal characters imported from GLTF/FBX. skinning_root_node_id is the scene-array index of the armature root node created during model import (pass the Node id, not a UUID).

Inputs: scene_path (required), node_id (required), mesh_uuid, skeleton_uuid, +4 more. Returns: result

cocos_add_sliced_spriteC

Attach cc.Sprite with type=SLICED (9-slice). Stretches center, keeps corners.

Inputs: scene_path (required), node_id (required), sprite_frame_uuid, color_r, +3 more. Returns: result

cocos_add_slide_inA

Slide a node in from off-screen at scene start.

from_side: "left" / "right" / "top" / "bottom". The end pose is the node's CURRENT _lpos — set the final position first, then call this to animate the entrance.

Returns {clip_uuid, clip_path, anim_component_id}.

Inputs: scene_path (required), node_id (required), from_side, distance, +3 more.

cocos_add_sliderC

Attach cc.Slider. slide_events: list from cocos_make_event_handler().

Inputs: scene_path (required), node_id (required), direction, progress, +1 more. Returns: result

cocos_add_slider_joint2dC

Attach cc.SliderJoint2D — translates along an axis (elevators, pistons).

Inputs: scene_path (required), node_id (required), connected_body_id, anchor_x, +11 more. Returns: result

cocos_add_sphere_collider_3dC

Attach cc.SphereCollider (3D sphere shape).

Inputs: scene_path (required), node_id (required), radius, center_x, +3 more. Returns: result

cocos_add_sphere_lightB

Attach cc.SphereLight — point-light with physical size (bulb, lantern).

term: 0=LUMINOUS_FLUX (default), 1=LUMINANCE. light_range is the falloff distance.

Inputs: scene_path (required), node_id (required), color_r, color_g, +8 more. Returns: result

cocos_add_spineB

Attach sp.Skeleton (Spine). Use cocos_add_spine_data to import assets first.

Inputs: scene_path (required), node_id (required), skeleton_data_uuid, default_skin, +3 more. Returns: result

cocos_add_spine_dataC

Import Spine skeleton assets (.json + .atlas + textures).

Returns {skeleton_data_uuid, atlas_uuid, textures, dir}. Use skeleton_data_uuid with cocos_add_spine().

Inputs: project_path (required), spine_json_path (required), atlas_path (required), texture_paths, +1 more.

cocos_add_spot_lightC

Attach cc.SpotLight — cone-shaped light (torch, stage spot).

Inputs: scene_path (required), node_id (required), color_r, color_g, +12 more. Returns: result

cocos_add_spring_joint2dC

Attach cc.SpringJoint2D — soft springy distance (suspensions, ropes).

Inputs: scene_path (required), node_id (required), connected_body_id, anchor_x, +8 more. Returns: result

cocos_add_spriteB

Attach a cc.Sprite to a node.

sprite_frame_uuid is the <uuid>@f9941 form returned by cocos_add_image or cocos_get_sprite_frame_uuid. size_mode: 0=CUSTOM (use UITransform's contentSize), 1=TRIMMED, 2=RAW. color_preset: pick from the project's UI theme (e.g. "primary", "surface") to tint the sprite — overrides the explicit RGBA args.

Inputs: scene_path (required), node_id (required), sprite_frame_uuid, size_mode, +5 more. Returns: result

cocos_add_styled_text_blockA

Title + optional subtitle + optional divider + optional body, stacked.

The single most frequently rebuilt pattern in AI UI code — hoisted here so you don't compose it from 4-6 add_label calls every time. Pulls colors from the active UI theme: title uses text preset, subtitle uses text_dim, divider uses border. Body has wrap + overflow=RESIZE_HEIGHT so long paragraphs grow the block instead of clipping.

Divider only materializes when body is present AND show_divider=True — dividing the top of the block from nothing is visual noise. align: "left" / "center" / "right" applies to all text pieces.

Returns {block_node_id, title_node_id, subtitle_node_id, divider_node_id, body_node_id}; None for absent pieces.

Inputs: scene_path (required), parent_node_id (required), title (required), subtitle, +4 more.

cocos_add_terrain_collider_3dC

Attach cc.TerrainCollider (pass a cc.Terrain asset UUID).

Inputs: scene_path (required), node_id (required), terrain_uuid, center_x, +3 more. Returns: result

cocos_add_tiled_layerC

Attach cc.TiledLayer (usually auto-created by TiledMap).

Inputs: scene_path (required), node_id (required), layer_name. Returns: result

cocos_add_tiled_mapB

Attach cc.TiledMap component. Use cocos_add_tiled_map_asset to import first.

Inputs: scene_path (required), node_id (required), tmx_asset_uuid. Returns: result

cocos_add_tiled_map_assetA

Import TiledMap assets (.tmx + .tsx tilesets + tileset PNGs).

Returns {tmx_uuid, tsx_files, textures, dir}. Use tmx_uuid with cocos_add_tiled_map().

Inputs: project_path (required), tmx_path (required), tsx_paths, texture_paths, +1 more.

cocos_add_tiled_spriteC

Attach cc.Sprite with type=TILED (repeating pattern fill).

Inputs: scene_path (required), node_id (required), sprite_frame_uuid, color_r, +3 more. Returns: result

cocos_add_toastA

Transient pill notification — fade in, hold, fade out.

variant picks the background:

  • "info" → surface (neutral gray/slate)

  • "success" / "warn" / "danger" → matching semantic color Text uses text preset (info) or bg (colored variants) so it always reads against the bg.

duration is total time including 0.25s fade-in + 0.25s fade-out. Minimum 0.6s (else there's no readable hold window). Clip plays once and holds invisible — toast stays in scene as a zero-opacity node.

Returns {toast_node_id, label_node_id, animation_component_id}.

Inputs: scene_path (required), parent_node_id (required), text (required), duration, +4 more.

cocos_add_toggleD

Attach cc.Toggle. check_events: list from cocos_make_event_handler().

Inputs: scene_path (required), node_id (required), is_checked, transition, +1 more. Returns: result

cocos_add_toggle_containerC

Attach cc.ToggleContainer (radio group). Children are mutually exclusive.

Inputs: scene_path (required), node_id (required), allow_switch_off. Returns: result

cocos_add_ui_opacityB

Attach cc.UIOpacity (0=invisible, 255=opaque). Required for fade animations.

Inputs: scene_path (required), node_id (required), opacity. Returns: result

cocos_add_uitransformC

Attach a cc.UITransform to a node. Required for any UI rendering.

Inputs: scene_path (required), node_id (required), width (required), height (required), +2 more. Returns: result

cocos_add_video_playerA

Attach cc.VideoPlayer — plays mp4 from a local cc.VideoClip or remote URL.

resource_type: 0=REMOTE (use remote_url), 1=LOCAL (use clip_uuid).

Use cases:

  • Cinematic intro / cutscenes (LOCAL with clip_uuid)

  • Rewarded video ads (REMOTE with ad-server URL)

  • In-game tutorials (LOCAL, loop=True)

On WeChat mini-game the player is a native overlay; stay_on_bottom and full_screen_on_awake change platform-specific layering.

Inputs: scene_path (required), node_id (required), resource_type, remote_url, +8 more. Returns: result

cocos_add_webviewC

Attach cc.WebView — embedded browser pane for ToS / activity pages.

Inputs: scene_path (required), node_id (required), url. Returns: result

cocos_add_wheel_joint2dC

Attach cc.WheelJoint2D — wheel + axle (slide along axis + spring + motor combined; vehicles).

Inputs: scene_path (required), node_id (required), connected_body_id, anchor_x, +10 more. Returns: result

cocos_add_widgetC

Attach a cc.Widget for screen-anchor layout. align_flags is a bitmask.

Inputs: scene_path (required), node_id (required), align_flags, target_id. Returns: result

cocos_anchor_to_edgeB

Pin node to an edge / corner of its parent via cc.Widget.

edge: top / bottom / left / right / top-left / top-right / bottom-left / bottom-right. margin: distance from the edge (from both edges for corners). Returns the Widget component id.

Inputs: scene_path (required), node_id (required), edge (required), margin. Returns: result

cocos_apply_post_build_patchesA

Apply registered patches for platform to build/<platform>/.

Normally cocos_build invokes this automatically on success — call directly only for dry-run preview (dry_run=True) or when you need to re-apply without rebuilding.

Returns {platform, dry_run, build_dir, applied, skipped, errors, ok}. Stops on first patch error so a failure can't cascade across files.

Inputs: project_path (required), platform (required), dry_run.

cocos_assert_scene_stateA

Declarative expectations against a scene/prefab — regression- test style.

Each entry in assertions:

{"path": "", "op": "", "value": }

with optional root-finder shortcuts:

{"find_node_by_name": "Player", # find first cc.Node _name "path": "_lpos.x", "op": "gt", "value": 0}

{"find_component": {"type": "cc.Sprite", "on_node_named": "Enemy"}, "path": "_color.r", "op": "eq", "value": 255}

Ops: eq / ne / gt / ge / lt / le / in / not_in / contains / match / is_null / not_null / type_is / exists / not_exists

Path syntax: _children[0].__id__ / 15._lpos.x. First dotted segment as int + root is list → list index. [N] always list index. Missing path → LookupError surfaces as a failed assertion (or passes if op=not_exists).

Runs EVERY assertion even if earlier ones fail — regression checks want a full report, not a first-failure bail.

Returns {ok, scene_path, total, passed_count, failed_count, passed: [...], failed: [...]}.

Inputs: scene_path (required), assertions (required).

cocos_attach_scriptA

Attach a custom TypeScript script component to a node.

script_uuid_compressed is the 23-char short form (run cocos_compress_uuid on the .ts.meta uuid).

props lets you set @property fields. Pass int values for node/component refs (they'll be wrapped as {"id": N}). Pass strings/numbers/bools for plain values.

Inputs: scene_path (required), node_id (required), script_uuid_compressed (required), props. Returns: result

cocos_audit_scene_modulesA

Cross-check scene components against the project's engine.json.

Catches the single highest-frequency "build succeeded, game broken at runtime" failure: using a component (RigidBody2D, Spine, VideoPlayer, ...) whose engine module is currently disabled. Build produces artifacts, the scene loads, but the components silently do nothing.

project_path=None → walks up from the scene file looking for package.json. Pass explicitly when the scene lives outside the project (prefab library, template copy).

Returns {ok, project_path, required, enabled, disabled, actions}. When ok=False, actions lists copy-pasteable next steps (cocos_set_engine_module calls + the library clean that module changes need).

Inputs: scene_path (required), project_path.

cocos_batch_scene_opsA

PREFERRED for ≥3 sequential mutations on the same scene.

Execute multiple scene operations in a single file read/write cycle. ~80× faster than calling individual cocos_add_* / cocos_set_* tools when building more than a handful of nodes/components on the same scene; the file is parsed once, mutated in memory, and serialized once at the end.

Rule of thumb: if you would otherwise call cocos_add_*, cocos_attach_*, cocos_set_*, or cocos_link_* three or more times in a row on the same scene, use this tool instead. Pass all the ops in one call; use "$N" back-references for ids that earlier ops produced.

Each operation is a dict with an op key and operation-specific params. Returns {object_count, ops_executed, results, named_results}:

  • results is the positional list (preserved for callers that use "$N" index back-refs).

  • named_results is a dict keyed by the name field set on any op — ops without name don't contribute. Let's you use "$bird" instead of "$0" which stays stable across edits.

Supported ops: Structural: - {"op": "add_node", "parent_id": N, "name": "...", "lpos": [x, y, z]?, "lscale": [sx, sy, sz]?, "pos_x": ..., "pos_y": ..., "pos_z": ..., "sx": ..., "sy": ..., "sz": ..., "layer": L?, "active": true/false?, "sibling_index": -1?} (lpos / lscale tuple forms match direct sb.add_node; pos_x/y/z and sx/sy/sz scalars are the legacy form. Tuple wins when both supplied. Prior releases silently dropped lscale — every batch-created node was left at (1,1,1) regardless of op input.) - {"op": "attach_script", "node_id": N, "script_uuid_compressed": "...", "props": {...}} (36-char standard UUIDs auto-compressed, matching cocos_add_script.) - {"op": "link_property", "component_id": N, "prop_name": "...", "target_id": M} - {"op": "set_property", "object_id": N, "prop_name": "...", "value": ...} - {"op": "set_uuid_property", "object_id": N, "prop_name": "...", "uuid": "..."} - {"op": "set_position", "node_id": N, "lpos": [x, y, z]? OR "x": ..., "y": ..., "z": ...} - {"op": "set_scale", "node_id": N, "lscale": [sx, sy, sz]? OR "sx": ..., "sy": ..., "sz": ...} - {"op": "set_rotation", "node_id": N, "angle_z": deg} - {"op": "set_layer", "node_id": N, "layer": L} - {"op": "set_active", "node_id": N, "active": true/false}

Components: - {"op": "add_uitransform", "node_id": N, "width": W, "height": H, "anchor_x": ..., "anchor_y": ...} - {"op": "add_widget", "node_id": N, "align_flags": 45, "target_id": M?} - {"op": "add_sprite", "node_id": N, "sprite_frame_uuid": "...", "size_mode": 0} - {"op": "add_label", "node_id": N, "text": "...", "font_size": 40, "color_r"...} - {"op": "add_graphics", "node_id": N} - {"op": "add_camera", "node_id": N, "ortho_height": ..., "clear_color_r"...} - {"op": "add_mask", "node_id": N, "mask_type": 0, "inverted": false, "segments": 64} - {"op": "add_richtext", "node_id": N, "text": "Hi", "font_size": 40, ...} - {"op": "add_button", "node_id": N, "transition": 2, "zoom_scale": 1.1} - {"op": "add_layout", "node_id": N, "layout_type": 1, "spacing_x": ..., ...} - {"op": "add_progress_bar", "node_id": N, "mode": 0, "total_length": 100, "progress": 1.0, "bar_sprite_id": M?} - {"op": "add_audio_source", "node_id": N, "clip_uuid": "...", "volume": 1.0, "loop": false, "play_on_awake": false} - {"op": "add_animation", "node_id": N, "default_clip_uuid": "...", "clip_uuids": [...], "play_on_load": true} - {"op": "add_rigidbody2d", "node_id": N, "body_type": 2, ...} - {"op": "add_box_collider2d", "node_id": N, "width": W, ...} - {"op": "add_circle_collider2d", "node_id": N, "radius": R, ...} - {"op": "add_polygon_collider2d", "node_id": N, "points": [[x,y], ...], ...} - {"op": "add_component", "node_id": N, "type_name": "cc.X", "props": {...}}

Physics 2D joints (Cocos 3.8 has eight — all present): - {"op": "add_distance_joint2d", "node_id": N, "connected_body_id": M?, "distance": 100, ...} - {"op": "add_hinge_joint2d", "node_id": N, "enable_motor": true, "motor_speed": 50, ...} - {"op": "add_spring_joint2d", "node_id": N, "frequency": 5, "damping_ratio": 0.7, ...} - {"op": "add_mouse_joint2d", "node_id": N, "max_force": 1000, "target_x": ..., "target_y": ...} - {"op": "add_slider_joint2d", "node_id": N, "angle": 0, "enable_motor": true, ...} - {"op": "add_wheel_joint2d", "node_id": N, "angle": 90, ...} - {"op": "add_fixed_joint_2d", "node_id": N, "angle": 0, ...} (cc.FixedJoint2D — previously mis-named "weld"; 3.8 renames it.) - {"op": "add_relative_joint2d", "node_id": N, "linear_offset_x": 10, ...}

Back-reference forms inside any op value:

  • "$N" — positional id of op index N (0-based).

  • "$name" — named id, resolves against prior ops' name field.

Example mixing both forms::

[{"op": "add_node", "parent_id": 2, "name": "bird"}, # $0 or $bird {"op": "add_uitransform", "node_id": "$bird", "width": 50, "height": 50}, {"op": "add_rigidbody2d", "node_id": "$bird", "body_type": 2}, {"op": "add_circle_collider2d", "node_id": "$bird", "radius": 25}]

Inputs: scene_path (required), operations (required).

cocos_buildA

Headlessly build the project via CocosCreator --build.

Common platforms: web-mobile, web-desktop, wechatgame, ios, android, mac, windows

Convenience booleans for the most-tweaked release flags:

  • source_maps: emit .map files for stack-trace symbolication

  • md5_cache: append md5 hashes to asset filenames (cache busting)

  • skip_compress_texture: skip texture compression (faster iteration)

  • inline_enum: inline enum members to integer literals (smaller JS)

  • mangle_properties: minify property names (breaks reflection APIs)

Pass None on any boolean to let Cocos's own default apply. For flags without an explicit param, use build_options={"flagName": value} — explicit params still win on conflict.

After a successful build, automatically applies any patches registered via cocos_register_post_build_patch to the output directory — so edits to files Cocos regenerates (style.css, project.config.json, etc.) survive every rebuild. Set apply_patches=False to skip that step.

Returns {exit_code, success, duration_sec, log_tail, build_dir, artifacts, plus error_code/hint on failure, post_build_patches dict when patches ran}. First build is slow (~1-2 min); subsequent builds with clean_temp=False are much faster.

Inputs: project_path (required), platform, debug, creator_version, +8 more.

cocos_center_in_parentB

Attach cc.Widget with centering flags on either/both axes.

horizontal=False centers only vertically, and vice versa. Returns the Widget component id.

Inputs: scene_path (required), node_id (required), horizontal, vertical. Returns: result

cocos_clean_projectA

Clean build artifacts. level: build/temp/library/all/default.

'default' removes build/ + temp/. 'all' also removes library/ (next build re-imports all assets, slow).

Inputs: project_path (required), level.

cocos_click_previewA

Click at page coordinates (x, y) in a running preview.

Use this to drive UI you just built — a "Start" button, a menu tab, a card. Coordinates are in PAGE space (top-left origin), NOT viewport-relative. button is 'left' / 'right' / 'middle'. wait_ms gives post-click animations/scene-changes time to settle before the tool returns.

Requires the optional playwright dependency (same as cocos_screenshot_preview). Returns {ok: True} on success, raises on navigation/launch failure with an actionable hint.

Inputs: url (required), x (required), y (required), button, +4 more.

cocos_compress_uuidA

Compress a 36-char UUID to Cocos Creator's 23-char short form.

Required when referencing a custom TS script class as a component __type__ in a scene/prefab JSON. Example: '5372d6f5-721e-43f6-b004-d30da1c8a9a0' -> '5372db1ch5D9rAE0w2hyKmg'

Inputs: uuid (required). Returns: result

cocos_constantsA

Return commonly used Cocos Creator constants.

Saves you from looking up layer bitmasks, blend factors, alignment enum values, etc.

Inputs: no named parameters.

cocos_create_animation_clipA

Create a .anim AnimationClip file.

Each track dict: {path, property, keyframes: [{time, value}, ...]}. Properties: 'position' (value=[x,y,z]), 'scale' ([sx,sy,sz]), 'rotation' ([ez]), 'opacity' (0-255), 'color' ([r,g,b,a]), 'active' (bool).

Returns {path, rel_path, uuid}. Use uuid with cocos_add_animation().

Example track: {"path": "", "property": "position", "keyframes": [{"time": 0, "value": [0,0,0]}, {"time": 1, "value": [100,0,0]}]}

Inputs: project_path (required), clip_name (required), duration, sample, +2 more.

cocos_create_nodeA

Append a new cc.Node under parent_id, return its array index.

layer defaults to UI_2D (33554432). Use 1073741824 for the camera node. The new node has no components yet — call cocos_add_uitransform, cocos_add_sprite etc. to attach them.

Inputs: scene_path (required), parent_id (required), name (required), pos_x, +5 more. Returns: result

cocos_create_physics_materialA

Create a cc.PhysicsMaterial (.pmat) asset. Returns {path, rel_path, uuid}.

Bind to a collider via cocos_set_uuid_property(collider_id, "_material", <uuid>).

Defaults match engine: friction=0.6, restitution=0 (no bounce). For bouncy materials set restitution 0.3-0.9; for ice set friction 0.02.

Inputs: project_path (required), material_name (required), friction, rolling_friction, +3 more.

cocos_create_prefabC

Create an empty .prefab in assets/prefabs/ with a single root node.

Inputs: project_path (required), prefab_name (required), root_name.

cocos_create_sceneA

Create a minimal empty 2D scene + meta in assets/scenes/.

Includes Canvas + UICamera (cc.Camera) + cc.Canvas + Widget + SceneGlobals (Ambient/Skybox/Shadows) + PrefabInfo. The Camera's clearColor is set so a solid sky-blue background is visible even before any sprite is added.

Returns canonical IDs: {scene_path, scene_uuid, scene_node_id, canvas_node_id, ui_camera_node_id, camera_component_id, canvas_component_id}

These IDs are array-index references into the scene's JSON; use them as parent_id / node_id in subsequent tool calls.

Inputs: project_path (required), scene_name, canvas_width, canvas_height, +3 more.

cocos_create_sprite_atlasA

Create an AutoAtlas bundle (Cocos 3.8 build-time packing).

Drops a <atlas_name>.pac marker + correct meta into a folder (default assets/atlas/<name>/). From that point on, every sprite-frame PNG in that folder is automatically packed into one atlas texture when cocos_build runs — no manual enumeration needed afterward.

png_paths is optional. If provided, the PNGs are copied into the atlas folder + sprite-frame metas are written. For PNGs already in the folder (e.g. cocos_add_image(rel_path= "assets/atlas/<name>/foo.png")), no copy is required; they are picked up at build time automatically.

Tunables (all match Cocos Creator 3.8 defaults):

  • max_width / max_height — atlas texture size cap (1024).

  • padding — gap between frames in px (2).

  • power_of_two — force ^2 sizes; usually off.

  • force_squared — force 1:1 aspect; usually off.

  • filter_unused — drop unreferenced sprite frames from the final bundle.

  • algorithm — "MaxRects" (default) or "Basic".

  • quality — 0-100 PNG quality.

Returns {dir, atlas_uuid, pac_path, images, atlas_dir_rel}. atlas_dir_rel is the project-relative folder — drop more PNGs there later to add them to the atlas without running this tool again.

Inputs: project_path (required), atlas_name (required), png_paths, rel_dir, +8 more.

cocos_decompress_uuidA

Reverse cocos_compress_uuid: 23-char short -> 36-char dashed.

Inputs: short_uuid (required). Returns: result

cocos_delete_nodeA

Soft-delete a node (disconnect from parent, deactivate). Indices stay stable.

Inputs: scene_path (required), node_id (required). Returns: result

cocos_derive_theme_from_seedA

Generate a coherent UI palette from one brand color.

Given seed_hex (the game's primary/brand color) and a mode ("dark" or "light"), computes a full color set via HSL math:

  • secondary = complementary hue

  • bg / surface = seed hue at low saturation (subtle brand tint)

  • text / text_dim = high-contrast against bg

  • border = mid-lightness neutral

  • success/warn/danger stay at fixed green/amber/red (severity readability trumps brand consistency)

Returns a {color: {...}} dict ready to pass through to cocos_set_ui_theme(project, custom=<this>). The caller may also merge in font_size / spacing / radius overrides before passing.

Typical use::

palette = cocos_derive_theme_from_seed("#6366f1", mode="dark")
cocos_set_ui_theme("/game", custom=palette)

Inputs: seed_hex (required), mode.

cocos_drag_previewB

Drag the mouse from (from_x, from_y) to (to_x, to_y).

steps is the number of intermediate move events — bump it if Cocos isn't picking up the drag (some handlers need minimum motion per frame). 5 is enough for a typical slider or card move.

Inputs: url (required), from_x (required), from_y (required), to_x (required), +7 more.

cocos_duplicate_nodeB

Shallow-copy a node (no children/components). Returns new node index.

Inputs: scene_path (required), node_id (required), new_name. Returns: result

cocos_enable_dynamic_atlasA

Generate a boot script that enables Cocos 3.8's runtime dynamic atlas (dynamicAtlasManager.enabled = true).

Complements cocos_create_sprite_atlas — AutoAtlas packs at BUILD time, DynamicAtlas packs at RUN time. Turning both on catches small UI frames the AutoAtlas doesn't cover (e.g. runtime-generated text, sprite frames loaded lazily).

The generated .ts flips the global flag on onLoad; attach the resulting component to any persistent scene node (typically a GameManager). Typical flow::

r = cocos_enable_dynamic_atlas(project)
cocos_add_script(scene, gm_node_id, r["uuid_compressed"])

Parameters:

  • rel_path — defaults to DynamicAtlasBooter.ts under assets/scripts/.

  • max_frame_size — sprite frames larger than this (px) are NOT batched. Engine default 512.

  • class_name — TypeScript class name on the script.

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), rel_path, max_frame_size, class_name.

cocos_find_node_by_nameA

Find the first node with the given name. Returns its array index, or None.

Inputs: scene_path (required), name (required). Returns: result

cocos_generate_assetA

Generate a game asset via AI and import it into the project in one step.

Built-in AI image generation (no external dependencies):

  • 智谱 CogView-3-Flash (free) — set ZHIPU_API_KEY in cocos-mcp/.env

  • Pollinations Flux (free, no key) — use provider="pollinations"

Flow: AI generate PNG → remove white background → write sprite-frame meta. Config: create .env file in cocos-mcp/ root with ZHIPU_API_KEY=your_key

Example: result = cocos_generate_asset(project, "cute yellow cartoon bird", "bird", style="icon") cocos_add_sprite(scene, node, sprite_frame_uuid=result["sprite_frame_uuid"])

Styles: icon, pixel, character, tile, ui, portrait, item, scene, none.

Inputs: project_path (required), prompt (required), name (required), style, +5 more.

cocos_get_engine_modulesC

List all engine modules and their enabled/disabled status.

Inputs: project_path (required).

cocos_get_objectB

Return the raw JSON dict of a scene object (for debugging/inspection).

Inputs: scene_path (required), object_id (required).

cocos_get_object_countB

Return the total number of objects in the scene/prefab JSON array.

Inputs: scene_path (required). Returns: result

cocos_get_project_infoC

Read package.json + list assets / scenes / scripts in the project.

Inputs: project_path (required).

cocos_get_sprite_frame_uuidC

Return the <uuid>@f9941 sprite-frame sub-uuid for a PNG meta.

Inputs: meta_path (required). Returns: result

cocos_get_ui_tokensA

Return the project's active UI theme (fully resolved).

Always returns a complete theme — un-themed projects get the dark_game default with source='fallback'. Source is 'registry' when the project has explicitly pinned a theme.

Inputs: project_path (required).

cocos_hex_to_rgbaA

Convert #rrggbb / #rgb / #rrggbbaa to RGBA ints.

Returns {r, g, b, a} suitable for any tool that takes color_r/color_g/color_b/color_a params. Lets the caller paste CSS / design-tool hex codes without hand-translating to int quadruples (a common source of off-by-one color bugs).

Inputs: hex_color (required), alpha.

cocos_init_projectA

Initialize a new Cocos Creator project from a template.

Copies a built-in template (default empty-2d) into dst_path, patches package.json with a fresh project UUID and the right creator version, and creates standard assets/ subdirectories.

Use cocos_list_creator_installs first to see available versions.

Inputs: dst_path (required), creator_version, template, project_name.

cocos_instantiate_prefabA

Drop a .prefab file into the scene as a child node — returns root id.

Reads the .prefab JSON, deep-copies its node tree (root + children + components), shifts every internal id reference, gives every cloned object a fresh _id, refreshes each cc.PrefabInfo.fileId so multiple instances of the same prefab don't alias, and parents the new root under parent_id.

Treats the prefab as unlinked (a one-shot copy). If you later edit the .prefab, instances already dropped into the scene will NOT update — re-instantiate to pick up the changes.

Pass any of name / pos_x / pos_y / pos_z / scale to override the root's defaults (otherwise the prefab's own values stay).

Inputs: scene_path (required), parent_id (required), prefab_path (required), name, +4 more. Returns: result

cocos_lint_uiA

Non-structural UI quality check (complement to cocos_validate_scene).

Flags issues that build + load cleanly but produce bad UX:

  • Button touch target below 44×44 (iOS HIG / Material 48dp min)

  • Label overflow=NONE + wrap off in a box that likely clips the text

  • UI component on a node with layer != UI_2D (UICamera won't render it)

Returns {ok, scene_path, warnings:[{rule, node_id, node_name, message}]}. All warnings are non-fatal; the caller decides what to fix.

Inputs: scene_path (required).

cocos_list_assetsA

List all assets in the project grouped by type, with their UUIDs.

Returns {scripts: [...], scenes: [...], images: [...], prefabs: [...]}. Each entry has at minimum {rel, uuid}; images additionally include sprite_frame_uuid if the meta is upgraded.

Inputs: project_path (required).

cocos_list_builtin_themesA

Return all five bundled UI themes verbatim.

Useful for previewing the palette before pinning one, or as a starting point for a custom= override passed to cocos_set_ui_theme.

Inputs: no named parameters.

cocos_list_creator_installsA

List every locally installed Cocos Creator version.

Returns a list of {version, exe, template_dir} dicts. Looks under /Applications/Cocos/Creator on macOS, C:/CocosDashboard/Creator on Windows, /opt/Cocos/Creator on Linux.

Inputs: no named parameters. Returns: result

cocos_list_post_build_patchesC

Return all registered post-build patches with their indices.

Inputs: project_path (required).

cocos_list_scene_nodesB

List every cc.Node in the scene with its id, name, parent, components, children.

Inputs: scene_path (required). Returns: result

cocos_list_toolsA

List the tools actually registered on this MCP server.

Addresses stale-catalog scenarios where a subagent's MCP session can't reliably see tools registered after the session started — asking the server directly is the ground truth. Returns {count, tools: [{name, category, summary}, ...]} where summary is the first non-empty line of the docstring.

Filters (all optional):

  • name_contains — case-insensitive substring on the tool name. Pass "joint" to list every Joint2D helper, "scaffold" for the 9 gameplay scaffolds.

  • category — coarse bucket inferred from the name prefix: uuid / project / asset / scene / physics2d / physics3d / rendering / ui / media / build / interact / scaffold / composite / meta / other. Inference is heuristic — a tool shows up in exactly one bucket.

Empty filters return every tool. Use this whenever you need to double-check whether a capability is already baked in before implementing it manually.

Inputs: name_contains, category.

cocos_make_click_eventA

Build a cc.ClickEvent dict for use with cocos_add_button's click_events.

Args: target_node_id: Node that holds the script (array index) component_name: @ccclass name (e.g. 'GameManager') handler: Method name to call (e.g. 'onStartClick')

Returns a dict to pass in click_events list of cocos_add_button.

Example workflow: evt = cocos_make_click_event(scene, gm_node, 'GameManager', 'onStart') cocos_add_button(scene, btn_node, click_events=[evt])

Inputs: scene_path (required), target_node_id (required), component_name (required), handler (required), +1 more.

cocos_make_event_handlerB

Build a cc.EventHandler dict for component event bindings.

Use with: cocos_add_scroll_view(scroll_events=[...]), cocos_add_toggle(check_events=[...]), cocos_add_slider(slide_events=[...]), cocos_add_editbox(editing_return=[...]).

Same pattern as cocos_make_click_event but for non-Button components.

Inputs: scene_path (required), target_node_id (required), component_name (required), handler (required), +1 more.

cocos_make_fullscreenA

Attach cc.Widget so the node stretches to fill its parent.

Use for backgrounds, modal backdrops, full-bleed panels. Replaces the align_flags=15 incantation (top+bottom+left+right bitmask). Returns the Widget component id.

Inputs: scene_path (required), node_id (required). Returns: result

cocos_move_nodeC

Re-parent a node. sibling_index=-1 appends as last child.

Inputs: scene_path (required), node_id (required), new_parent_id (required), sibling_index. Returns: result

cocos_new_uuidA

Generate a fresh standard UUID4 (36-char dashed lowercase hex).

Used as the main UUID for new scripts, scenes, prefabs, and images.

Inputs: no named parameters. Returns: result

cocos_press_key_previewA

Press a single key in the running preview.

key uses Playwright's names — 'Enter', 'Space', 'ArrowUp', 'Escape', 'a', 'F1', etc. Cocos's systemEvent KeyCode hook fires on keydown/keyup as expected. Use this for keyboard-driven input (pause menus, player movement, form submit).

Inputs: url (required), key (required), wait_ms, viewport_width, +2 more.

cocos_preview_statusB

List currently running preview servers.

Inputs: no named parameters.

cocos_read_preview_stateA

Evaluate a JavaScript expression against the running preview and return the value.

The preview page must expose state on window for this to be useful — the pattern is window.game = this inside a GameManager's onLoad. Then you can read window.game.score, cc.director.getScene().name, etc.

Returns {ok, value, error}. On a JS exception, ok=False and error carries the message — a bad expression can't crash the tool.

Inputs: url (required), expression, wait_ms, viewport_width, +2 more.

cocos_register_post_build_patchA

Register declarative patches that auto-apply after every successful build.

Use when a customization has no Cocos source-config switch and would otherwise get wiped on the next cocos_build (classic examples: style.css body background, project.config.json fields WeChat wants beyond what builder.json exposes, custom index.html overrides).

Each patch dict needs:

platform: str — "web-mobile" / "wechatgame" / "ios" / etc. file: str — path relative to build/<platform>/ (no absolute paths, no '..' segments). kind: one of: - "json_set" + path (dotted key) + value - "regex_sub" + find (regex) + replace (str) - "copy_from" + source (project-relative path to src file)

mode: "append" (default) adds to existing list, "replace" overwrites. To clear all patches, pass patches=[] with "replace".

All patches are validated at register time — invalid regex or unsafe path fails here, not at build time.

Inputs: project_path (required), patches (required), mode.

cocos_remove_post_build_patchesA

Remove patches by index list OR by platform/file filter.

indices takes precedence; otherwise AND of platform+file filters. Calling with all None is a no-op (explicit wipe requires cocos_register_post_build_patch([], mode='replace')).

Inputs: project_path (required), indices, platform, file.

cocos_run_preview_sequenceA

Run a list of actions in a SINGLE browser session.

Essential for play-testing: game state resets on every page reload, so a multi-step test plan (click Start → type name → press Enter → read score) MUST share one session.

Each action is a dict with a kind + kind-specific keys: {"kind": "click", "x": int, "y": int, "wait_ms"?: int, "button"?: str} {"kind": "key", "key": str, "wait_ms"?: int} {"kind": "type", "text": str, "wait_ms"?: int} {"kind": "drag", "from_x": int, "from_y": int, "to_x": int, "to_y": int, "steps"?: int} {"kind": "wait", "ms": int} {"kind": "read_state", "expression": str} {"kind": "screenshot"}

Returns a list parallel to actions: each entry is {kind, ok, result, error}. A single failed action does NOT abort the sequence, so earlier successful reads/screenshots still come back.

screenshot results return {"png_bytes_hex": "..."} — decode with bytes.fromhex() to get raw PNG data (MCP JSON can't carry bytes natively).

Inputs: url (required), actions (required), viewport_width, viewport_height, +1 more. Returns: result

cocos_save_subtree_as_prefabA

Extract a fully-configured scene subtree into a reusable .prefab.

The usual case: build your "Enemy" in a scratch scene with Sprite + RigidBody2D + Collider + Animation + script all wired, then save-as-prefab to spawn dozens. Without this, every copy requires re-running the same add_* stack against a new node.

Self-contained rule: every cc.Node referenced from inside the subtree (script field pointing at another Node, Button target, etc.) must already BE inside the subtree. External cc.Node refs raise with a message naming the offender — Cocos's prefab format has no way to express late-bound cross-scene refs, so silent clipping would produce a broken prefab. Asset UUID refs ({__uuid__: ...} for SpriteFrames, clips, meshes, other prefabs) survive unchanged; those travel through the asset DB.

Effects on scene_path: NONE (read-only). If you want the scene to now use an instance instead of the raw subtree: delete the source node, then cocos_instantiate_prefab the fresh prefab. That's a deliberately-explicit two-step so you don't lose the raw subtree on a misfired single call.

Returns {prefab_path, prefab_uuid, root_node_id (=1), object_count, source_root_name}.

Inputs: scene_path (required), root_node_id (required), prefab_path (required), prefab_uuid.

cocos_scaffold_audio_controllerA

Generate AudioController.ts — singleton BGM + SFX manager.

Runtime API::

AudioController.I.playBGM(clipName)    // cross-fades if switching tracks
AudioController.I.stopBGM()
AudioController.I.playSFX(clipName)    // overlaps via playOneShot
AudioController.I.setBGMVolume(v)      // 0..1, persists
AudioController.I.setSFXVolume(v)

Inspector: @property bgmClips: AudioClip[] — keyed by clip .name for playBGM lookup. @property sfxClips: AudioClip[] — same convention. @property bgmFadeDuration — tween cross-fade seconds; 0 = hard cut.

Auto-attaches two cc.AudioSource components to its own node (looping BGM source + non-loop SFX source) via addComponent in onLoad — no manual Inspector wiring needed. Volumes persist to localStorage under 'cocos-mcp-audio' with swallowed write failures (private browsing, WeChat mini-game).

Idempotent: playBGM('already-playing') is a no-op. Unknown clip names: silently skipped (avoid crashing on stale references to clips the designer removed).

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), rel_path.

cocos_scaffold_camera_followA

Generate CameraFollow.ts — attach to the Camera node to track a target with deadzone + frame-rate-independent smoothing + optional world bounds.

@property target (Node) — typically the Player. @property offsetX/offsetY/fixedZ — fixed camera offset; fixedZ == -1 means "follow target's z" (sentinel since 0 is a legitimate z value and Cocos Inspector has no null-number). @property smoothing — 0 = instant snap, 1 = very slow lerp. Uses 1 - Math.pow(smoothing, dt) so feel is identical at 30 vs 60 vs 120 fps. @property deadzoneWidth/Height — camera only moves when target leaves this centered rect; kills idle-state jitter. @property useWorldBounds + worldBoundsMin/MaxX/Y — optional clamp.

Zero per-frame allocation (reuses private _tmp + _desired Vec3s); null-checks target each lateUpdate (target may be destroyed mid- scene).

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), rel_path.

cocos_scaffold_enemy_aiA

Generate Enemy{Kind}.ts — common enemy-behaviour starters.

"patrol" — oscillates between @property Nodes patrolA ↔ patrolB. Flips optional @property mirrorSprite on direction change. Exposes @property speed. "chase" — tracks @property target Node when within chaseRadius; gives up past loseAggroRadius (hysteresis prevents aggro flicker). Kinematic setPosition update. @property moveSpeed. "shoot" — stationary turret. Every @property fireInterval s, instantiates @property bulletPrefab with velocity toward @property target if within @property range.

Default rel_path per kind: EnemyPatrol.ts / EnemyChase.ts / EnemyShoot.ts. Returns the usual four keys.

Inputs: project_path (required), kind, rel_path.

cocos_scaffold_game_loopA

Generate GameLoop.ts — singleton state machine.

states: ordered list, default ["menu", "play", "over"]. Each state name generates a pair of inspector-visible callbacks: onEnter<PascalCase> and onExit<PascalCase> — so "game_over" becomes onEnterGameOver / onExitGameOver. Designers can wire either from the Inspector or from script code.

Runtime API::

GameLoop.I.current          // current state name
GameLoop.I.go(state)        // transition; fires onExit<old> → onEnter<new>
GameLoop.I.reset()          // jump to first state

State-name validation at scaffold time:

  • at least one state

  • identifier-safe (no spaces, no leading digits)

  • no duplicates Violations raise ValueError so the broken template never lands.

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), states, rel_path.

cocos_scaffold_input_abstractionA

Generate InputManager.ts + meta - unified keyboard/touch input singleton.

The generated script exposes a stable runtime API that other game scripts read each frame::

InputManager.I.moveDir       // cc.Vec2, normalized, x/y in -1..1
                             //   WASD + arrows; diagonals scaled 0.707
InputManager.I.jumpPressed   // boolean, true for exactly one frame
                             //   after SPACE press; reset in lateUpdate
InputManager.I.firePressed   // boolean, true for one frame after
                             //   KEY_J or any touch-start

Singleton pattern: attach to exactly one persistent GameManager-like node. Extra instances self-destroy in onLoad.

Typical flow::

r = cocos_scaffold_input_abstraction(project)
# r["uuid_compressed"] is the 23-char form the scene needs
cocos_add_script(scene, gm_node_id, r["uuid_compressed"])

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), rel_path.

cocos_scaffold_player_controllerA

Generate Player{Kind}.ts — game-type-specific player controller.

Reads the InputManager singleton (run cocos_scaffold_input_abstraction FIRST) and drives node motion. Which fields the script exposes on the Inspector depends on the kind:

"platformer" — side-view with gravity. Reads moveDir.x + jumpPressed. Requires cc.RigidBody2D + cc.Collider2D on the node. @property moveSpeed / jumpForce / doubleJumpEnabled. "topdown" — bird's-eye. Full moveDir. RigidBody2D gravityScale should be 0. @property moveSpeed. "flappy" — jump-only. jumpPressed → fixed velocity.y impulse. @property flapForce. Gravity carries it down. "click_only" — no physics body. Each click eases node _lpos toward the hit point via tween. @property easeSpeed.

Default rel_path per kind: PlayerPlatformer.ts / PlayerTopdown.ts / PlayerFlappy.ts / PlayerClick.ts. Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), kind, rel_path.

cocos_scaffold_score_systemA

Generate GameScore.ts + meta - current/high score singleton with localStorage persistence and optional Label auto-render.

Runtime API::

GameScore.I.add(points)   // bump current; update high if beaten
GameScore.I.reset()       // clear current (high survives)
GameScore.I.current       // number, current run's score
GameScore.I.high          // number, best ever, persisted

The script has two optional @property(Label) slots: scoreLabel renders 'Score: N' on every change, highLabel renders 'High: N'. Wire them after attach::

cocos_set_uuid_property(scene, script_comp, 'scoreLabel', label_uuid)

... or let the user hook them up from the inspector if they prefer.

High-score persistence uses localStorage under the key cocos-mcp-high-score; write failures (private browsing, WeChat mini-game) are swallowed so gameplay never crashes over a missing save.

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), rel_path.

cocos_scaffold_spawnerA

Generate Spawner{Kind}.ts — instantiate @property prefab on a trigger.

"time" — every @property interval s, up to @property maxActive concurrent. Jitters spawn position within @property spawnBoxSize half-extents. Over cap: despawn oldest (destroy + shift queue). "proximity" — spawn when @property player is within @property triggerRadius, respecting @property cooldown seconds and @property maxActive cap.

Both variants parent spawned nodes under this.node.parent (NOT the spawner itself — inheriting the spawner's transform is usually wrong) and fire optional @property onSpawn callback post- addChild so game code can attach health, patrol targets, etc.

Default rel_path: SpawnerTime.ts / SpawnerProximity.ts.

Inputs: project_path (required), kind, rel_path.

cocos_scaffold_ui_screenA

Generate Screen.ts — full-screen UI controller tied to GameLoop.

Kinds (all subscribe to the GameLoop singleton — scaffold that first so references resolve):

"menu" — title screen. @property startButton, shows when GameLoop.current == 'menu', click → go('play') + hide. "settings" — toggleable panel. @property closeButton + exposes .show() / .hide() / .toggle() for external callers. "pause" — overlay. Listens for Escape key via cc.input directly (doesn't require InputManager scaffolded). @property resumeButton. Toggles 'pause' ↔ 'play'. "game_over" — shown when GameLoop.current == 'over'. Reads GameScore.I.current + .high into @property scoreLabel / highLabel. @property restartButton → GameScore.reset() + GameLoop.go('play').

Every variant toggles @property rootNode.active for show/hide (whole-subtree toggle beats per-node UIOpacity for full screens).

Default rel_path per kind: MenuScreen.ts / SettingsScreen.ts / PauseScreen.ts / GameOverScreen.ts.

Returns {path, rel_path, uuid_standard, uuid_compressed}.

Inputs: project_path (required), kind, rel_path.

cocos_screenshot_previewA

Capture a PNG screenshot of a running preview URL via Playwright.

Closes the visual-feedback loop for AI clients — after cocos_build + cocos_start_preview call this to see what the browser actually rendered and iterate on UI with sight, not guesswork.

wait_ms gives the page time to run scripts after networkidle fires — Cocos's web build finishes asset loading before the first frame draws, so the default 500ms covers most scenes. Bump for heavy 3D scenes.

OPTIONAL DEPENDENCY: needs playwright + the chromium browser binary. Install with::

uv pip install playwright
playwright install chromium

Returns the PNG as an MCP Image, shown inline in the chat.

Inputs: url, viewport_width, viewport_height, wait_ms, +2 more.

cocos_screenshot_preview_diffA

Compare two PNG files on disk and report the change.

Lets an AI confirm whether an action actually DID something — e.g. take a screenshot, click, take another, diff: if diff_ratio is ~0 the click had no visible effect.

threshold is a per-channel absolute delta; pixels below are considered identical (8 rejects typical PNG compression noise).

Returns {width, height, total_pixels, different_pixels, diff_ratio} where diff_ratio is in [0, 1].

This tool is pure Pillow — it does NOT need playwright / chromium installed. Both inputs must be file paths; save via cocos_screenshot_preview first.

Inputs: before_png_path (required), after_png_path (required), threshold.

cocos_set_ambientA

Configure ambient lighting on the scene's cc.AmbientInfo.

Colors are floats 0..1 (NOT 0..255 — sky/ground colors in Cocos are normalized like material PBR inputs). Pass None to leave unchanged. sky_illum is in lux, default ~20000. The scene must have been created via cocos_create_scene (which auto-attaches AmbientInfo).

Inputs: scene_path (required), sky_color_r, sky_color_g, sky_color_b, +6 more.

cocos_set_bundle_configA

Mark a folder as an Asset Bundle by patching its .meta sidecar.

folder_rel_path: relative to project root, e.g. 'assets/levels/world1'. bundle_name: defaults to the folder's basename when None. priority: bundle load priority 1..N (higher = loaded first). compression_type: {platform: mode}. Common modes:

  • 'merge_dep' (default for most platforms)

  • 'subpackage' (WeChat — requires also calling cocos_set_wechat_subpackages with matching root)

  • 'zip' (compress entire bundle)

  • 'none' (no compression) Example: {"web-mobile": "merge_dep", "wechatgame": "subpackage"} is_remote: {platform: bool} to enable remote/CDN loading per platform.

At runtime, load via cc.assetManager.loadBundle('<bundle_name>').

Inputs: project_path (required), folder_rel_path (required), bundle_name, is_bundle, +3 more.

cocos_set_design_resolutionC

Set design resolution for multi-screen adaptation.

fit_width+fit_height=SHOW_ALL; only fit_width=FIT_WIDTH; only fit_height=FIT_HEIGHT.

Inputs: project_path (required), width, height, fit_width, +1 more.

cocos_set_engine_moduleA

Enable/disable an engine module (physics-2d-box2d, spine, dragon-bones, tiled-map, etc.).

IMPORTANT: You MUST enable 'physics-2d-box2d' before using RigidBody2D/Collider2D, 'spine' before using sp.Skeleton, 'dragon-bones' before DragonBones, 'tiled-map' before TiledMap. After changing modules, clean library+temp and rebuild.

Common modules: physics-2d-box2d, physics-2d-builtin, spine, dragon-bones, tiled-map, particle-2d, audio, animation, 2d, ui, graphics, mask, rich-text, tween, video, webview.

Inputs: project_path (required), module_name (required), enabled (required).

cocos_set_fogA

Configure volumetric fog on the scene's cc.FogInfo.

Fourth scene-global alongside ambient/skybox/shadows. Lazy-creates a cc.FogInfo + links it from cc.SceneGlobals if the scene doesn't have one yet (scenes built before this tool existed won't).

fog_type: 0=LINEAR (use start+end), 1=EXP (density), 2=EXP_SQUARED, 3=LAYERED (top+range). Atmospheric settings are inter-dependent — LINEAR ignores density, EXP/EXP_SQUARED ignore start/end.

Inputs: scene_path (required), enabled, fog_type, color_r, +10 more.

cocos_set_native_build_configA

Configure iOS or Android native build settings in builder.json.

platform: 'ios' or 'android'. orientation: 'portrait' / 'landscape' / 'auto'. icon_path / splash_path: paths to PNG files (relative to project). ios_team_id: Apple Developer Team ID (10-char string). android_min_api / android_target_api: Android API levels (e.g. 21 / 30). android_use_debug_keystore=True for dev builds; set False + provide keystore_path/password/alias/alias_password for release signing. android_app_bundle: True to produce .aab instead of .apk.

All fields are optional — None leaves existing values unchanged.

Inputs: project_path (required), platform (required), package_name, orientation, +11 more.

cocos_set_node_activeC

Toggle a node's _active flag (True = visible/ticking, False = disabled).

Inputs: scene_path (required), node_id (required), active (required). Returns: result

cocos_set_node_layerA

Set a node's layer bitmask. Common: UI_2D=33554432, DEFAULT=1073741824.

Inputs: scene_path (required), node_id (required), layer (required). Returns: result

cocos_set_node_positionB

Set a node's local position (x, y, z). z defaults to 0 for 2D scenes.

Inputs: scene_path (required), node_id (required), x (required), y (required), +1 more. Returns: result

cocos_set_node_rotationB

Set 2D rotation (euler Z) in degrees.

Inputs: scene_path (required), node_id (required), angle_z (required). Returns: result

cocos_set_node_scaleC

Set a node's local scale.

Inputs: scene_path (required), node_id (required), sx (required), sy (required), +1 more. Returns: result

cocos_set_physics_2d_configA

Configure 2D physics: gravity, timestep, solver iterations.

Default gravity is (0, -320). Must call this before build if using physics.

Inputs: project_path (required), gravity_x, gravity_y, fixed_time_step, +3 more.

cocos_set_physics_3d_configA

Configure 3D physics: gravity (m/s²), timestep, sub-step cap.

Default gravity is (0, -10, 0) in metric units (NOT pixels — 2D uses -320 because of its pixel coord system). Writes settings/v2/packages/physics.json. Bump max_sub_steps to 3-4 if physics drops frames after hitches.

Inputs: project_path (required), gravity_x, gravity_y, gravity_z, +5 more.

cocos_set_propertyA

Set a literal (non-reference) property on any scene object.

Use this for things like _string, _fontSize, _color, etc. For node/component references, use cocos_link_property instead.

Inputs: scene_path (required), object_id (required), prop_name (required), value (required). Returns: result

cocos_set_shadowsA

Configure planar shadows on the scene's cc.ShadowsInfo.

normal: ground plane normal, defaults to (0, 1, 0) for flat ground. distance: signed offset along normal from world origin. color: shadow color, ints 0..255.

Pass None on any axis/channel to leave it unchanged. Enabling planar shadows also typically requires at least one DirectionalLight in the scene.

Inputs: scene_path (required), enabled, normal_x, normal_y, +6 more.

cocos_set_skyboxB

Configure the scene's cc.SkyboxInfo.

env_lighting_type: 0=HEMISPHERE_DIFFUSE (cheap default), 1=AUTOGEN_HEMISPHERE_DIFFUSE, 2=DIFFUSEMAP_WITH_REFLECTION (PBR, needs envmap).

envmap_uuid points at a cc.TextureCube asset. Pass empty string "" to clear. Pass None to leave fields unchanged.

Inputs: scene_path (required), enabled, envmap_uuid, use_hdr, +1 more.

cocos_set_sprite_frame_borderA

Set 9-slice border on an existing sprite-frame meta in pixels.

Required before using a PNG with cc.Sprite type=SLICED (rounded buttons, UI panels, dialog backgrounds — anything that should keep crisp corners while stretching the middle).

Idempotent. The meta must already be sprite-frame type (run cocos_upgrade_image_meta first if it's still texture-only).

Inputs: meta_path (required), top, bottom, left, +1 more.

cocos_set_start_sceneC

Set the project's start scene in settings/v2/packages/project.json.

The engine loads this scene first at runtime.

Inputs: project_path (required), scene_uuid (required).

cocos_set_ui_themeA

Pin a UI theme so every subsequent cocos_add_label / cocos_add_button / cocos_add_sprite call with color_preset=… / size_preset=… resolves through the same design tokens — produces a visually consistent game.

Built-in theme names: dark_game, light_minimal, neon_arcade, pastel_cozy, corporate. Pass a custom dict ({color, font_size, spacing, radius}) for something bespoke — missing preset names fall through to dark_game defaults so no lookup ever fails.

Preset vocabulary every theme MUST provide: color: primary / secondary / bg / surface / text / text_dim / success / warn / danger / border (10) font_size: title / heading / body / caption (4) spacing: xs / sm / md / lg / xl (5) radius: sm / md / lg / pill (4)

Calling with no args pins dark_game.

Inputs: project_path (required), theme, custom.

cocos_set_uuid_propertyC

Set a property to a uuid resource ref (SpriteFrame, AudioClip, etc.).

Inputs: scene_path (required), object_id (required), prop_name (required), uuid (required). Returns: result

cocos_set_wechat_appidC

Write appid to builder.json for the wechatgame platform.

Inputs: project_path (required), appid (required).

cocos_set_wechat_subpackagesA

Configure WeChat mini-game subpackages.

Each entry must be {"name": "", "root": "assets/"}. Example: [{"name": "level1", "root": "assets/levels/world1"}, {"name": "audio", "root": "assets/audio"}]

WeChat hard-caps the main package at 4 MB; without subpackages any non-trivial game gets rejected at upload time.

Replaces the entire subpackages list (atomic). Pair with cocos_set_bundle_config on each root folder to actually mark them as bundles in the asset DB.

Inputs: project_path (required), subpackages (required).

cocos_stack_horizontallyB

cc.Layout type=HORIZONTAL — children arrange left-to-right.

align here is the cross-axis: top/center/bottom. Returns the Layout component id.

Inputs: scene_path (required), node_id (required), spacing, padding, +1 more. Returns: result

cocos_stack_verticallyB

cc.Layout type=VERTICAL — children arrange top-to-bottom.

spacing / padding accept a design-token name (xs/sm/md/lg/xl) or a raw int in logical pixels. align: left/center/right. Returns the Layout component id.

Inputs: scene_path (required), node_id (required), spacing, padding, +1 more. Returns: result

cocos_start_previewA

Start a local HTTP server serving the build// directory.

Returns {port, url, serving}. Idempotent — replaces any server already on port. Run cocos_build first.

Inputs: project_path (required), platform, port.

cocos_stop_previewC

Stop the preview HTTP server on the given port.

Inputs: port.

cocos_type_previewA

Type a string into whatever widget currently has focus.

Ideal for filling name-entry fields, high-score initials, chat boxes. The text is emitted one char at a time via the keyboard API, so IME/input-event handlers fire per character.

Inputs: url (required), text (required), wait_ms, viewport_width, +2 more.

cocos_upgrade_image_metaA

Upgrade a texture-only PNG meta to include a sprite-frame sub.

Cocos Creator's CLI --build auto-generates type: texture metas when it imports a fresh PNG. To reference such a PNG from cc.Sprite, run this tool to add the f9941 (sprite-frame) sub. Idempotent — does nothing if the sub already exists.

Returns the updated meta dict.

Inputs: meta_path (required).

cocos_validate_sceneA

Sanity-check a scene file: ref ranges, type tags, parent linkage.

Returns {valid: bool, object_count: int, issues: [...]}. Run this after building a scene to catch dangling id references before invoking cocos_build.

NOTE: structural-only. To check whether the scene's components match the project's enabled engine modules (the "build succeeds but RigidBody2D doesn't work" class of bugs), also call cocos_audit_scene_modules.

Inputs: scene_path (required).

cocos_wait_for_previewB

Navigate, sleep ms, close — useful between a build and a screenshot to let async asset loading finish.

Inputs: url (required), ms, viewport_width, viewport_height, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 184 tools

    Disambiguation2/5

    The tool set has significant overlap and ambiguity, with many tools performing similar functions or having unclear boundaries. For example, there are multiple tools for adding components (cocos_add_component, cocos_add_rigidbody2d, cocos_add_box_collider2d, etc.) and many specialized tools that could be confused with more general ones (e.g., cocos_add_button_with_label vs cocos_add_button plus cocos_add_label). The descriptions help, but the sheer number of overlapping tools makes disambiguation difficult.

    Naming Consistency5/5

    Tool names follow a highly consistent snake_case pattern with a clear 'cocos_' prefix and descriptive verb_noun structure throughout. Examples include cocos_add_script, cocos_create_scene, cocos_set_property, and cocos_scaffold_game_loop. There are no deviations in naming conventions, making the set predictable and readable.

    Tool Count1/5

    With 184 tools, the count is extremely high for any server's purpose, indicating severe bloat and lack of focus. This many tools will overwhelm agents and make selection challenging, as many tools could be consolidated or removed without losing functionality. The scope appears to cover every possible Cocos Creator operation, but such comprehensiveness comes at the cost of usability.

    Completeness5/5

    The tool set provides exhaustive coverage of the Cocos Creator domain, including asset management, scene editing, physics, UI, animation, build processes, and testing. There are no obvious gaps; tools support full CRUD operations, lifecycle management, and integration with external systems like AI generation and preview interaction. The surface is complete for game development workflows.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      MCP server for Cocos Creator that enables AI tools to automate scene editing, resource management, and project operations via HTTP and stdio interfaces.
      27 npm
      236
      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.
      26 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.
      26 npm
      1
      MIT