godot-cli 0.1.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.
Files changed (110) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +101 -0
  3. package/bin/godot-cli.js +2 -0
  4. package/dist/cli.d.ts +11 -0
  5. package/dist/cli.js +17 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/close.d.ts +18 -0
  8. package/dist/commands/close.js +112 -0
  9. package/dist/commands/close.js.map +1 -0
  10. package/dist/commands/configure.d.ts +2 -0
  11. package/dist/commands/configure.js +92 -0
  12. package/dist/commands/configure.js.map +1 -0
  13. package/dist/commands/install-plugin.d.ts +2 -0
  14. package/dist/commands/install-plugin.js +35 -0
  15. package/dist/commands/install-plugin.js.map +1 -0
  16. package/dist/commands/open.d.ts +16 -0
  17. package/dist/commands/open.js +124 -0
  18. package/dist/commands/open.js.map +1 -0
  19. package/dist/commands/remove-plugin.d.ts +2 -0
  20. package/dist/commands/remove-plugin.js +31 -0
  21. package/dist/commands/remove-plugin.js.map +1 -0
  22. package/dist/commands/run-system-tool.d.ts +1 -0
  23. package/dist/commands/run-system-tool.js +13 -0
  24. package/dist/commands/run-system-tool.js.map +1 -0
  25. package/dist/commands/run-tool-builder.d.ts +25 -0
  26. package/dist/commands/run-tool-builder.js +119 -0
  27. package/dist/commands/run-tool-builder.js.map +1 -0
  28. package/dist/commands/run-tool.d.ts +1 -0
  29. package/dist/commands/run-tool.js +13 -0
  30. package/dist/commands/run-tool.js.map +1 -0
  31. package/dist/commands/setup-mcp.d.ts +2 -0
  32. package/dist/commands/setup-mcp.js +58 -0
  33. package/dist/commands/setup-mcp.js.map +1 -0
  34. package/dist/commands/status.d.ts +2 -0
  35. package/dist/commands/status.js +64 -0
  36. package/dist/commands/status.js.map +1 -0
  37. package/dist/commands/update.d.ts +2 -0
  38. package/dist/commands/update.js +75 -0
  39. package/dist/commands/update.js.map +1 -0
  40. package/dist/commands/wait-for-ready.d.ts +2 -0
  41. package/dist/commands/wait-for-ready.js +57 -0
  42. package/dist/commands/wait-for-ready.js.map +1 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.js +69 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/install-plugin.d.ts +22 -0
  47. package/dist/lib/install-plugin.js +118 -0
  48. package/dist/lib/install-plugin.js.map +1 -0
  49. package/dist/lib/open.d.ts +34 -0
  50. package/dist/lib/open.js +198 -0
  51. package/dist/lib/open.js.map +1 -0
  52. package/dist/lib/progress.d.ts +7 -0
  53. package/dist/lib/progress.js +16 -0
  54. package/dist/lib/progress.js.map +1 -0
  55. package/dist/lib/run-tool.d.ts +12 -0
  56. package/dist/lib/run-tool.js +192 -0
  57. package/dist/lib/run-tool.js.map +1 -0
  58. package/dist/lib/setup-mcp.d.ts +16 -0
  59. package/dist/lib/setup-mcp.js +118 -0
  60. package/dist/lib/setup-mcp.js.map +1 -0
  61. package/dist/lib/types.d.ts +210 -0
  62. package/dist/lib/types.js +8 -0
  63. package/dist/lib/types.js.map +1 -0
  64. package/dist/lib/validation.d.ts +30 -0
  65. package/dist/lib/validation.js +44 -0
  66. package/dist/lib/validation.js.map +1 -0
  67. package/dist/lib.d.ts +5 -0
  68. package/dist/lib.js +19 -0
  69. package/dist/lib.js.map +1 -0
  70. package/dist/utils/agents.d.ts +31 -0
  71. package/dist/utils/agents.js +188 -0
  72. package/dist/utils/agents.js.map +1 -0
  73. package/dist/utils/config.d.ts +40 -0
  74. package/dist/utils/config.js +97 -0
  75. package/dist/utils/config.js.map +1 -0
  76. package/dist/utils/connection.d.ts +57 -0
  77. package/dist/utils/connection.js +129 -0
  78. package/dist/utils/connection.js.map +1 -0
  79. package/dist/utils/godot-editor.d.ts +42 -0
  80. package/dist/utils/godot-editor.js +184 -0
  81. package/dist/utils/godot-editor.js.map +1 -0
  82. package/dist/utils/godot-process.d.ts +10 -0
  83. package/dist/utils/godot-process.js +93 -0
  84. package/dist/utils/godot-process.js.map +1 -0
  85. package/dist/utils/godot-shutdown.d.ts +16 -0
  86. package/dist/utils/godot-shutdown.js +67 -0
  87. package/dist/utils/godot-shutdown.js.map +1 -0
  88. package/dist/utils/input.d.ts +13 -0
  89. package/dist/utils/input.js +72 -0
  90. package/dist/utils/input.js.map +1 -0
  91. package/dist/utils/json-parse.d.ts +25 -0
  92. package/dist/utils/json-parse.js +83 -0
  93. package/dist/utils/json-parse.js.map +1 -0
  94. package/dist/utils/probe.d.ts +18 -0
  95. package/dist/utils/probe.js +61 -0
  96. package/dist/utils/probe.js.map +1 -0
  97. package/dist/utils/project-godot.d.ts +41 -0
  98. package/dist/utils/project-godot.js +126 -0
  99. package/dist/utils/project-godot.js.map +1 -0
  100. package/dist/utils/semver.d.ts +4 -0
  101. package/dist/utils/semver.js +25 -0
  102. package/dist/utils/semver.js.map +1 -0
  103. package/dist/utils/ui.d.ts +61 -0
  104. package/dist/utils/ui.js +238 -0
  105. package/dist/utils/ui.js.map +1 -0
  106. package/dist/utils/update-check.d.ts +19 -0
  107. package/dist/utils/update-check.js +92 -0
  108. package/dist/utils/update-check.js.map +1 -0
  109. package/docs/README.md +7 -0
  110. package/package.json +73 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to `godot-cli` are documented in this file.
