dexe-mcp 0.1.2 → 0.1.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Fixed
6
+ - **`'npx' is not recognized`** from inside `npm run compile` (and other npm scripts that internally call `npx hardhat …`) on stripped-Node Windows installs. v0.1.4 got `npm` itself spawning cleanly, but DeXe-Protocol's `compile` script is literally `npx hardhat compile --force`, and when npm spawned that child, `cmd.exe` couldn't find `npx.cmd` on PATH — the stripped `C:\Program Files\nodejs\` has `node.exe` only. Root cause: we weren't propagating the resolved Node's shim directory into the child's `PATH`.
7
+ - New `deriveNodeBinDir()` + `envWithNodeBinDir()` helpers in `src/runtime.ts` derive the directory containing `npm.cmd`/`npx.cmd` (Windows) or `bin/npm`/`bin/npx` (Unix) from the resolved `npm-cli.js` path, and prepend it to `PATH` on every child spawn (`bootstrap` npm install, `runNpmScript`, `runHardhat`). Child shells launched by npm scripts can now resolve `npx` / `npm` / any locally-installed binary as expected.
8
+ - `npmCommand()` now returns a `binDir` field alongside `command` / `prefixArgs` / `needsShell`. Bootstrap logs the prepended directory on first run so it's visible which Node install is contributing the shims.
9
+
10
+ ## 0.1.4
11
+
12
+ ### Fixed
13
+ - **`spawn EINVAL` during first-run `npm install`** on Windows hosts where `process.execPath` points at a Node install that does not bundle npm (e.g. a bare `node.exe` dropped under `C:\Program Files\nodejs\` without the rest of the toolchain). Two root causes addressed:
14
+ 1. `resolveNpmCli()` now searches a broader set of locations for a usable `npm-cli.js` — including `%APPDATA%\nvm\v*\node_modules\npm\bin\npm-cli.js` (nvm-windows), `%APPDATA%\npm\node_modules\npm\bin\npm-cli.js` (per-user npm prefix), `C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js` (stock Windows installer), `~/.nvm/versions/node/v*/lib/node_modules/npm/bin/npm-cli.js` (nvm Unix), and Homebrew paths. Because `npm-cli.js` is plain JavaScript, *any* modern `node` can execute any of these, so the MCP process's own Node is free to "borrow" npm from a completely different Node install.
15
+ 2. When no `npm-cli.js` is found anywhere and we fall back to spawning `npm.cmd` directly, `execFile` / `execa` now pass `{ shell: true }` — without it, Node refuses to spawn `.cmd` / `.bat` files (CVE-2024-27980 mitigation) and throws `spawn EINVAL`.
16
+ - Progress logging on first bootstrap now prints the resolved `npm-cli.js` path (or "shell-resolved" fallback), so "which npm is about to run" is visible in stderr.
17
+
18
+ ## 0.1.3
19
+
20
+ ### Docs
21
+ - **Windows install section rewritten** to lead with the absolute-path recipe (`node <abs path to dist/index.js>`) instead of `cmd /c dexe-mcp`. End-to-end testing against Claude Code on Windows showed the `cmd /c` wrapper, while standalone functional, did not reliably complete the MCP handshake when spawned by Claude Code — the absolute-path recipe has zero shim resolution and is known-working.
22
+ - **New prereq step**: verify `npm --version` actually runs in your shell *before* attempting `npm install -g dexe-mcp`. Users with a stripped `node.exe`-only install (common on Windows) will hit a silent `npm i -g` no-op otherwise, with no visible error.
23
+ - Added a "Verify the install" section showing how to smoke-test `dexe-mcp` over stdio without involving Claude Code, so users can distinguish "MCP server broken" from "client registration broken".
24
+
25
+ No code changes — 0.1.3 is a docs-only patch on top of 0.1.2's behavior.
26
+
3
27
  ## 0.1.2
4
28
 
5
29
  ### Fixed
package/README.md CHANGED
@@ -6,7 +6,15 @@ MCP server for Claude Code / Antigravity that wraps the [DeXe Protocol](https://
6
6
 
7
7
  ## Prerequisites
8
8
 
9
- - **Node.js >= 20** (with a bundled `npm` i.e. any official installer, nvm, nvm-windows, or Homebrew build)
9
+ - **Node.js >= 20** with a working `npm`. Verify before continuing:
10
+
11
+ ```bash
12
+ node --version # should print v20.x or higher
13
+ npm --version # MUST print a version, not "command not found"
14
+ ```
15
+
16
+ If `npm --version` fails, you have a stripped Node install (a bare `node.exe` without the rest of the toolchain — common on Windows when `C:\Program Files\nodejs\node.exe` was placed manually). Install Node from <https://nodejs.org> or via [nvm](https://github.com/nvm-sh/nvm) / [nvm-windows](https://github.com/coreybutler/nvm-windows) and retry. Without npm, `npm install -g dexe-mcp` silently does nothing.
17
+
10
18
  - **Git** — only needed on first run, to clone DeXe-Protocol. If you already have a local checkout, point `DEXE_PROTOCOL_PATH` at it and git is optional.
11
19
 
12
20
  ## Install
@@ -17,21 +25,28 @@ MCP server for Claude Code / Antigravity that wraps the [DeXe Protocol](https://
17
25
  npm install -g dexe-mcp
18
26
  ```
