@metalntwx/metal-agent 0.3.0 → 0.3.1

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.
@@ -20,8 +20,8 @@ set, and pass it with `--rpc-url`. A user without one creates it as
20
20
  The key file defaults to `~/.metal-agent/key.json`. It holds the private key
21
21
  in the clear, owner-readable only; treat the file as the secret.
22
22
 
23
- If `metal-agent --help` runs and the user already has a key, go to the
24
- command you need. Otherwise start with Setup.
23
+ If `metal-agent --version` prints `0.3.1` and the user already has a key,
24
+ go to the command you need. Otherwise start with Setup.
25
25
 
26
26
  ## Setup
27
27
 
@@ -30,13 +30,15 @@ Run the steps in order. After each step, show the user its output.
30
30
  1. Check Node.js with `node --version`. If it is missing, tell the user to
31
31
  install Node.js, and stop.
32
32
 
33
- 2. Check for the CLI with `metal-agent --help`. If it is not found, install
34
- it:
33
+ 2. Install the CLI, or move an installed one to this version:
35
34
 
36
35
  ```bash
37
- npm install -g @metalntwx/metal-agent
36
+ npm install -g @metalntwx/metal-agent@0.3.1
38
37
  ```
39
38
 
39
+ Then `metal-agent --version` prints `0.3.1`. If it prints anything else,
40
+ another copy comes first on the `PATH`: tell the user, and stop.
41
+
40
42
  3. Install this skill, so that later sessions have it without fetching this
41
43
  page. Copy the directory
42
44
  `$(npm root -g)/@metalntwx/metal-agent/skills/metal-agent` into your
@@ -48,7 +50,7 @@ Run the steps in order. After each step, show the user its output.
48
50
  In Claude Code:
49
51
 
50
52
  ```bash
51
- claude mcp add metal-agent -- npx -y @metalntwx/metal-agent mcp
53
+ claude mcp add metal-agent -- npx -y @metalntwx/metal-agent@0.3.1 mcp
52
54
  ```
53
55
 
54
56
  In any other MCP host, add this server to its MCP configuration:
@@ -58,7 +60,7 @@ Run the steps in order. After each step, show the user its output.
58
60
  "mcpServers": {
59
61
  "metal-agent": {
60
62
  "command": "npx",
61
- "args": ["-y", "@metalntwx/metal-agent", "mcp"]
63
+ "args": ["-y", "@metalntwx/metal-agent@0.3.1", "mcp"]
62
64
  }
63
65
  }
64
66
  }
@@ -66,16 +68,22 @@ Run the steps in order. After each step, show the user its output.
66
68
 
67
69
  The server pays with the default key file. If the user's key is in
68
70
  another file, or the agent pays under a mandate, add `--key <file>` or
69
- `--mandate <credential>` after `mcp`.
71
+ `--mandate <credential>` after `mcp`. Under a mandate on testnet, also set
72
+ the user's endpoint in the server's environment, or in an `env` block in
73
+ another host's configuration:
74
+
75
+ ```bash
76
+ claude mcp add metal-agent -e METAL_RPC_URL=<endpoint> -- npx -y @metalntwx/metal-agent@0.3.1 mcp --mandate <credential>
77
+ ```
70
78
 
71
79
  The tools appear after the host reloads. If you cannot reload it, tell
72
80
  the user to, and carry on with the CLI.
73
81
 
74
82
  5. Get the agent's key. Ask the user whether they have a funded key file. If they do,
75
83
  ask for its path and run `metal-agent key import <path>`. Otherwise run
76
- `metal-agent key create`. Tell the user the address. If `key create`
77
- answers that the key file already holds a key, keep that key and ask the
78
- user for its address.
84
+ `metal-agent key create`. Tell the user the address. If either answers
85
+ that the key file already holds a key, tell the user the address in its
86
+ `address` field, and ask whether to pay with that key.
79
87
 
80
88
  6. Fund the key from the testnet faucet, unless the user said it is funded,
81
89
  and show the user the `transaction` and `explorer` lines:
@@ -135,11 +143,13 @@ Ask the public faucet for `*USDZ`; the faucet sets the amount.
135
143
  An address that already holds a full grant is reported as funded. A grant
136
144
  prints `transaction <hash>` and `explorer <url>`, the transaction's page on
137
145
  the block explorer. The faucet limits how often one client can ask: on a
138
- `client_rate_limited` error, wait the seconds it names; on a daily-limit
139
- error, load a pre-funded key with `key import`.
146
+ `client_rate_limited` error, wait the seconds it names; on
147
+ `client_daily_limit_reached`, fund the address from the Faucet page in the
148
+ Metal console the error names; on either daily-limit error, load a
149
+ pre-funded key with `key import`.
140
150
 
