web3-tools-mcp 3.0.0 → 3.1.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +86 -2
  2. package/README.md +76 -52
  3. package/dist/chain-meta.d.ts.map +1 -1
  4. package/dist/chain-meta.js +19 -8
  5. package/dist/chain-meta.js.map +1 -1
  6. package/dist/clear-signing.d.ts.map +1 -1
  7. package/dist/clear-signing.js +17 -6
  8. package/dist/clear-signing.js.map +1 -1
  9. package/dist/http-server.d.ts.map +1 -1
  10. package/dist/http-server.js +9 -3
  11. package/dist/http-server.js.map +1 -1
  12. package/dist/index.js +5 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/kv-storage.d.ts +2 -1
  15. package/dist/kv-storage.d.ts.map +1 -1
  16. package/dist/kv-storage.js +5 -2
  17. package/dist/kv-storage.js.map +1 -1
  18. package/dist/oauth.d.ts +18 -4
  19. package/dist/oauth.d.ts.map +1 -1
  20. package/dist/oauth.js +62 -26
  21. package/dist/oauth.js.map +1 -1
  22. package/dist/preview.d.ts.map +1 -1
  23. package/dist/preview.js +7 -5
  24. package/dist/preview.js.map +1 -1
  25. package/dist/tools/index.d.ts.map +1 -1
  26. package/dist/tools/index.js +14 -1
  27. package/dist/tools/index.js.map +1 -1
  28. package/dist/tools/read/advanced.d.ts +9 -4
  29. package/dist/tools/read/advanced.d.ts.map +1 -1
  30. package/dist/tools/read/advanced.js +45 -33
  31. package/dist/tools/read/advanced.js.map +1 -1
  32. package/dist/tools/read/balance.d.ts.map +1 -1
  33. package/dist/tools/read/balance.js +17 -32
  34. package/dist/tools/read/balance.js.map +1 -1
  35. package/dist/tools/read/contract-info.d.ts +2 -0
  36. package/dist/tools/read/contract-info.d.ts.map +1 -1
  37. package/dist/tools/read/contract-info.js +53 -122
  38. package/dist/tools/read/contract-info.js.map +1 -1
  39. package/dist/tools/read/contract.d.ts.map +1 -1
  40. package/dist/tools/read/contract.js +2 -1
  41. package/dist/tools/read/contract.js.map +1 -1
  42. package/dist/tools/read/ens.d.ts +20 -40
  43. package/dist/tools/read/ens.d.ts.map +1 -1
  44. package/dist/tools/read/ens.js +25 -33
  45. package/dist/tools/read/ens.js.map +1 -1
  46. package/dist/tools/read/gas.d.ts.map +1 -1
  47. package/dist/tools/read/gas.js +13 -48
  48. package/dist/tools/read/gas.js.map +1 -1
  49. package/dist/tools/read/logs.d.ts +61 -0
  50. package/dist/tools/read/logs.d.ts.map +1 -1
  51. package/dist/tools/read/logs.js +96 -115
  52. package/dist/tools/read/logs.js.map +1 -1
  53. package/dist/tools/read/signatures.d.ts.map +1 -1
  54. package/dist/tools/read/signatures.js +4 -3
  55. package/dist/tools/read/signatures.js.map +1 -1
  56. package/dist/tools/read/signing.d.ts.map +1 -1
  57. package/dist/tools/read/signing.js +8 -2
  58. package/dist/tools/read/signing.js.map +1 -1
  59. package/dist/tools/sign/transactions.d.ts +4 -4
  60. package/dist/tools/sign/transactions.d.ts.map +1 -1
  61. package/dist/tools/sign/transactions.js +54 -9
  62. package/dist/tools/sign/transactions.js.map +1 -1
  63. package/dist/utils.d.ts +18 -0
  64. package/dist/utils.d.ts.map +1 -1
  65. package/dist/utils.js +43 -1
  66. package/dist/utils.js.map +1 -1
  67. package/dist/wallet-client.d.ts +1 -0
  68. package/dist/wallet-client.d.ts.map +1 -1
  69. package/dist/wallet-client.js +16 -3
  70. package/dist/wallet-client.js.map +1 -1
  71. package/package.json +4 -7
  72. package/src/chain-meta.ts +16 -7
  73. package/src/clear-signing.ts +15 -9
  74. package/src/http-server.ts +8 -3
  75. package/src/index.ts +5 -1
  76. package/src/kv-storage.ts +6 -3
  77. package/src/oauth.ts +93 -34
  78. package/src/preview.ts +7 -5
  79. package/src/tools/index.ts +12 -1
  80. package/src/tools/read/advanced.ts +63 -34
  81. package/src/tools/read/balance.ts +18 -33
  82. package/src/tools/read/contract-info.ts +64 -144
  83. package/src/tools/read/contract.ts +2 -1
  84. package/src/tools/read/ens.ts +26 -33
  85. package/src/tools/read/gas.ts +13 -50
  86. package/src/tools/read/logs.ts +131 -143
  87. package/src/tools/read/signatures.ts +4 -4
  88. package/src/tools/read/signing.ts +8 -2
  89. package/src/tools/sign/transactions.ts +60 -9
  90. package/src/utils.ts +47 -1
  91. package/src/wallet-client.ts +17 -3
package/CHANGELOG.md CHANGED
@@ -2,7 +2,75 @@
2
2
 
3
3
  Notable changes per release. Dates are release dates; unreleased work sits at the top.
4
4
 
