@zerodust/mcp-server 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -53,9 +53,18 @@ Add to your `.claude/settings.json`:
53
53
  | `ZERODUST_API_URL` | Custom API URL | `https://api.zerodust.xyz` |
54
54
  | `ZERODUST_API_KEY` | API key for higher rate limits | - |
55
55
  | `ZERODUST_ALLOW_EXECUTE` | Set to `true` to enable sweeping | `false` |
56
- | `ZERODUST_PRIVATE_KEY` | Signing key for the agent's wallet | - |
57
56
  | `ZERODUST_ALLOWED_DESTINATIONS` | Comma-separated destination allowlist | own address only |
58
57
 
58
+ Signing keys have their own section below — there are four ways to supply one,
59
+ and exactly one may be set at a time.
60
+
61
+ | Variable | Description |
62
+ |----------|-------------|
63
+ | `ZERODUST_SIGNER_MODULE` | Module returning a viem `LocalAccount` (Turnkey, Privy, KMS, ...) |
64
+ | `ZERODUST_KEYSTORE_FILE` | Encrypted V3 keystore, with `ZERODUST_KEYSTORE_PASSWORD_FILE` or `ZERODUST_KEYSTORE_PASSWORD` |
65
+ | `ZERODUST_PRIVATE_KEY_FILE` | File containing a hex private key |
66
+ | `ZERODUST_PRIVATE_KEY` | Hex private key inline |
67
+
59
68
  ## Available Tools
60
69
 
61
70
  Read-only by default:
@@ -68,6 +77,7 @@ Read-only by default:
68
77
  | `zerodust_get_quote` | Get a quote for sweeping a chain |
69
78
  | `zerodust_get_sweep_status` | Check status of a submitted sweep |
70
79
  | `zerodust_list_sweeps` | List past sweeps for an address |
80
+ | `zerodust_register_api_key` | Issue this agent its own API key, no human signup |
71
81
 
72
82
  Added when execution is enabled (see below):
73
83
 
@@ -77,27 +87,91 @@ Added when execution is enabled (see below):
77
87
  | `zerodust_sweep` | Sweep one chain to exactly zero |
78
88
  | `zerodust_sweep_all` | Sweep every chain with a balance to one destination |
79
89
 
90
+ ## Try it without moving funds
91
+
92
+ Every sweep tool accepts `dryRun`. It fetches a real quote, requests the real
93
+ EIP-712 typed data, and produces all three real signatures with your key, then
94
+ stops before submitting. Nothing is broadcast and no balance changes.
95
+
96
+ > "Do a dry run of sweeping my Arbitrum balance to Base"
97
+
98
+ Use this first. It exercises the entire path an actual sweep takes — key
99
+ handling, chain support, fee limits, signature construction — so anything
100
+ misconfigured surfaces while your funds are still where they were.
101
+
102
+ There is deliberately no testnet mode: the ZeroDust API currently serves no
103
+ testnet chains, so a testnet flag would only produce empty chain lists and
104
+ failing quotes. `dryRun` gives you the same confidence against production.
105
+
80
106
  ## Enabling sweeps
81
107
 
82
- Sweeping moves real funds, so it is off unless you turn it on. Set **both**:
108
+ Sweeping moves real funds, so it is off unless you turn it on. Set
109
+ `ZERODUST_ALLOW_EXECUTE=true` **and** exactly one signing key.
110
+
111
+ Whichever you choose, the key is used locally to sign an EIP-7702 authorization
112
+ and an EIP-712 sweep intent. It is never transmitted — only signatures reach the
113
+ ZeroDust API.
114
+
115
+ ### Option 1: a signer module (recommended for production)
116
+
117
+ Point ZeroDust at a module that returns a viem `LocalAccount`. This is how you
118
+ use Turnkey, Privy, AWS KMS, or any other custody service: ZeroDust never sees a
119
+ raw key, and it does not need to know which vendor you use.
120
+
121
+ ```js
122
+ // my-signer.mjs
123
+ export default async function createAccount() {
124
+ // Build a viem LocalAccount however your custody provider prefers.
125
+ // Any account that can sign EIP-712 typed data and EIP-7702
126
+ // authorizations works.
127
+ return await myProvider.toViemAccount();
128
+ }
129
+ ```
83
130
 