141
151
  ```bash
142
- metal-agent fund 0x40daBEc53aA45faC6d0eaCCA5713fac49d8d213c --network testnet
152
+ metal-agent fund <address> --network testnet
143
153
  ```
144
154
 
145
155
  ## pay
@@ -168,10 +178,11 @@ metal-agent pay https://example.com/report --network testnet --max 5
168
178
  For a request other than GET, pass `--method` (POST when there is a body),
169
179
  `--body` (sent as `application/json` unless a `--header` names a content
170
180
  type) and repeated `--header 'name: value'`; `pay` sends them again with the
171
- payment. To buy RPC over x402, POST the JSON-RPC call to the RPC URL:
181
+ payment. To buy RPC over x402, POST the JSON-RPC call to
182
+ `https://rpc-testnet.metalntwx.com/v1`:
172
183
 
173
184
  ```bash
174
- metal-agent pay <rpc url> --network testnet --method POST --body '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
185
+ metal-agent pay https://rpc-testnet.metalntwx.com/v1 --network testnet --method POST --body '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
175
186
  ```
176
187
 
177
188
  The output's `header rpc-aas-endpoint: <url>` is the endpoint that payment
@@ -187,15 +198,16 @@ A refusal exits 1 with the reason:
187
198
  `offer signs for the EIP-712 domain …` means the offer asks for something
188
199
  other than `*USDZ`. Tell the user; a larger `--max` does not change it.
189
200
  - `error: payment refused: <reason>` means the facilitator refused at
190
- verification, or the seller's own check refused.
201
+ verification, or the seller's own check refused; nothing was paid.
191
202
  - `error: payment refused at settlement: <reason>` means the facilitator
192
- refused at settlement, with the transaction hash when there is one. On
203
+ refused at settlement for a reason that moves nothing, with the
204
+ transaction hash when there is one; nothing was paid. On
193
205
  `daily_limit_reached`, retry later.
194
- - On `settlement_in_doubt`, or any error after the `nonce` line that is
195
- not a `payment refused` line, such as `fetch failed` or an HTTP status
196
- from the seller, the payment may have settled. Do not pay again. Tell
197
- the user, with the `nonce` line `pay` printed; when the error names a
198
- transaction hash, `status` on it shows whether it landed.
206
+ - On `error: payment in doubt at settlement: …`, or any error after the
207
+ `nonce` line that is not a `payment refused` line, such as `fetch failed`
208
+ or an HTTP status from the seller, the payment may have settled. Do not
209
+ pay again. Tell the user, with the `nonce` line `pay` printed; when the
210
+ error names a transaction hash, `status` on it shows whether it landed.
199
211
 
200
212
  ## `pay --mandate`
201
213
 
@@ -221,8 +233,8 @@ mandate's, ask the user where the key file is, and pass it as
221
233
 
222
234
  A seller that asks for your signed order gets it with the payment, and
223
235
  `pay` prints it as `signed-offer <text>`. Keep it, and pass it to
224
- `mandate verify --issuer <file> --tx <hash> --signed-offer <text>` to check the two
225
- together.
236
+ `mandate verify --credential <file> --issuer <file> --tx <hash> --signed-offer <text> --network testnet --rpc-url <endpoint>`
237
+ to check the two together.
226
238
 
227
239
  `mandate status` shows what is left: read `spent <amount> of <budget>`,
228
240
  `revoked yes|no` and the `payee` lines.
@@ -232,26 +244,41 @@ metal-agent mandate status --credential ./mandate.json --network testnet --rpc-u
232
244
  ```
233
245
 
234
246
  `mandate pull` pays an address the mandate allows, with no seller. The
235
- facilitator submits it and pays the gas. The `outcome` line says what
236
- happened: `paid`; `refused, not sent` with `reason` and `recorded no`, for
237
- a pull refused when checked, which sends nothing; `refused` with `reason`,
238
- for one the account refused and recorded; `refused, not paid`, for a sent
239
- pull that can no longer land; `held`, for one the payee's
240
- receive policy sent to escrow, so the payee was not paid; or `pending`. Pass
241
- `--record-refusal`, with `--key` naming a funded key to send it, only when
242
- the user asks for the refusal to be recorded on chain. On `outcome pending`,
243
- run the same command again, with the same `--to` and `--amount`: it sends
244
- the same pull, which pays at most once, or reports how it ended. Never
245
- change the amount to pay a pending pull again.
247
+ facilitator submits it and pays the gas. Pass `--payment-id` with the id of
248
+ the payment it is for, such as the refund's or the invoice's: two payouts of
249
+ one amount to one payee, while the first is pending, are two payments
250
+ only under two ids. The `outcome`
251
+ line says what happened: `paid`, exit 0; `refused, not sent` with `reason`
252
+ and `recorded no`, for a pull refused when checked, which sends nothing;
253
+ `refused` with `reason`, for one the account refused and recorded;
254
+ `refused, not paid`, for a sent pull that can no longer land; `held`,
255
+ exit 4, for one the payee's receive policy holds in escrow, so the payee was
256
+ not paid and the amount counts against the budget: do not send it again;
257
+ the payee, or the authority its policy names, releases it; or `pending`,
258
+ exit 3. Refusals exit 1. Pass `--record-refusal`, with `--key` naming a
259
+ funded key to send it, only when the user asks for the refusal to be
260
+ recorded on chain. On `outcome pending`, run the same command again, on the
261
+ same machine, with the same credential, `--payment-id`, `--to` and
262
+ `--amount`: it sends the same pull, which pays at most once, or reports its
263
+ outcome. Never add, drop or change the payment id, or change the amount, to
264
+ pay a pending pull again. After `outcome refused`, nothing was paid, and the
265
+ same payment id may be sent with other values. `error: the pull was not
266
+ sent: …` names why, such as the facilitator's refusal; tell the user.
267
+ An error saying `the pull kept before may have been sent and can land until
268
+ …` means that pull can still land until then: tell the user, and never pay
269
+ it under another payment id. The same holds for an error naming an event the SDK
270
+ does not decode: the pull may have paid.
246
271
 
247
272
  ```bash