5
- ## [3.0.0] — 2026-09-23
5
+ ## [3.1.0] — 2026-10-01
6
+
7
+ Mostly fixes, several of them for security — worth taking on any hosted server.
8
+
9
+ From this release `web3-wallet-relay` shares the server's version number, jumping from 2.0.0
10
+ to 3.1.0. The two speak one protocol that carries no version of its own, so the package
11
+ version is what matches them: a relay hosted on its own runs at the version of the server
12
+ pointing at it. `web3-tools-mcp` still pins it exactly.
13
+
14
+ ### Added
15
+
16
+ - A host's `Login` can name the `credential` it checks, binding every code and token issued
17
+ under it so that rotating the secret revokes them, and its `page()` is told which client
18
+ is asking and where the code will go.
19
+
20
+ ### Changed
21
+
22
+ - `trace_transaction`'s `traceType` is `trace`, `prestate` or `stateDiff`. `vmTrace` is gone:
23
+ it ran the prestate tracer under another name, and `stateDiff` asked for a tracer no node
24
+ has. Traces too large for an agent's context are cut short and say so.
25
+ - `get_logs` returns at most 1,000 logs, with `truncated` and the `nextBlock` to continue
26
+ from. `toBlock` is inclusive on both paths, a list in `eventArgs` is an OR filter, and an
27
+ invalid `address` is an error rather than a filter silently dropped.
28
+ - `get_balance`, `read_contract` and `batch_resolve_ens_names` take at most 25 items.
29
+ - ENS tools take `mainnet`, `linea` or `base` — the chains that have a resolver — and the
30
+ no-op `universalResolver` parameter is gone.
31
+ - `render.yaml` is a single service: the relay runs inside the MCP server, as on Fly.
32
+ - Keeping OAuth state in Upstash needs per-field hash expiry (`HEXPIRE`, Redis ≥ 7.4), so
33
+ expired tokens no longer pile up. The file store prunes them on write.
34
+
35
+ ### Fixed
36
+
37
+ - `send_erc20_token` no longer assumes 18 decimals. It reads them on-chain and refuses a
38
+ `decimals` that disagrees; a token whose decimals cannot be read needs them passed.
39
+ - `write_contract` takes numeric arguments only as safe integers — pass a large uint or int
40
+ as a string — and coerces string arguments to their ABI types, as `read_contract` does.
41
+ - `sign_message` sends the browser the message hex-encoded, as the phone gets it, so both
42
+ sign the same bytes. The phone signs on a chain its session approved, not mainnet.
43
+ - Phone signing on `localhost` is refused up front: the phone has no route to that node. Use
44
+ the browser.
45
+ - The signing preview names each labelled address as `Name (0x…)`, shows token amounts with
46
+ the token's address, and gives an amount whose decimals are unknown as the raw integer,
47
+ marked so, rather than assuming 18. Its summary includes `to`.
48
+ - `get_logs` over Hypersync no longer drops the last block, reports a response cut short
49
+ by the server, or scans from genesis when `fromBlock` is omitted.
50
+ - `get_error_signature` hashes tuple parameters correctly.
51
+ - `get_gas_price` shows sub-gwei L2 prices instead of "0.00", and costs in the chain's own
52
+ native token.
53
+ - An invalid, expired or replayed OAuth code or refresh token answers `invalid_grant`, not a
54
+ 500, so connectors re-authorise instead of retrying.
55
+ - Etherscan errors say why ("Invalid API Key", rate limit) rather than "NOTOK".
56
+ - `npx web3-wallet-relay` starts the relay.
57
+
58
+ ### Security
59
+
60
+ - The provider API key no longer appears in tool output.
61
+ - `get_ens_avatar` returns the raw avatar record rather than fetching it server-side.
62
+ - Requests carry `expiresAt`, and the signing page cancels an approval that arrives after
63
+ the request timed out or was disconnected. A request that failed any way but an explicit
64
+ rejection now reports `outcome_unknown` — it may still have been broadcast — instead of
65
+ `rejected_or_failed`, so an agent checks before retrying rather than paying twice.
66
+ - The signing page is hardened against script injection and framing, with a strict CSP.
67
+ - OAuth refresh tokens expire, and rotating `MCP_TOKEN` revokes every token issued under
68
+ it — existing tokens predate the binding, so single-token deployments re-authorise once.
69
+ The login page names the client and where it redirects, and cannot be framed.
70
+ `MCP_TRUST_PROXY` lets rate limiting see client addresses behind a proxy.
71
+ - The hosted signer link is no longer written to the logs.
72
+
73
+ ## [3.0.0] — 2026-09-26
6
74
 
7
75
  The theme is multi-tenancy: one server can now carry several people without their wallets
8
76
  meeting. Nothing turns that on by itself — a server still authenticates its deployment
@@ -36,6 +104,22 @@ handshake changed, so a mismatched pair cannot pair at all.
36
104
  tools take `account` to choose between them, as does `disconnect_phone_wallet` — which
37
105
  still clears everything when no account is named. With one wallet paired nothing changes,
38
106
  and omitting `account` uses the most recently paired.
107
+ - **`simulate_bundle`** runs several transactions in order in one block, each on the state
108
+ the last left — approve then swap, deposit then borrow. Offered with an Alchemy key.
109
+ - **Signing requests outlive their call.** One not approved in time comes back with a
110
+ `requestId`, and `check_signing_request` collects it instead of a second prompt landing in
111
+ the wallet. A phone request returns as soon as the wallet has it, and both signers wait
112
+ for the receipt, reporting mined, reverted or still pending. The signing page shows every
113
+ request waiting, approvable in any order.
114
+ - A host assembling its own server can mount routes, hand a pairing made under a
115
+ placeholder to the address it proved, and draw the pairing QR as SVG (`qrSvg`).
116
+ - The server declares an icon, so a connector list shows more than a letter.
117
+ - `pair_phone_wallet` warns when the same wallet app is already paired, and reports a
118
+ pairing the wallet ended itself.
119
+
120
+ ### Fixed
121
+
122
+ - An ERC-721 `Transfer` reads as a token id, not as an ERC-20 transfer of nothing.
39
123
 