19
27
 
20
- This installs a `dexe-mcp` binary on your PATH. Verify:
28
+ Verify the install landed by asking npm where it put it:
21
29
 
22
30
  ```bash
23
- dexe-mcp --version # or: where dexe-mcp (Windows) / which dexe-mcp (Mac/Linux)
31
+ npm root -g
32
+ # Mac/Linux: /usr/local/lib/node_modules (or ~/.nvm/versions/node/vXX.X.X/lib/node_modules)
33
+ # Windows: C:\Users\<you>\AppData\Roaming\nvm\<version>\node_modules
34
+ # (or C:\Users\<you>\AppData\Roaming\npm\node_modules for non-nvm)
24
35
  ```
25
36
 
37
+ Note the output — you'll need it for the Windows install step below. The package lives at `<npm-root>/dexe-mcp/dist/index.js`.
38
+
26
39
  ### 2. Register the MCP server
27
40
 
28
41
  #### Mac / Linux
29
42
 
43
+ Bare command works because Unix `exec` resolves PATH directly:
44
+
30
45
  ```bash
31
46
  claude mcp add dexe -- dexe-mcp
32
47
  ```
33
48
 
34
- Or add to your MCP client config (`.mcp.json`, `claude_desktop_config.json`, etc.):
49
+ Or in JSON (`.mcp.json`, `claude_desktop_config.json`, etc.):
35
50
 
36
51
  ```json
37
52
  {
@@ -43,41 +58,67 @@ Or add to your MCP client config (`.mcp.json`, `claude_desktop_config.json`, etc
43
58
  }
44
59
  ```
45
60
 
46
- #### Windows
61
+ #### Windows — recommended: absolute path to `node` + `dist/index.js`
47
62
 
48
- Windows `CreateProcess` does not resolve `.cmd` shims from a bare command name, so wrap the call with `cmd /c`:
63
+ On Windows, `dexe-mcp` is installed as a `.cmd` shim that many MCP clients (including Claude Code as of this writing) fail to spawn cleanly over stdio. The **absolute-path** form bypasses shim resolution entirely and is the known-good recipe:
49
64
 
50
65
  ```bash
51
- claude mcp add dexe -- cmd /c dexe-mcp
66
+ claude mcp add dexe -- "C:\Program Files\nodejs\node.exe" "C:\Users\<you>\AppData\Roaming\nvm\<version>\node_modules\dexe-mcp\dist\index.js"
52
67
  ```
53
68
 
54
- Or in JSON:
69
+ Substitute `<you>` and `<version>` (or use whatever `npm root -g` printed above). In JSON:
55
70
 
56
71
  ```json
57
72
  {
58
73
  "mcpServers": {
59
74
  "dexe": {
60
- "command": "cmd",
61
- "args": ["/c", "dexe-mcp"]
75
+ "command": "C:/Program Files/nodejs/node.exe",
76
+ "args": ["C:/Users/<you>/AppData/Roaming/nvm/<version>/node_modules/dexe-mcp/dist/index.js"]
62
77
  }
63
78
  }
64
79
  }
65
80
  ```
66
81
 
67
- **Absolute-path fallback** (works everywhere, zero PATH dependency):
82
+ This works because:
83
+ - No PATH dependency — every argument is an absolute path
84
+ - No `.cmd` / `.ps1` shim in the chain, so `CreateProcess` semantics don't trip over missing extensions
85
+ - `dexe-mcp` internally invokes `npm`/`hardhat` via `process.execPath`, so it uses whichever Node you pointed at and does not need npm on the spawned process PATH
86
+
87
+ <details>
88
+ <summary>Alternative: <code>cmd /c dexe-mcp</code> (not recommended — often unreliable with Claude Code)</summary>
68
89
 