84
131
  ```json
85
- {
86
- "mcpServers": {
87
- "zerodust": {
88
- "command": "npx",
89
- "args": ["@zerodust/mcp-server"],
90
- "env": {
91
- "ZERODUST_ALLOW_EXECUTE": "true",
92
- "ZERODUST_PRIVATE_KEY": "0x..."
93
- }
94
- }
95
- }
132
+ "env": {
133
+ "ZERODUST_ALLOW_EXECUTE": "true",
134
+ "ZERODUST_SIGNER_MODULE": "./my-signer.mjs"
135
+ }
136
+ ```
137
+
138
+ The module is validated when it loads: if the account it returns cannot sign an
139
+ EIP-7702 authorization, the server says so immediately rather than failing part
140
+ way through a sweep.
141
+
142
+ ### Option 2: an encrypted keystore
143
+
144
+ The V3 keystore format produced by `cast wallet import` and geth. Keep the
145
+ password in a file so neither the key nor the password lives in your MCP config.
146
+
147
+ ```json
148
+ "env": {
149
+ "ZERODUST_ALLOW_EXECUTE": "true",
150
+ "ZERODUST_KEYSTORE_FILE": "./agent-keystore.json",
151
+ "ZERODUST_KEYSTORE_PASSWORD_FILE": "./agent-keystore.pass"
152
+ }
153
+ ```
154
+
155
+ ### Option 3: a key file
156
+
157
+ ```json
158
+ "env": {
159
+ "ZERODUST_ALLOW_EXECUTE": "true",
160
+ "ZERODUST_PRIVATE_KEY_FILE": "./agent.key"
96
161
  }
97
162
  ```
98
163
 
99
- The key is used locally to sign an EIP-7702 authorization and an EIP-712 sweep
100
- intent. It is never transmitted — only signatures reach the ZeroDust API.
164
+ ### Option 4: an inline key
165
+
166
+ Simplest, and the least private — the key sits in a config file you may well
167
+ commit. Fine for a throwaway wallet, not for one holding anything you care about.
168
+
169
+ ```json
170
+ "env": {
171
+ "ZERODUST_ALLOW_EXECUTE": "true",
172
+ "ZERODUST_PRIVATE_KEY": "0x..."
173
+ }
174
+ ```
101
175
 
102
176
  ### Destination allowlist
103
177
 
@@ -125,9 +199,30 @@ Once configured, you can ask Claude:
125
199
 
126
200
  With execution enabled:
127
201
 
202
+ - "Do a dry run of sweeping my Arbitrum balance to Base" (moves nothing)
128
203
  - "Sweep my Arbitrum balance to Base"
129
204
  - "Exit every chain and consolidate everything on Base"
130
205
 
206
+ ## No install: the hosted server
207
+
208
+ If you only need the read-only tools, there is nothing to install. Connect to
209
+ the hosted server by URL:
210
+
211
+ ```
212
+ https://api.zerodust.xyz/mcp
213
+ ```
214
+
215
+ It exposes the same tool names as this package. Sweeping is not available there,
216
+ because sweeping needs a key and the hosted server does not have yours.
217
+
218
+ ## Development
219
+
220
+ ```bash
221
+ npm install
222
+ npm test # unit tests
223
+ npm run build
224
+ ```
225
+
131
226
  ## License
132
227
 
133
228
  MIT
package/dist/execute.d.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  * This module adds the tools that actually perform a sweep, which requires a
6
6
  * signing key and is therefore opt-in.
7
7
  *
8
- * Execution is disabled unless BOTH of these are set:
9
- * ZERODUST_PRIVATE_KEY - hex private key for the agent's own wallet
10
- * ZERODUST_ALLOW_EXECUTE - must be exactly "true"
8
+ * Execution is disabled unless BOTH of these are true:
9
+ * ZERODUST_ALLOW_EXECUTE=true - explicit acknowledgement that funds can move
10
+ * a signing key is configured - see signer.ts for the four accepted forms
11
11
  *
12
12
  * Optional:
13
13
  * ZERODUST_ALLOWED_DESTINATIONS - comma-separated address allowlist.
@@ -16,11 +16,17 @@
16
16
  * The allowlist is the main defence against prompt injection: an agent that is
