unity-mcp-cli 0.84.3 → 0.85.1
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.
- package/README.md +62 -11
- package/dist/commands/install-plugin.js +13 -5
- package/dist/commands/install-plugin.js.map +1 -1
- package/dist/commands/setup-mcp.js +4 -1
- package/dist/commands/setup-mcp.js.map +1 -1
- package/dist/lib/setup-mcp.d.ts +14 -8
- package/dist/lib/setup-mcp.js +59 -139
- package/dist/lib/setup-mcp.js.map +1 -1
- package/dist/lib/types.d.ts +11 -1
- package/dist/utils/agents.d.ts +6 -32
- package/dist/utils/agents.js +26 -563
- package/dist/utils/agents.js.map +1 -1
- package/dist/utils/cloud-login.d.ts +18 -3
- package/dist/utils/cloud-login.js +20 -15
- package/dist/utils/cloud-login.js.map +1 -1
- package/dist/utils/enroll.d.ts +15 -100
- package/dist/utils/enroll.js +14 -247
- package/dist/utils/enroll.js.map +1 -1
- package/dist/utils/machine-credentials.d.ts +7 -62
- package/dist/utils/machine-credentials.js +6 -109
- package/dist/utils/machine-credentials.js.map +1 -1
- package/dist/utils/port.d.ts +10 -17
- package/dist/utils/port.js +14 -73
- package/dist/utils/port.js.map +1 -1
- package/dist/utils/project-marker.d.ts +7 -24
- package/dist/utils/project-marker.js +6 -43
- package/dist/utils/project-marker.js.map +1 -1
- package/dist/utils/server-version.d.ts +1 -1
- package/dist/utils/server-version.js +1 -1
- package/package.json +2 -1
- package/dist/utils/auth.d.ts +0 -28
- package/dist/utils/auth.js +0 -111
- package/dist/utils/auth.js.map +0 -1
package/README.md
CHANGED
|
@@ -66,8 +66,8 @@ unity-mcp-cli create-project ./MyUnityProject # │ codex
|
|
|
66
66
|
# 2. Install "AI Game Developer" in Unity project # │ gemini │
|
|
67
67
|
unity-mcp-cli install-plugin ./MyUnityProject # │ github-copilot-cli │
|
|
68
68
|
# │ kilo-code │
|
|
69
|
-
# 3.
|
|
70
|
-
unity-mcp-cli login
|
|
69
|
+
# 3. Sign in to ai-game.dev (OAuth device flow) # │ open-code │
|
|
70
|
+
unity-mcp-cli login # │ rider-junie │
|
|
71
71
|
# │ unity-ai │
|
|
72
72
|
# 4. Open Unity project (auto-connects and generates skills) │ vs-copilot │
|
|
73
73
|
unity-mcp-cli open ./MyUnityProject # │ vscode-copilot │
|
|
@@ -95,6 +95,7 @@ npx unity-mcp-cli install-plugin /path/to/unity/project
|
|
|
95
95
|
- [`create-project`](#create-project)
|
|
96
96
|
- [`install-plugin`](#install-plugin)
|
|
97
97
|
- [`install-unity`](#install-unity)
|
|
98
|
+
- [`login`](#login)
|
|
98
99
|
- [`open`](#open)
|
|
99
100
|
- [`close`](#close)
|
|
100
101
|
- [`run-tool`](#run-tool)
|
|
@@ -182,16 +183,22 @@ unity-mcp-cli create-project ./MyGame --unity 2022.3.62f1
|
|
|
182
183
|
|
|
183
184
|
## `install-plugin`
|
|
184
185
|
|
|
185
|
-
Install the Unity-MCP plugin into a Unity project's `Packages/manifest.json`.
|
|
186
|
+
Install the Unity-MCP plugin into a Unity project's `Packages/manifest.json`. Optionally download the RID-matched MCP server binary and redeem a team enrollment code in the same run.
|
|
186
187
|
|
|
187
188
|
```bash
|
|
188
|
-
|
|
189
|
+
# Run from inside the Unity project folder — the path is optional
|
|
190
|
+
cd ./MyGame && unity-mcp-cli install-plugin
|
|
189
191
|
```
|
|
190
192
|
|
|
191
193
|
| Option | Required | Description |
|
|
192
194
|
|---|---|---|
|
|
193
|
-
| `[path]` |
|
|
195
|
+
| `[path]` | No | Path to the Unity project (positional or `--path`). Defaults to the current directory; the resolved directory is verified to be a real Unity project (`Packages/manifest.json` marker) and, on a miss, the error lists exactly what was checked. |
|
|
194
196
|
| `--plugin-version <version>` | No | Plugin version to install (defaults to latest from [OpenUPM](https://openupm.com/packages/com.ivanmurzak.unity.mcp/)) |
|
|
197
|
+
| `--with-server` | No | Also download the RID-matched [GameDev-MCP-Server](https://github.com/IvanMurzak/GameDev-MCP-Server) binary into the CLI-managed directory |
|
|
198
|
+
| `--server-version <version>` | No | Server version to download with `--with-server` (default: the CLI's pinned server version) |
|
|
199
|
+
| `--server-source <path-or-url>` | No | Offline/CI override — install the server from a local zip path or URL (skips checksum verification) |
|
|
200
|
+
| `--enroll <code>` | No | Redeem an enrollment code for a plugin credential (planted in the shared machine store and pinned to this project) |
|
|
201
|
+
| `--enroll-stdin` | No | Read the enrollment code from stdin instead of argv (keeps it out of shell history) |
|
|
195
202
|
|
|
196
203
|
This command:
|
|
197
204
|
1. Adds the **OpenUPM scoped registry** with all required scopes
|
|
@@ -204,6 +211,12 @@ This command:
|
|
|
204
211
|
unity-mcp-cli install-plugin ./MyGame --plugin-version 0.51.6
|
|
205
212
|
```
|
|
206
213
|
|
|
214
|
+
**Example — redeem a team enrollment code (path defaults to cwd):**
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
cd ./MyGame && unity-mcp-cli install-plugin --enroll <code>
|
|
218
|
+
```
|
|
219
|
+
|
|
207
220
|
> After running this command, open the project in Unity Editor to complete the package installation.
|
|
208
221
|
|
|
209
222
|

|
|
@@ -231,6 +244,35 @@ unity-mcp-cli install-unity --path ./MyGame
|
|
|
231
244
|
|
|
232
245
|

|
|
233
246
|
|
|
247
|
+
## `login`
|
|
248
|
+
|
|
249
|
+
Sign in to **ai-game.dev** and store the credential in the shared machine credential store (`~/.ai-game-dev/credentials.json`). Runs the browser-based **OAuth 2.1 device flow** — there is no personal access token to create or paste. The stored credential is the single source of truth for cloud authentication (consumed by `open`, `run-tool`, and the Unity Editor plugin).
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
unity-mcp-cli login
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
| Option | Required | Description |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `--project <path>` | No | Store the credential in a project-local store (`<path>/.ai-game-dev/`) instead of the shared machine store |
|
|
258
|
+
| `--force` | No | Re-authenticate even if a credential already exists |
|
|
259
|
+
|
|
260
|
+
The command prints a short user code and a verification URL, opens your browser, and polls until you approve the sign-in. If a credential already exists it exits early with *"Already signed in"* — pass `--force` to replace it.
|
|
261
|
+
|
|
262
|
+
**Example — sign in (shared machine store):**
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
unity-mcp-cli login
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Example — store the credential next to a specific project:**
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
unity-mcp-cli login --project ./MyGame
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+

|
|
275
|
+
|
|
234
276
|
## `open`
|
|
235
277
|
|
|
236
278
|
Open a Unity project in the Unity Editor. By default, sets MCP connection environment variables if connection options are provided. Use `--no-connect` to open without MCP connection.
|
|
@@ -249,10 +291,10 @@ cd ./MyGame && unity-mcp-cli open
|
|
|
249
291
|
| `--unity <version>` | — | No | Specific Unity Editor version to use (defaults to version from project settings, falls back to highest installed) |
|
|
250
292
|
| `--editor-path <path>` | — | No | Explicit path to the Unity Editor executable. Skips Unity Hub discovery, useful for custom install locations. |
|
|
251
293
|
| `--no-connect` | — | No | Open without MCP connection environment variables |
|
|
252
|
-
| `--url <url>` | `
|
|
294
|
+
| `--url <url>` | `UNITY_MCP_CLOUD_URL` | No | MCP server URL to connect to (the CLI still exports the legacy alias `UNITY_MCP_HOST`, which the plugin also accepts) |
|
|
253
295
|
| `--keep-connected` | `UNITY_MCP_KEEP_CONNECTED` | No | Force keep the connection alive |
|
|
254
296
|
| `--token <token>` | `UNITY_MCP_TOKEN` | No | Authentication token |
|
|
255
|
-
| `--auth <option>` | `UNITY_MCP_AUTH_OPTION` | No | Auth mode: `none` or `
|
|
297
|
+
| `--auth <option>` | `UNITY_MCP_AUTH_OPTION` | No | Auth mode: `none`, `oauth`, or `token` |
|
|
256
298
|
| `--tools <names>` | `UNITY_MCP_TOOLS` | No | Comma-separated list of tools to enable |
|
|
257
299
|
| `--transport <method>` | `UNITY_MCP_TRANSPORT` | No | Transport method: `streamableHttp` or `stdio` |
|
|
258
300
|
| `--start-server <value>` | `UNITY_MCP_START_SERVER` | No | Set to `true` or `false` to control MCP server auto-start |
|
|
@@ -292,7 +334,7 @@ unity-mcp-cli open ./MyGame --no-connect
|
|
|
292
334
|
unity-mcp-cli open ./MyGame \
|
|
293
335
|
--url http://my-server:8080 \
|
|
294
336
|
--token my-secret-token \
|
|
295
|
-
--auth
|
|
337
|
+
--auth token \
|
|
296
338
|
--tools gameobject-create,gameobject-find
|
|
297
339
|
```
|
|
298
340
|
|
|
@@ -428,6 +470,8 @@ unity-mcp-cli wait-for-ready --url http://localhost:8080 --timeout 30000
|
|
|
428
470
|
|
|
429
471
|
Write MCP config files for AI agents, enabling headless/CI setup without the Unity Editor UI. Supports all 14 agents (Claude Code, Cursor, Gemini, Codex, etc.).
|
|
430
472
|
|
|
473
|
+
By default the written config is **credential-free** (the client authenticates with your native OAuth sign-in from [`login`](#login)) and **pinned** to this project via a per-project URL (`https://ai-game.dev/mcp/p/<pin>` for http transport, or a `project=<pin>` argument for stdio). Pass `--no-pin` for the shared, unpinned endpoint, or `--token` to opt into writing a static credential (PAT) into the config. This output matches the Unity Editor's **Configure MCP** button byte-for-byte.
|
|
474
|
+
|
|
431
475
|
```bash
|
|
432
476
|
unity-mcp-cli setup-mcp claude-code ./MyGame
|
|
433
477
|
```
|
|
@@ -438,7 +482,8 @@ unity-mcp-cli setup-mcp claude-code ./MyGame
|
|
|
438
482
|
| `[path]` | No | Unity project path (defaults to cwd) |
|
|
439
483
|
| `--transport <transport>` | No | Transport method: `stdio` or `http` (default: `http`) |
|
|
440
484
|
| `--url <url>` | No | Server URL override (for http transport) |
|
|
441
|
-
| `--token <token>` | No |
|
|
485
|
+
| `--token <token>` | No | Explicit PAT opt-in — writes a static credential into the config (default: credential-free, native OAuth) |
|
|
486
|
+
| `--no-pin` | No | Write an unpinned URL / omit the `project=` argument (default: pin to this project via `/mcp/p/<pin>`) |
|
|
442
487
|
| `--list` | No | List all available agent IDs |
|
|
443
488
|
|
|
444
489
|
**Example — list all supported agents:**
|
|
@@ -453,6 +498,12 @@ unity-mcp-cli setup-mcp --list
|
|
|
453
498
|
unity-mcp-cli setup-mcp cursor ./MyGame --transport stdio
|
|
454
499
|
```
|
|
455
500
|
|
|
501
|
+
**Example — write an unpinned config (shared `/mcp` endpoint):**
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
unity-mcp-cli setup-mcp claude-code ./MyGame --no-pin
|
|
505
|
+
```
|
|
506
|
+
|
|
456
507
|

|
|
457
508
|
|
|
458
509
|
## `setup-skills`
|
|
@@ -568,8 +619,8 @@ unity-mcp-cli install-plugin ./MyAIGame
|
|
|
568
619
|
# 3. Enable all MCP tools
|
|
569
620
|
unity-mcp-cli configure ./MyAIGame --enable-all-tools
|
|
570
621
|
|
|
571
|
-
# 4.
|
|
572
|
-
unity-mcp-cli login
|
|
622
|
+
# 4. Sign in to ai-game.dev (browser OAuth; credential saved to ~/.ai-game-dev)
|
|
623
|
+
unity-mcp-cli login
|
|
573
624
|
|
|
574
625
|
# 5. Open the project (auto-connects and generates skills for claude-code)
|
|
575
626
|
unity-mcp-cli open ./MyAIGame
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
|
-
import * as path from 'path';
|
|
4
3
|
import * as ui from '../utils/ui.js';
|
|
5
4
|
import { verbose } from '../utils/ui.js';
|
|
6
5
|
import { installPlugin } from '../lib/install-plugin.js';
|
|
@@ -8,6 +7,7 @@ import { downloadServerBinary } from '../utils/managed-server.js';
|
|
|
8
7
|
import { DEFAULT_SERVER_VERSION } from '../utils/server-version.js';
|
|
9
8
|
import { resolveEnrollCode, runEnroll, EnrollmentError } from '../utils/enroll.js';
|
|
10
9
|
import { MachineCredentialStore } from '../utils/machine-credentials.js';
|
|
10
|
+
import { resolveInstallTarget, unityAdapter } from '@baizor/gamedev-cli-core';
|
|
11
11
|
export const installPluginCommand = new Command('install-plugin')
|
|
12
12
|
.description('Install Unity-MCP plugin into a Unity project (optionally download the server + enroll)')
|
|
13
13
|
.argument('[path]', 'Path to the Unity project')
|
|
@@ -19,12 +19,19 @@ export const installPluginCommand = new Command('install-plugin')
|
|
|
19
19
|
.option('--enroll <code>', 'Redeem an enrollment code for a plugin credential (planted in the shared machine store)')
|
|
20
20
|
.option('--enroll-stdin', 'Read the enrollment code from stdin (never argv/shell history)')
|
|
21
21
|
.action(async (positionalPath, options) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// T5/B1: path is OPTIONAL — resolve `path? → --path? → cwd`, then verify the directory is a real
|
|
23
|
+
// Unity project (marker probe for `Packages/manifest.json`). On a miss the error lists exactly
|
|
24
|
+
// what was checked, so `install-plugin` "just works" from a project folder with no path.
|
|
25
|
+
const target = resolveInstallTarget({
|
|
26
|
+
adapter: unityAdapter,
|
|
27
|
+
positional: positionalPath,
|
|
28
|
+
path: options.path,
|
|
29
|
+
});
|
|
30
|
+
if (target.kind === 'failure') {
|
|
31
|
+
ui.error(target.error.message);
|
|
25
32
|
process.exit(1);
|
|
26
33
|
}
|
|
27
|
-
const projectPath =
|
|
34
|
+
const projectPath = target.projectRoot;
|
|
28
35
|
// ── Phase 1: install the plugin into the Unity project's manifest ────────
|
|
29
36
|
// Wire the library's progress events back into the CLI's chalk-
|
|
30
37
|
// styled ui so the terminal experience stays identical.
|
|
@@ -106,6 +113,7 @@ export const installPluginCommand = new Command('install-plugin')
|
|
|
106
113
|
const enrolled = await runEnroll({
|
|
107
114
|
code,
|
|
108
115
|
projectPath,
|
|
116
|
+
adapter: unityAdapter,
|
|
109
117
|
store: new MachineCredentialStore(),
|
|
110
118
|
});
|
|
111
119
|
enrollSpinner.success('Enrollment complete');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-plugin.js","sourceRoot":"","sources":["../../src/commands/install-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"install-plugin.js","sourceRoot":"","sources":["../../src/commands/install-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,8 @@ export const setupMcpCommand = new Command('setup-mcp')
|
|
|
12
12
|
.argument('[path]', 'Unity project path (defaults to cwd)')
|
|
13
13
|
.option('--transport <transport>', 'Transport method: stdio or http (default: http)', 'http')
|
|
14
14
|
.option('--url <url>', 'Server URL override (for http transport)')
|
|
15
|
-
.option('--token <token>', '
|
|
15
|
+
.option('--token <token>', 'Explicit PAT opt-in — writes a static credential into the config (default: credential-free, native OAuth)')
|
|
16
|
+
.option('--no-pin', 'Write an unpinned URL / omit the project= arg (default: pin to this project via /mcp/p/<pin>)')
|
|
16
17
|
.option('--list', 'List all available agent IDs')
|
|
17
18
|
.action(async (agentId, positionalPath, options) => {
|
|
18
19
|
if (options.list) {
|
|
@@ -43,6 +44,8 @@ export const setupMcpCommand = new Command('setup-mcp')
|
|
|
43
44
|
transport,
|
|
44
45
|
url: options.url,
|
|
45
46
|
token: options.token,
|
|
47
|
+
// commander sets `options.pin === false` when `--no-pin` was passed.
|
|
48
|
+
noPin: options.pin === false,
|
|
46
49
|
});
|
|
47
50
|
if (result.kind === 'failure') {
|
|
48
51
|
spinner.error('Failed to write config');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/commands/setup-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/commands/setup-mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/setup-mcp.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import type { SetupMcpOptions, SetupMcpResult } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Write MCP configuration for the given AI agent, so it can talk to
|
|
4
|
-
* Unity-MCP. Library-safe: no stdout noise, no process.exit, no throws
|
|
5
|
-
* past the public boundary.
|
|
3
|
+
* Write MCP configuration for the given AI agent, so it can talk to the Unity MCP hub.
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* This is now a thin adapter over `@baizor/gamedev-cli-core`'s `setupMcp` (auth-fixes T4/M7/M8):
|
|
6
|
+
* - the http URL is **pinned by default** to `<base>/mcp/p/<pin-v2>` and the stdio config carries a
|
|
7
|
+
* `project=<pin>` arg, so the config routes strictly to this project's engine instance even when
|
|
8
|
+
* the account has several (`--no-pin` is the escape hatch);
|
|
9
|
+
* - the config is **credential-free by default** — a static `Authorization: Bearer` header (http)
|
|
10
|
+
* or `token=` arg (stdio) is written ONLY on an explicit `--token` PAT opt-in, so an OAuth-capable
|
|
11
|
+
* client authorizes natively (RFC 9728) instead of being suppressed by a static header;
|
|
12
|
+
* - the config bytes are written by cli-core's golden-vector-gated JSON/TOML writers, so `setup-mcp`
|
|
13
|
+
* output matches the Unity Editor's Configure output byte-for-byte.
|
|
14
|
+
*
|
|
15
|
+
* Library-safe: no stdout noise, no `process.exit`, no throws past the public boundary. Narrow the
|
|
16
|
+
* returned `SetupMcpResult` with `result.kind === 'success'` / `=== 'failure'`.
|
|
10
17
|
*/
|
|
11
18
|
export declare function setupMcp(opts: SetupMcpOptions): Promise<SetupMcpResult>;
|
|
12
19
|
/**
|
|
13
|
-
* List every agent id known to
|
|
14
|
-
* consumer UIs that want to render a picker.
|
|
20
|
+
* List every agent id known to `setupMcp`. Useful for consumer UIs that want to render a picker.
|
|
15
21
|
*/
|
|
16
22
|
export declare function listAgentIds(): string[];
|
package/dist/lib/setup-mcp.js
CHANGED
|
@@ -1,180 +1,100 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import {
|
|
4
|
-
import { readConfig, resolveConnectionFromConfig } from '../utils/config.js';
|
|
5
|
-
import { getAgentById, getAgentIds, resolveServerBinaryPath, writeJsonAgentConfig, writeTomlAgentConfig, MCP_SERVER_NAME, } from '../utils/agents.js';
|
|
6
|
-
import { emitProgress } from './progress.js';
|
|
3
|
+
import { setupMcp as coreSetupMcp, unityAdapter, getAgentIds, } from '@baizor/gamedev-cli-core';
|
|
7
4
|
import { requireExistingPath } from './validation.js';
|
|
8
5
|
function isValidTransport(t) {
|
|
9
6
|
return t === 'stdio' || t === 'http';
|
|
10
7
|
}
|
|
11
8
|
/**
|
|
12
|
-
*
|
|
13
|
-
* project-directory-derived deterministic port on any parse failure.
|
|
14
|
-
*/
|
|
15
|
-
function portFromHost(host, projectPath) {
|
|
16
|
-
if (!host)
|
|
17
|
-
return generatePortFromDirectory(projectPath);
|
|
18
|
-
try {
|
|
19
|
-
return parseInt(new URL(host).port, 10) || generatePortFromDirectory(projectPath);
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return generatePortFromDirectory(projectPath);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* True when `configPath` resolves to a location at or under `projectRoot`
|
|
27
|
-
* (separator- and case-insensitive) — i.e. a VCS-visible project-scoped file.
|
|
28
|
-
* Mirrors the b6 configurator's `IsProjectScopedPath`, used to decide whether a
|
|
29
|
-
* written access token would land in a committable file (design 03 Flow C).
|
|
30
|
-
*/
|
|
31
|
-
function isProjectScoped(configPath, projectRoot) {
|
|
32
|
-
const norm = (p) => path.resolve(p).replace(/\\/g, '/').replace(/\/+$/, '').toLowerCase();
|
|
33
|
-
const root = norm(projectRoot);
|
|
34
|
-
const target = norm(configPath);
|
|
35
|
-
return target === root || target.startsWith(root + '/');
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Write MCP configuration for the given AI agent, so it can talk to
|
|
39
|
-
* Unity-MCP. Library-safe: no stdout noise, no process.exit, no throws
|
|
40
|
-
* past the public boundary.
|
|
9
|
+
* Write MCP configuration for the given AI agent, so it can talk to the Unity MCP hub.
|
|
41
10
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
11
|
+
* This is now a thin adapter over `@baizor/gamedev-cli-core`'s `setupMcp` (auth-fixes T4/M7/M8):
|
|
12
|
+
* - the http URL is **pinned by default** to `<base>/mcp/p/<pin-v2>` and the stdio config carries a
|
|
13
|
+
* `project=<pin>` arg, so the config routes strictly to this project's engine instance even when
|
|
14
|
+
* the account has several (`--no-pin` is the escape hatch);
|
|
15
|
+
* - the config is **credential-free by default** — a static `Authorization: Bearer` header (http)
|
|
16
|
+
* or `token=` arg (stdio) is written ONLY on an explicit `--token` PAT opt-in, so an OAuth-capable
|
|
17
|
+
* client authorizes natively (RFC 9728) instead of being suppressed by a static header;
|
|
18
|
+
* - the config bytes are written by cli-core's golden-vector-gated JSON/TOML writers, so `setup-mcp`
|
|
19
|
+
* output matches the Unity Editor's Configure output byte-for-byte.
|
|
20
|
+
*
|
|
21
|
+
* Library-safe: no stdout noise, no `process.exit`, no throws past the public boundary. Narrow the
|
|
22
|
+
* returned `SetupMcpResult` with `result.kind === 'success'` / `=== 'failure'`.
|
|
45
23
|
*/
|
|
46
24
|
export async function setupMcp(opts) {
|
|
47
|
-
|
|
48
|
-
|
|
25
|
+
// This wrapper never accumulates its own warnings/next-steps — cli-core owns the warning channel
|
|
26
|
+
// (`result.warnings`), and `nextSteps` is always empty here. Both fields are written as literals
|
|
27
|
+
// on each return to satisfy the `SetupMcpResult` shape.
|
|
49
28
|
try {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
29
|
+
// Resolve project path. If the caller supplied one explicitly it must exist; otherwise cli-core
|
|
30
|
+
// falls back to cwd (matching the CLI behaviour and closing the "path required" half of B1).
|
|
31
|
+
let projectPath;
|
|
32
|
+
if (opts.unityProjectPath) {
|
|
33
|
+
const validated = requireExistingPath(opts.unityProjectPath);
|
|
34
|
+
if (!validated.ok) {
|
|
35
|
+
return { kind: 'failure', success: false, warnings: [], nextSteps: [], error: validated.error };
|
|
36
|
+
}
|
|
37
|
+
projectPath = validated.projectPath;
|
|
58
38
|
}
|
|
59
|
-
const
|
|
60
|
-
if (!
|
|
39
|
+
const transport = opts.transport ?? 'http';
|
|
40
|
+
if (!isValidTransport(transport)) {
|
|
61
41
|
return {
|
|
62
42
|
kind: 'failure',
|
|
63
43
|
success: false,
|
|
64
|
-
warnings,
|
|
65
|
-
nextSteps,
|
|
66
|
-
error: new Error(`
|
|
44
|
+
warnings: [],
|
|
45
|
+
nextSteps: [],
|
|
46
|
+
error: new Error(`Invalid transport: "${transport}". Must be "stdio" or "http".`),
|
|
67
47
|
};
|
|
68
48
|
}
|
|
69
|
-
const
|
|
70
|
-
|
|
49
|
+
const result = coreSetupMcp({
|
|
50
|
+
adapter: unityAdapter,
|
|
51
|
+
agentId: opts.agentId,
|
|
52
|
+
transport,
|
|
53
|
+
projectPath,
|
|
54
|
+
url: opts.url,
|
|
55
|
+
token: opts.token,
|
|
56
|
+
noPin: opts.noPin === true,
|
|
57
|
+
});
|
|
58
|
+
if (result.kind === 'failure') {
|
|
71
59
|
return {
|
|
72
60
|
kind: 'failure',
|
|
73
61
|
success: false,
|
|
74
|
-
warnings,
|
|
75
|
-
nextSteps,
|
|
76
|
-
error:
|
|
62
|
+
warnings: result.warnings,
|
|
63
|
+
nextSteps: [],
|
|
64
|
+
error: result.error,
|
|
77
65
|
};
|
|
78
66
|
}
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
if (opts.unityProjectPath) {
|
|
83
|
-
const validated = requireExistingPath(opts.unityProjectPath);
|
|
84
|
-
if (!validated.ok) {
|
|
85
|
-
return { kind: 'failure', success: false, warnings, nextSteps, error: validated.error };
|
|
86
|
-
}
|
|
87
|
-
projectPath = validated.projectPath;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
projectPath = path.resolve(process.cwd());
|
|
91
|
-
}
|
|
92
|
-
emitProgress(opts.onProgress, {
|
|
93
|
-
phase: 'start',
|
|
94
|
-
message: `Configuring ${agent.name} (${transport}) for ${projectPath}`,
|
|
95
|
-
});
|
|
96
|
-
const config = readConfig(projectPath);
|
|
97
|
-
const fromConfig = config
|
|
98
|
-
? resolveConnectionFromConfig(config)
|
|
99
|
-
: { url: undefined, token: undefined };
|
|
100
|
-
const port = portFromHost(config?.host, projectPath);
|
|
101
|
-
const timeout = config?.timeoutMs ?? 10000;
|
|
102
|
-
const auth = config?.authOption ?? 'none';
|
|
103
|
-
// Explicit PAT opt-in (design 03 Flow C): a token the caller passed on the
|
|
104
|
-
// command line (`--token`). Only an explicit opt-in — never a token merely
|
|
105
|
-
// resolved from the project config — places a static credential in the file.
|
|
106
|
-
const patOptIn = typeof opts.token === 'string' && opts.token.length > 0;
|
|
107
|
-
const token = opts.token ?? fromConfig.token ?? '';
|
|
108
|
-
// b6 credential policy (design decision D11): the DEFAULT http config is
|
|
109
|
-
// credential-free. OAuth-capable clients perform native RFC 9728 OAuth
|
|
110
|
-
// against the URL (Flow A), so a static `Authorization: Bearer` header both
|
|
111
|
-
// FAILS (the hosted ai-game.dev/mcp endpoint 401s the token) AND suppresses
|
|
112
|
-
// the client's own OAuth handshake ("OAuth fallback is disabled when
|
|
113
|
-
// headers.Authorization is set"). A static header is written ONLY for an
|
|
114
|
-
// explicit PAT opt-in (Flow C) or a client that cannot do MCP OAuth
|
|
115
|
-
// (`supportsOAuth === false`) — never automatically for an OAuth-capable
|
|
116
|
-
// client, regardless of the server's `authRequired` setting.
|
|
117
|
-
const supportsOAuth = agent.supportsOAuth !== false;
|
|
118
|
-
const emitAuthHeader = token.length > 0 && (patOptIn || !supportsOAuth);
|
|
119
|
-
const serverPath = resolveServerBinaryPath(projectPath).replace(/\\/g, '/');
|
|
120
|
-
// Resolve URL for HTTP — explicit override, then config, then
|
|
121
|
-
// deterministic localhost fallback. Trailing slash stripped.
|
|
122
|
-
const serverUrl = (opts.url ?? fromConfig.url ?? `http://localhost:${port}`).replace(/\/$/, '');
|
|
123
|
-
const configPath = agent.getConfigPath(projectPath);
|
|
124
|
-
let props;
|
|
125
|
-
let removeKeys;
|
|
67
|
+
// Preserve the historical stdio-server-missing warning (cli-core does not emit it): the plugin
|
|
68
|
+
// downloads the server binary when Unity opens, so a stdio config written before that is valid
|
|
69
|
+
// but not yet runnable.
|
|
126
70
|
if (transport === 'stdio') {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
props = agent.getHttpProps(serverUrl, token, emitAuthHeader);
|
|
132
|
-
removeKeys = agent.httpRemoveKeys;
|
|
133
|
-
}
|
|
134
|
-
if (agent.configFormat === 'toml') {
|
|
135
|
-
writeTomlAgentConfig(configPath, agent.bodyPath, MCP_SERVER_NAME, props, removeKeys);
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
writeJsonAgentConfig(configPath, agent.bodyPath, MCP_SERVER_NAME, props, removeKeys);
|
|
139
|
-
}
|
|
140
|
-
emitProgress(opts.onProgress, {
|
|
141
|
-
phase: 'manifest-patched',
|
|
142
|
-
message: `Wrote ${configPath}`,
|
|
143
|
-
manifestPath: configPath,
|
|
144
|
-
});
|
|
145
|
-
// Flow C credential-placement rule (design 03): a static access token
|
|
146
|
-
// written into a project-scoped config file is VCS-visible. Warn so the
|
|
147
|
-
// user prefers an env-var / user-scope placement for the credential.
|
|
148
|
-
if (transport === 'http' && emitAuthHeader && isProjectScoped(configPath, projectPath)) {
|
|
149
|
-
warnings.push(`Wrote an access token into project-scoped config file "${configPath}" — it is under the project root and may be committed to version control. Prefer an env-var or user-scope placement for the access token (design 03 Flow C).`);
|
|
150
|
-
}
|
|
151
|
-
if (transport === 'stdio' && !fs.existsSync(serverPath.replace(/\//g, path.sep))) {
|
|
152
|
-
warnings.push('Server binary not found. Open Unity with the MCP plugin to download it automatically.');
|
|
71
|
+
const serverPath = unityAdapter.serverBinaryPath(projectPath ?? path.resolve(process.cwd()));
|
|
72
|
+
if (!fs.existsSync(serverPath)) {
|
|
73
|
+
result.warnings.push('Server binary not found. Open Unity with the MCP plugin to download it automatically.');
|
|
74
|
+
}
|
|
153
75
|
}
|
|
154
|
-
emitProgress(opts.onProgress, { phase: 'done', message: `${agent.name} configured successfully.` });
|
|
155
76
|
return {
|
|
156
77
|
kind: 'success',
|
|
157
78
|
success: true,
|
|
158
|
-
agentId:
|
|
159
|
-
configPath,
|
|
160
|
-
transport,
|
|
161
|
-
warnings,
|
|
162
|
-
nextSteps,
|
|
79
|
+
agentId: result.agentId,
|
|
80
|
+
configPath: result.configPath,
|
|
81
|
+
transport: result.transport,
|
|
82
|
+
warnings: result.warnings,
|
|
83
|
+
nextSteps: [],
|
|
163
84
|
};
|
|
164
85
|
}
|
|
165
86
|
catch (err) {
|
|
166
87
|
return {
|
|
167
88
|
kind: 'failure',
|
|
168
89
|
success: false,
|
|
169
|
-
warnings,
|
|
170
|
-
nextSteps,
|
|
90
|
+
warnings: [],
|
|
91
|
+
nextSteps: [],
|
|
171
92
|
error: err instanceof Error ? err : new Error(String(err)),
|
|
172
93
|
};
|
|
173
94
|
}
|
|
174
95
|
}
|
|
175
96
|
/**
|
|
176
|
-
* List every agent id known to
|
|
177
|
-
* consumer UIs that want to render a picker.
|
|
97
|
+
* List every agent id known to `setupMcp`. Useful for consumer UIs that want to render a picker.
|
|
178
98
|
*/
|
|
179
99
|
export function listAgentIds() {
|
|
180
100
|
return getAgentIds();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/lib/setup-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/lib/setup-mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -201,8 +201,18 @@ export interface SetupMcpOptions {
|
|
|
201
201
|
transport?: McpTransport;
|
|
202
202
|
/** Explicit server URL override (for http transport). */
|
|
203
203
|
url?: string;
|
|
204
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Explicit PAT opt-in (`--token`). The ONLY input that writes a static credential into the config
|
|
206
|
+
* (auth-fixes M7); a credential is never emitted merely because the server requires auth.
|
|
207
|
+
*/
|
|
205
208
|
token?: string;
|
|
209
|
+
/**
|
|
210
|
+
* `--no-pin` escape hatch (auth-fixes T4/B4). By default the http URL is pinned to this project's
|
|
211
|
+
* routing segment (`<base>/mcp/p/<pin-v2>`) and the stdio config carries a `project=<pin>` arg, so
|
|
212
|
+
* the config routes strictly to this project's engine instance. Set `true` to write an unpinned URL
|
|
213
|
+
* / omit the `project=` arg.
|
|
214
|
+
*/
|
|
215
|
+
noPin?: boolean;
|
|
206
216
|
onProgress?: ProgressCallback;
|
|
207
217
|
}
|
|
208
218
|
export interface SetupMcpSuccess {
|
package/dist/utils/agents.d.ts
CHANGED
|
@@ -1,33 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
configFormat: 'json' | 'toml';
|
|
7
|
-
bodyPath: string;
|
|
8
|
-
/**
|
|
9
|
-
* Whether this agent can complete native MCP OAuth (RFC 9728) against the
|
|
10
|
-
* server URL on the default http path (design 03 Flow A / decision D11).
|
|
11
|
-
* `undefined`/`true` — the default across the registry, mirroring the shared
|
|
12
|
-
* b6 configurators — means the default config is credential-free: the client
|
|
13
|
-
* runs its own authorize flow, so injecting a static `Authorization` header
|
|
14
|
-
* would both fail (the hosted endpoint 401s the token) and suppress that
|
|
15
|
-
* flow. Set `false` only for a client that cannot do MCP OAuth; such a client
|
|
16
|
-
* still receives a header only via the explicit PAT fallback (Flow C).
|
|
17
|
-
*/
|
|
18
|
-
supportsOAuth?: boolean;
|
|
19
|
-
getConfigPath(projectPath: string): string;
|
|
20
|
-
getStdioProps(serverPath: string, port: number, timeout: number, auth: string, token: string): Record<string, unknown>;
|
|
21
|
-
getHttpProps(url: string, token: string, emitAuthHeader: boolean): Record<string, unknown>;
|
|
22
|
-
stdioRemoveKeys: string[];
|
|
23
|
-
httpRemoveKeys: string[];
|
|
24
|
-
}
|
|
25
|
-
declare const MCP_SERVER_NAME = "ai-game-developer";
|
|
26
|
-
export declare const agentRegistry: readonly AgentDefinition[];
|
|
27
|
-
export declare function getAgentById(id: string): AgentDefinition | undefined;
|
|
28
|
-
export declare function getAgentIds(): string[];
|
|
29
|
-
export declare function listAgentTable(heading: string, locationLabel: string, locationFn: (agent: AgentDefinition) => string): void;
|
|
30
|
-
export declare function resolveServerBinaryPath(projectPath: string): string;
|
|
31
|
-
export declare function writeJsonAgentConfig(configPath: string, bodyPath: string, serverName: string, props: Record<string, unknown>, removeKeys: string[]): void;
|
|
32
|
-
export declare function writeTomlAgentConfig(configPath: string, bodyPath: string, serverName: string, props: Record<string, unknown>, removeKeys: string[]): void;
|
|
1
|
+
import { agentRegistry, getAgentById, getAgentIds, type AgentDefinition } from '@baizor/gamedev-cli-core';
|
|
2
|
+
export { agentRegistry, getAgentById, getAgentIds };
|
|
3
|
+
export type { AgentDefinition };
|
|
4
|
+
/** The Unity MCP server-entry name written under an agent config's body path. */
|
|
5
|
+
declare const MCP_SERVER_NAME: string;
|
|
33
6
|
export { MCP_SERVER_NAME };
|
|
7
|
+
export declare function listAgentTable(heading: string, locationLabel: string, locationFn: (agent: AgentDefinition) => string): void;
|