@metalntwx/metal-agent 0.1.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 +78 -52
- package/dist/chain.js +1 -1
- package/dist/commands/mandate.js +564 -131
- package/dist/commands/pay.js +16 -7
- package/dist/help.js +119 -0
- package/dist/index.js +52 -96
- package/dist/keystore.js +6 -10
- package/dist/mcp.js +59 -39
- package/package.json +7 -7
- package/skills/metal-agent/SKILL.md +53 -27
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metalntwx/metal-agent",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The `metal-agent` CLI and MCP server: create or import
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "The `metal-agent` CLI and MCP server: create or import the agent's key, fund it on Metal devnet or testnet, pay x402 offers in *USDZ, look up a settlement, and set spending limits for an agent that Metal enforces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
"skills"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@metalntwx/metal-ts": "^0.3.
|
|
22
|
-
"@metalntwx/metal-pay": "^0.
|
|
23
|
-
"@modelcontextprotocol/sdk": "1.
|
|
24
|
-
"@x402/core": "2.
|
|
21
|
+
"@metalntwx/metal-ts": "^0.3.2",
|
|
22
|
+
"@metalntwx/metal-pay": "^0.3.0",
|
|
23
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
24
|
+
"@x402/core": "2.28.0",
|
|
25
25
|
"viem": "^2.54.6",
|
|
26
26
|
"zod": "^3.25.76"
|
|
27
27
|
},
|
|
28
28
|
"dependencyRationale": {
|
|
29
|
-
"@metalntwx/metal-ts": "Funds
|
|
29
|
+
"@metalntwx/metal-ts": "Funds a key on devnet with a MIP20 transfer.",
|
|
30
30
|
"@metalntwx/metal-pay": "The one-call x402 payment clients, mandates, and the Metal network constants.",
|
|
31
31
|
"@modelcontextprotocol/sdk": "The stdio MCP server behind `metal-agent mcp`.",
|
|
32
32
|
"@x402/core": "Decodes the `payment-response` header a paid request returns.",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: metal-agent
|
|
3
|
-
description: "Set up and use the metal-agent CLI to pay x402 sellers on Metal: install it, create or import the agent's
|
|
3
|
+
description: "Set up and use the metal-agent CLI to pay x402 sellers on Metal: install it, create or import the agent's key, fund it, pay a URL that answers 402, pay under a mandate from an account the agent does not own, and look up a settlement. Use when a task needs an agent to pay for an HTTP resource in *USDZ on Metal, to pay with a mandate credential the user gives it, to set up metal-agent, or to check what a Metal payment settled."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
`metal-agent` is the CLI and MCP server of the `@metalntwx/metal-agent` npm
|
|
@@ -12,8 +12,8 @@ Every command that touches the chain takes `--network testnet`. Metal's
|
|
|
12
12
|
demo seller is at `https://x402-demo-testnet.metalntwx.com/quote` and the
|
|
13
13
|
block explorer at `https://testnet.metalntwx.com`.
|
|
14
14
|
|
|
15
|
-
`key`, `fund` and `pay` need no RPC endpoint. `status` and
|
|
16
|
-
commands need the user's own: ask for it, unless `METAL_RPC_URL` is already
|
|
15
|
+
`key`, `fund` and `pay` need no RPC endpoint. `status`, `account create` and
|
|
16
|
+
the `mandate` commands other than `credential create` need the user's own: ask for it, unless `METAL_RPC_URL` is already
|
|
17
17
|
set, and pass it with `--rpc-url`. A user without one creates it as
|
|
18
18
|
`https://docs.metalntwx.com/network/endpoints` describes.
|
|
19
19
|
|
|
@@ -64,10 +64,14 @@ Run the steps in order. After each step, show the user its output.
|
|
|
64
64
|
}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
The server pays with the default key file. If the user's key is in
|
|
68
|
+
another file, or the agent pays under a mandate, add `--key <file>` or
|
|
69
|
+
`--mandate <credential>` after `mcp`.
|
|
70
|
+
|
|
67
71
|
The tools appear after the host reloads. If you cannot reload it, tell
|
|
68
72
|
the user to, and carry on with the CLI.
|
|
69
73
|
|
|
70
|
-
5. Get the agent's
|
|
74
|
+
5. Get the agent's key. Ask the user whether they have a funded key file. If they do,
|
|
71
75
|
ask for its path and run `metal-agent key import <path>`. Otherwise run
|
|
72
76
|
`metal-agent key create`. Tell the user the address. If `key create`
|
|
73
77
|
answers that the key file already holds a key, keep that key and ask the
|
|
@@ -100,7 +104,7 @@ Run the steps in order. After each step, show the user its output.
|
|
|
100
104
|
- Before you pass a `--max` above the default of 1 `*USDZ`.
|
|
101
105
|
- Before you import a key, or write a key anywhere but the default file.
|
|
102
106
|
- Before you run `account create`, `mandate credential create`, `bind`,
|
|
103
|
-
`replace` or `revoke`. They are the account owner's to run.
|
|
107
|
+
`replace`, `renew` or `revoke`. They are the account owner's to run.
|
|
104
108
|
|
|
105
109
|
Never print a private key or the contents of a key file. Never move, copy
|
|
106
110
|
or delete a key file. If the owner's key file is within your reach, tell
|
|
@@ -108,12 +112,12 @@ the user; the limits bind you only while it is not.
|
|
|
108
112
|
|
|
109
113
|
## key create
|
|
110
114
|
|
|
111
|
-
Generate the agent's
|
|
115
|
+
Generate the agent's key and write its key file. Prints the address
|
|
112
116
|
and the key file's path. It does not overwrite an existing key file; `--out` writes
|
|
113
117
|
another.
|
|
114
118
|
|
|
115
119
|
```bash
|
|
116
|
-
metal-agent key create --out ./
|
|
120
|
+
metal-agent key create --out ./key.json
|
|
117
121
|
```
|
|
118
122
|
|
|
119
123
|
## key import
|
|
@@ -145,7 +149,7 @@ named network, sign the authorization with the key file, retry, and print
|
|
|
145
149
|
the settlement, the response headers and the body.
|
|
146
150
|
|
|
147
151
|
```bash
|
|
148
|
-
metal-agent pay https://x402-demo-testnet.metalntwx.com/quote --network testnet --key ./
|
|
152
|
+
metal-agent pay https://x402-demo-testnet.metalntwx.com/quote --network testnet --key ./key.json
|
|
149
153
|
```
|
|
150
154
|
|
|
151
155
|
Read `transaction <hash>` from the output for the settlement,
|
|
@@ -183,11 +187,15 @@ A refusal exits 1 with the reason:
|
|
|
183
187
|
`offer signs for the EIP-712 domain …` means the offer asks for something
|
|
184
188
|
other than `*USDZ`. Tell the user; a larger `--max` does not change it.
|
|
185
189
|
- `error: payment refused: <reason>` means the facilitator refused at
|
|
186
|
-
verification.
|
|
190
|
+
verification, or the seller's own check refused.
|
|
187
191
|
- `error: payment refused at settlement: <reason>` means the facilitator
|
|
188
192
|
refused at settlement, with the transaction hash when there is one. On
|
|
189
|
-
`daily_limit_reached`, retry later.
|
|
190
|
-
|
|
193
|
+
`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.
|
|
191
199
|
|
|
192
200
|
## `pay --mandate`
|
|
193
201
|
|
|
@@ -200,16 +208,20 @@ when the mandate names them, the payees.
|
|
|
200
208
|
metal-agent pay https://example.com/report --mandate ./mandate.json --network testnet
|
|
201
209
|
```
|
|
202
210
|
|
|
203
|
-
|
|
204
|
-
`mandate.
|
|
211
|
+
`pay` signs with the mandate key beside the credential, `mandate.key.json`
|
|
212
|
+
for `mandate.json`; `--mandate-key-file <file>` names it when it is
|
|
213
|
+
elsewhere. Never show the key file's contents. `--max` and `--key` do not
|
|
205
214
|
apply. A payment outside the mandate exits 1 with
|
|
206
215
|
`error: payment refused: <reason> (…)`, a reason starting `mandate_`. Tell
|
|
207
216
|
the user which limit it was; only the owner can change a mandate. After
|
|
208
|
-
`mandate_revoked`, ask the user for the credential that replaced it
|
|
217
|
+
`mandate_revoked`, ask the user for the credential that replaced it, and
|
|
218
|
+
pay with that. If the error says no key beside the credential is this
|
|
219
|
+
mandate's, ask the user where the key file is, and pass it as
|
|
220
|
+
`--mandate-key-file`.
|
|
209
221
|
|
|
210
222
|
A seller that asks for your signed order gets it with the payment, and
|
|
211
223
|
`pay` prints it as `signed-offer <text>`. Keep it, and pass it to
|
|
212
|
-
`mandate verify --tx <hash> --signed-offer <text>` to check the two
|
|
224
|
+
`mandate verify --issuer <file> --tx <hash> --signed-offer <text>` to check the two
|
|
213
225
|
together.
|
|
214
226
|
|
|
215
227
|
`mandate status` shows what is left: read `spent <amount> of <budget>`,
|
|
@@ -219,10 +231,18 @@ together.
|
|
|
219
231
|
metal-agent mandate status --credential ./mandate.json --network testnet --rpc-url <endpoint>
|
|
220
232
|
```
|
|
221
233
|
|
|
222
|
-
`mandate pull` pays an address the mandate allows, with no seller. The
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
234
|
+
`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.
|
|
226
246
|
|
|
227
247
|
```bash
|
|
228
248
|
metal-agent mandate pull --credential ./mandate.json --to <payee address> --amount 2.50 --network testnet --rpc-url <endpoint>
|
|
@@ -231,12 +251,17 @@ metal-agent mandate pull --credential ./mandate.json --to <payee address> --amou
|
|
|
231
251
|
`mandate verify` checks the mandate and every payment under it from the
|
|
232
252
|
chain alone, or one `--tx <hash>`, and exits 1 when a check fails. Run it
|
|
233
253
|
when the user asks whether a payment was within the mandate; read
|
|
234
|
-
`verified yes|no`, and a failed `step` line names what differs.
|
|
254
|
+
`verified yes|no`, and a failed `step` line names what differs. It needs
|
|
255
|
+
the issuer's public key file, the `issuer-public-file` that `credential
|
|
256
|
+
create` printed; ask the user for it.
|
|
235
257
|
|
|
236
258
|
```bash
|
|
237
|
-
metal-agent mandate verify --credential ./mandate.json --network testnet --rpc-url <endpoint>
|
|
259
|
+
metal-agent mandate verify --credential ./mandate.json --issuer <issuer public key file> --network testnet --rpc-url <endpoint>
|
|
238
260
|
```
|
|
239
261
|
|
|
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
|
+
|
|
240
265
|
## status
|
|
241
266
|
|
|
242
267
|
Show a settlement from chain data: status, block, submitter, gas paid in
|
|
@@ -251,13 +276,14 @@ metal-agent status <transaction hash> --network testnet --rpc-url <endpoint>
|
|
|
251
276
|
## mcp
|
|
252
277
|
|
|
253
278
|
Serve `pay`, `fund` and `status` as MCP tools, each taking a `network`, over
|
|
254
|
-
stdio for an MCP host. `pay`
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
281
|
+
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.
|
|
260
285
|
|
|
261
286
|
```bash
|
|
262
287
|
metal-agent mcp
|
|
288
|
+
metal-agent mcp --mandate /path/to/mandate.json
|
|
263
289
|
```
|