dexe-mcp 0.1.1 → 0.1.2

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/.mcp.example.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
+ "_comment": "Mac/Linux: use `dexe-mcp` directly. Windows: replace with { command: 'cmd', args: ['/c', 'dexe-mcp'] }. See README.md for the full install matrix.",
2
3
  "mcpServers": {
3
4
  "dexe": {
4
- "command": "npx",
5
- "args": ["-y", "dexe-mcp"]
5
+ "command": "dexe-mcp"
6
6
  }
7
7
  }
8
8
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Fixed
6
+ - **Server no longer hangs / fails on first launch.** The heavy `git clone` + `npm install` bootstrap is now lazy — it runs only when a build tool (`dexe_compile`, `dexe_test`, `dexe_coverage`, `dexe_lint`) is first invoked, not inside MCP `initialize()`. Previously the MCP handshake would block for minutes or time out, and crash outright on hosts where `npm` / `git` were not on the spawned process's PATH.
7
+ - **PATH-independent spawning of `npm` and `hardhat`.** The runner now invokes `node <npm-cli.js>` and `node <protocol>/node_modules/hardhat/internal/cli/cli.js` directly via `process.execPath`, so it works on Windows installs where `npm.cmd` / `npx.cmd` aren't on the MCP client's spawn PATH (common with nvm-windows and with stripped `node.exe`-only installs).
8
+ - **Actionable error messages** when `git` is not installed, when `DEXE_PROTOCOL_PATH` points at a non-Hardhat directory, or when the user-managed checkout is missing `node_modules`.
9
+ - Concurrent build-tool calls now coalesce into a single bootstrap instead of racing `git clone` / `npm install`.
10
+
11
+ ### Changed
12
+ - `loadConfig()` no longer hard-fails when the DeXe-Protocol checkout is missing or incomplete at startup — it logs a soft warning to stderr and defers preparation to the first build-tool invocation.
13
+ - `src/bootstrap.ts` split into `resolveProtocolPath()` (cheap, startup-safe) and `ensureBuildReady()` (lazy, idempotent).
14
+ - New `src/runtime.ts` with portable `npmCommand()` / `hardhatCommand()` / `hasGit()` helpers.
15
+
16
+ ### Docs
17
+ - README now has an OS-specific install matrix (Mac/Linux vs. Windows) and a "dev / local checkout" recipe. Troubleshooting section updated for the new lazy-bootstrap behavior and the `process.execPath` npm resolution.
18
+
3
19
  ## 0.1.1
4
20
 
5
21
  ### Added