69
90
  ```json
70
91
  {
71
92
  "mcpServers": {
72
93
  "dexe": {
73
- "command": "node",
74
- "args": ["C:/Users/<you>/AppData/Roaming/npm/node_modules/dexe-mcp/dist/index.js"]
94
+ "command": "cmd",
95
+ "args": ["/c", "dexe-mcp"]
75
96
  }
76
97
  }
77
98
  }
78
99
  ```
79
100
 
80
- ### 3. Restart your MCP client
101
+ Use only if the absolute-path form is inconvenient. End-to-end testing showed this can pass a direct stdio check but fail to complete the MCP handshake when spawned by Claude Code.
102
+ </details>
103
+
104
+ ### 3. Verify the install (optional but recommended)
105
+
106
+ Before wiring the server into your MCP client, confirm the binary can actually speak MCP over stdio. On any OS:
107
+
108
+ ```bash
109
+ # Send a minimal initialize request, expect a capabilities JSON back.
110
+ echo "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"t\",\"version\":\"1\"}}}" | dexe-mcp
111
+ ```
112
+
113
+ On Windows if the above hangs, try instead:
114
+
115
+ ```bash
116
+ echo {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}} | node "C:\Users\<you>\AppData\Roaming\nvm\<version>\node_modules\dexe-mcp\dist\index.js"
117
+ ```
118
+
119
+ A healthy response starts with a single stderr line (`[dexe-mcp] connected on stdio. …`) and a stdout JSON blob containing `"serverInfo":{"name":"dexe-mcp"}`. If you see that, the server is fine and any "failed to connect" from your MCP client is purely a client-side spawn/config problem, not a bug in dexe-mcp.
120
+
121
+ ### 4. Restart your MCP client
81
122
 
82
123
  On the first build-tool call (e.g. `dexe_compile`), `dexe-mcp` will automatically:
83
124
 
@@ -192,13 +233,20 @@ Usually means your Node install lacks a bundled `npm` (e.g. a stripped `node.exe
192
233
 
193
234
  ### "Failed to connect" in Claude Code (Windows)
194
235
 
195
- Claude Code spawns MCP servers with `CreateProcess`, which can't resolve `.cmd` shims from a bare name. Wrap the command:
236
+ Run the direct stdio test from the "Verify the install" section first. If that prints a clean `serverInfo` response, the server is fine and the problem is in how your client is spawning it.
196
237
 
197
- ```json
198
- { "command": "cmd", "args": ["/c", "dexe-mcp"] }
238
+ The fix is almost always to switch to the **absolute-path** registration:
239
+
240
+ ```bash
241
+ claude mcp remove dexe
242
+ claude mcp add dexe -- "C:\Program Files\nodejs\node.exe" "C:\Users\<you>\AppData\Roaming\nvm\<version>\node_modules\dexe-mcp\dist\index.js"
199
243
  ```
200
244
 
201
- Or use the absolute-path fallback pointing at `node` + `dist/index.js` directly.
245
+ Bare `dexe-mcp` and `cmd /c dexe-mcp` both rely on shim resolution that Claude Code's `CreateProcess`-based spawn does not always handle. The absolute-path form has zero shim resolution.
246
+
247
+ ### `npm install -g dexe-mcp` reported success but `dexe-mcp` is nowhere to be found
248
+
249
+ You're almost certainly on a stripped Node install whose `npm` silently no-ops. Check with `npm --version` — if it fails, install Node properly (see Prerequisites). If it prints a version, check `npm root -g` and look inside that directory; the package should be at `<npm-root>/dexe-mcp`.
202
250
 
203
251
  ### "Hardhat artifacts not found — run dexe_compile first"
204
252
 
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAO1D;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuF1E"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAO1D;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiG1E"}
package/dist/bootstrap.js CHANGED
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  import { homedir, platform } from "node:os";
4
4
  import { execFile } from "node:child_process";
5
5
  import { promisify } from "node:util";
6
- import { hasGit, npmCommand } from "./runtime.js";
6
+ import { envWithNodeBinDir, hasGit, npmCommand } from "./runtime.js";
7
7
  const execFileAsync = promisify(execFile);
8
8
  const REPO_URL = "https://github.com/dexe-network/DeXe-Protocol.git";
9
9
  const CACHE_DIR_NAME = "dexe-mcp";
