dexe-mcp 0.1.1 → 0.1.3
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 +2 -2
- package/CHANGELOG.md +25 -0
- package/README.md +171 -18
- package/dist/bootstrap.d.ts +23 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +100 -41
- package/dist/bootstrap.js.map +1 -1
- package/dist/config.d.ts +5 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -18
- package/dist/config.js.map +1 -1
- package/dist/hardhat.d.ts +12 -2
- package/dist/hardhat.d.ts.map +1 -1
- package/dist/hardhat.js +27 -9
- package/dist/hardhat.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime.d.ts +55 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +90 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +1 -1
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": "
|
|
5
|
-
"args": ["-y", "dexe-mcp"]
|
|
5
|
+
"command": "dexe-mcp"
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.3
|
|
4
|
+
|
|
5
|
+
### Docs
|
|
6
|
+
- **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.
|
|
7
|
+
- **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.
|
|
8
|
+
- 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".
|
|
9
|
+
|
|
10
|
+
No code changes — 0.1.3 is a docs-only patch on top of 0.1.2's behavior.
|
|
11
|
+
|
|
12
|
+
## 0.1.2
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **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.
|
|
16
|
+
- **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).
|
|
17
|
+
- **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`.
|
|
18
|
+
- Concurrent build-tool calls now coalesce into a single bootstrap instead of racing `git clone` / `npm install`.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- `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.
|
|
22
|
+
- `src/bootstrap.ts` split into `resolveProtocolPath()` (cheap, startup-safe) and `ensureBuildReady()` (lazy, idempotent).
|
|
23
|
+
- New `src/runtime.ts` with portable `npmCommand()` / `hardhatCommand()` / `hasGit()` helpers.
|
|
24
|
+
|
|
25
|
+
### Docs
|
|
26
|
+
- 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.
|
|
27
|
+
|
|
3
28
|
## 0.1.1
|
|
4
29
|
|
|
5
30
|
### Added
|
package/README.md
CHANGED
|
@@ -6,41 +6,142 @@ 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 working `npm`. Verify before continuing:
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
```bash
|
|
12
|
+
node --version # should print v20.x or higher
|
|
13
|
+
npm --version # MUST print a version, not "command not found"
|
|
14
|
+
```
|
|
13
15
|
|
|
14
|
-
|
|
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
|
+
|
|
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.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
### 1. Install the package globally
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g dexe-mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Verify the install landed by asking npm where it put it:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
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)
|
|
35
|
+
```
|
|
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
|
+
|
|
39
|
+
### 2. Register the MCP server
|
|
40
|
+
|
|
41
|
+
#### Mac / Linux
|
|
42
|
+
|
|
43
|
+
Bare command works because Unix `exec` resolves PATH directly:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
claude mcp add dexe -- dexe-mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or in JSON (`.mcp.json`, `claude_desktop_config.json`, etc.):
|
|
15
50
|
|
|
16
51
|
```json
|
|
17
52
|
{
|
|
18
53
|
"mcpServers": {
|
|
19
54
|
"dexe": {
|
|
20
|
-
"command": "
|
|
21
|
-
"args": ["-y", "dexe-mcp"]
|
|
55
|
+
"command": "dexe-mcp"
|
|
22
56
|
}
|
|
23
57
|
}
|
|
24
58
|
}
|
|
25
59
|
```
|
|
26
60
|
|
|
27
|
-
|
|
61
|
+
#### Windows — recommended: absolute path to `node` + `dist/index.js`
|
|
28
62
|
|
|
29
|
-
|
|
30
|
-
2. Run `npm install` in the checkout
|
|
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:
|
|
31
64
|
|
|
32
|
-
|
|
65
|
+
```bash
|
|
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"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Substitute `<you>` and `<version>` (or use whatever `npm root -g` printed above). In JSON:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"dexe": {
|
|
75
|
+
"command": "C:/Program Files/nodejs/node.exe",
|
|
76
|
+
"args": ["C:/Users/<you>/AppData/Roaming/nvm/<version>/node_modules/dexe-mcp/dist/index.js"]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
33
81
|
|
|
34
|
-
|
|
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
|
|
35
86
|
|
|
36
|
-
|
|
87
|
+
<details>
|
|
88
|
+
<summary>Alternative: <code>cmd /c dexe-mcp</code> (not recommended — often unreliable with Claude Code)</summary>
|
|
37
89
|
|
|
38
90
|
```json
|
|
39
91
|
{
|
|
40
92
|
"mcpServers": {
|
|
41
93
|
"dexe": {
|
|
42
|
-
"command": "
|
|
43
|
-
"args": ["
|
|
94
|
+
"command": "cmd",
|
|
95
|
+
"args": ["/c", "dexe-mcp"]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
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
|
|
122
|
+
|
|
123
|
+
On the first build-tool call (e.g. `dexe_compile`), `dexe-mcp` will automatically:
|
|
124
|
+
|
|
125
|
+
1. Shallow-clone `dexe-network/DeXe-Protocol` into a platform cache directory (~200 MB)
|
|
126
|
+
2. Run `npm install` in that checkout (a few minutes, one time)
|
|
127
|
+
|
|
128
|
+
The MCP server itself starts instantly — the heavy work is deferred until you actually need it. Cache locations:
|
|
129
|
+
|
|
130
|
+
| OS | Path |
|
|
131
|
+
|----|------|
|
|
132
|
+
| Windows | `%LOCALAPPDATA%\dexe-mcp\DeXe-Protocol` |
|
|
133
|
+
| macOS | `~/Library/Caches/dexe-mcp/DeXe-Protocol` |
|
|
134
|
+
| Linux | `$XDG_CACHE_HOME/dexe-mcp/DeXe-Protocol` (or `~/.cache/dexe-mcp/DeXe-Protocol`) |
|
|
135
|
+
|
|
136
|
+
### Advanced: existing DeXe-Protocol checkout
|
|
137
|
+
|
|
138
|
+
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`:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"mcpServers": {
|
|
143
|
+
"dexe": {
|
|
144
|
+
"command": "dexe-mcp",
|
|
44
145
|
"env": {
|
|
45
146
|
"DEXE_PROTOCOL_PATH": "/absolute/path/to/your/DeXe-Protocol"
|
|
46
147
|
}
|
|
@@ -49,9 +150,36 @@ If you already have a DeXe-Protocol checkout or want to control its location:
|
|
|
49
150
|
}
|
|
50
151
|
```
|
|
51
152
|
|
|
153
|
+
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.
|
|
154
|
+
|
|
155
|
+
### Dev mode (working on dexe-mcp itself)
|
|
156
|
+
|
|
157
|
+
Clone this repo, build, and point the MCP command at the local `dist/index.js`:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
git clone https://github.com/edward-arinin-web-dev/dexe-mcp.git
|
|
161
|
+
cd dexe-mcp
|
|
162
|
+
npm install
|
|
163
|
+
npm run build
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"mcpServers": {
|
|
169
|
+
"dexe": {
|
|
170
|
+
"command": "node",
|
|
171
|
+
"args": ["/absolute/path/to/dexe-mcp/dist/index.js"],
|
|
172
|
+
"env": {
|
|
173
|
+
"DEXE_PROTOCOL_PATH": "/absolute/path/to/DeXe-Protocol"
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
52
180
|
## First run
|
|
53
181
|
|
|
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.
|
|
182
|
+
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
183
|
|
|
56
184
|
## Tool catalog
|
|
57
185
|
|
|
@@ -89,19 +217,44 @@ Before introspection tools work, run `dexe_compile` once per session to populate
|
|
|
89
217
|
|
|
90
218
|
| Variable | Required | Purpose |
|
|
91
219
|
|----------|----------|---------|
|
|
92
|
-
| `DEXE_PROTOCOL_PATH` | no |
|
|
220
|
+
| `DEXE_PROTOCOL_PATH` | no | Use an existing DeXe-Protocol checkout; disables auto clone/install |
|
|
93
221
|
| `DEXE_RPC_URL` | no | JSON-RPC endpoint for `dexe_decode_proposal` and `dexe_read_gov_state` |
|
|
94
222
|
| `DEXE_FORK_BLOCK` | no | Pin the fork to a specific block (Phase B) |
|
|
95
223
|
|
|
96
224
|
## Troubleshooting
|
|
97
225
|
|
|
226
|
+
### "`git` is not on PATH"
|
|
227
|
+
|
|
228
|
+
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.
|
|
229
|
+
|
|
230
|
+
### "`npm install` failed inside DeXe-Protocol"
|
|
231
|
+
|
|
232
|
+
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.
|
|
233
|
+
|
|
234
|
+
### "Failed to connect" in Claude Code (Windows)
|
|
235
|
+
|
|
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.
|
|
237
|
+
|
|
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"
|
|
243
|
+
```
|
|
244
|
+
|
|
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`.
|
|
250
|
+
|
|
98
251
|
### "Hardhat artifacts not found — run dexe_compile first"
|
|
99
252
|
|
|
100
253
|
Introspection tools require compiled artifacts. Run `dexe_compile` once after the initial setup to populate them.
|
|
101
254
|
|
|
102
|
-
### "
|
|
255
|
+
### "DEXE_PROTOCOL_PATH=… is missing node_modules"
|
|
103
256
|
|
|
104
|
-
|
|
257
|
+
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
258
|
|
|
106
259
|
### "DEXE_RPC_URL is not set"
|
|
107
260
|
|
package/dist/bootstrap.d.ts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
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
|
|
7
|
+
* 2. Auto-managed path inside the platform cache directory
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
|
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
|
package/dist/bootstrap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"
|
|
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 {
|
|
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
|
-
*
|
|
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
|
|
39
|
+
* 2. Auto-managed path inside the platform cache directory
|
|
40
40
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
41
|
+
* The returned path may not exist yet on disk. Call `ensureBuildReady()`
|
|
42
|
+
* before invoking tools that require hardhat.
|
|
43
43
|
*/
|
|
44
|
-
export
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!existsSync(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
throw new Error(`npm install failed in DeXe-Protocol checkout.\n${msg}`);
|
|
136
|
+
finally {
|
|
137
|
+
inflightEnsure = null;
|
|
78
138
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return protocolPath;
|
|
139
|
+
})();
|
|
140
|
+
return inflightEnsure;
|
|
82
141
|
}
|
|
83
142
|
//# sourceMappingURL=bootstrap.js.map
|
package/dist/bootstrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB
|
|
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
|
|
2
|
-
import { resolve
|
|
3
|
-
import {
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { resolveProtocolPath, isBuildReady } from "./bootstrap.js";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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;
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
}
|
package/dist/hardhat.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
/**
|
|
33
|
-
|
|
34
|
-
|
|
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 () => {
|
package/dist/hardhat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hardhat.js","sourceRoot":"","sources":["../src/hardhat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAsB,MAAM,OAAO,CAAC;AAClD,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
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.
|
|
8
|
+
const server = new McpServer({ name: "dexe-mcp", version: "0.1.3" }, {
|
|
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"}
|
package/dist/runtime.js
ADDED
|
@@ -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