package/README.md CHANGED
@@ -6,41 +6,101 @@ MCP server for Claude Code / Antigravity that wraps the [DeXe Protocol](https://
6
6
 
7
7
  ## Prerequisites
8
8
 
9
- - **Node.js >= 20**
10
- - **Git** (the server auto-clones DeXe-Protocol on first run)
9
+ - **Node.js >= 20** (with a bundled `npm` — i.e. any official installer, nvm, nvm-windows, or Homebrew build)
10
+ - **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
11
 
12
- ## Quick start
12
+ ## Install
13
13
 
14
- Add this to your project's `.mcp.json` (or your MCP client config):
14
+ ### 1. Install the package globally
15
+
16
+ ```bash
17
+ npm install -g dexe-mcp
18
+ ```
19
+
20
+ This installs a `dexe-mcp` binary on your PATH. Verify:
21
+
22
+ ```bash
23
+ dexe-mcp --version # or: where dexe-mcp (Windows) / which dexe-mcp (Mac/Linux)
24
+ ```
25
+
26
+ ### 2. Register the MCP server
27
+
28
+ #### Mac / Linux
29
+
30
+ ```bash
31
+ claude mcp add dexe -- dexe-mcp
32
+ ```
33
+
34
+ Or add to your MCP client config (`.mcp.json`, `claude_desktop_config.json`, etc.):
15
35
 
16
36
  ```json
17
37
  {
18
38
  "mcpServers": {
19
39
  "dexe": {
20
- "command": "npx",
21
- "args": ["-y", "dexe-mcp"]
40
+ "command": "dexe-mcp"
22
41
  }
23
42
  }
24
43
  }
25
44
  ```
26
45
 
27
- Restart your MCP client. On first launch, `dexe-mcp` will automatically:
46
+ #### Windows
28
47
 
29
- 1. Clone `dexe-network/DeXe-Protocol` to a local cache directory (~200 MB, shallow clone)
30
- 2. Run `npm install` in the checkout
48
+ Windows `CreateProcess` does not resolve `.cmd` shims from a bare command name, so wrap the call with `cmd /c`:
31
49
 
32
- Subsequent launches are instant. No manual setup needed.
50
+ ```bash
51
+ claude mcp add dexe -- cmd /c dexe-mcp
52
+ ```
53
+
54
+ Or in JSON:
33
55
 
34
- ### Advanced: custom checkout path
56
+ ```json
57
+ {
58
+ "mcpServers": {
59
+ "dexe": {
60
+ "command": "cmd",
61
+ "args": ["/c", "dexe-mcp"]
62
+ }
63
+ }
64
+ }
65
+ ```
35
66
 
36
- If you already have a DeXe-Protocol checkout or want to control its location:
67
+ **Absolute-path fallback** (works everywhere, zero PATH dependency):
37
68
 
38
69
  ```json
39
70
  {
40
71
  "mcpServers": {
41
72
  "dexe": {
42
- "command": "npx",
43
- "args": ["-y", "dexe-mcp"],
73
+ "command": "node",
74
+ "args": ["C:/Users/<you>/AppData/Roaming/npm/node_modules/dexe-mcp/dist/index.js"]
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ### 3. Restart your MCP client
81
+
82
+ On the first build-tool call (e.g. `dexe_compile`), `dexe-mcp` will automatically:
83
+
84
+ 1. Shallow-clone `dexe-network/DeXe-Protocol` into a platform cache directory (~200 MB)
85
+ 2. Run `npm install` in that checkout (a few minutes, one time)
86
+
87
+ The MCP server itself starts instantly — the heavy work is deferred until you actually need it. Cache locations:
88
+
89
+ | OS | Path |
90
+ |----|------|
91
+ | Windows | `%LOCALAPPDATA%\dexe-mcp\DeXe-Protocol` |
92
+ | macOS | `~/Library/Caches/dexe-mcp/DeXe-Protocol` |
93
+ | Linux | `$XDG_CACHE_HOME/dexe-mcp/DeXe-Protocol` (or `~/.cache/dexe-mcp/DeXe-Protocol`) |
94
+
95
+ ### Advanced: existing DeXe-Protocol checkout
96
+
97
+ If you already have a DeXe-Protocol clone you want to reuse (and have run `npm install` there at least once), set `DEXE_PROTOCOL_PATH`:
98
+
99
+ ```json
100
+ {
101
+ "mcpServers": {
102
+ "dexe": {
103
+ "command": "dexe-mcp",
44
104
  "env": {
45
105
  "DEXE_PROTOCOL_PATH": "/absolute/path/to/your/DeXe-Protocol"
46
106
  }
@@ -49,9 +109,36 @@ If you already have a DeXe-Protocol checkout or want to control its location:
49
109
  }
50
110
  ```
51
111
 
112
+ With this set, dexe-mcp will **not** clone or install anything — it trusts the path you gave it. On Windows, wrap `command` with `cmd /c` as above.
113
+
114
+ ### Dev mode (working on dexe-mcp itself)
115
+
116
+ Clone this repo, build, and point the MCP command at the local `dist/index.js`:
117
+
118
+ ```bash
119
+ git clone https://github.com/edward-arinin-web-dev/dexe-mcp.git
120
+ cd dexe-mcp
121
+ npm install
122
+ npm run build
123
+ ```
124
+
125
+ ```json
126
+ {
127
+ "mcpServers": {
128
+ "dexe": {
129
+ "command": "node",
130
+ "args": ["/absolute/path/to/dexe-mcp/dist/index.js"],
131
+ "env": {
132
+ "DEXE_PROTOCOL_PATH": "/absolute/path/to/DeXe-Protocol"
133
+ }
134
+ }
135
+ }
136
+ }
137
+ ```
138
+
52
139
  ## First run
53
140
 
54
- Before introspection tools work, run `dexe_compile` once per session to populate `DeXe-Protocol/artifacts/`. You will get a clear "artifacts not found" error otherwise.
141
+ Before introspection tools work, run `dexe_compile` once per session to populate `DeXe-Protocol/artifacts/`. You will get a clear "artifacts not found" error otherwise. On a brand-new install the first `dexe_compile` also triggers the clone + `npm install` steps described above.
55
142
 
56
143
  ## Tool catalog
57
144
 
@@ -89,19 +176,37 @@ Before introspection tools work, run `dexe_compile` once per session to populate
89
176
 
90
177
  | Variable | Required | Purpose |
91
178
  |----------|----------|---------|
92
- | `DEXE_PROTOCOL_PATH` | no | Override the auto-managed DeXe-Protocol checkout path |
179
+ | `DEXE_PROTOCOL_PATH` | no | Use an existing DeXe-Protocol checkout; disables auto clone/install |
93
180
  | `DEXE_RPC_URL` | no | JSON-RPC endpoint for `dexe_decode_proposal` and `dexe_read_gov_state` |
94
181
  | `DEXE_FORK_BLOCK` | no | Pin the fork to a specific block (Phase B) |
95
182
 
96
183
  ## Troubleshooting
97
184
 
185
+ ### "`git` is not on PATH"
186
+
187
+ Install git from <https://git-scm.com/downloads> and restart your MCP client. Alternatively, clone DeXe-Protocol manually and set `DEXE_PROTOCOL_PATH` to skip the clone step entirely.
188
+
189
+ ### "`npm install` failed inside DeXe-Protocol"
190
+
191
+ Usually means your Node install lacks a bundled `npm` (e.g. a stripped `node.exe` dropped on PATH without the rest of the install). Reinstall Node from <https://nodejs.org> or via nvm / nvm-windows and retry. dexe-mcp invokes npm via `process.execPath` so it uses whichever Node is running it — it does not need `npm` on the spawn PATH.
192
+
193
+ ### "Failed to connect" in Claude Code (Windows)
194
+
195
+ Claude Code spawns MCP servers with `CreateProcess`, which can't resolve `.cmd` shims from a bare name. Wrap the command:
196
+
197
+ ```json
198
+ { "command": "cmd", "args": ["/c", "dexe-mcp"] }
199
+ ```
200
+
201
+ Or use the absolute-path fallback pointing at `node` + `dist/index.js` directly.
202
+
98
203
  ### "Hardhat artifacts not found — run dexe_compile first"
99
204
 
100
205
  Introspection tools require compiled artifacts. Run `dexe_compile` once after the initial setup to populate them.
101
206
 
102
- ### "Failed to clone DeXe-Protocol"
207
+ ### "DEXE_PROTOCOL_PATH=… is missing node_modules"
103
208
 
104
- Make sure `git` is installed and available on your PATH, and that you have internet access. The server clones from `https://github.com/dexe-network/DeXe-Protocol.git`.
209
+ You pointed `DEXE_PROTOCOL_PATH` at a checkout that hasn't been installed yet. `cd` into it and run `npm install` once, then retry.
105
210
 
106
211
  ### "DEXE_RPC_URL is not set"
107
212
 
@@ -1,12 +1,30 @@
1
1
  /**
2
- * Ensures a DeXe-Protocol checkout is available, returning its absolute path.
2
+ * Cheap, synchronous resolution of where the DeXe-Protocol checkout *should*
3
+ * live. **Does not** clone or install anything — safe to call at MCP startup.
3
4
  *
4
5
  * Priority:
5
6
  * 1. `DEXE_PROTOCOL_PATH` env var (power-user override)
6
- * 2. Auto-managed clone in the platform cache directory
7
+ * 2. Auto-managed path inside the platform cache directory
7
8
  *
8
- * On first run the clone + npm install may take a few minutes.
9
- * Progress is logged to stderr (stdout is the MCP protocol channel).
9
+ * The returned path may not exist yet on disk. Call `ensureBuildReady()`
10
+ * before invoking tools that require hardhat.
10
11
  */
11
- export declare function ensureProtocolCheckout(): Promise<string>;
12
+ export declare function resolveProtocolPath(): string;
13
+ /**
14
+ * True if `protocolPath` looks like a hardhat project with installed deps.
15
+ * Used by build/test tools to short-circuit the lazy bootstrap.
16
+ */
17
+ export declare function isBuildReady(protocolPath: string): boolean;
18
+ /**
19
+ * Lazy, expensive bootstrap: ensures a DeXe-Protocol checkout exists at
20
+ * `protocolPath` and that its npm dependencies are installed. Idempotent.
21
+ *
22
+ * Only called from build/test tools. MCP startup must **not** await this.
23
+ *
24
+ * Skipped entirely when `DEXE_PROTOCOL_PATH` points at a user-managed
25
+ * checkout — we trust the user to keep it in shape.
26
+ *
27
+ * Throws with an actionable message if `git` or `npm` are unavailable.
28
+ */
29
+ export declare function ensureBuildReady(protocolPath: string): Promise<void>;
12
30
  //# sourceMappingURL=bootstrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAsCA;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAgD9D"}
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"}
package/dist/bootstrap.js CHANGED
@@ -1,7 +1,10 @@
1
1
  import { existsSync, mkdirSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { homedir, platform } from "node:os";
4
- import { execSync } from "node:child_process";
4
+ import { execFile } from "node:child_process";
5
+ import { promisify } from "node:util";
6
+ import { hasGit, npmCommand } from "./runtime.js";
7
+ const execFileAsync = promisify(execFile);
5
8
  const REPO_URL = "https://github.com/dexe-network/DeXe-Protocol.git";
6
9
  const CACHE_DIR_NAME = "dexe-mcp";
7
10
  const CHECKOUT_DIR = "DeXe-Protocol";
@@ -21,63 +24,119 @@ function getCacheDir() {
21
24
  if (os === "darwin") {
22
25
  return join(homedir(), "Library", "Caches", CACHE_DIR_NAME);
23
26
  }
24
- // Linux / others — respect XDG_CACHE_HOME
25
27
  const base = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
26
28
  return join(base, CACHE_DIR_NAME);
27
29
  }
28
30
  function log(msg) {
29
31
  process.stderr.write(`[dexe-mcp] ${msg}\n`);
30
32
  }
31
- function runSync(cmd, cwd) {
32
- execSync(cmd, { cwd, stdio: ["ignore", "pipe", "pipe"] });
33
- }
34
33
  /**
35
- * Ensures a DeXe-Protocol checkout is available, returning its absolute path.
34
+ * Cheap, synchronous resolution of where the DeXe-Protocol checkout *should*
35
+ * live. **Does not** clone or install anything — safe to call at MCP startup.
36
36
  *
37
37
  * Priority:
38
38
  * 1. `DEXE_PROTOCOL_PATH` env var (power-user override)
39
- * 2. Auto-managed clone in the platform cache directory
39
+ * 2. Auto-managed path inside the platform cache directory
40
40
  *
41
- * On first run the clone + npm install may take a few minutes.
42
- * Progress is logged to stderr (stdout is the MCP protocol channel).
41
+ * The returned path may not exist yet on disk. Call `ensureBuildReady()`
42
+ * before invoking tools that require hardhat.
43
43
  */
44
- export async function ensureProtocolCheckout() {
45
- // ---- explicit override ----
44
+ export function resolveProtocolPath() {
46
45
  const explicit = process.env.DEXE_PROTOCOL_PATH?.trim();
47
46
  if (explicit)
48
47
  return explicit;
49
- // ---- auto-managed clone ----
50
- const cacheDir = getCacheDir();
51
- const protocolPath = join(cacheDir, CHECKOUT_DIR);
52
- if (!existsSync(cacheDir)) {
53
- mkdirSync(cacheDir, { recursive: true });
54
- }
55
- const gitDir = join(protocolPath, ".git");
56
- if (!existsSync(gitDir)) {
57
- log(`Cloning DeXe-Protocol (shallow, ~200 MB) into ${protocolPath} …`);
58
- log("This only happens once. Subsequent launches will be instant.");
59
- try {
60
- runSync(`git clone --depth 1 ${REPO_URL} "${CHECKOUT_DIR}"`, cacheDir);
61
- }
62
- catch (err) {
63
- const msg = err instanceof Error ? err.message : String(err);
64
- throw new Error(`Failed to clone DeXe-Protocol. Make sure git is installed and you have internet access.\n${msg}`);
65
- }
66
- log("Clone complete.");
67
- }
68
- // Ensure npm dependencies are installed
69
- const nodeModules = join(protocolPath, "node_modules");
70
- if (!existsSync(nodeModules)) {
71
- log("Installing DeXe-Protocol npm dependencies (first run only) …");
48
+ return join(getCacheDir(), CHECKOUT_DIR);
49
+ }
50
+ /**
51
+ * True if `protocolPath` looks like a hardhat project with installed deps.
52
+ * Used by build/test tools to short-circuit the lazy bootstrap.
53
+ */
54
+ export function isBuildReady(protocolPath) {
55
+ if (!existsSync(protocolPath))
56
+ return false;
57
+ const hasConfig = existsSync(join(protocolPath, "hardhat.config.js")) ||
58
+ existsSync(join(protocolPath, "hardhat.config.ts"));
59
+ const hasNodeModules = existsSync(join(protocolPath, "node_modules"));
60
+ return hasConfig && hasNodeModules;
61
+ }
62
+ // Promise-coalescing: if two tools call ensureBuildReady() concurrently,
63
+ // they should share a single clone+install, not race.
64
+ let inflightEnsure = null;
65
+ /**
66
+ * Lazy, expensive bootstrap: ensures a DeXe-Protocol checkout exists at
67
+ * `protocolPath` and that its npm dependencies are installed. Idempotent.
68
+ *
69
+ * Only called from build/test tools. MCP startup must **not** await this.
70
+ *
71
+ * Skipped entirely when `DEXE_PROTOCOL_PATH` points at a user-managed
72
+ * checkout — we trust the user to keep it in shape.
73
+ *
74
+ * Throws with an actionable message if `git` or `npm` are unavailable.
75
+ */
76
+ export async function ensureBuildReady(protocolPath) {
77
+ if (isBuildReady(protocolPath))
78
+ return;
79
+ if (inflightEnsure)
80
+ return inflightEnsure;
81
+ inflightEnsure = (async () => {
72
82
  try {
73
- runSync("npm install", protocolPath);
83
+ const explicit = process.env.DEXE_PROTOCOL_PATH?.trim();
84
+ if (explicit) {
85
+ // User-managed checkout: don't touch it. Give a clear diagnosis.
86
+ if (!existsSync(protocolPath)) {
87
+ throw new Error(`DEXE_PROTOCOL_PATH points at ${protocolPath}, but that directory does not exist.`);
88
+ }
89
+ if (!existsSync(join(protocolPath, "hardhat.config.js")) &&
90
+ !existsSync(join(protocolPath, "hardhat.config.ts"))) {
91
+ throw new Error(`DEXE_PROTOCOL_PATH=${protocolPath} is not a Hardhat project (no hardhat.config.{js,ts}).`);
92
+ }
93
+ if (!existsSync(join(protocolPath, "node_modules"))) {
94
+ throw new Error(`DEXE_PROTOCOL_PATH=${protocolPath} is missing node_modules. Run \`npm install\` there once and retry.`);
95
+ }
96
+ return;
97
+ }
98
+ // Auto-managed cache path: we own it, we can clone + install into it.
99
+ const cacheDir = getCacheDir();
100
+ if (!existsSync(cacheDir))
101
+ mkdirSync(cacheDir, { recursive: true });
102
+ if (!existsSync(join(protocolPath, ".git"))) {
103
+ if (!(await hasGit())) {
104
+ throw new Error("`git` is not on PATH. Install git (https://git-scm.com/downloads) and retry — dexe-mcp needs it to fetch the DeXe-Protocol sources on first run.");
105
+ }
106
+ log(`Cloning DeXe-Protocol (shallow, ~200 MB) into ${protocolPath} …`);
107
+ log("This only happens once. Subsequent calls will be instant.");
108
+ try {
109
+ await execFileAsync("git", ["clone", "--depth", "1", REPO_URL, CHECKOUT_DIR], { cwd: cacheDir, windowsHide: true });
110
+ }
111
+ catch (err) {
112
+ const msg = err instanceof Error ? err.message : String(err);
113
+ throw new Error(`Failed to clone DeXe-Protocol. Check internet access and git credentials.\n${msg}`);
114
+ }
115
+ log("Clone complete.");
116
+ }
117
+ if (!existsSync(join(protocolPath, "node_modules"))) {
118
+ log("Installing DeXe-Protocol npm dependencies (first run only) — this takes a few minutes …");
119
+ const npm = npmCommand();
120
+ try {
121
+ await execFileAsync(npm.command, [...npm.prefixArgs, "install", "--no-audit", "--no-fund"], {
122
+ cwd: protocolPath,
123
+ windowsHide: true,
124
+ maxBuffer: 64 * 1024 * 1024,
125
+ });
126
+ }
127
+ catch (err) {
128
+ const msg = err instanceof Error ? err.message : String(err);
129
+ throw new Error(`\`npm install\` failed inside ${protocolPath}.\n` +
130
+ `If your Node install lacks a bundled npm (e.g. a stripped node.exe), ` +
131
+ `install Node from https://nodejs.org or via nvm and retry.\n${msg}`);
132
+ }
133
+ log("Dependencies installed.");
134
+ }
74
135
  }
75
- catch (err) {
76
- const msg = err instanceof Error ? err.message : String(err);
77
- throw new Error(`npm install failed in DeXe-Protocol checkout.\n${msg}`);
136
+ finally {
137
+ inflightEnsure = null;
78
138
  }
79
- log("Dependencies installed.");
80
- }
81
- return protocolPath;
139
+ })();
140
+ return inflightEnsure;
82
141
  }
83
142
  //# sourceMappingURL=bootstrap.js.map
@@ -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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"}
package/dist/config.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export interface DexeConfig {
2
- /** Absolute, normalized path to the DeXe-Protocol checkout. */
2
+ /** Absolute, normalized path to the DeXe-Protocol checkout (may not exist yet). */
3
3
  protocolPath: string;
4
4
  /** Optional JSON-RPC endpoint for on-chain gov tools. */
5
5
  rpcUrl?: string;
@@ -7,13 +7,10 @@ export interface DexeConfig {
7
7
  forkBlock?: number;
8
8
  }
9
9
  /**
10
- * Validates environment and returns a frozen config.
11
- *
12
- * If `DEXE_PROTOCOL_PATH` is set, uses it directly (power-user override).
13
- * Otherwise, auto-clones DeXe-Protocol into a platform cache directory.
14
- *
15
- * Exported primarily for the MCP entrypoint; tests can construct their own
16
- * config objects directly.
10
+ * Reads environment and returns a frozen config. **Fast and side-effect-free**
11
+ * — safe to await during MCP `initialize`. Does not clone, install, or shell
12
+ * out. The protocol checkout may not exist yet; `ensureBuildReady` handles
13
+ * that lazily from inside build/test tools.
17
14
  */
18
15
  export declare function loadConfig(): Promise<DexeConfig>;
19
16
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CA4BtD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CA4BtD"}
package/dist/config.js CHANGED
@@ -1,25 +1,22 @@
1
- import { existsSync, statSync } from "node:fs";
2
- import { resolve, join } from "node:path";
3
- import { ensureProtocolCheckout } from "./bootstrap.js";
1
+ import { existsSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { resolveProtocolPath, isBuildReady } from "./bootstrap.js";
4
4
  /**
5
- * Validates environment and returns a frozen config.
6
- *
7
- * If `DEXE_PROTOCOL_PATH` is set, uses it directly (power-user override).
8
- * Otherwise, auto-clones DeXe-Protocol into a platform cache directory.
9
- *
10
- * Exported primarily for the MCP entrypoint; tests can construct their own
11
- * config objects directly.
5
+ * Reads environment and returns a frozen config. **Fast and side-effect-free**
6
+ * — safe to await during MCP `initialize`. Does not clone, install, or shell
7
+ * out. The protocol checkout may not exist yet; `ensureBuildReady` handles
8
+ * that lazily from inside build/test tools.
12
9
  */
13
10
  export async function loadConfig() {
14
- const raw = await ensureProtocolCheckout();
15
- const protocolPath = resolve(raw);
16
- if (!existsSync(protocolPath) || !statSync(protocolPath).isDirectory()) {
17
- fatal(`DeXe-Protocol path does not exist or is not a directory: ${protocolPath}`);
11
+ const protocolPath = resolve(resolveProtocolPath());
12
+ // Soft warning only — don't block startup. The lazy bootstrap will either
13
+ // create the checkout (auto-managed path) or surface a clear error when a
14
+ // build tool is actually invoked (DEXE_PROTOCOL_PATH override).
15
+ if (!existsSync(protocolPath)) {
16
+ process.stderr.write(`[dexe-mcp] DeXe-Protocol checkout not found at ${protocolPath} — will be prepared on first dexe_compile call.\n`);
18
17
  }
19
- const hardhatConfig = join(protocolPath, "hardhat.config.js");
20
- const hardhatConfigTs = join(protocolPath, "hardhat.config.ts");
21
- if (!existsSync(hardhatConfig) && !existsSync(hardhatConfigTs)) {
22
- fatal(`DeXe-Protocol path is not a Hardhat project — no hardhat.config.{js,ts} found at ${protocolPath}`);
18
+ else if (!isBuildReady(protocolPath)) {
19
+ process.stderr.write(`[dexe-mcp] DeXe-Protocol checkout at ${protocolPath} is incomplete (missing node_modules or hardhat.config) — will be prepared on first dexe_compile call.\n`);
23
20
  }
24
21
  const rpcUrl = process.env.DEXE_RPC_URL?.trim() || undefined;
25
22
  let forkBlock;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAWxD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,GAAG,GAAG,MAAM,sBAAsB,EAAE,CAAC;IAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACvE,KAAK,CAAC,4DAA4D,YAAY,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;IAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;IAChE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAC/D,KAAK,CACH,oFAAoF,YAAY,EAAE,CACnG,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAE7D,IAAI,SAA6B,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,wDAAwD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,SAAS,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,oDAAoD;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAWnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAEpD,0EAA0E;IAC1E,0EAA0E;IAC1E,gEAAgE;IAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kDAAkD,YAAY,mDAAmD,CAClH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wCAAwC,YAAY,0GAA0G,CAC/J,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAE7D,IAAI,SAA6B,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,wDAAwD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,SAAS,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,oDAAoD;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
package/dist/hardhat.d.ts CHANGED
@@ -17,9 +17,19 @@ export interface RunResult {
17
17
  export declare class HardhatRunner {
18
18
  private readonly config;
19
19
  constructor(config: DexeConfig);
20
- /** Run `npm run <script>` in the protocol directory. */
20
+ /**
21
+ * Run `npm run <script>` in the protocol directory.
22
+ *
23
+ * Uses `node <npm-cli.js>` under the hood so this works regardless of
24
+ * whether `npm` is on the MCP's spawn PATH.
25
+ */
21
26
  runNpmScript(script: string, extraArgs?: string[]): Promise<RunResult>;
22
- /** Run `npx hardhat <subcommand> <args...>` in the protocol directory. */
27
+ /**
28
+ * Run `hardhat <subcommand> <args...>` in the protocol directory.
29
+ *
30
+ * Uses `node <protocol>/node_modules/hardhat/internal/cli/cli.js` so this
31
+ * doesn't require `npx` on PATH.
32
+ */
23
33
  runHardhat(subcommand: string, args?: string[]): Promise<RunResult>;
24
34
  private run;
25
35
  }
@@ -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;AAE9C,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,wDAAwD;IACxD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAQ1E,0EAA0E;IAC1E,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAIvE,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;IAQhF;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAW7E,OAAO,CAAC,GAAG;CAuDZ"}
package/dist/hardhat.js CHANGED
@@ -3,6 +3,8 @@ import pLimit from "p-limit";
3
3
  import { writeFileSync, mkdtempSync } from "node:fs";
4
4
  import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
+ import { ensureBuildReady } from "./bootstrap.js";
7
+ import { hardhatCommand, npmCommand } from "./runtime.js";
6
8
  const HARDHAT_TIMEOUT_MS = 10 * 60 * 1000;
7
9
  const STDOUT_TAIL_LINES = 200;
8
10
  const STDERR_TAIL_LINES = 100;
@@ -21,17 +23,33 @@ export class HardhatRunner {
21
23
  constructor(config) {
22
24
  this.config = config;
23
25
  }
24
- /** Run `npm run <script>` in the protocol directory. */
25
- runNpmScript(script, extraArgs = []) {
26
- const args = ["run", script];
27
- if (extraArgs.length > 0) {
26
+ /**
27
+ * Run `npm run <script>` in the protocol directory.
28
+ *
29
+ * Uses `node <npm-cli.js>` under the hood so this works regardless of
30
+ * whether `npm` is on the MCP's spawn PATH.
31
+ */
32
+ async runNpmScript(script, extraArgs = []) {
33
+ await ensureBuildReady(this.config.protocolPath);
34
+ const npm = npmCommand();
35
+ const args = [...npm.prefixArgs, "run", script];
36
+ if (extraArgs.length > 0)
28
37
  args.push("--", ...extraArgs);
29
- }
30
- return this.run("npm", args, `npm-run-${script}`);
38
+ return this.run(npm.command, args, `npm-run-${script}`);
31
39
  }
32
- /** Run `npx hardhat <subcommand> <args...>` in the protocol directory. */
33
- runHardhat(subcommand, args = []) {
34
- return this.run("npx", ["hardhat", subcommand, ...args], `hardhat-${subcommand}`);
40
+ /**
41
+ * Run `hardhat <subcommand> <args...>` in the protocol directory.
42
+ *
43
+ * Uses `node <protocol>/node_modules/hardhat/internal/cli/cli.js` so this
44
+ * doesn't require `npx` on PATH.
45
+ */
46
+ async runHardhat(subcommand, args = []) {
47
+ await ensureBuildReady(this.config.protocolPath);
48
+ const hh = hardhatCommand(this.config.protocolPath);
49
+ if (!hh) {
50
+ throw new Error(`Hardhat is not installed inside ${this.config.protocolPath}. This should have been fixed by ensureBuildReady — did npm install fail?`);
51
+ }
52
+ return this.run(hh.command, [...hh.prefixArgs, subcommand, ...args], `hardhat-${subcommand}`);
35
53
  }
36
54
  run(command, args, label) {
37
55
  return limit(async () => {
@@ -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.1" }, {
8
+ const server = new McpServer({ name: "dexe-mcp", version: "0.1.2" }, {
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);
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Portable runtime helpers for spawning `npm`, `npx`, `hardhat`, and `git`
3
+ * without depending on the MCP process's PATH.
4
+ *
5
+ * Claude Code (and other MCP clients) spawn servers with a minimal PATH.
6
+ * On Windows in particular, `npm`/`npx` are `.cmd` shims that `CreateProcess`
7
+ * won't find unless they're on that PATH. We side-step the whole problem by
8
+ * invoking JS entry points (`npm-cli.js`, `hardhat/internal/cli/cli.js`)
9
+ * directly through `process.execPath`.
10
+ */
11
+ /**
12
+ * Locate the `npm-cli.js` that ships with the currently-running Node.
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
19
+ *
20
+ * Returns `null` if nothing is found — caller should fall back to `npm` on PATH.
21
+ */
22
+ export declare function resolveNpmCli(): string | null;
23
+ /**
24
+ * Locate Hardhat's CLI entry point inside a protocol checkout.
25
+ * Returns `null` if `node_modules` isn't installed yet.
26
+ */
27
+ export declare function resolveHardhatCli(protocolPath: string): string | null;
28
+ export declare function hasGit(): Promise<boolean>;
29
+ /**
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.
32
+ *
33
+ * If `npm-cli.js` is found, we return `(process.execPath, [cliPath])`.
34
+ * Otherwise we fall back to `("npm", [])` which requires PATH — and may fail
35
+ * on machines where npm isn't on the spawn PATH, but that's strictly better
36
+ * than crashing at startup.
37
+ */
38
+ export declare function npmCommand(): {
39
+ command: string;
40
+ prefixArgs: string[];
41
+ };
42
+ /**
43
+ * Describe the command we'd use to run Hardhat against a given protocol path.
44
+ *
45
+ * Prefers `node <protocolPath>/node_modules/hardhat/internal/cli/cli.js` which
46
+ * has zero PATH dependency. Falls back to `npx hardhat` (requires PATH).
47
+ *
48
+ * Returns `null` if the protocol's `node_modules` isn't installed — caller
49
+ * should trigger `ensureBuildReady` first.
50
+ */
51
+ export declare function hardhatCommand(protocolPath: string): {
52
+ command: string;
53
+ prefixArgs: string[];
54
+ } | null;
55
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,90 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { platform } from "node:os";
4
+ import { execFile } from "node:child_process";
5
+ /**
6
+ * Portable runtime helpers for spawning `npm`, `npx`, `hardhat`, and `git`
7
+ * without depending on the MCP process's PATH.
8
+ *
9
+ * Claude Code (and other MCP clients) spawn servers with a minimal PATH.
10
+ * On Windows in particular, `npm`/`npx` are `.cmd` shims that `CreateProcess`
11
+ * won't find unless they're on that PATH. We side-step the whole problem by
12
+ * invoking JS entry points (`npm-cli.js`, `hardhat/internal/cli/cli.js`)
13
+ * directly through `process.execPath`.
14
+ */
15
+ /**
16
+ * Locate the `npm-cli.js` that ships with the currently-running Node.
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
23
+ *
24
+ * Returns `null` if nothing is found — caller should fall back to `npm` on PATH.
25
+ */
26
+ 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
+ ];
34
+ for (const c of candidates) {
35
+ if (existsSync(c))
36
+ return c;
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Locate Hardhat's CLI entry point inside a protocol checkout.
42
+ * Returns `null` if `node_modules` isn't installed yet.
43
+ */
44
+ export function resolveHardhatCli(protocolPath) {
45
+ const p = join(protocolPath, "node_modules", "hardhat", "internal", "cli", "cli.js");
46
+ return existsSync(p) ? p : null;
47
+ }
48
+ /** Detect whether `git` is available on PATH. Cached per-process. */
49
+ let gitAvailable = null;
50
+ export function hasGit() {
51
+ if (gitAvailable !== null)
52
+ return Promise.resolve(gitAvailable);
53
+ return new Promise((resolvePromise) => {
54
+ execFile("git", ["--version"], { windowsHide: true }, (err) => {
55
+ gitAvailable = !err;
56
+ resolvePromise(gitAvailable);
57
+ });
58
+ });
59
+ }
60
+ /**
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.
63
+ *
64
+ * If `npm-cli.js` is found, we return `(process.execPath, [cliPath])`.
65
+ * Otherwise we fall back to `("npm", [])` which requires PATH — and may fail
66
+ * on machines where npm isn't on the spawn PATH, but that's strictly better
67
+ * than crashing at startup.
68
+ */
69
+ export function npmCommand() {
70
+ const cli = resolveNpmCli();
71
+ if (cli)
72
+ return { command: process.execPath, prefixArgs: [cli] };
73
+ return { command: platform() === "win32" ? "npm.cmd" : "npm", prefixArgs: [] };
74
+ }
75
+ /**
76
+ * Describe the command we'd use to run Hardhat against a given protocol path.
77
+ *
78
+ * Prefers `node <protocolPath>/node_modules/hardhat/internal/cli/cli.js` which
79
+ * has zero PATH dependency. Falls back to `npx hardhat` (requires PATH).
80
+ *
81
+ * Returns `null` if the protocol's `node_modules` isn't installed — caller
82
+ * should trigger `ensureBuildReady` first.
83
+ */
84
+ export function hardhatCommand(protocolPath) {
85
+ const cli = resolveHardhatCli(protocolPath);
86
+ if (cli)
87
+ return { command: process.execPath, prefixArgs: [cli] };
88
+ return null;
89
+ }
90
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dexe-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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",