@@ -117,11 +117,20 @@ export async function ensureBuildReady(protocolPath) {
117
117
  if (!existsSync(join(protocolPath, "node_modules"))) {
118
118
  log("Installing DeXe-Protocol npm dependencies (first run only) — this takes a few minutes …");
119
119
  const npm = npmCommand();
120
+ log(npm.prefixArgs.length > 0
121
+ ? `Using npm-cli.js at ${npm.prefixArgs[0]}`
122
+ : `Using ${npm.command} from PATH (shell-resolved)`);
123
+ if (npm.binDir)
124
+ log(`Prepending ${npm.binDir} to child PATH for npx/npm resolution`);
120
125
  try {
121
126
  await execFileAsync(npm.command, [...npm.prefixArgs, "install", "--no-audit", "--no-fund"], {
122
127
  cwd: protocolPath,
123
128
  windowsHide: true,
124
129
  maxBuffer: 64 * 1024 * 1024,
130
+ // Windows `.cmd` shims cannot be invoked via execFile without
131
+ // shell:true as of Node's CVE-2024-27980 mitigation.
132
+ shell: npm.needsShell,
133
+ env: envWithNodeBinDir(npm.binDir),
125
134
  });
126
135
  }
127
136
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hardhat.d.ts","sourceRoot":"","sources":["../src/hardhat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAiBD,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAE/C;;;;;OAKG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAQhF;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAW7E,OAAO,CAAC,GAAG;CAuDZ"}
1
+ {"version":3,"file":"hardhat.d.ts","sourceRoot":"","sources":["../src/hardhat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAiBD,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAE/C;;;;;OAKG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAchF;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAqB7E,OAAO,CAAC,GAAG;CA+DZ"}
package/dist/hardhat.js CHANGED
@@ -4,7 +4,7 @@ import { writeFileSync, mkdtempSync } from "node:fs";
4
4
  import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import { ensureBuildReady } from "./bootstrap.js";
7
- import { hardhatCommand, npmCommand } from "./runtime.js";
7
+ import { envWithNodeBinDir, hardhatCommand, npmCommand } from "./runtime.js";
8
8
  const HARDHAT_TIMEOUT_MS = 10 * 60 * 1000;
9
9
  const STDOUT_TAIL_LINES = 200;
10
10
  const STDERR_TAIL_LINES = 100;
@@ -35,7 +35,7 @@ export class HardhatRunner {
35
35
  const args = [...npm.prefixArgs, "run", script];
36
36
  if (extraArgs.length > 0)
37
37
  args.push("--", ...extraArgs);
38
- return this.run(npm.command, args, `npm-run-${script}`);
38
+ return this.run(npm.command, args, `npm-run-${script}`, npm.needsShell, envWithNodeBinDir(npm.binDir));
39
39
  }
40
40
  /**
41
41
  * Run `hardhat <subcommand> <args...>` in the protocol directory.
@@ -49,9 +49,13 @@ export class HardhatRunner {
49
49
  if (!hh) {
50
50
  throw new Error(`Hardhat is not installed inside ${this.config.protocolPath}. This should have been fixed by ensureBuildReady — did npm install fail?`);
51
51
  }
52
- return this.run(hh.command, [...hh.prefixArgs, subcommand, ...args], `hardhat-${subcommand}`);
52
+ // Hardhat is invoked via `node <cli.js>`, which has zero PATH dependency
53
+ // for the command itself, but the hardhat task may still spawn helpers
54
+ // that look for npx on PATH — keep the bin dir prepended to be safe.
55
+ const npm = npmCommand();
56
+ return this.run(hh.command, [...hh.prefixArgs, subcommand, ...args], `hardhat-${subcommand}`, false, envWithNodeBinDir(npm.binDir));
53
57
  }
54
- run(command, args, label) {
58
+ run(command, args, label, useShell, extraEnv) {
55
59
  return limit(async () => {
56
60
  const started = Date.now();
57
61
  let timedOut = false;
@@ -60,7 +64,8 @@ export class HardhatRunner {
60
64
  timeout: HARDHAT_TIMEOUT_MS,
61
65
  reject: false,
62
66
  all: true,
63
- env: { ...process.env, FORCE_COLOR: "0", CI: "1" },
67
+ env: { ...extraEnv, FORCE_COLOR: "0", CI: "1" },
68
+ shell: useShell,
64
69
  });
65
70
  // Best-effort: mirror child stderr to ours in near-real-time so the
66
71
  // user sees progress in the MCP's stderr logs. The return value still
@@ -1 +1 @@
1
- {"version":3,"file":"hardhat.js","sourceRoot":"","sources":["../src/hardhat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hardhat.js","sourceRoot":"","sources":["../src/hardhat.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { loadConfig } from "./config.js";
5
5
  import { registerAll } from "./tools/index.js";
6
6
  async function main() {
7
7
  const config = await loadConfig();
8
- const server = new McpServer({ name: "dexe-mcp", version: "0.1.2" }, {
8
+ const server = new McpServer({ name: "dexe-mcp", version: "0.1.5" }, {
9
9
  instructions: "Tools for the DeXe Protocol governance-DAO codebase. Before calling any dexe_get_* / dexe_list_contracts / dexe_find_selector tool, ensure artifacts exist by calling dexe_compile once per session. dexe_decode_proposal and dexe_read_gov_state require DEXE_RPC_URL to be set.",
10
10
  });
11
11
  registerAll(server, config);
package/dist/runtime.d.ts CHANGED
@@ -9,15 +9,20 @@
9
9
  * directly through `process.execPath`.
10
10
  */
11
11
  /**
12
- * Locate the `npm-cli.js` that ships with the currently-running Node.
12
+ * Locate a usable `npm-cli.js` on the system.
13
13
  *
14
- * Layouts we handle:
15
- * - Windows (official installer / nvm-windows):
16
- * <execDir>\node_modules\npm\bin\npm-cli.js
17
- * - Unix (nvm, homebrew, official installer):
18
- * <execDir>/../lib/node_modules/npm/bin/npm-cli.js
14
+ * Since `npm-cli.js` is plain JavaScript, any modern `node` binary can run
15
+ * it we don't need to find the npm that "ships with" the current Node.
16
+ * That matters on stripped Windows installs where `C:\Program Files\nodejs\`
17
+ * contains only `node.exe` (no bundled npm), but another Node (e.g. nvm)
18
+ * has a complete npm install elsewhere.
19
19
  *
20
- * Returns `null` if nothing is found — caller should fall back to `npm` on PATH.
20
+ * Search order:
21
+ * 1. Next to `process.execPath` (covers sane installs)
22
+ * 2. Platform-specific alternate locations (nvm / nvm-windows / npm prefix)
23
+ *
24
+ * Returns `null` if nothing is found — caller should fall back to shell
25
+ * resolution of `npm` / `npm.cmd`.
21
26
  */
22
27
  export declare function resolveNpmCli(): string | null;
23
28
  /**
@@ -25,19 +30,52 @@ export declare function resolveNpmCli(): string | null;
25
30
  * Returns `null` if `node_modules` isn't installed yet.
26
31
  */
27
32
  export declare function resolveHardhatCli(protocolPath: string): string | null;
33
+ /**
34
+ * Given the absolute path to `npm-cli.js`, derive the directory that holds
35
+ * the matching `npm.cmd`/`npx.cmd` (Windows) or `bin/npm`/`bin/npx` (Unix)
36
+ * shims. Returned directory should be **prepended** to the `PATH` of any
37
+ * child process that might invoke `npx` / `npm` internally — most notably
38
+ * `npm run <script>` children whose scripts reference `npx hardhat …`,
39
+ * which is the case for DeXe-Protocol's own `compile` / `coverage` scripts.
40
+ *
41
+ * Returns `null` if `npmCliPath` is `null` or the derived layout is
42
+ * unfamiliar (caller should leave `PATH` untouched).
43
+ */
44
+ export declare function deriveNodeBinDir(npmCliPath: string | null): string | null;
45
+ /**
46
+ * Build an `env` object that extends `process.env` with the Node shim
47
+ * directory prepended to `PATH`, so that child processes spawned by
48
+ * `npm run <script>` can resolve `npx` / `npm` even when the MCP server
49
+ * itself was launched by a stripped Node install whose PATH lacks them.
50
+ *
51
+ * Pass the returned env to `execa` / `execFile`. Idempotent — passing
52
+ * a `null` binDir returns the unchanged `process.env`.
53
+ */
54
+ export declare function envWithNodeBinDir(binDir: string | null): NodeJS.ProcessEnv;
28
55
  export declare function hasGit(): Promise<boolean>;
29
56
  /**
30
- * Describe the PATH-independent command we'd use to run `npm` / `npx`.
31
- * Returns the `[command, prefixArgs]` tuple so callers can append script args.
57
+ * Describe the command we'd use to run `npm`.
58
+ *
59
+ * Preferred form: `(process.execPath, [<absolute npm-cli.js>])` — invokes
60
+ * npm through the currently-running Node with zero PATH dependency, and
61
+ * works with `execFile` directly (no `shell: true` required).
32
62
  *
33
- * If `npm-cli.js` is found, we return `(process.execPath, [cliPath])`.
34
- * Otherwise we fall back to `("npm", [])` which requires PATHand may fail
35
- * on machines where npm isn't on the spawn PATH, but that's strictly better
36
- * than crashing at startup.
63
+ * Fallback: plain `npm` / `npm.cmd` on PATH. The `needsShell` flag tells
64
+ * the caller to set `{ shell: true }` on the spawn options without it,
65
+ * Node refuses to `execFile` a `.cmd` or `.bat` (CVE-2024-27980 fix), and
66
+ * callers get `spawn EINVAL`.
37
67
  */
38
68
  export declare function npmCommand(): {
39
69
  command: string;
40
70
  prefixArgs: string[];
71
+ needsShell: boolean;
72
+ /**
73
+ * Directory containing `npm.cmd`/`npx.cmd` (Windows) or `bin/npm`/`bin/npx`
74
+ * (Unix), paired with the `npm-cli.js` we resolved. Should be prepended
75
+ * to child PATH via `envWithNodeBinDir()` so npm scripts that invoke
76
+ * `npx foo` internally can find it.
77
+ */
78
+ binDir: string | null;
41
79
  };
42
80
  /**
43
81
  * Describe the command we'd use to run Hardhat against a given protocol path.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrE;AAID,wBAAgB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAQzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAItE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAIlD"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAM7C;AA2ED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAkBzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,UAAU,CAK1E;AAID,wBAAgB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAQzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,IAAI;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAgBA;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAIlD"}
package/dist/runtime.js CHANGED
@@ -1,6 +1,6 @@
1
- import { existsSync } from "node:fs";
1
+ import { existsSync, readdirSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
- import { platform } from "node:os";
3
+ import { homedir, platform } from "node:os";
4
4
  import { execFile } from "node:child_process";
5
5
  /**
6
6
  * Portable runtime helpers for spawning `npm`, `npx`, `hardhat`, and `git`
@@ -13,30 +13,92 @@ import { execFile } from "node:child_process";
13
13
  * directly through `process.execPath`.
14
14
  */
15
15
  /**
16
- * Locate the `npm-cli.js` that ships with the currently-running Node.
16
+ * Locate a usable `npm-cli.js` on the system.
17
17
  *
18
- * Layouts we handle:
19
- * - Windows (official installer / nvm-windows):
20
- * <execDir>\node_modules\npm\bin\npm-cli.js
21
- * - Unix (nvm, homebrew, official installer):
22
- * <execDir>/../lib/node_modules/npm/bin/npm-cli.js
18
+ * Since `npm-cli.js` is plain JavaScript, any modern `node` binary can run
19
+ * it we don't need to find the npm that "ships with" the current Node.
20
+ * That matters on stripped Windows installs where `C:\Program Files\nodejs\`
21
+ * contains only `node.exe` (no bundled npm), but another Node (e.g. nvm)
22
+ * has a complete npm install elsewhere.
23
23
  *
24
- * Returns `null` if nothing is found — caller should fall back to `npm` on PATH.
24
+ * Search order:
25
+ * 1. Next to `process.execPath` (covers sane installs)
26
+ * 2. Platform-specific alternate locations (nvm / nvm-windows / npm prefix)
27
+ *
28
+ * Returns `null` if nothing is found — caller should fall back to shell
29
+ * resolution of `npm` / `npm.cmd`.
25
30
  */
26
31
  export function resolveNpmCli() {
27
- const execDir = dirname(process.execPath);
28
- const candidates = platform() === "win32"
29
- ? [join(execDir, "node_modules", "npm", "bin", "npm-cli.js")]
30
- : [
31
- join(execDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
32
- join(execDir, "..", "libexec", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
33
- ];
32
+ const candidates = [...primaryNpmCandidates(), ...alternateNpmCandidates()];
34
33
  for (const c of candidates) {
35
- if (existsSync(c))
34
+ if (c && existsSync(c))
36
35
  return c;
37
36
  }
38
37
  return null;
39
38
  }
39
+ function primaryNpmCandidates() {
40
+ const execDir = dirname(process.execPath);
41
+ if (platform() === "win32") {
42
+ return [join(execDir, "node_modules", "npm", "bin", "npm-cli.js")];
43
+ }
44
+ return [
45
+ join(execDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
46
+ join(execDir, "..", "libexec", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
47
+ ];
48
+ }
49
+ function alternateNpmCandidates() {
50
+ const out = [];
51
+ const home = homedir();
52
+ const os = platform();
53
+ if (os === "win32") {
54
+ // nvm-windows: scan %APPDATA%\nvm\v* for the newest version that ships npm
55
+ const nvmRoots = [
56
+ process.env.NVM_HOME,
57
+ join(process.env.APPDATA || join(home, "AppData", "Roaming"), "nvm"),
58
+ ].filter((p) => !!p && existsSync(p));
59
+ for (const nvmRoot of nvmRoots) {
60
+ try {
61
+ const versions = readdirSync(nvmRoot)
62
+ .filter((d) => d.startsWith("v"))
63
+ .sort()
64
+ .reverse();
65
+ for (const v of versions) {
66
+ out.push(join(nvmRoot, v, "node_modules", "npm", "bin", "npm-cli.js"));
67
+ }
68
+ }
69
+ catch {
70
+ // ignore — unreadable nvm dir
71
+ }
72
+ }
73
+ // Per-user global prefix
74
+ out.push(join(process.env.APPDATA || join(home, "AppData", "Roaming"), "npm", "node_modules", "npm", "bin", "npm-cli.js"));
75
+ // System-wide stock install (if user later reinstalls without nvm)
76
+ out.push(join("C:\\", "Program Files", "nodejs", "node_modules", "npm", "bin", "npm-cli.js"));
77
+ }
78
+ else {
79
+ // nvm (Unix): scan ~/.nvm/versions/node/v*/lib/node_modules/npm/bin/npm-cli.js
80
+ const nvmDir = process.env.NVM_DIR || join(home, ".nvm");
81
+ const versionsDir = join(nvmDir, "versions", "node");
82
+ if (existsSync(versionsDir)) {
83
+ try {
84
+ const versions = readdirSync(versionsDir)
85
+ .filter((d) => d.startsWith("v"))
86
+ .sort()
87
+ .reverse();
88
+ for (const v of versions) {
89
+ out.push(join(versionsDir, v, "lib", "node_modules", "npm", "bin", "npm-cli.js"));
90
+ }
91
+ }
92
+ catch {
93
+ // ignore
94
+ }
95
+ }
96
+ // Homebrew
97
+ out.push("/opt/homebrew/lib/node_modules/npm/bin/npm-cli.js");
98
+ out.push("/usr/local/lib/node_modules/npm/bin/npm-cli.js");
99
+ }
100
+ return out;
101
+ }
40
102
  /**
41
103
  * Locate Hardhat's CLI entry point inside a protocol checkout.
42
104
  * Returns `null` if `node_modules` isn't installed yet.
@@ -45,6 +107,53 @@ export function resolveHardhatCli(protocolPath) {
45
107
  const p = join(protocolPath, "node_modules", "hardhat", "internal", "cli", "cli.js");
46
108
  return existsSync(p) ? p : null;
47
109
  }
110
+ /**
111
+ * Given the absolute path to `npm-cli.js`, derive the directory that holds
112
+ * the matching `npm.cmd`/`npx.cmd` (Windows) or `bin/npm`/`bin/npx` (Unix)
113
+ * shims. Returned directory should be **prepended** to the `PATH` of any
114
+ * child process that might invoke `npx` / `npm` internally — most notably
115
+ * `npm run <script>` children whose scripts reference `npx hardhat …`,
116
+ * which is the case for DeXe-Protocol's own `compile` / `coverage` scripts.
117
+ *
118
+ * Returns `null` if `npmCliPath` is `null` or the derived layout is
119
+ * unfamiliar (caller should leave `PATH` untouched).
120
+ */
121
+ export function deriveNodeBinDir(npmCliPath) {
122
+ if (!npmCliPath)
123
+ return null;
124
+ if (platform() === "win32") {
125
+ // Windows layout: <nodeRoot>\node_modules\npm\bin\npm-cli.js
126
+ // `.cmd` shims live at `<nodeRoot>\npm.cmd`, `<nodeRoot>\npx.cmd`.
127
+ // dirname x4 peels bin → npm → node_modules → nodeRoot.
128
+ const nodeRoot = dirname(dirname(dirname(dirname(npmCliPath))));
129
+ return existsSync(join(nodeRoot, "npm.cmd")) || existsSync(join(nodeRoot, "npx.cmd"))
130
+ ? nodeRoot
131
+ : null;
132
+ }
133
+ // Unix layouts (official installer / nvm / Homebrew):
134
+ // <prefix>/lib/node_modules/npm/bin/npm-cli.js
135
+ // Binaries live at `<prefix>/bin/npm` and `<prefix>/bin/npx`.
136
+ // dirname x5 peels bin → npm → node_modules → lib → prefix.
137
+ const prefix = dirname(dirname(dirname(dirname(dirname(npmCliPath)))));
138
+ const binDir = join(prefix, "bin");
139
+ return existsSync(join(binDir, "npx")) || existsSync(join(binDir, "npm")) ? binDir : null;
140
+ }
141
+ /**
142
+ * Build an `env` object that extends `process.env` with the Node shim
143
+ * directory prepended to `PATH`, so that child processes spawned by
144
+ * `npm run <script>` can resolve `npx` / `npm` even when the MCP server
145
+ * itself was launched by a stripped Node install whose PATH lacks them.
146
+ *
147
+ * Pass the returned env to `execa` / `execFile`. Idempotent — passing
148
+ * a `null` binDir returns the unchanged `process.env`.
149
+ */
150
+ export function envWithNodeBinDir(binDir) {
151
+ if (!binDir)
152
+ return { ...process.env };
153
+ const sep = platform() === "win32" ? ";" : ":";
154
+ const existing = process.env.PATH || process.env.Path || "";
155
+ return { ...process.env, PATH: `${binDir}${sep}${existing}` };
156
+ }
48
157
  /** Detect whether `git` is available on PATH. Cached per-process. */
49
158
  let gitAvailable = null;
50
159
  export function hasGit() {
@@ -58,19 +167,33 @@ export function hasGit() {
58
167
  });
59
168
  }
60
169
  /**
61
- * Describe the PATH-independent command we'd use to run `npm` / `npx`.
62
- * Returns the `[command, prefixArgs]` tuple so callers can append script args.
170
+ * Describe the command we'd use to run `npm`.
171
+ *
172
+ * Preferred form: `(process.execPath, [<absolute npm-cli.js>])` — invokes
173
+ * npm through the currently-running Node with zero PATH dependency, and
174
+ * works with `execFile` directly (no `shell: true` required).
63
175
  *
64
- * If `npm-cli.js` is found, we return `(process.execPath, [cliPath])`.
65
- * Otherwise we fall back to `("npm", [])` which requires PATHand may fail
66
- * on machines where npm isn't on the spawn PATH, but that's strictly better
67
- * than crashing at startup.
176
+ * Fallback: plain `npm` / `npm.cmd` on PATH. The `needsShell` flag tells
177
+ * the caller to set `{ shell: true }` on the spawn options without it,
178
+ * Node refuses to `execFile` a `.cmd` or `.bat` (CVE-2024-27980 fix), and
179
+ * callers get `spawn EINVAL`.
68
180
  */
69
181
  export function npmCommand() {
70
182
  const cli = resolveNpmCli();
71
- if (cli)
72
- return { command: process.execPath, prefixArgs: [cli] };
73
- return { command: platform() === "win32" ? "npm.cmd" : "npm", prefixArgs: [] };
183
+ if (cli) {
184
+ return {
185
+ command: process.execPath,
186
+ prefixArgs: [cli],
187
+ needsShell: false,
188
+ binDir: deriveNodeBinDir(cli),
189
+ };
190
+ }
191
+ return {
192
+ command: platform() === "win32" ? "npm.cmd" : "npm",
193
+ prefixArgs: [],
194
+ needsShell: platform() === "win32",
195
+ binDir: null,
196
+ };
74
197
  }
75
198
  /**
76
199
  * Describe the command we'd use to run Hardhat against a given protocol path.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;;;;;;GASG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GACd,QAAQ,EAAE,KAAK,OAAO;QACpB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QAC7D,CAAC,CAAC;YACE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC;YACtE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC;SAClF,CAAC;IACR,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAoB;IACpD,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrF,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED,qEAAqE;AACrE,IAAI,YAAY,GAAmB,IAAI,CAAC;AACxC,MAAM,UAAU,MAAM;IACpB,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAChE,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE;QACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;YAC5D,YAAY,GAAG,CAAC,GAAG,CAAC;YACpB,cAAc,CAAC,YAAY,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,GAAG;QAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AACjF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,YAAoB;IAEpB,MAAM,GAAG,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,GAAG;QAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dexe-mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "MCP server wrapping DeXe Protocol for Claude Code dev tooling (build/test, contract introspection, governance-domain tools)",
5
5
  "type": "module",
6
6
  "license": "MIT",