dsh-unity-mcp-bridge 0.0.0-stage → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,150 @@
1
+ # 功能说明与方案对比
2
+
3
+ 本文档两部分:**这个插件做什么**,以及**用工具 / 不用工具直接处理**在 token 与耗时上的实测差距。
4
+
5
+ 所有数字都是在本机(Windows + Unity 2022 项目 + 同一台机器上的 DSH)实测得到的,标注了「实测」或「按 X 换算」;没有凭空估计的数字。
6
+
7
+ ---
8
+
9
+ ## 一、插件做什么
10
+
11
+ `dsh-unity-mcp-bridge` 是给 DeepSeek Harness(DSH)用的 **Unity MCP 桥接插件**。它把 Unity 编辑器(AI Game Developer / `com.ivanmurzak.unity.mcp`)的能力接到 DSH 里,并额外解决三件事:
12
+
13
+ | 能力 | 说明 |
14
+ |---|---|
15
+ | **桥接** | 连接 Unity 的 MCP 服务端(默认 `http://localhost:24009/p/<token>`),把它的工具注册成模型可直接调用的 `mcp__unity__*` |
16
+ | **自动重同步** | 配置项 `resyncAfterTools`:列出的工具调用返回后,桥接自己重新拉取 `tools/list` 并替换注册表。**不依赖**服务端的 `notifications/tools/list_changed`(DSH 的长连接会话收不到该通知) |
17
+ | **一键恢复** | 原生工具 `unity_tools_restore`:关闭除 `tool-set-enabled-state` 以外的全部 Unity 工具,把常驻工具集恢复成最小状态 |
18
+ | **技能文档** | 激活时把自带的分层命令目录注册为运行时技能,模型按需加载(索引 → 分类详情) |
19
+
20
+ ### 三个必须理解的事实
21
+
22
+ 1. **工具表在请求边界重建。** 开启一个命令后,要**下一个步骤**才能调用它,不能在同一个步骤里开启并调用。
23
+ 2. **关闭的命令无法调用。** 文档只是知识,不产生能力;只有 Unity 侧启用的命令才会出现在模型工具表里。
24
+ 3. **启用的命令会持续占用上下文。** 每个处于开启状态的命令,其完整 JSON Schema 都会进入之后**每一次**模型请求,直到被关闭。
25
+
26
+ ---
27
+
28
+ ## 二、怎么用:**按需启用**(默认休眠)
29
+
30
+ **Unity 能力默认完全关闭。** 插件挂载后处于休眠:不连接 Unity、不注册任何 `mcp__unity__*` 工具,常驻只有两个钩子工具。
31
+
32
+ | 环节 | 谁触发 | 说明 |
33
+ |---|---|---|
34
+ | 插件挂载 | 自动 | DSH 启动时挂载,但**保持休眠**(可用 `autoStart: true` 改回"启动即连接") |
35
+ | 技能是否对模型可见 | ❌ 不可见 | 技能设为「仅用户可调用」(`skillModelInvocable: false`),模型目录里**没有它**,不会自己加载、更不会自动开启 |
36
+ | 启用 | **你** | 输入 `/unity-mcp-tools` 调用技能 |
37
+ | 激活连接 | 模型 | 技能正文(作为指令注入)告诉模型先调 `unity_mcp_activate` |
38
+ | 开启/调用/关闭命令 | 模型 | `mcp__unity__tool-set-enabled-state` / `unity_tools_restore` |
39
+
40
+ 状态机:
41
+
42
+ ```
43
+ 启动 ─► 休眠 ──(/unity-mcp-tools → unity_mcp_activate)──► 激活 ──(unity_tools_restore)──► 休眠
44
+ 2 个钩子工具 桥接 mcp__unity__* 工具
45
+ ```
46
+
47
+ 判据(实测):休眠时注册表里只有 `unity_mcp_activate` 与 `unity_tools_restore`,桥接工具数为 **0**;激活后出现 `mcp__unity__*`;恢复后桥接工具数回到 **0** 且连接断开。
48
+
49
+ ---
50
+
51
+ ## 三、三种做法的对比
52
+
53
+ | | A. 插件(默认休眠,按需激活) | B. 不用插件,工具全开 | C. 不用工具,AI 直接处理项目文件 |
54
+ |---|---|---|---|
55
+ | 常驻成本(休眠) | **895 字符 ≈ 224 tokens**(2 个钩子工具,实测) | — | 0 |
56
+ | 常驻成本(激活后) | 869~1,809 字符 ≈ 217~452 tokens | **84,972 字符**(41 个工具,实测请求头增量) | 0 |
57
+ | 换算 token | ≈ **224**(休眠)~452(激活后) | ≈ **21,243** tokens/请求 | 0 |
58
+ | 会不会自动开启 | ❌ 只有 `/unity-mcp-tools` 才启用 | ❌(但一直付全开的成本) | ❌ |
59
+ | 能做编辑器操作 | ✅ 全部(按需开启) | ✅ 全部 | ❌ 只能改文件(改不到未保存状态) |
60
+ | 创建物体/组件 | ✅ 一步调用 | ✅ | ❌ 需手写 `.unity` YAML,实质不可行 |
61
+ | 是否需要重启/审批 | ❌ | ❌ | ❌ |
62
+
63
+ **相对全开,按需方案把 Unity 部分的常驻开销降低约 98~99%**(21,243 → 224 tokens 休眠 / 452 tokens 激活后)。
64
+
65
+ ---
66
+
67
+ ## 四、实测:单次操作的成本差距
68
+
69
+ ### 场景 1:查询场景中某物体的组件列表
70
+
71
+ | 路径 | 上下文成本 | 结果体积 | 服务端耗时 |
72
+ |---|---|---|---|
73
+ | **工具**(`gameobject-find`) | schema 4,987 字符(**仅启用期间**)+ 调用参数 ~150 | **946 字符** | **129 ms**(实测) |
74
+ | 文件:读整个场景 | **99,294 字符** ≈ **24,800 tokens** | — | 0~1 ms |
75
+ | 文件:只 grep 物体名 | 824 字符 ≈ 205 tokens | 拿不到组件类型 | ~0 ms |
76
+ | 文件:补齐组件类型 | 再提取 32 个脚本 GUID(1,055 字符)+ **逐个反查 `.meta`** | — | 0 ms + 多次查找 |
77
+
78
+ 结论:**要拿到"组件列表"这个答案**,工具约 1,300~1,500 tokens(含临时 schema,用完即关);文件路径约 24,800 tokens(约 **16 倍**),或用 grep 省 token 但**答不出组件类型**。
79
+
80
+ ### 场景 2:创建一个带组件的物体
81
+
82
+ | 路径 | 上下文成本 | 可行性 |
83
+ |---|---|---|
84
+ | **工具**(`gameobject-create` 等) | schema 2,195 字符 ≈ 550 tokens(仅启用期间)+ 参数 ~110 + 结果 **79 字符** | ✅ 一步完成,实测 113~129 ms |
85
+ | 文件:手改 `.unity` YAML | 需构造 GameObject / Transform / MeshFilter / MeshRenderer / BoxCollider 五个序列化块,`fileID`/`GUID` 自编且必须正确互引;为安全编辑还需先读大量片段(数千~99,294 字符) | ❌ **实质不可行**(极易损坏场景,且编辑器会覆盖) |
86
+ | 文件:写 C# 脚本让你手动跑 | 脚本约 1,000~2,000 字符输出 | ⚠️ 把工作推迟给你,不算完成 |
87
+
88
+ ### 场景 3:只读少量信息(列出场景根对象)
89
+
90
+ | 路径 | 上下文成本 | 耗时 |
91
+ |---|---|---|
92
+ | 工具 `scene-get-data`(仅根对象) | 1,856 字符结果 + 60 字符 schema ≈ **480 tokens** | 109 ms |
93
+ | 读整个场景文件 | 99,294 字符 ≈ **24,800 tokens** | 0~1 ms |
94
+
95
+ ---
96
+
97
+ ## 五、实测:执行速度到底差在哪
98
+
99
+ 单次调用耗时(本机 localhost,实测 5 次):
100
+
101
+ | 操作 | 耗时 |
102
+ |---|---|
103
+ | `scene-list-opened` | 84 ms |
104
+ | `scene-get-data`(根对象) | 109 ms |
105
+ | `tool-set-enabled-state`(开启/关闭) | 113 / 114 ms |
106
+ | `gameobject-find`(1 个物体含组件) | 129 ms |
107
+ | 本地读取 99,294 字符的场景文件 | 0~1 ms |
108
+ | 本地扫描全部 `m_Name` | ~0 ms |
109
+
110
+ > 上表测于插件 **0.9x**(当时 `scene-*` / `gameobject-*` 还在)。插件 **1.2.0** 起这些细粒度命令已从插件移除,同样的读写走 `rql-query` / `rql-mutate`(一次调用覆盖多个对象),注册命令数 73 → 18。结论不变:一次 MCP 调用是 ~100 ms 量级。
111
+
112
+ **纯 I/O 上,文件操作比 MCP 调用快约两个数量级**(0~1 ms vs 84~129 ms)。但这不是任务总耗时的决定因素:
113
+
114
+ | 决定因素 | 实测数据 |
115
+ |---|---|
116
+ | **模型往返**(每多一步) | 本会话 396 步实测:**平均每步 6,322 ms**(其中首字延迟均值 2,055 ms) |
117
+ | 解码速度 | 本会话 429,674 output tokens / 1,680 s ≈ **256 tokens/s** |
118
+ | 上下文体积 | 读一次场景 = 24,800 tokens **长期留在上下文**,之后每一步都要重新处理,直到被压缩 |
119
+
120
+ 所以:
121
+
122
+ - **一次性的、grep 就能回答的问题**:文件路径可能更快(1 步 vs 工具的 2 步,相差约 6.3 秒),但信息量更少;
123
+ - **需要准确答案、或需要多步操作**:工具路径明显更优——上下文小 16 倍以上,且不会把 24,800 tokens 一直背在每一步后面;
124
+ - **创建/修改类操作**:文件路径不是"慢",而是**做不到**。
125
+
126
+ ### 关于"多出来的那一步"
127
+
128
+ 按需方案开启工具需要一步(约 6.3 s 模型时间),这是它的固有代价。但这一步换来的是:常驻上下文从 21,243 tokens 降到 217 tokens,**之后每一步**都便宜。任务只要超过 1~2 步,这笔账就是赚的。
129
+
130
+ ---
131
+
132
+ ## 六、推荐用法
133
+
134
+ 1. **默认休眠,按需开启**:需要 Unity 操作时输入 `/unity-mcp-tools`;插件不会自动激活(技能对模型不可见)。
135
+ 2. **激活后保持最小常驻集**:只留 `tool-set-enabled-state`(可选再加 `unity-tool-list` 用于运行时核对清单),其余命令按需开启。
136
+ 3. **任务结束务必恢复**:让模型调用 `unity_tools_restore` —— 它会关闭临时开启的命令并断开连接,回到休眠(技能正文已写明这一步必做)。忘记恢复 = 把临时成本永久留在上下文里。
137
+ 4. **不用 Unity 工具的任务不要开**:纯写 `Assets/**` 里的 C# 代码时,DSH 自带的文件工具就够了,此时连 `/unity-mcp-tools` 都不必调用。
138
+ 5. **需要"改动即生效"的自动化时**:可把 `resyncIntervalMs` 设为 30000 之类的值,定时兜底重同步(能看到在 Unity 窗口里手动改的开关);代价是每周期重建一次工具注册表。
139
+
140
+ ---
141
+
142
+ ## 附:本文数据来源
143
+
144
+ | 数据 | 来源 |
145
+ |---|---|
146
+ | 工具 schema 体积、请求头增量 | 实测会话请求头(`request/header`)与桥接插件上报 |
147
+ | 场景文件体积、物体/组件查询结果 | 实测:本地文件读取 + MCP 直接调用 |
148
+ | MCP 调用耗时 | 实测:原始 MCP 客户端连续调用 5 次取单次值 |
149
+ | 每步模型耗时、解码速度 | 实测:本会话 396 步统计(`llmMs` / `steps` / `decodeTokens`) |
150
+ | 字符→token 换算 | 按 **4.0 字符/token** 换算(与 DSH 自身 token 计量表的换算比例一致,属估算) |
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,44 @@
1
- # Temporary Holding Version
1
+ # dsh-unity-mcp-bridge
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 中文 → [README.zh.md](README.zh.md)
4
+
5
+ A DeepSeek Harness (DSH) plugin that bridges a Unity MCP server (`com.ivanmurzak.unity.mcp` / AI Game Developer) into DSH. It stays dormant until you ask for Unity.
6
+
7
+ ## Intro
8
+
9
+ - Dormant from boot: no connection, no Unity tools — two hook tools, ~224 tokens.
10
+ - `/unity-mcp-tools` then `unity_mcp_activate` connects and registers `mcp__unity__*`.
11
+ - Enabled commands take effect on the **next** step; `unity_tools_restore` disables them and disconnects.
12
+ - Ships the command catalog for plugin 1.6.0 (19 commands, RQL-first; regenerable from the offline package via `/unity-mcp-update-tools`) and the `/unity-mcp-install` / `/unity-mcp-check` / `/unity-mcp-update` / `/unity-mcp-update-tools` skills.
13
+ - `resyncAfterTools`: after a management-tool call the bridge re-fetches `tools/list` itself, because DSH's long-lived session never receives `list_changed`.
14
+
15
+ ## Install
16
+
17
+ ```powershell
18
+ dsh plugin --profile <profile> add git+https://github.com/xiake-1/dsh-unity-mcp-bridge.git
19
+ ```
20
+
21
+ `<profile>` is `web` (`dsh web`) or `desktop`. Restart the app. The shipped bundle patch inserts the `unity-mcp` row (`http://localhost:20000/mcp`) itself — nothing to write by hand.
22
+
23
+ Override the row only when this profile uses a different endpoint, in `%DSH_HOME%/profiles/<profile>/cordis.patch.yml`:
24
+
25
+ ```yaml
26
+ - id: unity-mcp
27
+ config:
28
+ url: http://localhost:20000/p/<your-token>
29
+ ```
30
+
31
+ Uninstall: `dsh plugin --profile <profile> remove dsh-unity-mcp-bridge`
32
+
33
+ ## Usage
34
+
35
+ | Entry | What it does |
36
+ |---|---|
37
+ | `/unity-mcp-install` | Installs the Unity-side plugin and the MCP Server into the workspace's Unity project |
38
+ | `/unity-mcp-check` | Checks plugin install, port 20000, DSH bundle loading, minimal tool set and catalog version, then runs the connect test |
39
+ | `/unity-mcp-update` | Checks the official CLI, the local `vendor/` offline package and the Unity plugin for updates; upgrades only after you agree |
40
+ | `/unity-mcp-update-tools` | Refreshes the offline package and regenerates the `/unity-mcp-tools` command and extension indexes |
41
+ | `/unity-mcp-tools` | Opens Unity capability: activate → find the command → enable only what the task needs |
42
+ | `unity_tools_restore` | Disables everything except the management tool and returns to dormant |
43
+
44
+ Everything else — configuration fields, the offline `vendor/` package, catalog regeneration, self-test — is in [docs/DETAILS.md](docs/DETAILS.md); measured feature comparison in [FEATURES-AND-COMPARISON.md](FEATURES-AND-COMPARISON.md).
package/README.zh.md ADDED
@@ -0,0 +1,44 @@
1
+ # dsh-unity-mcp-bridge
2
+
3
+ English → [README.md](README.md)
4
+
5
+ 给 **DeepSeek Harness(DSH)** 用的 Unity-MCP 桥接插件:把 Unity 编辑器里的 MCP 服务端(`com.ivanmurzak.unity.mcp` / AI Game Developer)接入 DSH。默认休眠,要用的时候才连。
6
+
7
+ ## 简介
8
+
9
+ - 开机即休眠:不连接、不注册任何 Unity 工具,只有 2 个钩子工具(约 224 tokens)。
10
+ - `/unity-mcp-tools` → `unity_mcp_activate` 才连接并注册 `mcp__unity__*`。
11
+ - 开启的命令**下一步**才生效;`unity_tools_restore` 关闭它们并断开,回到休眠。
12
+ - 随包发布插件 1.6.0 的命令目录(19 个命令,RQL-first;`/unity-mcp-update-tools` 可按新离线包重生成)与 `/unity-mcp-install`、`/unity-mcp-check`、`/unity-mcp-update`、`/unity-mcp-update-tools` 四个技能。
13
+ - `resyncAfterTools`:管理工具调用返回后桥接自己重拉 `tools/list`,不依赖 DSH 长会话收不到的 `list_changed` 通知。
14
+
15
+ ## 安装
16
+
17
+ ```powershell
18
+ dsh plugin --profile <profile> add git+https://github.com/xiake-1/dsh-unity-mcp-bridge.git
19
+ ```
20
+
21
+ `<profile>` 是 `web`(`dsh web`)或 `desktop`。装完重启应用。包自带的 bundle patch 会自己插入 `unity-mcp` 行(`http://localhost:20000/mcp`),不需要手写 profile patch。
22
+
23
+ 只有这个 profile 要连别的端点时才覆盖它,写在 `%DSH_HOME%/profiles/<profile>/cordis.patch.yml`:
24
+
25
+ ```yaml
26
+ - id: unity-mcp
27
+ config:
28
+ url: http://localhost:20000/p/<your-token>
29
+ ```
30
+
31
+ 卸载:`dsh plugin --profile <profile> remove dsh-unity-mcp-bridge`
32
+
33
+ ## 使用
34
+
35
+ | 入口 | 作用 |
36
+ |---|---|
37
+ | `/unity-mcp-install` | 给工作区里的 Unity 工程装上 Unity 侧插件与 MCP Server |
38
+ | `/unity-mcp-check` | 检查插件安装、端口 20000(不是就改)、DSH bundle 加载、工具集初始化、命令目录版本,再实测连通 |
39
+ | `/unity-mcp-update` | 检查 CLI、本地离线包(`vendor/`)与 Unity 插件的新版本,问过你才更新 |
40
+ | `/unity-mcp-update-tools` | 把离线包刷到最新并重生成 `/unity-mcp-tools` 的命令索引与扩展索引 |
41
+ | `/unity-mcp-tools` | 打开 Unity 能力:激活 → 找到命令 → 只开本次要用的 |
42
+ | `unity_tools_restore` | 关闭除管理工具外的全部工具并断开,回到休眠 |
43
+
44
+ 其余全部细节(配置字段、`vendor/` 离线包、命令目录重生成、自测)见 [docs/DETAILS.md](docs/DETAILS.md);特性与实测对比见 [FEATURES-AND-COMPARISON.md](FEATURES-AND-COMPARISON.md)。
@@ -0,0 +1,33 @@
1
+ # The plugin row ships with the bundle, because installing the package has to be
2
+ # enough to make it active. A bundle whose patch inserts no row installs as
3
+ # "installed but not in effect": nothing instantiates it, and a desktop profile
4
+ # that regenerates its own cordis.patch.yml from its settings store drops any row
5
+ # you added there by hand, so the plugin silently stops working after a restart.
6
+ #
7
+ # The default endpoint is the standard Unity-side one: gamedev-mcp-server.exe
8
+ # listening on port 20000, mounted at /mcp. The token-carrying /p/<pin> path is
9
+ # an alternative mount on that same listener, not a different port.
10
+ #
11
+ # To point this profile's row somewhere else, override it in YOUR layer (the
12
+ # profile's cordis.patch.yml) with a plain id entry - not a second insert:
13
+ #
14
+ # - id: unity-mcp
15
+ # config:
16
+ # url: http://localhost:20000/p/<your-token>
17
+ #
18
+ # See README.md for the full configuration table and the install procedure.
19
+ - insert:
20
+ - id: unity-mcp
21
+ name: 'dsh-unity-mcp-bridge'
22
+ config:
23
+ serverName: unity
24
+ transport: streamable-http
25
+ url: http://localhost:20000/mcp
26
+ toolCallTimeoutMs: 120000
27
+ # After a call to any listed tool returns, this bridge re-fetches
28
+ # tools/list itself and swaps the registry, instead of waiting for the
29
+ # server's tools/list_changed notification.
30
+ resyncAfterTools:
31
+ - tool-set-enabled-state
32
+ # Safety-net periodic re-sync in ms (0 = off).
33
+ resyncIntervalMs: 0
@@ -0,0 +1,183 @@
1
+ # dsh-unity-mcp-bridge — 详细文档 / Details
2
+
3
+ README 只写简介、安装、使用。这里放其余全部细节。
4
+
5
+ This file holds everything the README leaves out.
6
+
7
+ ---
8
+
9
+ ## 为什么不用直接 patch 已装包 / Why not patch the installed package
10
+
11
+ `@deepseek-ai/dsh-mcp-client` 是 npx 缓存里的构建产物,`npx @deepseek-ai/dsh` 随时可能重装或升级它,手工 patch 会被静默抹掉。本包自带实现,版本由自己钉住。
12
+
13
+ The bridge is vendored here, so a DSH/npx upgrade cannot silently revert it.
14
+
15
+ 核心修复是 **`resyncAfterTools`**:列出的工具调用返回后,桥接自己重新拉 `tools/list` 并替换注册表,不等服务端的 `notifications/tools/list_changed`(DSH 长会话收不到该通知)。
16
+
17
+ ---
18
+
19
+ ## DSH 版本兼容 / Version compatibility
20
+
21
+ 五个 `@deepseek-ai/dsh-*` peer 声明的是下限而非钉版(`>=0.1.5-rc.2`),一份 checkout 可装进 0.1.5-rc.2 起的任意 DSH 运行时。已按宿主自己的门禁(`dsh-app-boot` → `evaluatePluginCompatibility`,即 `semver.satisfies(version, range, { includePrerelease: true })`)验证 0.1.5-rc.2、0.1.7-rc.2、0.2.0-rc.2。`@deepseek-ai/cordis` 保持 `^4.0.2`(独立版本线,宿主不 gate)。真正不兼容的未来运行时由宿主安装期门禁报出。
22
+
23
+ ---
24
+
25
+ ## 安装细节 / Install details
26
+
27
+ 本地源码安装:
28
+
29
+ ```powershell
30
+ dsh plugin --profile <profile> add file:<path-to-this-checkout>
31
+ ```
32
+
33
+ 插件包自带的 bundle patch 会插入 `unity-mcp` 行(`url: http://localhost:20000/mcp`),不需要手写 profile patch。bundle 不插入任何行时插件会显示「已安装,未生效」;桌面端会把 profile 的 `cordis.patch.yml` 当成自己设置存储的导出文件重写,手写行下次重启即消失。若仍显示未生效,检查该 profile `package.json` 的 `dsh.profile.bundles` 是否包含 `dsh-unity-mcp-bridge`——决定 bundle 是否加载的是它,不是 patch。
34
+
35
+ > 不要同时运行本桥接和原版 `@deepseek-ai/dsh-mcp-client` 连同一个 `serverName`:两者是不同模块实例,各自认为命名空间归自己,会发布同名工具。
36
+
37
+ ---
38
+
39
+ ## 配置 / Configuration
40
+
41
+ 原版客户端接受的字段(`serverName`、`transport`、stdio 的 `command`/`args`/`env`/`cwd`、streamable-http 的 `url`/`headers`、`toolCallTimeoutMs`、`failOnStartupError`、`reconnect.*`)全部照旧可用。此外:
42
+
43
+ | 字段 | 默认 | 说明 |
44
+ |---|---|---|
45
+ | `autoStart` | **`false`** | 默认休眠:不连接、不注册桥接工具。设 `true` 则开机即连(旧的常驻行为)。 |
46
+ | `activateToolName` | `unity_mcp_activate` | 常驻激活钩子的名字。 |
47
+ | `restoreDeactivates` | `true` | `unity_tools_restore` 同时断开连接,回到休眠;`false` 保持连接。 |
48
+ | `skillModelInvocable` | **`false`** | 命令目录技能不提供给模型,因此不会自动加载,Unity 能力不会自己开启。 |
49
+ | `skillUserInvocable` | `true` | 用户可调用:`/unity-mcp-tools` 是唯一的开启入口。 |
50
+ | `resyncAfterTools` | `[]` | 这些原始 MCP 工具名的**调用完成**会触发一次 `tools/list` 重同步与注册表替换。按需工作流设为 `['tool-set-enabled-state']`。触发在调用返回后约 200 ms,先让本次结果收尾。 |
51
+ | `resyncIntervalMs` | `0` | 周期性重同步(ms),`0` 关闭。开启后也能发现手工在 Unity 窗口里改的开关,代价是每轮重建工具注册。 |
52
+ | `restoreToolName` | `unity_tools_restore` | 原生恢复钩子的名字。 |
53
+ | `keepEnabledTools` | `[]` | 恢复时额外保留的原始工具名(除 `tool-set-enabled-state` 之外)。 |
54
+ | `registerCatalogSkill` | `true` | 是否注册随包的命令目录技能。 |
55
+ | `skillName` | `unity-mcp-tools` | 技能名 / 斜杠命令。 |
56
+ | `registerHelperSkills` | `true` | 是否注册四个辅助技能。 |
57
+ | `installSkillName` | `unity-mcp-install` | 安装 Unity 侧插件的技能名。 |
58
+ | `checkSkillName` | `unity-mcp-check` | 检查「插件已装 / 端口 20000 / DSH bundle 加载 / 工具集 / 命令目录 / 能连上 DSH」的技能名。 |
59
+ | `updateSkillName` | `unity-mcp-update` | 检查并(经用户同意后)更新官方 CLI、本地 `vendor/` 离线包与 Unity 插件的技能名。 |
60
+ | `updateToolsSkillName` | `unity-mcp-update-tools` | 刷新本地离线包并重生成命令目录与扩展索引的技能名。 |
61
+ | `helperSkillsModelInvocable` | `true` | 辅助技能与目录不同,会提供给模型。 |
62
+ | `helperSkillsUserInvocable` | `true` | 同时也是用户斜杠命令。 |
63
+
64
+ ---
65
+
66
+ ## 激活模型 / Activation model
67
+
68
+ 插件**开机即休眠**:只注册两个极小的钩子工具,不连接 Unity。不用 Unity 的会话只多约 **895 字符(~224 tokens)**。
69
+
70
+ ```
71
+ boot ──► DORMANT ──(/unity-mcp-tools ─► unity_mcp_activate)──► ACTIVE ──(unity_tools_restore)──► DORMANT
72
+ 2 hook tools bridged mcp__unity__* tools
73
+ ```
74
+
75
+ 每个**可见**命令的完整 JSON Schema 都会进入**之后每一次**模型请求;隐藏的命令贡献为零(1.6.0 起叫“可见性”,隐藏的工具仍可按名调用但不再列给模型)。开启是临时、可回收的成本——忘记第 4 步才会变成永久成本。恢复工具的存在就是为了让第 4 步不必枚举所有已注册名字(数量本身随版本变:0.9x 是 73 个,1.2.0 是 18 个,1.6.0 是 19 个;默认可见数都是 7)。
76
+
77
+ ---
78
+
79
+ ## 辅助技能做什么 / What the helper skills do
80
+
81
+ | 技能 | 内容 |
82
+ |---|---|
83
+ | `/unity-mcp-install` | 检查 `unity-mcp-cli` 是否在本机(缺则 `npm install -g unity-mcp-cli`),并核对 **CLI / Unity 插件 / MCP Server 三者 lockstep**(老 CLI 的 AI agent 列表会缺项,例如没有 `kilo-code`)。在工作区内按 `ProjectSettings/ProjectVersion.txt` 定位 Unity 工程;`Packages/manifest.json` 里已有 `com.ivanmurzak.unity.mcp` 就报告,否则 `unity-mcp-cli install-plugin <project> --with-server`(同时把 `GameDev-MCP-Server` 二进制放进 CLI 托管目录 `~/.ai-game-dev/server/<rid>/`),再重读 manifest 验证。GitHub 下载失败时走本机系统代理(Clash):端口从注册表读而不是猜,`NODE_USE_ENV_PROXY=1` 必需(Node 24 的全局 `fetch` 否则忽略 `HTTP_PROXY`),`NO_PROXY` 必须让 OpenUPM/npm 直连。最后手段:带断点续传的代理下载 + 对 release `SHA256SUMS` 校验 + `--server-source` 安装。仓库带 `vendor/` 离线包时优先离线:`tools/offline-package.mjs install` 写 Unity 官方支持的 `file:` 本地 tarball 依赖(自动备份 manifest),Server 来自缓存 zip,全新工程不联网即可装好。 |
84
+ | `/unity-mcp-check` | 链路体检:**① Unity 工程里是否装了插件**(`Packages/manifest.json` 依赖 + `Library/PackageCache/com.ivanmurzak.unity.mcp@*`);**② 端口是否为 20000**(Unity 侧读项目 `UserSettings/AI-Game-Developer-Config.json` 的 `host`,不是 20000 就 `bootstrap-local --url http://localhost:20000/` 改过来,先备份再改,改完必须让 Unity 重载;DSH 侧只看 profile 有没有把 url 覆盖成别的端口);**③ DSH 依赖与 bundle**(`package.json` 依赖 + `dsh.profile.bundles` + bundle patch 里的 `unity-mcp` 行,确认没有第二份同 `serverName` 的 stock `dsh-mcp-client`);**④ 工具集**(`configure --list` 确认只剩 `tool-set-enabled-state`;初始化必须分两条:先 `--disable-all-tools` 再 `--enable-tools tool-set-enabled-state`,合并会把唯一的开关一起关掉);**⑤ 命令目录版本自检**(`skills/unity-mcp-tools/SKILL.md` 标题行版本 vs 项目 `PackageCache` 里的包版本,不一致就重生成 + 重启 `dsh web`);**⑥ 连通性**(`unity_mcp_activate` 实测,`ECONNREFUSED` = 没人听、404/405 = 端点不对、401/403 = token 不对)。不做版本检查与升级(→ `/unity-mcp-update`),也不配 AI agent。 |
85
+ | `/unity-mcp-update` | 检查并更新三样东西:**官方 CLI**(npm `unity-mcp-cli`)、**本地离线包**(插件自带 `vendor/`:插件 tarball + `GameDev-MCP-Server` zip + `SHA256SUMS` + `manifest.json`)、**Unity 内插件**(`com.ivanmurzak.unity.mcp`,Server 跟随插件钉住的版本)。`tools/offline-package.mjs check --project <proj> --cli-version (unity-mcp-cli --version)` 一次比「上游最新 / `vendor/` / 项目已装 / 本机 CLI」四层,只读不改。**有更新先问用户**(列出目标版本、会动哪些文件、需要重启什么),用户明确同意才更新:CLI `npm install -g unity-mcp-cli` → 离线包 `fetch --plugin-version <latest>`(只动 `vendor/`,可单独执行,不动工程、不用重启)→ 工程 `install --project`(自动备份 manifest)+ Server 按插件钉住的版本 `install-plugin --with-server --server-source <vendor zip>` → 重生成命令目录并重启 `dsh web`。用户不同意就只给报告与可复制命令。 |
86
+ | `/unity-mcp-update-tools` | 只刷新「知识层」:把 `vendor/` 离线包升到上游最新(`offline-package.mjs fetch`,SHA256 校验 + 断点续传,Server 按新插件钉住的版本),再**依据新离线包**重生成 `skills/unity-mcp-tools/SKILL.md`、`reference/*.md` 与 `reference/extensions.md`。生成器直接读 tarball 解出的包目录(`-PackageRoot`,版本取自包内 `package.json`),不需要 Unity 工程。`extensions.md` 列出插件包 `extensions.catalog.json` 里的 10 个可选扩展及各自会带的命令(扩展命令本身仍不进索引,装完用 `unity-tool-list` 取实时清单)。只改 `<bridge>`,不碰工程内插件;最后提示重启 `dsh web`。 |
87
+
88
+ 四者都遵循官方安装流程 <https://ai-game.dev/engines/unity>。设 `registerHelperSkills: false` 可不发布它们。
89
+
90
+ ---
91
+
92
+ ## 离线包与更新检查(`vendor/`)/ Offline package cache
93
+
94
+ 上游 `com.ivanmurzak.unity.mcp` 已发 **180 个 release**(`0.8.3` 2025-06-23 → `1.5.0` 2026-10-24)。改动最大的是 **`1.0.0`(2026-10-15):RQL 取代数据类工具**——两条 `feat(rql)!` breaking 把 0.9x 的 73 个细粒度命令缩成 18 个(`rql-query` / `rql-mutate` / `rql-schema`),命令目录必须跨这个版本重生成。其余大改造:`0.81.0`(MCP Server 拆成共享的 `GameDev-MCP-Server`,从此独立编号)、`0.84.0`/`0.85.0`(鉴权重做:`ConnectionConfig.Token` 迁移、`cloudToken` 移除)、`1.1.0`(扩展包独立发布,现为 `2.0.x`)、`1.3.0`(`script-execute` 换 Code-Exec、CLI editor sessions、McpPlugin 8.11.0 工具超时)、`1.5.0`(独立 CLI 与 App skills)。
95
+
96
+ `vendor/` 缓存可安装产物,让新 Unity 工程不碰 GitHub 也能装(明细见 [vendor/README.md](../vendor/README.md)):插件 tarball `com.ivanmurzak.unity.mcp-1.6.0.tgz`(960,306 B)与 `gamedev-mcp-server-win-x64-9.3.0.zip`(44,088,479 B,对 release `SHA256SUMS` 校验)。**lockstep 是读出来的,不是猜的**:`tools/offline-package.mjs` 从 tarball 里取 `McpServerManager.ServerVersion`(插件 `1.6.0` 钉 Server `9.3.0`),CLI 与插件同号。
97
+
98
+ 日常的「有没有新版本 / 要不要升级」走 `/unity-mcp-update`:先只读跑下面的 `check`(四层:上游最新 / `vendor/` / 项目已装 / 本机 CLI),有更新先问用户,同意后才 `fetch` 刷新本地离线包、再 `install` 进工程。
99
+
100
+ ```powershell
101
+ # 四层比对:上游最新 / vendor 缓存 / 项目已装 / 本机 CLI
102
+ node "<plugin>\tools\offline-package.mjs" check --project <unity-project> --cli-version (unity-mcp-cli --version)
103
+
104
+ # 刷新:优先代理(GitHub release 资产是最不稳的一条),断点续传 + SHA256 校验
105
+ $env:HTTPS_PROXY = 'http://127.0.0.1:7897'; $env:NODE_USE_ENV_PROXY = '1'
106
+ node "<plugin>\tools\offline-package.mjs" fetch
107
+
108
+ # 装进新的 Unity 工程
109
+ node "<plugin>\tools\offline-package.mjs" install --project <unity-project>
110
+ unity-mcp-cli install-plugin <unity-project> --with-server --server-version 9.3.0 `
111
+ --server-source "<plugin>\vendor\gamedev-mcp-server-win-x64-9.3.0.zip"
112
+ ```
113
+
114
+ `install-plugin` **没有** `--plugin-source`;离线路径是 Unity 官方支持的 `file:` 本地 tarball 依赖。CLI 不会覆盖 `file:` / `git+` / `http:` 依赖(`dist/utils/manifest.js` 的 `nonSemverPrefixes`),所以之后重跑 `install-plugin` 也安全。
115
+
116
+ ---
117
+
118
+ ## 重新生成命令目录 / Regenerating the catalog
119
+
120
+ `tools/generate-unity-mcp-catalog.ps1` 扫描插件包源码,重写 `skills/unity-mcp-tools/SKILL.md`、`skills/unity-mcp-tools/reference/<分类>.md` 与 `reference/extensions.md`(分类取自插件自己的 `[AiTool(Title = ...)]` 属性;扩展清单取自包内 `extensions.catalog.json`)。升级插件后重跑,再重启 `dsh web`。
121
+
122
+ ```powershell
123
+ # 从 Unity 工程里已解析的包生成
124
+ powershell -NoProfile -ExecutionPolicy Bypass -File tools/generate-unity-mcp-catalog.ps1 -ProjectRoot <your-unity-project>
125
+
126
+ # 或直接从 vendor 离线包生成(不需要 Unity 工程;版本取自包内 package.json)
127
+ tar -xzf vendor/com.ivanmurzak.unity.mcp-<ver>.tgz -C <临时目录>
128
+ powershell -NoProfile -ExecutionPolicy Bypass -File tools/generate-unity-mcp-catalog.ps1 -PackageRoot <临时目录>/package
129
+ ```
130
+
131
+ 插件 1.2.0 不再把工具描述写成字符串字面量,而是常量引用(如 `[Description(RqlGuide.QueryDescription)]`),`RqlGuide` 还会把字面量与其他常量拼接。生成器会求值这些常量,RQL 语言手册因此能落到 `reference/rql.md`:`-BodyTools`(默认 `rql-*`)决定哪些命令带上插件自己的 `[AiToolBody]`/`[AiSkillBody]` 正文,于是机械类命令保持一行,语言类工具带完整指南。脚本必须存为 **带 BOM 的 UTF-8**——Windows PowerShell 5.1 会把无 BOM 的 UTF-8 当 ANSI,中文会变成解析错误。扩展是独立 UPM 包,生成器只扫基础包,所以扩展命令不进索引,`extensions.md` 只回答「可选哪些扩展 + 各带哪些命令」。
132
+
133
+ ---
134
+
135
+ ## 卸载 / Uninstall
136
+
137
+ ```powershell
138
+ dsh plugin --profile <profile> remove dsh-unity-mcp-bridge
139
+ ```
140
+
141
+ `unity-mcp` 行随 bundle 一起消失。只有曾在本 profile 的 `cordis.patch.yml` 里加过覆盖行时才需要删掉它。本包不修改自身以外的文件,所以回滚就是移除。
142
+
143
+ ---
144
+
145
+ ## 出处与许可 / Provenance and license
146
+
147
+ MIT。`lib/index.js` 派生自 `@deepseek-ai/dsh-mcp-client` v0.1.5-rc.2(MIT, Copyright (c) 2026 DeepSeek,见 [LICENSE](../LICENSE))。文件头列明改动:插件改名、`resyncAfterTools`/`resyncIntervalMs`、同步完成回报、恢复钩子、运行时命令目录技能。MIT 允许这样做,上游版权声明保留。
148
+
149
+ ---
150
+
151
+ ## 自测 / Self-test
152
+
153
+ `tools/selftest.mjs` 用一个最小假宿主上下文驱动真实插件连一个活的 Unity MCP 服务端,不需要重启 DSH。需要先装好包依赖(包内 `pnpm install`,或从已有依赖的 profile 里跑),端点从 `UNITY_MCP_URL` 读,仓库里不存项目 token。
154
+
155
+ ```powershell
156
+ $env:UNITY_MCP_URL = 'http://localhost:24009/p/<your-token>'
157
+ node tools/selftest.mjs
158
+ ```
159
+
160
+ 依次断言:模块导出;`Config` 接受全部新字段且默认值与上游兼容;`apply()` 连接并注册桥接工具与原生钩子;命令目录技能以正确的 `resourceBase` 注册且正文含工作流;**调用桥接管理工具会让桥接自行重同步**(新开启的工具出现在注册表里);恢复钩子关闭 keep 集之外的一切。
161
+
162
+ 参考环境上的实测输出:
163
+
164
+ ```
165
+ 3) apply() 启动…
166
+ [info] unity-mcp-bridge: catalog skill "unity-mcp-tools" registered
167
+ 桥接工具: mcp__unityprobe__tool-set-enabled-state
168
+ 原生工具: unity_tools_restore
169
+ 技能正文包含工作流与恢复指令: true
170
+ 4) 通过桥接工具开启 gameobject-find …
171
+ [info] unity-mcp-bridge(unityprobe): tool tool-set-enabled-state returned, re-syncing tool list
172
+ >>> 自动重同步是否生效: 是 ✓
173
+ 5) 调用恢复工具 keep=[unity-tool-list] …
174
+ 返回: Disabled 1 Unity-MCP tool(s); kept enabled: tool-set-enabled-state, unity-tool-list.
175
+ 恢复后桥接工具: mcp__unityprobe__tool-set-enabled-state
176
+ ```
177
+
178
+ ---
179
+
180
+ ## 验证状态 / Status
181
+
182
+ - **已对活服务端验证**:模块加载、`Config` 默认值、`apply()` 注册(桥接工具 + 原生钩子)、运行时技能注册与 `resourceBase`、管理工具调用后的自驱动重同步、恢复钩子的「关闭除 keep 之外全部」行为。见 `tools/selftest.mjs`。
183
+ - **未在此验证**:通过 `dsh plugin --profile web add` 的安装与完整 `dsh web` 启动挂载——那需要 profile 安装与一次 DSH 重启。