4
+
5
+ ## 0.1.0
6
+
7
+ Initial release. A cross-platform CLI for Godot-MCP, mirroring `unity-mcp-cli`'s feature set and structure,
8
+ adapted for Godot.
9
+
10
+ - `open` — resolve the Godot editor binary (`GODOT_BIN`/`GODOT4_BIN` → PATH → per-OS common dirs) and
11
+ launch `--editor --path <project>` with the `GODOT_MCP_*` connection env vars.
12
+ - `run-tool` / `run-system-tool` — POST to `<url>/api/tools/<name>` and `<url>/api/system-tools/<name>`.
13
+ - `status` — detect a running Godot editor and probe MCP-server health.
14
+ - `wait-for-ready` — poll the server until it answers `ping`.
15
+ - `setup-mcp` — write an AI-agent MCP-client config (claude-code, claude-desktop, cursor, vscode, custom)
16
+ pointing at the Godot server's `<host>/mcp` URL.
17
+ - `configure` — list / enable / disable tools, prompts, and resources in the project-local
18
+ `.godot-mcp/features.json`.
19
+ - `close` — gracefully terminate the Godot editor for a project (`--force` to hard-kill).
20
+ - `install-plugin` / `remove-plugin` — enable/disable the `godot_mcp` addon in `project.godot`
21
+ `[editor_plugins]`.
22
+ - `update` — check npm for a newer version and install it.
23
+
24
+ `setup-skills` is intentionally not ported: Godot skills are generated addon-side by the McpPlugin engine,
25
+ and the Godot MCP server exposes no skill-generate HTTP endpoint.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # godot-cli
2
+
3
+ Cross-platform CLI for **Godot-MCP** — the [Godot](https://godotengine.org/) editor addon that bridges
4
+ LLMs (Claude, Cursor, Copilot, …) with the Godot editor via the
5
+ [Model Context Protocol](https://modelcontextprotocol.io/).
6
+
7
+ The CLI is the Godot analog of [`unity-mcp-cli`](https://www.npmjs.com/package/unity-mcp-cli): it resolves
8
+ and launches the Godot editor with the right `GODOT_MCP_*` connection environment variables, runs MCP and
9
+ system tools over the server's HTTP API, probes server health, writes AI-agent MCP-client config, and
10
+ enables/disables the `godot_mcp` addon in a project.
11
+
12
+ > **Licensed under Apache-2.0.**
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install -g godot-cli
18
+ # or run ad-hoc:
19
+ npx godot-cli <command>
20
+ ```
21
+
22
+ Requires Node `^20.19.0 || >=22.12.0`.
23
+
24
+ ## Commands
25
+
26
+ | Command | What it does |
27
+ | --- | --- |
28
+ | `open [path]` | Resolve the Godot editor binary and launch `--editor --path <project>` with `GODOT_MCP_*` connection env vars. |
29
+ | `run-tool <tool> [path]` | POST to `<url>/api/tools/<tool>` with JSON input. |
30
+ | `run-system-tool <tool> [path]` | POST to `<url>/api/system-tools/<tool>` (tools not exposed to MCP clients). |
31
+ | `status [path]` | Detect a running Godot editor for the project and probe MCP-server health. |
32
+ | `wait-for-ready [path]` | Poll the MCP server until it answers `ping`. |
33
+ | `setup-mcp <agent> [path]` | Write the agent's MCP-client config pointing at the Godot server's `<host>/mcp` URL. |
34
+ | `configure [path]` | List / enable / disable tools, prompts, and resources in the project-local `.godot-mcp/features.json`. |
35
+ | `close [path]` | Gracefully stop the Godot editor running for a project (`--force` to hard-kill). |
36
+ | `install-plugin [path]` | Enable the `godot_mcp` addon in `project.godot` `[editor_plugins]`. |
37
+ | `remove-plugin [path]` | Disable the `godot_mcp` addon in `project.godot` `[editor_plugins]`. |
38
+ | `update` | Check npm for a newer `godot-cli` and install it. |
39
+
40
+ ### Editor resolution (`open`)
41
+
42
+ `open` locates the Godot editor binary in this order:
43
+
44
+ 1. `--editor-path <path>` (explicit).
45
+ 2. `GODOT_BIN` / `GODOT4_BIN` environment variables.
46
+ 3. The first matching Godot binary on `PATH` (the mono build is preferred on Windows).
47
+ 4. Per-OS common install directories — Windows prefers the mono build; macOS resolves the
48
+ `.app/Contents/MacOS/Godot` binary; Linux scans common extracted-binary locations.
49
+
50
+ ### Connection env vars
51
+
52
+ `open` forwards these to the editor process (names match the addon's `GodotMcpConfig`):
53
+
54
+ | Flag | Env var |
55
+ | --- | --- |
56
+ | `--url <host>` | `GODOT_MCP_HOST` |
57
+ | `--cloud-url <url>` | `GODOT_MCP_CLOUD_URL` |
58
+ | `--token <token>` | `GODOT_MCP_TOKEN` |
59
+ | `--auth None\|Required` | `GODOT_MCP_AUTH_OPTION` |
60
+ | `--mode Cloud\|Custom` | `GODOT_MCP_CONNECTION_MODE` |
61
+ | `--log-level <level>` | `GODOT_MCP_LOG_LEVEL` |
62
+
63
+ ### Server URL resolution (`run-tool` / `status` / `wait-for-ready`)
64
+
65
+ Unlike Unity, the Godot plugin is a **server-less client** whose persisted config lives in `user://`
66
+ (outside the project tree), so there is no deterministic project-path → port hash. The server base URL is
67
+ resolved as:
68
+
69
+ 1. `--url <url>` (explicit override).
70
+ 2. `GODOT_MCP_HOST` env (Custom-mode host).
71
+ 3. `GODOT_MCP_CLOUD_URL` env / Cloud mode → cloud base (`https://ai-game.dev`).
72
+ 4. Default custom host (`http://localhost:8080`).
73
+
74
+ Pass `--url http://localhost:<port>` to target a local/self-hosted server.
75
+
76
+ ## `setup-skills` is not in v1
77
+
78
+ Unlike the Unity CLI, there is **no `setup-skills` command**. Godot skills are generated **addon-side** by
79
+ the McpPlugin engine on plugin boot (`GodotMcpConnection.Start` → `GenerateSkillFilesIfNeeded`, driven by
80
+ the `GodotMcpConfig.GenerateSkillFiles` toggle, with a manual "Generate" button in the dock's Skills card).
81
+ The Godot MCP server exposes **no** `skill-generate` HTTP endpoint for the CLI to call, so porting
82
+ `setup-skills` would have nothing to invoke. It is intentionally out of scope for v1.
83
+
84
+ ## Library API
85
+
86
+ The package also exports a side-effect-free library (the `.` entry):
87
+
88
+ ```ts
89
+ import { openProject, runTool, setupMcp, installPlugin } from 'godot-cli';
90
+ ```
91
+
92
+ Every function returns a discriminated union (`{ kind: 'success', ... }` / `{ kind: 'failure', error }`)
93
+ and never throws past the public boundary.
94
+
95
+ ## Development
96
+
97
+ ```bash
98
+ npm install
99
+ npm run build # tsc → dist/ (ESM)
100
+ npm test # vitest
101
+ ```
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js';
package/dist/cli.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export { openCommand } from './commands/open.js';
2
+ export { runToolCommand } from './commands/run-tool.js';
3
+ export { runSystemToolCommand } from './commands/run-system-tool.js';
4
+ export { statusCommand } from './commands/status.js';
5
+ export { waitForReadyCommand } from './commands/wait-for-ready.js';
6
+ export { setupMcpCommand } from './commands/setup-mcp.js';
7
+ export { configureCommand } from './commands/configure.js';
8
+ export { closeCommand } from './commands/close.js';
9
+ export { createUpdateCommand } from './commands/update.js';
10
+ export { installPluginCommand } from './commands/install-plugin.js';
11
+ export { removePluginCommand } from './commands/remove-plugin.js';
package/dist/cli.js ADDED
@@ -0,0 +1,17 @@
1
+ // CLI entry-point re-exports (`godot-cli/cli`).
2
+ //
3
+ // Exposes the commander Command instances so a consumer can compose them into
4
+ // their own program. The runnable program lives in `index.ts` (imported by
5
+ // `bin/godot-cli.js`).
6
+ export { openCommand } from './commands/open.js';
7
+ export { runToolCommand } from './commands/run-tool.js';
8
+ export { runSystemToolCommand } from './commands/run-system-tool.js';
9
+ export { statusCommand } from './commands/status.js';
10
+ export { waitForReadyCommand } from './commands/wait-for-ready.js';
11
+ export { setupMcpCommand } from './commands/setup-mcp.js';
12
+ export { configureCommand } from './commands/configure.js';
13
+ export { closeCommand } from './commands/close.js';
14
+ export { createUpdateCommand } from './commands/update.js';
15
+ export { installPluginCommand } from './commands/install-plugin.js';
16
+ export { removePluginCommand } from './commands/remove-plugin.js';
17
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,uBAAuB;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Command } from 'commander';
2
+ export interface CloseOptions {
3
+ timeout?: string;
4
+ force?: boolean;
5
+ }
6
+ /** Resolve the project path argument to an absolute, canonical path. */
7
+ export declare function resolveCloseProjectPath(positionalPath: string | undefined, cwd: string): string;
8
+ /** True when `<projectPath>/project.godot` exists. */
9
+ export declare function isGodotProjectRoot(projectPath: string): boolean;
10
+ /**
11
+ * Parse a positive-integer `--timeout` value (seconds). Returns the parsed
12
+ * value, or `null` when the input is not a valid positive integer. Exported for
13
+ * unit tests.
14
+ */
15
+ export declare function parseTimeoutSeconds(raw: string | undefined): number | null;
16
+ /** Resolve the editor PID for a given project path, or null when not running. */
17
+ export declare function resolveEditorPid(projectPath: string): number | null;
18
+ export declare const closeCommand: Command;
@@ -0,0 +1,112 @@
1
+ import { Command } from 'commander';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { platform as nodePlatform } from 'os';
5
+ import * as ui from '../utils/ui.js';
6
+ import { verbose } from '../utils/ui.js';
7
+ import { findGodotProcess } from '../utils/godot-process.js';
8
+ import { isProcessAlive, sendGracefulShutdown, sendForceKill, waitForExit, } from '../utils/godot-shutdown.js';
9
+ const DEFAULT_TIMEOUT_SECONDS = 30;
10
+ /** Resolve the project path argument to an absolute, canonical path. */
11
+ export function resolveCloseProjectPath(positionalPath, cwd) {
12
+ const explicit = positionalPath ?? cwd;
13
+ let resolved = path.resolve(explicit);
14
+ try {
15
+ resolved = fs.realpathSync(resolved);
16
+ }
17
+ catch {
18
+ // Path may not exist — let the caller decide what to do.
19
+ }
20
+ return resolved;
21
+ }
22
+ /** True when `<projectPath>/project.godot` exists. */
23
+ export function isGodotProjectRoot(projectPath) {
24
+ return fs.existsSync(path.join(projectPath, 'project.godot'));
25
+ }
26
+ /**
27
+ * Parse a positive-integer `--timeout` value (seconds). Returns the parsed
28
+ * value, or `null` when the input is not a valid positive integer. Exported for
29
+ * unit tests.
30
+ */
31
+ export function parseTimeoutSeconds(raw) {
32
+ if (raw === undefined)
33
+ return DEFAULT_TIMEOUT_SECONDS;
34
+ const parsed = Number(raw);
35
+ if (!Number.isInteger(parsed) || parsed <= 0)
36
+ return null;
37
+ return parsed;
38
+ }
39
+ /** Resolve the editor PID for a given project path, or null when not running. */
40
+ export function resolveEditorPid(projectPath) {
41
+ const proc = findGodotProcess(projectPath);
42
+ if (proc) {
43
+ verbose(`Godot editor PID ${proc.pid} matched for project`);
44
+ return proc.pid;
45
+ }
46
+ return null;
47
+ }
48
+ export const closeCommand = new Command('close')
49
+ .description('Gracefully terminate the Godot editor instance running for a given project path')
50
+ .argument('[path]', 'Path to the Godot project (defaults to current directory)')
51
+ .option('--timeout <seconds>', `Polite-quit timeout in seconds (default: ${DEFAULT_TIMEOUT_SECONDS})`, String(DEFAULT_TIMEOUT_SECONDS))
52
+ .option('--force', 'Hard-kill the editor if it does not exit within --timeout')
53
+ .action(async (positionalPath, options) => {
54
+ const projectPath = resolveCloseProjectPath(positionalPath, process.cwd());
55
+ verbose(`close invoked for project: ${projectPath}`);
56
+ if (!fs.existsSync(projectPath)) {
57
+ ui.error(`Project path does not exist: ${projectPath}`);
58
+ process.exit(1);
59
+ }
60
+ if (!isGodotProjectRoot(projectPath)) {
61
+ ui.error(`Not a Godot project root: ${projectPath}`);
62
+ process.exit(1);
63
+ }
64
+ const timeoutSeconds = parseTimeoutSeconds(options.timeout);
65
+ if (timeoutSeconds === null) {
66
+ ui.error(`Invalid --timeout value: "${options.timeout}". Must be a positive integer (seconds).`);
67
+ process.exit(1);
68
+ }
69
+ const platform = nodePlatform();
70
+ const pid = resolveEditorPid(projectPath);
71
+ if (pid === null) {
72
+ ui.success(`no running editor for project at ${projectPath}`);
73
+ process.exit(0);
74
+ }
75
+ ui.heading('Closing Godot Editor');
76
+ ui.label('Project', projectPath);
77
+ ui.label('PID', String(pid));
78
+ ui.label('Timeout', `${timeoutSeconds}s`);
79
+ ui.label('Force', options.force ? 'yes' : 'no');
80
+ ui.divider();
81
+ const spinner = ui.startSpinner(`Sending polite-quit to PID ${pid}...`);
82
+ const sent = sendGracefulShutdown(pid, platform);
83
+ if (!sent) {
84
+ spinner.error(`Failed to deliver polite-quit signal to PID ${pid}`);
85
+ process.exit(1);
86
+ }
87
+ spinner.text = `Waiting up to ${timeoutSeconds}s for PID ${pid} to exit...`;
88
+ const exited = await waitForExit(pid, timeoutSeconds * 1000, platform);
89
+ if (exited) {
90
+ spinner.success(`Godot editor (PID ${pid}) exited cleanly`);
91
+ process.exit(0);
92
+ }
93
+ if (!options.force) {
94
+ spinner.error(`Godot editor (PID ${pid}) did not exit within ${timeoutSeconds}s. ` +
95
+ `Re-run with --force to hard-kill, or close it manually.`);
96
+ process.exit(1);
97
+ }
98
+ spinner.text = `Force-killing PID ${pid}...`;
99
+ const killed = sendForceKill(pid, platform);
100
+ if (!killed) {
101
+ spinner.error(`Failed to force-kill PID ${pid}`);
102
+ process.exit(1);
103
+ }
104
+ const reaped = await waitForExit(pid, 5000, platform);
105
+ if (reaped || !isProcessAlive(pid, platform)) {
106
+ spinner.success(`Godot editor (PID ${pid}) force-killed`);
107
+ process.exit(0);
108
+ }
109
+ spinner.error(`Godot editor (PID ${pid}) is still alive after force-kill`);
110
+ process.exit(1);
111
+ });
112
+ //# sourceMappingURL=close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close.js","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const configureCommand: Command;
@@ -0,0 +1,92 @@
1
+ import { Command } from 'commander';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as ui from '../utils/ui.js';
5
+ import { verbose } from '../utils/ui.js';
6
+ import { getOrCreateConfig, writeConfig, updateFeatures, } from '../utils/config.js';
7
+ function parseCommaSeparated(value) {
8
+ return value.split(',').map((s) => s.trim()).filter(Boolean);
9
+ }
10
+ function buildAction(enable, disable, enableAll, disableAll) {
11
+ if (!enable && !disable && !enableAll && !disableAll)
12
+ return undefined;
13
+ return { enableNames: enable, disableNames: disable, enableAll, disableAll };
14
+ }
15
+ function snapshotFeatures(config, key) {
16
+ const raw = config[key];
17
+ if (!Array.isArray(raw))
18
+ return [];
19
+ return raw
20
+ .filter((f) => typeof f === 'object' && f !== null && typeof f.name === 'string' && typeof f.enabled === 'boolean')
21
+ .map((f) => ({ name: f.name, enabled: f.enabled }));
22
+ }
23
+ export const configureCommand = new Command('configure')
24
+ .description('List / enable / disable MCP tools, prompts, and resources in the project-local .godot-mcp/features.json')
25
+ .argument('[path]', 'Path to the Godot project')
26
+ .option('--path <path>', 'Path to the Godot project')
27
+ .option('--enable-tools <names>', 'Enable specific tools (comma-separated)', parseCommaSeparated)
28
+ .option('--disable-tools <names>', 'Disable specific tools (comma-separated)', parseCommaSeparated)
29
+ .option('--enable-all-tools', 'Enable all tools')
30
+ .option('--disable-all-tools', 'Disable all tools')
31
+ .option('--enable-prompts <names>', 'Enable specific prompts (comma-separated)', parseCommaSeparated)
32
+ .option('--disable-prompts <names>', 'Disable specific prompts (comma-separated)', parseCommaSeparated)
33
+ .option('--enable-all-prompts', 'Enable all prompts')
34
+ .option('--disable-all-prompts', 'Disable all prompts')
35
+ .option('--enable-resources <names>', 'Enable specific resources (comma-separated)', parseCommaSeparated)
36
+ .option('--disable-resources <names>', 'Disable specific resources (comma-separated)', parseCommaSeparated)
37
+ .option('--enable-all-resources', 'Enable all resources')
38
+ .option('--disable-all-resources', 'Disable all resources')
39
+ .option('--list', 'List current configuration')
40
+ .action(async (positionalPath, options) => {
41
+ const resolvedPath = positionalPath ?? options.path;
42
+ if (!resolvedPath) {
43
+ ui.error('Path is required. Usage: godot-cli configure <path> or --path <path>');
44
+ process.exit(1);
45
+ }
46
+ const projectPath = path.resolve(resolvedPath);
47
+ if (!fs.existsSync(projectPath)) {
48
+ ui.error(`Project path does not exist: ${projectPath}`);
49
+ process.exit(1);
50
+ }
51
+ verbose(`Loading config for project: ${projectPath}`);
52
+ const toolsAction = options.list
53
+ ? undefined
54
+ : buildAction(options.enableTools, options.disableTools, options.enableAllTools, options.disableAllTools);
55
+ const promptsAction = options.list
56
+ ? undefined
57
+ : buildAction(options.enablePrompts, options.disablePrompts, options.enableAllPrompts, options.disableAllPrompts);
58
+ const resourcesAction = options.list
59
+ ? undefined
60
+ : buildAction(options.enableResources, options.disableResources, options.enableAllResources, options.disableAllResources);
61
+ const config = getOrCreateConfig(projectPath);
62
+ const hasAny = (a) => !!a && (!!a.enableNames?.length || !!a.disableNames?.length || a.enableAll === true || a.disableAll === true);
63
+ if (hasAny(toolsAction))
64
+ updateFeatures(config, 'tools', toolsAction);
65
+ if (hasAny(promptsAction))
66
+ updateFeatures(config, 'prompts', promptsAction);
67
+ if (hasAny(resourcesAction))
68
+ updateFeatures(config, 'resources', resourcesAction);
69
+ if (hasAny(toolsAction) || hasAny(promptsAction) || hasAny(resourcesAction)) {
70
+ writeConfig(projectPath, config);
71
+ }
72
+ if (options.list) {
73
+ ui.heading('Current configuration');
74
+ const printFeatures = (featureLabel, features) => {
75
+ ui.heading(featureLabel);
76
+ if (features.length === 0) {
77
+ ui.info('(none configured - all enabled by default)');
78
+ return;
79
+ }
80
+ for (const f of features) {
81
+ ui.featureRow(f.name, f.enabled);
82
+ }
83
+ };
84
+ printFeatures('Tools', snapshotFeatures(config, 'tools'));
85
+ printFeatures('Prompts', snapshotFeatures(config, 'prompts'));
86
+ printFeatures('Resources', snapshotFeatures(config, 'resources'));
87
+ return;
88
+ }
89
+ verbose('Writing updated configuration');
90
+ ui.success('Configuration updated successfully.');
91
+ });
92
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/commands/configure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const installPluginCommand: Command;
@@ -0,0 +1,35 @@
1
+ import { Command } from 'commander';
2
+ import * as path from 'path';
3
+ import * as ui from '../utils/ui.js';
4
+ import { verbose } from '../utils/ui.js';
5
+ import { installPlugin } from '../lib/install-plugin.js';
6
+ export const installPluginCommand = new Command('install-plugin')
7
+ .description('Enable the godot_mcp addon in a project (adds res://addons/godot_mcp/plugin.cfg to project.godot [editor_plugins])')
8
+ .argument('[path]', 'Path to the Godot project')
9
+ .option('--path <path>', 'Path to the Godot project')
10
+ .action(async (positionalPath, options) => {
11
+ const resolvedPath = positionalPath ?? options.path ?? process.cwd();
12
+ const projectPath = path.resolve(resolvedPath);
13
+ ui.heading('Enabling godot_mcp addon');
14
+ verbose(`Project path: ${projectPath}`);
15
+ const spinner = ui.startSpinner('Updating project.godot...');
16
+ const result = await installPlugin({ godotProjectPath: projectPath });
17
+ if (result.kind === 'failure') {
18
+ spinner.error('Failed to enable plugin');
19
+ ui.error(result.error.message);
20
+ process.exit(1);
21
+ }
22
+ if (result.changed) {
23
+ spinner.success('godot_mcp addon enabled');
24
+ }
25
+ else {
26
+ spinner.success('godot_mcp addon was already enabled');
27
+ }
28
+ ui.label('project.godot', result.projectGodotPath);
29
+ ui.label('Enabled plugins', result.enabledPlugins.join(', ') || '(none)');
30
+ for (const warning of result.warnings) {
31
+ console.log('');
32
+ ui.warn(warning);
33
+ }
34
+ });
35
+ //# sourceMappingURL=install-plugin.js.map
@@ -0,0 +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,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC;KAC9D,WAAW,CAAC,oHAAoH,CAAC;KACjI,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;KAC/C,MAAM,CAAC,eAAe,EAAE,2BAA2B,CAAC;KACpD,MAAM,CAAC,KAAK,EAAE,cAAkC,EAAE,OAAgC,EAAE,EAAE;IACrF,MAAM,YAAY,GAAG,cAAc,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACrE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/C,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACvC,OAAO,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC;IAExC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC;IAEtE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACnD,EAAE,CAAC,KAAK,CAAC,iBAAiB,EAAE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAC;IAE1E,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ import { isGodotProjectDir as libIsGodotProjectDir } from '../lib/open.js';
3
+ export interface ResolveProjectPathResult {
4
+ /** Absolute, resolved path to the project directory. */
5
+ projectPath: string;
6
+ /** True if no path was supplied and we fell back to `process.cwd()`. */
7
+ usedCwdFallback: boolean;
8
+ }
9
+ /**
10
+ * Resolve the project path from the positional argument, `--path` option, or
11
+ * the current working directory when neither is provided. Re-exported for tests.
12
+ */
13
+ export declare function resolveOpenProjectPath(positionalPath: string | undefined, optionPath: string | undefined, cwd: string): ResolveProjectPathResult;
14
+ /** Re-export for backward compatibility with tests. */
15
+ export declare const isGodotProjectDir: typeof libIsGodotProjectDir;
16
+ export declare const openCommand: Command;
@@ -0,0 +1,124 @@
1
+ import { Command } from 'commander';
2
+ import * as path from 'path';
3
+ import * as ui from '../utils/ui.js';
4
+ import { verbose } from '../utils/ui.js';
5
+ import { openProject, resolveProjectPath as libResolveProjectPath, isGodotProjectDir as libIsGodotProjectDir, } from '../lib/open.js';
6
+ /**
7
+ * Resolve the project path from the positional argument, `--path` option, or
8
+ * the current working directory when neither is provided. Re-exported for tests.
9
+ */
10
+ export function resolveOpenProjectPath(positionalPath, optionPath, cwd) {
11
+ const explicit = positionalPath ?? optionPath;
12
+ return libResolveProjectPath(explicit, cwd);
13
+ }
14
+ /** Re-export for backward compatibility with tests. */
15
+ export const isGodotProjectDir = libIsGodotProjectDir;
16
+ export const openCommand = new Command('open')
17
+ .description('Open a Godot project in the Godot editor, optionally passing GODOT_MCP_* connection env vars when connection options (--url, --token, etc.) are provided. Use --no-connect to suppress all MCP env vars.')
18
+ .argument('[path]', 'Path to the Godot project (defaults to current directory)')
19
+ .option('--path <path>', 'Path to the Godot project (defaults to current directory)')
20
+ .option('--editor-path <path>', 'Explicit path to the Godot editor executable (skips discovery)')
21
+ .option('--no-connect', 'Open without MCP connection environment variables')
22
+ .option('--url <url>', 'MCP server host to connect to (sets GODOT_MCP_HOST)')
23
+ .option('--cloud-url <url>', 'Cloud base URL override (sets GODOT_MCP_CLOUD_URL)')
24
+ .option('--token <token>', 'Auth token (sets GODOT_MCP_TOKEN)')
25
+ .option('--auth <option>', 'Auth option: None or Required (sets GODOT_MCP_AUTH_OPTION)')
26
+ .option('--mode <mode>', 'Connection mode: Cloud or Custom (sets GODOT_MCP_CONNECTION_MODE)')
27
+ .option('--log-level <level>', 'Log level: Trace/Debug/Info/Warning/Error/None (sets GODOT_MCP_LOG_LEVEL)')
28
+ .action(async (positionalPath, options) => {
29
+ const { projectPath, usedCwdFallback } = resolveOpenProjectPath(positionalPath, options.path, process.cwd());
30
+ const fs = await import('fs');
31
+ if (!fs.existsSync(projectPath)) {
32
+ ui.error(`Project path does not exist: ${projectPath}`);
33
+ process.exit(1);
34
+ }
35
+ if (!libIsGodotProjectDir(projectPath)) {
36
+ if (usedCwdFallback) {
37
+ ui.error(`Current directory is not a Godot project: ${projectPath}`);
38
+ ui.info('Run this command from a Godot project folder, or pass a path: godot-cli open <path>');
39
+ }
40
+ else {
41
+ ui.error(`Not a Godot project (missing project.godot): ${projectPath}`);
42
+ }
43
+ process.exit(1);
44
+ }
45
+ if (usedCwdFallback) {
46
+ verbose(`No path provided — using current directory: ${projectPath}`);
47
+ }
48
+ verbose(`open invoked for project: ${projectPath}`);
49
+ verbose(`--no-connect: ${options.connect === false}`);
50
+ // Validate auth/mode here so the CLI emits a clear error + exit code.
51
+ if (options.auth !== undefined && options.auth !== 'None' && options.auth !== 'Required') {
52
+ ui.error('--auth must be "None" or "Required"');
53
+ process.exit(1);
54
+ }
55
+ if (options.mode !== undefined && options.mode !== 'Cloud' && options.mode !== 'Custom') {
56
+ ui.error('--mode must be "Cloud" or "Custom"');
57
+ process.exit(1);
58
+ }
59
+ const spinner = ui.startSpinner('Locating Godot editor...');
60
+ const result = await openProject({
61
+ projectPath,
62
+ editorPath: options.editorPath,
63
+ noConnect: options.connect === false,
64
+ url: options.url,
65
+ cloudUrl: options.cloudUrl,
66
+ token: options.token,
67
+ auth: options.auth,
68
+ mode: options.mode,
69
+ logLevel: options.logLevel,
70
+ onProgress: (event) => {
71
+ switch (event.phase) {
72
+ case 'editor-resolved': {
73
+ spinner.success('Godot editor located');
74
+ verbose(`Editor path: ${event.editorPath}`);
75
+ break;
76
+ }
77
+ case 'connection-details': {
78
+ const envVars = event.envVars;
79
+ if (Object.keys(envVars).length > 0) {
80
+ ui.heading('Connection Details');
81
+ ui.label('Project', event.projectPath);
82
+ ui.label('Editor', event.editorPath);
83
+ ui.heading('Environment Variables');
84
+ for (const [key, value] of Object.entries(envVars)) {
85
+ const display = key === 'GODOT_MCP_TOKEN' ? '***' : value;
86
+ ui.label(key, display);
87
+ }
88
+ ui.divider();
89
+ }
90
+ else {
91
+ verbose('MCP connection disabled via --no-connect or no options');
92
+ }
93
+ break;
94
+ }
95
+ case 'launching-editor': {
96
+ ui.label('Project', event.projectPath);
97
+ ui.label('Editor', event.editorPath);
98
+ break;
99
+ }
100
+ case 'editor-launched': {
101
+ ui.success(`Launched Godot editor (PID: ${event.pid ?? 'unknown'})`);
102
+ break;
103
+ }
104
+ default:
105
+ break;
106
+ }
107
+ },
108
+ });
109
+ if (result.kind === 'failure') {
110
+ // The spinner.success() on editor-resolved only fires on the happy
111
+ // path; on failure stop it so the error renders cleanly.
112
+ spinner.stop();
113
+ ui.error(result.errorMessage);
114
+ process.exit(1);
115
+ }
116
+ if (result.alreadyRunning) {
117
+ spinner.stop();
118
+ ui.success(`Godot is already running with this project (PID: ${result.editorPid ?? 'unknown'})`);
119
+ ui.info('Skipping launch. Use the running instance or close it first.');
120
+ process.exit(0);
121
+ }
122
+ verbose(`Resolved project path: ${path.resolve(result.projectPath)}`);
123
+ });
124
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const removePluginCommand: Command;