17
17
  * talked into sweeping somewhere it shouldn't still cannot send funds to an
18
18
  * address the operator never approved.
19
+ *
20
+ * Every sweep tool also accepts `dryRun`, which runs the whole flow and stops
21
+ * before submission. That exists because there is no testnet backend to point
22
+ * at, so without it the only way to evaluate ZeroDust is to move real money.
19
23
  */
20
24
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
25
+ import { type SignerSource } from "./signer.js";
21
26
  /** Resolved execution configuration, or null when execution is not enabled. */
22
27
  export interface ExecuteConfig {
23
- privateKey: `0x${string}`;
28
+ /** Where the signing key comes from. Resolved lazily, on first use. */
29
+ signer: SignerSource;
24
30
  /** Lowercased allowlist. Empty means "agent's own address only". */
25
31
  allowedDestinations: string[];
26
32
  }
@@ -41,8 +47,12 @@ export declare function checkDestination(destination: string, agentAddress: stri
41
47
  /**
42
48
  * Registers the sweep-execution tools on an MCP server.
43
49
  *
44
- * Call only when {@link readExecuteConfig} returned a config; the read-only
45
- * server is fully functional without these tools.
50
+ * Pass the result of {@link readExecuteConfig}, including null. The tools are
51
+ * registered either way: an agent has to be able to *see* that sweeping exists
52
+ * in order to tell the user how to turn it on, and a directory that introspects
53
+ * the server with no environment set should still discover the real tool
54
+ * surface. When config is null every handler refuses before touching a key, so
55
+ * advertising the tool grants no capability.
46
56
  */
47
- export declare function registerExecuteTools(server: McpServer, config: ExecuteConfig): void;
57
+ export declare function registerExecuteTools(server: McpServer, config: ExecuteConfig | null): void;
48
58
  //# sourceMappingURL=execute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqBzE,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IAC1B,oEAAoE;IACpE,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,GAAG,IAAI,CAoC5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,MAAM,GAAG,IAAI,CAgBf;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA+InF"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAqC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAmBnF,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,MAAM,EAAE,YAAY,CAAC;IACrB,oEAAoE;IACpE,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,aAAa,GAAG,IAAI,CAwC5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,MAAM,GAAG,IAAI,CAgBf;AA2CD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAiO1F"}
package/dist/execute.js CHANGED
@@ -5,9 +5,9 @@
5
5
  * This module adds the tools that actually perform a sweep, which requires a
6
6
  * signing key and is therefore opt-in.
7
7
  *
8
- * Execution is disabled unless BOTH of these are set:
9
- * ZERODUST_PRIVATE_KEY - hex private key for the agent's own wallet
10
- * ZERODUST_ALLOW_EXECUTE - must be exactly "true"
8
+ * Execution is disabled unless BOTH of these are true:
9
+ * ZERODUST_ALLOW_EXECUTE=true - explicit acknowledgement that funds can move
10
+ * a signing key is configured - see signer.ts for the four accepted forms
11
11
  *
12
12
  * Optional:
13
13
  * ZERODUST_ALLOWED_DESTINATIONS - comma-separated address allowlist.
@@ -16,10 +16,14 @@
16
16
  * The allowlist is the main defence against prompt injection: an agent that is
17
17
  * talked into sweeping somewhere it shouldn't still cannot send funds to an
18
18
  * address the operator never approved.
19
+ *
20
+ * Every sweep tool also accepts `dryRun`, which runs the whole flow and stops
21
+ * before submission. That exists because there is no testnet backend to point
22
+ * at, so without it the only way to evaluate ZeroDust is to move real money.
19
23
  */
20
24
  import { z } from "zod";
25
+ import { hasSignerEnv, resolveSignerSource } from "./signer.js";
21
26
  const ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
22
- const PRIVATE_KEY_RE = /^0x[a-fA-F0-9]{64}$/;
23
27
  function text(body, isError = false) {
24
28
  const result = { content: [{ type: "text", text: body }] };
25
29
  if (isError)
@@ -37,21 +41,23 @@ function errorText(prefix, error) {
37
41
  * because the agent discovers it only mid-task.
38
42
  */
39
43
  export function readExecuteConfig(env = process.env) {
40
- const privateKey = env.ZERODUST_PRIVATE_KEY?.trim();
41
44
  const allowExecute = env.ZERODUST_ALLOW_EXECUTE?.trim() === "true";
42
- if (!privateKey && !allowExecute)
45
+ const signerConfigured = hasSignerEnv(env);
46
+ if (!signerConfigured && !allowExecute)
43
47
  return null;
44
48
  if (!allowExecute) {
45
- throw new Error("ZERODUST_PRIVATE_KEY is set but ZERODUST_ALLOW_EXECUTE is not \"true\". " +
49
+ throw new Error("A ZeroDust signing key is configured but ZERODUST_ALLOW_EXECUTE is not \"true\". " +
46
50
  "Sweeping moves real funds, so it must be enabled explicitly.");
47
51
  }
48
- if (!privateKey) {
49
- throw new Error("ZERODUST_ALLOW_EXECUTE is \"true\" but ZERODUST_PRIVATE_KEY is not set.");
50
- }
51
- const normalizedKey = (privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`);
52
- if (!PRIVATE_KEY_RE.test(normalizedKey)) {
53
- throw new Error("ZERODUST_PRIVATE_KEY must be a 32-byte hex private key.");
52
+ if (!signerConfigured) {
53
+ throw new Error("ZERODUST_ALLOW_EXECUTE is \"true\" but no signing key is configured. Set exactly one of:\n" +
54
+ " ZERODUST_SIGNER_MODULE module returning a viem LocalAccount (Turnkey, Privy, KMS, ...)\n" +
55
+ " ZERODUST_KEYSTORE_FILE encrypted V3 keystore, with ZERODUST_KEYSTORE_PASSWORD_FILE\n" +
56
+ " ZERODUST_PRIVATE_KEY_FILE file containing a hex private key\n" +
57
+ " ZERODUST_PRIVATE_KEY hex private key inline");
54
58
  }
59
+ // Throws on a partial or ambiguous signer setup.
60
+ const signer = resolveSignerSource(env);
55
61
  const allowedDestinations = (env.ZERODUST_ALLOWED_DESTINATIONS ?? "")
56
62
  .split(",")
57
63
  .map((entry) => entry.trim())
@@ -62,7 +68,7 @@ export function readExecuteConfig(env = process.env) {
62
68
  }
63
69
  }
64
70
  return {
65
- privateKey: normalizedKey,
71
+ signer,
66
72
  allowedDestinations: allowedDestinations.map((entry) => entry.toLowerCase()),
67
73
  };
68
74
  }
@@ -84,33 +90,96 @@ export function checkDestination(destination, agentAddress, allowedDestinations)
84
90
  return (`Destination ${destination} is not in ZERODUST_ALLOWED_DESTINATIONS. ` +
85
91
  `Permitted: ${agentAddress} (own address), ${allowedDestinations.join(", ")}.`);
86
92
  }
93
+ /** Suffix appended to every sweep tool description so the gate is self-documenting. */
94
+ const GATE_NOTE = " Requires ZERODUST_ALLOW_EXECUTE=true plus a signing key; without them this tool returns an " +
95
+ "error and moves no funds. Pass dryRun=true to rehearse the whole flow without moving anything.";
96
+ const DISABLED_MESSAGE = [
97
+ "Sweep execution is disabled on this ZeroDust MCP server, so nothing was moved.",
98
+ "",
99
+ "To enable it, restart the server with ZERODUST_ALLOW_EXECUTE=true and exactly",
100
+ "one signing key:",
101
+ "",
102
+ " ZERODUST_SIGNER_MODULE=./my-signer.js",
103
+ " A module whose default export returns a viem LocalAccount. This is how",
104
+ " you use Turnkey, Privy, AWS KMS or any other custody service without",
105
+ " putting a raw key anywhere.",
106
+ "",
107
+ " ZERODUST_KEYSTORE_FILE=./agent-keystore.json",
108
+ " ZERODUST_KEYSTORE_PASSWORD_FILE=./agent-keystore.pass",
109
+ " An encrypted V3 keystore, as produced by `cast wallet import` or geth.",
110
+ "",
111
+ " ZERODUST_PRIVATE_KEY_FILE=./agent.key",
112
+ " A file containing a hex private key, so the key stays out of configs.",
113
+ "",
114
+ " ZERODUST_PRIVATE_KEY=0x...",
115
+ " A hex key inline. Simplest, and the least private of the four.",
116
+ "",
117
+ "Optionally set ZERODUST_ALLOWED_DESTINATIONS to permit sweeping to addresses",
118
+ "other than the agent's own. The read-only tools (balances, quotes, status)",
119
+ "work without any of this.",
120
+ ].join("\n");
121
+ /** Shared shape of the dryRun parameter, so both sweep tools describe it identically. */
122
+ const dryRunSchema = z
123
+ .boolean()
124
+ .optional()
125
+ .describe("Rehearse without moving funds (default false). Fetches a real quote and produces " +
126
+ "the real signatures, then stops before submitting. Use this to prove the setup " +
127
+ "works before sweeping a real balance.");
87
128
  /**
88
129
  * Registers the sweep-execution tools on an MCP server.
89
130
  *
90
- * Call only when {@link readExecuteConfig} returned a config; the read-only
91
- * server is fully functional without these tools.
131
+ * Pass the result of {@link readExecuteConfig}, including null. The tools are
132
+ * registered either way: an agent has to be able to *see* that sweeping exists
133
+ * in order to tell the user how to turn it on, and a directory that introspects
134
+ * the server with no environment set should still discover the real tool
135
+ * surface. When config is null every handler refuses before touching a key, so
136
+ * advertising the tool grants no capability.
92
137
  */
93
138
  export function registerExecuteTools(server, config) {
94
- // The agent is constructed lazily so a bad key surfaces on first use with a
95
- // clear message, rather than crashing the whole server at startup.
139
+ // The agent is constructed lazily so a bad key or an unreachable remote
140
+ // signer surfaces on first use with a clear message, rather than crashing the
141
+ // whole server at startup.
96
142
  let agentPromise = null;
97
- async function getAgent() {
143
+ async function getAgent(enabled) {
98
144
  if (!agentPromise) {
99
- agentPromise = import("@zerodust/sdk").then(({ createAgentFromPrivateKey }) => createAgentFromPrivateKey(config.privateKey, { environment: "mainnet" }));
145
+ agentPromise = (async () => {
146
+ const [{ ZeroDustAgent }, account] = await Promise.all([
147
+ import("@zerodust/sdk"),
148
+ enabled.signer.load(),
149
+ ]);
150
+ return new ZeroDustAgent({ account, environment: "mainnet" });
151
+ })();
152
+ // A failed load must not be cached, or a transient signer outage would
153
+ // wedge the server until restart.
154
+ agentPromise.catch(() => {
155
+ agentPromise = null;
156
+ });
100
157
  }
101
158
  return agentPromise;
102
159
  }
160
+ const disabled = () => text(DISABLED_MESSAGE, true);
103
161
  server.registerTool("zerodust_get_agent_address", {
104
- description: "Get the wallet address this ZeroDust MCP server signs with, plus which sweep destinations are permitted. Use before sweeping to confirm which wallet will be swept.",
162
+ description: "Show which wallet this ZeroDust server signs with, where its key comes from, and " +
163
+ "which destinations it is allowed to sweep to. Call this before any sweep to confirm " +
164
+ "the right wallet is about to be emptied." +
165
+ GATE_NOTE,
166
+ annotations: {
167
+ title: "Show the signing wallet",
168
+ readOnlyHint: true,
169
+ openWorldHint: false,
170
+ },
105
171
  inputSchema: {},
106
172
  }, async () => {
173
+ if (!config)
174
+ return disabled();
107
175
  try {
108
- const agent = await getAgent();
176
+ const agent = await getAgent(config);
109
177
  const allowed = config.allowedDestinations.length === 0
110
178
  ? "own address only"
111
179
  : `own address, ${config.allowedDestinations.join(", ")}`;
112
180
  return text([
113
181
  `Agent address: ${agent.address}`,
182
+ `Signing key: ${config.signer.description}`,
114
183
  `Execution: enabled`,
115
184
  `Permitted destinations: ${allowed}`,
116
185
  ].join("\n"));
@@ -120,9 +189,22 @@ export function registerExecuteTools(server, config) {
120
189
  }
121
190
  });
122
191
  server.registerTool("zerodust_sweep", {
123
- description: "Sweep 100% of the native gas token from one chain, leaving exactly zero balance. Moves real funds. Call zerodust_get_quote first to show the user what they will receive.",
192
+ description: "Empty one chain completely: move 100% of the native gas token off it and leave the " +
193
+ "balance at exactly zero. This is the operation an ordinary transfer cannot do, because " +
194
+ "sending the gas token requires keeping some gas token back to pay for the send. Use " +
195
+ "when the goal is to close out, wind down, decommission or fully exit a chain, or to " +
196
+ "recover a leftover or stranded balance that is too small to move normally. Moves real " +
197
+ "funds. Call zerodust_get_quote first to show the user what they will receive." +
198
+ GATE_NOTE,
199
+ annotations: {
200
+ title: "Empty a chain to exactly zero",
201
+ readOnlyHint: false,
202
+ destructiveHint: true,
203
+ idempotentHint: false,
204
+ openWorldHint: true,
205
+ },
124
206
  inputSchema: {
125
- fromChainId: z.number().int().positive().describe("Chain to sweep from"),
207
+ fromChainId: z.number().int().positive().describe("Chain to empty"),
126
208
  toChainId: z
127
209
  .number()
128
210
  .int()
@@ -133,10 +215,13 @@ export function registerExecuteTools(server, config) {
133
215
  .regex(ADDRESS_RE)
134
216
  .optional()
135
217
  .describe("Destination address (defaults to the agent's own address)"),
218
+ dryRun: dryRunSchema,
136
219
  },
137
- }, async ({ fromChainId, toChainId, destination }) => {
220
+ }, async ({ fromChainId, toChainId, destination, dryRun }) => {
221
+ if (!config)
222
+ return disabled();
138
223
  try {
139
- const agent = await getAgent();
224
+ const agent = await getAgent(config);
140
225
  const target = destination ?? agent.address;
141
226
  const denial = checkDestination(target, agent.address, config.allowedDestinations);
142
227
  if (denial)
@@ -145,10 +230,26 @@ export function registerExecuteTools(server, config) {
145
230
  fromChainId,
146
231
  toChainId,
147
232
  destination: target,
148
- });
233
+ }, dryRun ? { dryRun: true } : {});
149
234
  if (!result.success) {
150
235
  return text(`Sweep failed: ${result.error ?? "unknown error"}`, true);
151
236
  }
237
+ if (result.dryRun) {
238
+ return text([
239
+ `Dry run only - nothing was submitted and chain ${fromChainId} is untouched.`,
240
+ `Would send to: ${target} (chain ${toChainId})`,
241
+ result.quote
242
+ ? `Current balance: ${result.quote.userBalance} wei`
243
+ : null,
244
+ result.quote
245
+ ? `Would receive: ${result.quote.estimatedReceive} wei`
246
+ : null,
247
+ `Signatures produced: intent, delegation, revoke (all valid, none broadcast)`,
248
+ `Re-run without dryRun to execute for real.`,
249
+ ]
250
+ .filter(Boolean)
251
+ .join("\n"));
252
+ }
152
253
  const lines = [
153
254
  `Sweep complete. Chain ${fromChainId} balance is now exactly zero.`,
154
255
  `Sweep ID: ${result.sweepId}`,
@@ -163,7 +264,19 @@ export function registerExecuteTools(server, config) {
163
264
  }
164
265
  });
165
266
  server.registerTool("zerodust_sweep_all", {
166
- description: "Sweep every chain that holds a sweepable balance, consolidating to one destination chain. Moves real funds across multiple chains. Call zerodust_get_balances first to show the user what will be swept.",
267
+ description: "Empty every chain that still holds a native gas balance, consolidating all of it onto " +
268
+ "one destination chain and leaving each source at exactly zero. Use when the goal is to " +
269
+ "clean up a wallet across chains, collect scattered leftover gas, or retire a wallet " +
270
+ "entirely. Moves real funds across multiple chains. Call zerodust_get_balances first to " +
271
+ "show the user what will be swept." +
272
+ GATE_NOTE,
273
+ annotations: {
274
+ title: "Empty every chain with a balance",
275
+ readOnlyHint: false,
276
+ destructiveHint: true,
277
+ idempotentHint: false,
278
+ openWorldHint: true,
279
+ },
167
280
  inputSchema: {
168
281
  toChainId: z
169
282
  .number()
@@ -175,10 +288,13 @@ export function registerExecuteTools(server, config) {
175
288
  .regex(ADDRESS_RE)
176
289
  .optional()
177
290
  .describe("Destination address (defaults to the agent's own address)"),
291
+ dryRun: dryRunSchema,
178
292
  },
179
- }, async ({ toChainId, destination }) => {
293
+ }, async ({ toChainId, destination, dryRun }) => {
294
+ if (!config)
295
+ return disabled();
180
296
  try {
181
- const agent = await getAgent();
297
+ const agent = await getAgent(config);
182
298
  const target = destination ?? agent.address;
183
299
  const denial = checkDestination(target, agent.address, config.allowedDestinations);
184
300
  if (denial)
@@ -186,16 +302,23 @@ export function registerExecuteTools(server, config) {
186
302
  const result = await agent.sweepAll({
187
303
  toChainId,
188
304
  destination: target,
189
- });
305
+ }, dryRun ? { dryRun: true } : {});
190
306
  const summary = result.results
191
- .map((sweep) => sweep.success
192
- ? ` chain ${sweep.fromChainId}: swept${sweep.txHash ? ` (${sweep.txHash})` : ""}`
193
- : ` chain ${sweep.fromChainId}: failed - ${sweep.error ?? "unknown error"}`)
307
+ .map((sweep) => {
308
+ if (!sweep.success) {
309
+ return ` chain ${sweep.fromChainId}: failed - ${sweep.error ?? "unknown error"}`;
310
+ }
311
+ if (sweep.dryRun) {
312
+ const receive = sweep.quote ? ` (would receive ${sweep.quote.estimatedReceive} wei)` : "";
313
+ return ` chain ${sweep.fromChainId}: would sweep${receive}`;
314
+ }
315
+ return ` chain ${sweep.fromChainId}: swept${sweep.txHash ? ` (${sweep.txHash})` : ""}`;
316
+ })
194
317
  .join("\n");
195
- return text([
196
- `Swept ${result.successful}/${result.total} chains to ${target} on chain ${toChainId}.`,
197
- summary,
198
- ]
318
+ const headline = dryRun
319
+ ? `Dry run only - nothing was submitted. ${result.successful}/${result.total} chains would sweep to ${target} on chain ${toChainId}.`
320
+ : `Swept ${result.successful}/${result.total} chains to ${target} on chain ${toChainId}.`;
321
+ return text([headline, summary, dryRun ? "Re-run without dryRun to execute for real." : null]
199
322
  .filter(Boolean)
200
323
  .join("\n"));
201
324
  }
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -14,7 +14,23 @@
14
14
  * ZERODUST_API_KEY - Optional API key for higher rate limits
15
15
  *
16
16
  * Sweeping is read-only by default. To let an agent actually move funds, see
17
- * `execute.ts` for the ZERODUST_ALLOW_EXECUTE / ZERODUST_PRIVATE_KEY opt-in.
17
+ * `execute.ts` for the ZERODUST_ALLOW_EXECUTE opt-in and `signer.ts` for the
18
+ * four accepted ways to supply a signing key.
19
+ *
20
+ * Tool descriptions here lead with the problem rather than the product. An
21
+ * agent picks a tool by matching the user's words against a description, and
22
+ * "check balances" collides with every other balance tool in the client. What
23
+ * is actually distinctive is the impossibility ZeroDust removes: you cannot
24
+ * send 100% of a native gas token, because sending it costs it.
25
+ */
26
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
27
+ declare const server: McpServer;
28
+ /**
29
+ * The server instance with every read-only tool registered.
30
+ *
31
+ * Exported so tests can attach the execution tools and introspect the real tool
32
+ * surface over an in-memory transport, rather than asserting against a copy of
33
+ * the tool list that could drift from what agents actually see.
18
34
  */
19
- export {};
35
+ export { server };
20
36
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAepE,QAAA,MAAM,MAAM,WAGV,CAAC;AAkjBH;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAE,CAAC"}