248
- metal-agent mandate pull --credential ./mandate.json --to <payee address> --amount 2.50 --network testnet --rpc-url <endpoint>
273
+ metal-agent mandate pull --credential ./mandate.json --to <payee address> --amount 2.50 --payment-id <payment id> --network testnet --rpc-url <endpoint>
249
274
  ```
250
275
 
251
276
  `mandate verify` checks the mandate and every payment under it from the
252
277
  chain alone, or one `--tx <hash>`, and exits 1 when a check fails. Run it
253
278
  when the user asks whether a payment was within the mandate; read
254
- `verified yes|no`, and a failed `step` line names what differs. It needs
279
+ `verified yes|no`, and a failed `step` line names what differs. A failure
280
+ that names a topic the SDK does not decode means metal-agent and the
281
+ account may be different versions; tell the user. It needs
255
282
  the issuer's public key file, the `issuer-public-file` that `credential
256
283
  create` printed; ask the user for it.
257
284
 
@@ -259,9 +286,6 @@ create` printed; ask the user for it.
259
286
  metal-agent mandate verify --credential ./mandate.json --issuer <issuer public key file> --network testnet --rpc-url <endpoint>
260
287
  ```
261
288
 
262
- `--issuer` is the issuer's public key file the user gave you with the
263
- credential; ask for it if you do not have it.
264
-
265
289
  ## status
266
290
 
267
291
  Show a settlement from chain data: status, block, submitter, gas paid in
@@ -276,12 +300,23 @@ metal-agent status <transaction hash> --network testnet --rpc-url <endpoint>
276
300
  ## mcp
277
301
 
278
302
  Serve `pay`, `fund` and `status` as MCP tools, each taking a `network`, over
279
- stdio for an MCP host. What `pay` spends is fixed when the server starts,
280
- by its key and `--max`, or by one mandate; `pay` takes the request as
303
+ stdio for an MCP host; under a mandate, `mandate_pull`, `mandate_status` and
304
+ `mandate_verify` as well. What `pay` and `mandate_pull` spend is set when
305
+ the server starts, by whoever starts it: a key file and `--max`, or one
306
+ mandate's credential file, which each call reads. `pay` takes the request as
281
307
  optional `method`, `body` and `headers`, and under a key a `max` that can
282
- only lower the server's limit. `status` takes the endpoint as `rpcUrl`, which testnet
283
- needs unless the server's environment sets `METAL_RPC_URL`. No tool chooses a key, a mandate or a higher limit, and none
284
- sets or changes a mandate.
308
+ only lower the server's limit, and ends a refusal after signing, or a
309
+ payment that may have settled, with a `next:` line. `fund` and `status`
310
+ take the endpoint as `rpcUrl`, which
311
+ `status` on testnet needs unless the server's environment sets
312
+ `METAL_RPC_URL`. With the server's `METAL_RPC_URL`, `fund` asks the testnet
313
+ faucet nothing for an address that already holds about a full grant. The
314
+ mandate tools take no `rpcUrl`: they read the chain through the server's
315
+ `METAL_RPC_URL`, or devnet's default endpoint, and fail naming a chain other
316
+ than the network's. `mandate_pull` takes `to`, `amount` and a `paymentId`,
317
+ one per payment, and ends any outcome but `paid` with a `next:` line;
318
+ `mandate_verify` takes the `issuers` to trust. No tool chooses a key, a
319
+ mandate or a higher limit, and none sets or changes a mandate.
285
320
 
286
321
  ```bash
287
322
  metal-agent mcp