40
124
  ### Security
41
125
 
@@ -177,7 +261,7 @@ sign it.
177
261
  `call_contract_write` is now `write_contract` — the old pair gave no hint which one
178
262
  spent gas. The names now match viem's, and a saved prompt naming the old ones will need
179
263
  updating.
180
- - Every supported chain now lives in one table ([mcp/src/chains.ts](mcp/src/chains.ts)). Adding a
264
+ - Every supported chain now lives in one table ([mcp/src/chains.ts](https://github.com/hajnalben/web3-tools-mcp/blob/main/mcp/src/chains.ts)). Adding a
181
265
  chain is a single entry; the tool schemas, RPC selection, explorer links, Hypersync
182
266
  routing and `--help` all derive from it.
183
267
  - Tool errors surface the underlying failure rather than a re-wrapped message that hid it.
package/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
  **Your agent proposes the transaction. You approve it — in your own wallet, on your phone.** 📱
6
6
 
7
- 30 MCP tools for reading any EVM network and signing transactions in *your own* wallet.
7
+ 32 MCP tools for reading any EVM network and signing transactions in *your own* wallet.
8
8
  Every transaction is decoded, named and simulated before you approve it.
9
9
 
10
10
  [![npm](https://img.shields.io/npm/v/web3-tools-mcp?color=%233856d6&label=npm)](https://www.npmjs.com/package/web3-tools-mcp)
11
11
  [![downloads](https://img.shields.io/npm/dm/web3-tools-mcp?color=%233856d6)](https://www.npmjs.com/package/web3-tools-mcp)
12
12
  [![node](https://img.shields.io/node/v/web3-tools-mcp?color=%233856d6)](https://nodejs.org)
13
- [![license](https://img.shields.io/npm/l/web3-tools-mcp?color=%233856d6)](LICENSE)
13
+ [![license](https://img.shields.io/npm/l/web3-tools-mcp?color=%233856d6)](https://github.com/hajnalben/web3-tools-mcp/blob/main/LICENSE)
14
14
 
15
15
  </div>
16
16
 
@@ -22,7 +22,7 @@ One entry in that client's MCP config:
22
22
  ```
23
23
 
24
24
  Each app keeps that config somewhere different —
25
- [the file paths are below ↓](#-setup). You need Node.js ≥ 20; `npx` fetches the rest.
25
+ [the file paths are below ↓](#-setup). You need Node.js ≥ 20.19; `npx` fetches the rest.
26
26
 
27
27
  **ChatGPT, Grok** and **claude.ai** cannot launch anything locally — they only reach a URL.
28
28
  [Host it once ↓](#-hosting) and add it as a connector, and there is nothing running on your
@@ -91,7 +91,7 @@ npx web3-tools-mcp --walletconnect-project-id YOUR_PROJECT_ID
91
91
  | 💾 | **It sticks.** The session is stored on disk (or in Redis when hosted), so it survives restarts and redeploys. Pair once, not once a day |
92
92
  | ✍️ | **You choose each time.** Every signing tool takes a required `signWith`, so the agent asks whether this one goes to your phone or the browser. A paired phone never quietly claims a request |
93
93
  | 🧾 | **You still see the decode.** The full preview comes back in the tool response — your wallet shows its own summary, so read ours before you approve theirs |
94
- | 🔌 | **Drop it any time.** `disconnect_phone_wallet` clears every session and pairing |
94
+ | 🔌 | **Drop it any time.** `disconnect_phone_wallet` drops the wallet you name by `account`, or every session and pairing when you name none |
95
95
 
96
96
  Works with **MetaMask · Rabby · Trust · Coinbase Wallet** — anything speaking WalletConnect v2.
97
97
 
@@ -123,28 +123,36 @@ returns the page URL any time you want to open it yourself.
123
123
  ## 🧰 Tools
124
124
 
125
125
  <details>
126
- <summary><b>30 tools</b> — reads, writes, ENS, logs, tracing</summary>
126
+ <summary><b>32 tools</b> — reads, writes, ENS, logs, tracing</summary>
127
127
 
128
128
  ### ✍️ Transactions & signing
129
129
  | Tool | |
130
130
  | --- | --- |
131
- | `write_contract` | Send a transaction calling a state-changing function, via your wallet |
131
+ | `write_contract` | Send a transaction calling a state-changing function, via your wallet. Pass large integers as strings |
132
132
  | `send_native_token` | Send ETH or a native token |
133
- | `send_erc20_token` | Send an ERC-20 |
134
- | `sign_message` | Sign a message |
135
- | `wallet_status` | Which signer is connected — phone or browser |
133
+ | `send_erc20_token` | Send an ERC-20, with decimals read on-chain — a `decimals` you pass must agree |
134
+ | `sign_message` | Sign a message — the same bytes on either signer |
135
+ | `check_signing_request` | Collect a request still awaiting approval, by its `requestId` |
136
+ | `wallet_status` | Every signer and whether it is ready — phone wallets and the browser page |
136
137
  | `pair_phone_wallet` | Pair a phone over WalletConnect, returns a QR |
137
- | `disconnect_phone_wallet` | Drop every WalletConnect session and pairing |
138
+ | `disconnect_phone_wallet` | Drop one paired wallet by `account`, or every session and pairing |
138
139
 
139
140
  The four signing tools take a required `signWith` of `phone` or `browser`. There is no
140
141
  default on purpose — the agent has to ask you, so a request never lands on a device you are
141
- not holding.
142
+ not holding. On `localhost` only the browser can sign; a phone has no route to your node.
143
+ With several phones paired, the optional `account` picks one by address;
144
+ omitted, the most recently paired is used.
145
+
146
+ A request not approved within the call comes back with a `requestId` instead of hanging,
147
+ and `check_signing_request` collects it — asking again would put a second prompt in front
148
+ of your wallet.
142
149
 
143
150
  ### 📜 Contracts
144
151
  | Tool | |
145
152
  | --- | --- |
146
- | `read_contract` | Read state via view/pure functions — batched, no wallet, no gas |
153
+ | `read_contract` | Read state via view/pure functions — batched (up to 25 calls), no wallet, no gas |
147
154
  | `simulate_contract` | Simulate without broadcasting, with gas |
155
+ | `simulate_bundle` | Simulate several transactions in order, each on the state the last left — approve → swap. Needs `ALCHEMY_API_KEY` |
148
156
  | `get_contract_abi` | ABI, with proxy detection and verification status |
149
157
  | `get_contract_source_code` | Verified source, proxies included |
150
158
  | `get_contract_source_file` | One file out of the cached source |
@@ -157,14 +165,20 @@ not holding.
157
165
  ### ⛓️ Chain data
158
166
  | Tool | |
159
167
  | --- | --- |
160
- | `get_balance` | Native or ERC-20 balances — batched |
161
- | `get_logs` | Query and decode events, with Hypersync fallback |
168
+ | `get_balance` | Native or ERC-20 balances — batched, up to 25 queries |
169
+ | `get_logs` | Query and decode events; Hypersync when the RPC refuses the range. At most 1,000 logs — past that it returns `truncated` and the `nextBlock` to continue from. A list in `eventArgs` matches any of its values |
162
170
  | `get_block_info` | Block data |
163
171
  | `get_storage_at` | Storage slots, with type decoding |
164
172
  | `get_gas_price` | Current gas — legacy and EIP-1559 |
165
173
  | `estimate_gas` | Gas for any transaction |
166
- | `trace_transaction` | Call tree, VM trace, state diff |
167
- | `debug_call` | Trace a call without broadcasting, falling back to a local anvil fork |
174
+ | `trace_transaction` | Call tree, prestate or state diff |
175
+ | `debug_call` | Trace a call without broadcasting, through a node at `ANVIL_RPC_URL` |
176
+
177
+ Tracing prefers an RPC that exposes `debug_*`, and otherwise uses a node you already run at
178
+ `ANVIL_RPC_URL` (default `127.0.0.1:8545`, e.g. `anvil --fork-url …`) — nothing is started
179
+ for you. Replaying a transaction older than the fork re-forks that node, clearing its state,
180
+ so it happens only with `ANVIL_ALLOW_RESET=1`. A hosted server has no default and traces only
181
+ through an explicit `ANVIL_RPC_URL`.
168
182
 
169
183
  ### 🏷️ ENS
170
184
  | Tool | |
@@ -172,8 +186,10 @@ not holding.
172
186
  | `resolve_ens_name` | Name → address |
173
187
  | `reverse_resolve_ens` | Address → name |
174
188
  | `get_ens_text_record` | Text records |
175
- | `get_ens_avatar` | Avatar URI |
176
- | `batch_resolve_ens_names` | Many names at once |
189
+ | `get_ens_avatar` | The raw avatar record — URL, data URI or NFT reference, not fetched |
190
+ | `batch_resolve_ens_names` | Up to 25 names at once |
191
+
192
+ ENS tools take `mainnet` (ENS), `linea` (Linea Names) or `base` (Basenames).
177
193
 
178
194
  </details>
179
195
 
@@ -196,7 +212,7 @@ not holding.
196
212
  | Unichain | 130 | ✅ |
197
213
  | Localhost | 1337 | ❌ |
198
214
 
199
- Adding one is a single entry in [`mcp/src/chains.ts`](mcp/src/chains.ts).
215
+ Adding one is a single entry in [`mcp/src/chains.ts`](https://github.com/hajnalben/web3-tools-mcp/blob/main/mcp/src/chains.ts).
200
216
 
201
217
  </details>
202
218
 
@@ -291,7 +307,7 @@ What you lose is reach, not stability — so here is the honest version:
291
307
  | `WALLETCONNECT_PROJECT_ID` | [walletconnect](https://dashboard.walletconnect.com) | 📱 **No phone signing at all.** Browser wallet only, so a hosted instance has no way to sign |
292
308
  | `ALCHEMY_API_KEY`<br>or `INFURA_API_KEY`<br>or `CUSTOM_RPC` | [alchemy](https://alchemy.com) · [infura](https://infura.io) | **No historical state.** Public endpoints answer `403 Archive requests require a personal token`, which takes out balances, storage and calls at a past block, event ranges, and `trace_transaction` |
293
309
  | `ETHERSCAN_API_KEY` | [etherscan](https://etherscan.io/apis) | `get_contract_abi`, `get_contract_source_code` and `get_contract_source_file` refuse. Signing previews still decode — they try Sourcify first, then recover the ABI from bytecode |
294
- | `HYPERSYNC_API_KEY` | [envio](https://envio.dev) | Event queries fall back to plain RPC — slower, and past ranges then need one of the provider keys above |
310
+ | `HYPERSYNC_API_KEY` | [envio](https://envio.dev) | `get_logs` asks the RPC first and falls back to Hypersync when the RPC refuses the range. Without a token that fallback is gone, so wide or past ranges depend on your provider's limits |
295
311
 
296
312
  So with nothing configured you get current balances, contract reads, gas, ENS, simulation
297
313
  and browser signing. Add `WALLETCONNECT_PROJECT_ID` for your phone and one provider key for
@@ -299,7 +315,7 @@ history, and everything above lights up.
299
315
 
300
316
  Every key has a matching flag (`--etherscan-api-key`, …), RPC selection falls back
301
317
  Alchemy → Infura → public, and `CUSTOM_RPC` overrides all of it.
302
- `npx web3-tools-mcp --help` lists them; [.env.example](.env.example) documents each one.
318
+ `npx web3-tools-mcp --help` lists them; [.env.example](https://github.com/hajnalben/web3-tools-mcp/blob/main/.env.example) documents each one.
303
319
 
304
320
  ```bash
305
321
  npx web3-tools-mcp --etherscan-api-key KEY --walletconnect-project-id ID
@@ -319,26 +335,34 @@ transaction at your phone.
319
335
  <a href="https://fly.io/docs/launch/"><img src="https://img.shields.io/badge/Deploy%20on-Fly.io-8b5cf6?style=for-the-badge&logo=flydotio&logoColor=white" alt="Deploy on Fly.io" height="32"></a>
320
336
 
321
337
  **Render** reads `render.yaml`, generates `MCP_TOKEN` and asks for `WALLETCONNECT_PROJECT_ID`
322
- — genuinely one click.
338
+ — one click, on a paid `starter` instance with a 1 GB disk so it stays awake and keeps the
339
+ pairing. `MCP_PUBLIC_URL` defaults to the service's `onrender.com` address; set it only for a
340
+ custom domain.
323
341
 
324
342
  **Fly** ships no deploy button, so it is four commands. Worth it for a personal instance:
325
343
  volumes come with any plan, so the pairing survives redeploys without paying for a disk.
326
344
 
327
345
  ```bash
328
- fly launch --no-deploy --copy-config
346
+ fly launch --no-deploy --copy-config # then set MCP_PUBLIC_URL in fly.toml to https://<app>.fly.dev
329
347
  fly volumes create data --size 1
330
348
  fly secrets set MCP_TOKEN=$(openssl rand -hex 24) WALLETCONNECT_PROJECT_ID=<id>
331
349
  fly deploy
332
350
  ```
333
351
 
352
+ Without the right `MCP_PUBLIC_URL` the OAuth metadata and the wallet links point somewhere
353
+ clients cannot reach. Both `fly.toml` and `render.yaml` set `MCP_TRUST_PROXY=1`, so rate
354
+ limiting sees client addresses rather than the platform's proxy.
355
+
334
356
  <details>
335
357
  <summary>🐳 <b>Docker, and connecting a client</b></summary>
336
358
 
337
359
  There is a plain `Dockerfile` too, so Railway, Cloud Run or your own box work the same way:
338
360
 
339
361
  ```bash
362
+ docker build -t web3-tools-mcp .
340
363
  docker run -p 8080:8080 \
341
364
  -e MCP_TOKEN=<long random string> \
365
+ -e MCP_PUBLIC_URL=https://your-host \
342
366
  -e WALLETCONNECT_PROJECT_ID=<id> \
343
367
  web3-tools-mcp
344
368
  ```
@@ -352,54 +376,54 @@ claude mcp add --transport http web3-tools https://your-host/mcp \
352
376
 
353
377
  Clients that cannot send a header — claude.ai connectors, and the browser and phone apps —
354
378
  use OAuth, which the server implements against the same credential: it shows a page asking
355
- for `MCP_TOKEN` and issues a token once you paste it. No identity provider, no accounts. Set
356
- `MCP_PUBLIC_URL` to the address clients reach you on, since OAuth metadata must advertise it.
379
+ for `MCP_TOKEN` and issues a token once you paste it. No identity provider, no accounts.
357
380
 
358
381
  > 🔐 **`MCP_TOKEN` is mandatory** and the server refuses to start without it. Anyone who
359
382
  > reaches `/mcp` while your phone is paired can push signing prompts at it. You would still
360
383
  > approve each one, but that is a phishing surface, not a feature.
361
384
 
385
+ | Variable | |
386
+ | --- | --- |
387
+ | `MCP_HTTP_PORT` | Serve over HTTP on this port instead of stdio. Also switches on the hosted guards: no `localhost` chain, no loopback tracing node |
388
+ | `MCP_HTTP_HOST` | Bind address, default `0.0.0.0` |
389
+ | `MCP_TOKEN` | The one credential, as a bearer header or through OAuth. Changing it revokes every OAuth token issued against the old one |
390
+ | `MCP_PUBLIC_URL` | The address clients reach you on — advertised in OAuth metadata and used for wallet links |
391
+ | `MCP_TRUST_PROXY` | Reverse-proxy hops to trust for client IPs in rate limiting. `1` behind Fly or Render; off by default |
392
+ | `MCP_HOSTED` | The hosted guards without `MCP_HTTP_PORT`, for a host assembling its own server from the library |
393
+ | `XDG_CONFIG_HOME` | Where pairings, OAuth tokens and the relay token are stored, under `web3-tools-mcp/` |
394
+ | `UPSTASH_REDIS_REST_URL`<br>`UPSTASH_REDIS_REST_TOKEN` | Keep sessions and tokens in Redis instead. Needs per-field hash expiry (`HEXPIRE`: Upstash, or Redis ≥ 7.4) |
395
+ | `WALLET_TOKEN` | Relay secret. Unset, a hosted server mints one per boot |
396
+ | `WALLET_SERVER_URL` | A separately hosted relay, below |
397
+ | `ANVIL_RPC_URL`<br>`ANVIL_ALLOW_RESET` | Tracing node, and whether it may be re-forked — see Tools |
398
+
362
399
  Two things decide whether the pairing survives:
363
400
 
364
401
  - ⏰ **Keep the instance awake.** Sleeping drops the WalletConnect socket, so the first
365
402
  transaction after an idle period waits for the host to wake — about a minute on a free tier.
366
403
  - 💾 **Give the session somewhere durable.** Most hosts have an ephemeral filesystem, so a
367
404
  plain file is lost on redeploy and you rescan the QR. Attach a volume and point
368
- `XDG_CONFIG_HOME` at it (what `render.yaml` does), or set `UPSTASH_REDIS_REST_URL` and
369
- `UPSTASH_REDIS_REST_TOKEN` ([Upstash](https://upstash.com) has a free plan).
405
+ `XDG_CONFIG_HOME` at it (what `render.yaml` and `fly.toml` do), or set
406
+ `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` ([Upstash](https://upstash.com)
407
+ has a free plan).
370
408
 
371
409
  Render's free Key Value instance is not an option here — no persistence, so the pairing
372
410
  disappears at its next maintenance.
373
411
 
374
412
  Both signers work on a hosted instance. The signing page is served from the same port as
375
413
  `/mcp`, so `https://your-host/#t=<relay token>` is your wallet page — no second service to
376
- deploy. Ask the agent for `wallet_status` to get the link; it is behind `MCP_TOKEN`, and the
377
- relay token is minted fresh each boot rather than stored, so the URL changes when you
378
- redeploy.
414
+ deploy. Ask the agent for `wallet_status` to get the link; it is behind `MCP_TOKEN` and never written to the logs. Unless
415
+ you set `WALLET_TOKEN`, the relay secret is minted fresh each boot rather than stored, so the
416
+ URL changes when you redeploy.
379
417
 
380
418
  </details>
381
419
 
382
420
  <details>
383
421
  <summary>🖇️ <b>Host the signing page</b> separately</summary>
384
422
 
385
- The relay is its own package, [`wallet-relay/`](wallet-relay) — express, cors and ws, about
386
- 4 MB installed against ~180 MB for the server. It runs anywhere that keeps a Node process
387
- alive and supports WebSockets.
388
-
389
- ```bash
390
- WALLET_TOKEN=<long random string> \
391
- WALLET_PUBLIC_URL=https://wallet.example.com \
392
- npx web3-wallet-relay
393
- ```
394
-
395
- Then point the server at it with `WALLET_SERVER_URL` and the same `WALLET_TOKEN`.
396
- `render.yaml` deploys it as-is. Anyone holding `WALLET_TOKEN` can send your browser a
397
- transaction to sign — treat it like a password, and always serve over HTTPS.
398
-
399
- The pairing link the server prints carries a different token, derived from that one, which
400
- can only answer signing requests and not make them. Sharing a pairing link is therefore not
401
- the same as sharing `WALLET_TOKEN` — but it still lets whoever has it act as your wallet
402
- page, so a signing request can reach them instead of you.
423
+ The relay is its own package, [`web3-wallet-relay`](https://github.com/hajnalben/web3-tools-mcp/tree/main/wallet-relay),
424
+ and runs anywhere that keeps a Node process alive and supports WebSockets. Its README covers
425
+ hosting it; run it at this server's version, then point the server at it with
426
+ `WALLET_SERVER_URL` and the same `WALLET_TOKEN`.
403
427
 
404
428
  Locally nothing changes: the server embeds the same relay.
405
429
 
@@ -421,11 +445,11 @@ npm run typecheck
421
445
  npm test
422
446
  ```
423
447
 
424
- Two workspaces: [`mcp/`](mcp) is this server, [`wallet-relay/`](wallet-relay) is the signing
425
- page. [CONTRIBUTING.md](CONTRIBUTING.md) covers running a checkout against a client, the
426
- layout, and how to add a chain or a tool. Releases: [CHANGELOG.md](CHANGELOG.md).
448
+ Two workspaces: [`mcp/`](https://github.com/hajnalben/web3-tools-mcp/tree/main/mcp) is this server, [`wallet-relay/`](https://github.com/hajnalben/web3-tools-mcp/tree/main/wallet-relay) is the signing
449
+ page. [CONTRIBUTING.md](https://github.com/hajnalben/web3-tools-mcp/blob/main/CONTRIBUTING.md) covers running a checkout against a client, the
450
+ layout, and how to add a chain or a tool. Releases: [CHANGELOG.md](https://github.com/hajnalben/web3-tools-mcp/blob/main/CHANGELOG.md).
427
451
 
428
- Requires Node.js ≥ 20.
452
+ Requires Node.js ≥ 20.19.
429
453
 
430
454
  ## 📄 License
431
455
 
@@ -1 +1 @@
1
- {"version":3,"file":"chain-meta.d.ts","sourceRoot":"","sources":["../src/chain-meta.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,GAAG,EAA8B,MAAM,MAAM,CAAA;AAE3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAW3C,wBAAsB,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM;SAJvB,GAAG;YAAU,UAAU,GAAG,SAAS;YAAU,MAAM;WAAS,MAAM;GAqCzG;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM;aArClB,MAAM;eAAa,MAAM;GAyDrE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmBjG;AAED,wEAAwE;AACxE,eAAO,MAAM,WAAW,QAAoB,CAAA;AAC5C,eAAO,MAAM,mBAAmB,QAAmB,CAAA"}
1
+ {"version":3,"file":"chain-meta.d.ts","sourceRoot":"","sources":["../src/chain-meta.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,GAAG,EAA8B,MAAM,MAAM,CAAA;AAE3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAiB3C,wBAAsB,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM;SAP1B,GAAG;YAAU,UAAU,GAAG,SAAS;YAAU,MAAM;WAAS,MAAM;GAwCtG;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM;aAxCrB,MAAM;eAAa,MAAM;GA6DlE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqBjG;AAED,wEAAwE;AACxE,eAAO,MAAM,WAAW,QAAoB,CAAA;AAC5C,eAAO,MAAM,mBAAmB,QAAmB,CAAA"}
@@ -6,13 +6,18 @@
6
6
  import { whatsabi } from '@shazow/whatsabi';
7
7
  import { parseAbiItem } from 'viem';
8
8
  import { getClientManager } from './client.js';
9
+ import { TtlCache } from './utils.js';
9
10
  const ERC20_META_ABI = [
10
11
  parseAbiItem('function decimals() view returns (uint8)'),
11
12
  parseAbiItem('function symbol() view returns (string)')
12
13
  ];
13
- const abiCache = new Map();
14
- const labelCache = new Map();
15
- const metaCache = new Map();
14
+ // An hour covers a session's repeats while still noticing an upgraded proxy.
15
+ const TTL_MS = 60 * 60 * 1000;
16
+ const abiCache = new TtlCache(200, TTL_MS);
17
+ const labelCache = new TtlCache(1000, TTL_MS);
18
+ const metaCache = new TtlCache(1000, TTL_MS);
19
+ /** A local node is reset and redeployed at will, so nothing learned from it stays true. */
20
+ const cacheable = (chain) => chain !== 'localhost';
16
21
  export async function loadAbi(chain, address) {
17
22
  const key = `${chain}:${address.toLowerCase()}`;
18
23
  const cached = abiCache.get(key);
@@ -41,7 +46,8 @@ export async function loadAbi(chain, address) {
41
46
  proxy: result.address !== address ? result.address : undefined,
42
47
  name: result.contractResult?.name ?? undefined
43
48
  };
44
- abiCache.set(key, loaded);
49
+ if (cacheable(chain))
50
+ abiCache.set(key, loaded);
45
51
  return loaded;
46
52
  }
47
53
  export async function tokenMeta(chain, token) {
@@ -61,7 +67,9 @@ export async function tokenMeta(chain, token) {
61
67
  decimals: decimals.status === 'success' ? Number(decimals.result) : undefined,
62
68
  symbol: symbol.status === 'success' ? symbol.result : undefined
63
69
  };
64
- metaCache.set(key, meta);
70
+ // A failed call may be a flaky RPC rather than a token without that method.
71
+ if (cacheable(chain) && decimals.status === 'success' && symbol.status === 'success')
72
+ metaCache.set(key, meta);
65
73
  return meta;
66
74
  }
67
75
  /**
@@ -71,8 +79,9 @@ export async function tokenMeta(chain, token) {
71
79
  */
72
80
  export async function addressLabel(chain, address) {
73
81
  const key = `${chain}:${address.toLowerCase()}`;
74
- if (labelCache.has(key))
75
- return labelCache.get(key);
82
+ const cached = labelCache.get(key);
83
+ if (cached)
84
+ return cached.label;
76
85
  let label;
77
86
  try {
78
87
  const code = await getClientManager()
@@ -86,8 +95,10 @@ export async function addressLabel(chain, address) {
86
95
  }
87
96
  catch {
88
97
  // Unknown address — show it bare rather than failing the preview.
98
+ return undefined;
89
99
  }
90
- labelCache.set(key, label);
100
+ if (cacheable(chain))
101
+ labelCache.set(key, { label });
91
102
  return label;
92
103
  }
93
104
  /** uint256 max and anything near it means "infinite" in an approval. */
@@ -1 +1 @@
1
- {"version":3,"file":"chain-meta.js","sourceRoot":"","sources":["../src/chain-meta.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chain-meta.js","sourceRoot":"","sources":["../src/chain-meta.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"clear-signing.d.ts","sourceRoot":"","sources":["../src/clear-signing.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;;;;GAMG;AAEH,UAAU,UAAU;IAElB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAC7E;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAkCD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAiBD,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AA+DD,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAKxF;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,SAAS,EAChB,EAAE,EAAE,SAAS,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAiBlC"}
1
+ {"version":3,"file":"clear-signing.d.ts","sourceRoot":"","sources":["../src/clear-signing.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;;;;GAMG;AAEH,UAAU,UAAU;IAElB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAC7E;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAkCD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAiBD,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAqED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAKxF;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,SAAS,EAChB,EAAE,EAAE,SAAS,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAiBlC"}
@@ -80,11 +80,22 @@ async function formatField(chain, field, root, tx) {
80
80
  case 'amount': {
81
81
  const amount = typeof raw === 'bigint' ? raw : BigInt(raw);
82
82
  const token = field.params?.tokenAddress ?? (field.params?.tokenPath ? resolvePath(root, tx, field.params.tokenPath) : undefined);
83
- const meta = typeof token === 'string' && isAddress(token)
84
- ? await tokenMeta(chain, token).catch(() => ({ symbol: undefined, decimals: undefined }))
83
+ const tokenAddress = typeof token === 'string' && isAddress(token) ? getAddress(token) : undefined;
84
+ const meta = tokenAddress
85
+ ? await tokenMeta(chain, tokenAddress).catch(() => ({ symbol: undefined, decimals: undefined }))
85
86
  : { symbol: undefined, decimals: undefined };
86
- const symbol = meta.symbol ? ` ${meta.symbol}` : '';
87
- out.value = amount > UNLIMITED_THRESHOLD ? `Unlimited${symbol}` : `${formatUnits(amount, meta.decimals ?? 18)}${symbol}`;
87
+ // `amount` is the native currency, which always has 18 decimals.
88
+ const decimals = meta.decimals ?? (format === 'amount' && !tokenAddress ? 18 : undefined);
89
+ // symbol() is whatever the token contract says it is, so the address always goes with it.
90
+ const symbol = `${meta.symbol ? ` ${meta.symbol}` : ''}${tokenAddress ? ` (${tokenAddress})` : ''}`;
91
+ if (tokenAddress)
92
+ out.address = tokenAddress;
93
+ if (amount > UNLIMITED_THRESHOLD)
94
+ out.value = `Unlimited${symbol}`;
95
+ else if (decimals === undefined)
96
+ out.value = `${amount}${symbol} (decimals unknown)`;
97
+ else
98
+ out.value = `${formatUnits(amount, decimals)}${symbol}`;
88
99
  return out;
89
100
  }
90
101
  case 'addressName':
@@ -95,10 +106,10 @@ async function formatField(chain, field, root, tx) {
95
106
  return out;
96
107
  }
97
108
  const address = getAddress(raw);
98
- const name = registry()[address.toLowerCase()]?.protocol;
109
+ const name = lookupContract(chain, address)?.protocol;
99
110
  out.address = address;
100
111
  out.name = name ? protocolLabel(name) : await addressLabel(chain, address).catch(() => undefined);
101
- out.value = out.name ?? address;
112
+ out.value = out.name ? `${out.name} (${address})` : address;
102
113
  return out;
103
114
  }
104
115
  default:
@@ -1 +1 @@
1
- {"version":3,"file":"clear-signing.js","sourceRoot":"","sources":["../src/clear-signing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clear-signing.js","sourceRoot":"","sources":["../src/clear-signing.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mDAAmD,CAAA;AAE5F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAoBpD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wFAAwF;IACxF,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,eAAe,EAAE,MAAM,SAAS,CAAA;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,gGAAgG;IAChG,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CAChC;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6F5H"}
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mDAAmD,CAAA;AAE5F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAoBpD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wFAAwF;IACxF,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,eAAe,EAAE,MAAM,SAAS,CAAA;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,gGAAgG;IAChG,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CAChC;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkG5H"}
@@ -25,7 +25,7 @@ export async function startHttpServer(options) {
25
25
  if (!HOSTED) {
26
26
  throw new Error('Serving over HTTP needs MCP_HOSTED=1 (or MCP_HTTP_PORT) in the environment before web3-tools-mcp is imported');
27
27
  }
28
- const port = options.port ?? Number(process.env.MCP_HTTP_PORT) ?? DEFAULT_PORT;
28
+ const port = options.port ?? (Number(process.env.MCP_HTTP_PORT) || DEFAULT_PORT);
29
29
  const host = options.host ?? process.env.MCP_HTTP_HOST ?? '0.0.0.0';
30
30
  const token = options.token ?? process.env.MCP_TOKEN;
31
31
  // A reachable MCP server with a paired phone can push signing prompts at that phone. It
@@ -38,6 +38,12 @@ export async function startHttpServer(options) {
38
38
  const issuer = new URL(publicUrl);
39
39
  const provider = options.provider ?? new SingleUserOAuthProvider(token);
40
40
  const app = express();
41
+ // The auth routes rate-limit per req.ip, which behind a platform proxy is the proxy's own
42
+ // address — every caller would share one bucket. Only trust as many hops as are really
43
+ // in front, or anyone could pick their own bucket with a forged X-Forwarded-For.
44
+ const proxyHops = Number(process.env.MCP_TRUST_PROXY);
45
+ if (proxyHops)
46
+ app.set('trust proxy', proxyHops);
41
47
  app.use(express.json());
42
48
  // The login form posts a token, so the authorize route needs form bodies too.
43
49
  app.use(express.urlencoded({ extended: false }));
@@ -81,8 +87,8 @@ export async function startHttpServer(options) {
81
87
  }
82
88
  });
83
89
  const server = await new Promise((resolve, reject) => {
84
- const listening = app.listen(port, host, () => resolve(listening));
85
- listening.once('error', reject);
90
+ // Express 5 hands a listen error to this callback rather than leaving it to 'error'.
91
+ const listening = app.listen(port, host, (error) => (error ? reject(error) : resolve(listening)));
86
92
  });
87
93
  // The signing page rides on this same server, so a hosted deployment can offer browser
88
94
  // signing without a second service: one platform port serves both /mcp and the page.
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gEAAgE,CAAA;AAElG,OAAO,EAAE,oCAAoC,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAA;AAErH,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAA;AAClG,OAAO,OAAyB,MAAM,SAAS,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;GAYG;AAEH,MAAM,YAAY,GAAG,IAAI,CAAA;AAwBzB,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA0B;IAC9D,sFAAsF;IACtF,qFAAqF;IACrF,yBAAyB;IACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,8GAA8G,CAC/G,CAAA;IACH,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,YAAY,CAAA;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,SAAS,CAAA;IACnE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;IAEpD,wFAAwF;IACxF,sFAAsF;IACtF,oBAAoB;IACpB,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iGAAiG,CAAC,CAAA;IACpH,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,oBAAoB,IAAI,EAAE,CAAA;IAC/F,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,uBAAuB,CAAC,KAAe,CAAC,CAAA;IAEjF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;IACrB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACvB,8EAA8E;IAC9E,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAEhD,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,uFAAuF;IACvF,eAAe;IACf,GAAG,CAAC,GAAG,CACL,aAAa,CAAC;QACZ,QAAQ;QACR,SAAS,EAAE,MAAM;QACjB,OAAO,EAAE,MAAM;QACf,iBAAiB,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;QAC1C,YAAY,EAAE,gBAAgB;QAC9B,eAAe,EAAE,EAAE;KACpB,CAAC,CACH,CAAA;IAED,wFAAwF;IACxF,wFAAwF;IACxF,iEAAiE;IACjE,MAAM,YAAY,GAAG,iBAAiB,CAAC;QACrC,QAAQ,EAAE,QAAQ;QAClB,mBAAmB,EAAE,oCAAoC,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACnF,CAAC,CAAA;IAEF,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;IAErB,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,eAAe,EAAE,CAAA;QACrC,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC,EAAE,kBAAkB,EAAE,SAAS,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAA;QAEhH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,SAAS,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACjC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC7B,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC5B,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAA;YAC7C,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAA;YAC9F,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAgC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAClF,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;QAClE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,uFAAuF;IACvF,qFAAqF;IACrF,qFAAqF;IACrF,8CAA8C;IAC9C,IAAI,SAA6B,CAAA;IACjC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QACnE,SAAS,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,CAAA;IACrF,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,IAAI,EAAG,MAAM,CAAC,OAAO,EAAuB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAA;AACrH,CAAC"}
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"}