agent402-mcp 0.8.1 → 0.10.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 (3) hide show
  1. package/README.md +11 -8
  2. package/index.js +55 -20
  3. package/package.json +12 -4
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # agent402-mcp
2
2
 
3
- MCP server for [Agent402](https://agent402.tools) — **1,199 pay-per-call web tools** and **39 curated multi-tool skill packs** for AI agents, paid per call in USDC via the [x402 protocol](https://www.x402.org), or **with compute (proof-of-work)** when no wallet is configured. Built by [Mikey Petrillo](https://github.com/MikeyPetrillo).
3
+ MCP server for [Agent402](https://agent402.tools) — **1,338 pay-per-call web tools** and **42 curated multi-tool skill packs** for AI agents, paid per call in USDC via the [x402 protocol](https://www.x402.org), or **with compute (proof-of-work)** when no wallet is configured. Built by [Mike Petrillo](https://github.com/MikeyPetrillo).
4
4
 
5
- Your agent gets browser rendering, screenshots, PDF text extraction, URL→markdown, live web search **+ web answers with citations**, live **financial/crypto/macro data** (Yahoo stock quotes, CoinGecko, FRED, ECB FX, World Bank, yield curve), **SEC EDGAR filings** (10-K/10-Q text, XBRL, insider, 13F, IPO calendar), **deterministic stats & forecasting** (Pearson correlation, OLS, Holt-Winters), **compression** (gzip/brotli), DNS/TLS/WHOIS + email-deliverability checks, wallet-keyed shared memory, and ~1,000 utility/conversion tools — plus 39 **skill packs** like `security-audit`, `trend-analysis`, `structured-scrape`, `decode-blob`, and `forecasting-bake-off` callable as MCP prompts. Payment handled invisibly underneath the MCP calls. No signup, no API key.
5
+ Your agent gets browser rendering, screenshots, PDF text extraction, URL→markdown, live web search **+ web answers with citations**, live **financial/crypto/macro data** (Yahoo stock quotes, CoinGecko, FRED, ECB FX, World Bank, yield curve), **SEC EDGAR filings** (10-K/10-Q text, XBRL, insider, 13F, IPO calendar), **deterministic stats & forecasting** (Pearson correlation, OLS, Holt-Winters), **compression** (gzip/brotli), DNS/TLS/WHOIS + email-deliverability checks, wallet-keyed shared memory, and ~1,000 utility/conversion tools — plus 42 **skill packs** like `security-audit`, `trend-analysis`, `structured-scrape`, `decode-blob`, and `forecasting-bake-off` callable as MCP prompts. Payment handled invisibly underneath the MCP calls. No signup, no API key.
6
6
 
7
7
  ## Quick start
8
8
 
@@ -11,7 +11,7 @@ MCP server — e.g. claude.ai → Settings → Connectors → Add custom connect
11
11
  pure-CPU tools run free there (rate-limited); for the full catalog and no rate
12
12
  limit, run this package locally with a wallet:
13
13
 
14
- With a funded wallet (USDC on Base) — every tool available:
14
+ With a funded wallet (USDC on Base, Solana, Polygon, or Arbitrum) — every tool available:
15
15
 
16
16
  ```json
17
17
  {
@@ -42,9 +42,9 @@ Claude Code: `claude mcp add agent402 -- npx -y agent402-mcp`
42
42
  - On startup the server reads the live catalog from `https://agent402.tools/api/pricing` + `/openapi.json`.
43
43
  - The high-value tools (`extract`, `render`, `screenshot`, `pdf`, `meta`, `dns`, `http-check`, `tls-cert`, `whois`, the `memory-*` coordination tools, `hash`) are exposed as first-class MCP tools.
44
44
  - The other ~1,185 tools are reachable via `search_tools` (find by description) + `call_tool` (call by slug) — keeping your context window small.
45
- - When a call hits HTTP 402: with `AGENT_KEY` set, the server signs an x402 USDC payment and retries; without a key it solves the tool's proof-of-work challenge (~0.2 s of CPU) on the eligible tools.
45
+ - When a call hits HTTP 402: with a wallet key set (`AGENT_KEY` for Base/Polygon/Arbitrum, `SOLANA_AGENT_KEY` for Solana), the server signs an x402 USDC payment on a chain the seller accepts and retries; without a key it solves the tool's proof-of-work challenge (~0.2 s of CPU) on the eligible tools.
46
46
  - `payment_info` tells the model which mode it's in and what a wallet would unlock.
47
- - `top_x402_sellers` returns the live x402 leaderboard — which sellers are settling the most USDC on Base in the last ~24h, derived from on-chain transfers. Free to call (no payment, no proof-of-work). Useful for agents discovering the wider x402 economy beyond this single service's catalog.
47
+ - `top_x402_sellers` returns the live x402 leaderboard — which sellers are settling the most USDC (primarily on Base) in the last ~24h, derived from on-chain transfers. Free to call (no payment, no proof-of-work). Useful for agents discovering the wider x402 economy beyond this single service's catalog.
48
48
 
49
49
  ## Workflows (skill packs)
50
50
 
@@ -64,7 +64,8 @@ automatically:
64
64
 
65
65
  | env | default | meaning |
66
66
  | --- | --- | --- |
67
- | `AGENT_KEY` | _(unset)_ | Hex private key of a wallet funded with USDC on Base. Unset = proof-of-work mode. |
67
+ | `AGENT_KEY` | _(unset)_ | Hex private key of an EVM wallet funded with USDC on Base (or Polygon/Arbitrum). |
68
+ | `SOLANA_AGENT_KEY` | _(unset)_ | Base58 secret key (or JSON byte array) of a Solana wallet funded with USDC on Solana. |
68
69
  | `AGENT402_URL` | `https://agent402.tools` | Target service (point at your own deployment). |
69
70
  | `AGENT402_TOOLS` | curated set | Comma-separated slugs to expose as first-class tools. |
70
71
  | `AGENT402_MAX_PER_CALL` | unlimited | Refuse any single call priced above this many USD (e.g. `0.01`). |
@@ -72,8 +73,10 @@ automatically:
72
73
 
73
74
  Spend controls are enforced **before a payment is signed** — a runaway model is
74
75
  refused, not billed. `payment_info` reports the caps, what's been spent, and
75
- what remains. Use a dedicated low-value wallet for `AGENT_KEY`, funded only
76
- with what you intend to spend calls cost $0.001–$0.02 each.
76
+ what remains. With neither key set, the server runs in proof-of-work mode
77
+ (pure-CPU tools stay free). Use dedicated low-value wallets for `AGENT_KEY` /
78
+ `SOLANA_AGENT_KEY`, funded only with what you intend to spend — calls cost
79
+ $0.001–$0.02 each.
77
80
 
78
81
  ## Test
79
82
 
package/index.js CHANGED
@@ -3,8 +3,9 @@
3
3
  // web tools) to any MCP client (Claude, ChatGPT, custom agents) and settles
4
4
  // payment underneath, so the model never sees the 402 dance:
5
5
  //
6
- // • AGENT_KEY=0x… pay per call in USDC via x402 (any tool)
7
- // • no key pay with compute (proof-of-work) on the eligible tools
6
+ // • AGENT_KEY=0x… pay in USDC via x402 on the EVM chains (Base/Polygon/Arbitrum)
7
+ // • SOLANA_AGENT_KEY=base58 pay in USDC via x402 on Solana
8
+ // • no key pay with compute (proof-of-work) on the eligible tools
8
9
  //
9
10
  // The full catalog is too large to register as individual MCP tools, so the
10
11
  // high-value tools are first-class and everything else is reachable through
@@ -12,7 +13,8 @@
12
13
  //
13
14
  // Config (env):
14
15
  // AGENT402_URL target service (default https://agent402.tools)
15
- // AGENT_KEY hex private key of a funded wallet (USDC on Base) — optional
16
+ // AGENT_KEY hex private key of a funded EVM wallet (USDC on Base/Polygon/Arbitrum) — optional
17
+ // SOLANA_AGENT_KEY base58 (or JSON byte-array) secret key of a funded Solana wallet (USDC on Solana) — optional
16
18
  // AGENT402_TOOLS comma-separated slugs to expose first-class (overrides default)
17
19
  // AGENT402_MAX_PER_CALL refuse any single call priced above this many USD (e.g. 0.01)
18
20
  // AGENT402_BUDGET hard cap on total USDC spent this session (e.g. 1.00)
@@ -28,7 +30,12 @@ import {
28
30
 
29
31
  const BASE = (process.env.AGENT402_URL || "https://agent402.tools").replace(/\/$/, "");
30
32
  const AGENT_KEY = process.env.AGENT_KEY || "";
31
- const VERSION = "0.8.0";
33
+ // Solana secret key: base58 string (Phantom/solana-keygen export) or a JSON
34
+ // byte array. Either key alone enables paid calls; with both, the buyer can
35
+ // settle on whichever chain the seller offers (EVM accepts are tried first).
36
+ const SOLANA_AGENT_KEY = process.env.SOLANA_AGENT_KEY || "";
37
+ const HAS_WALLET = Boolean(AGENT_KEY || SOLANA_AGENT_KEY);
38
+ const VERSION = "0.10.0";
32
39
 
33
40
  // Spend controls — enforced BEFORE a payment is ever signed, so a confused or
34
41
  // runaway model cannot drain the wallet. Unset = unlimited (back-compat).
@@ -105,16 +112,37 @@ let payFetchPromise;
105
112
  function getPayFetch() {
106
113
  payFetchPromise ??= (async () => {
107
114
  const { x402Client } = await import("@x402/core/client");
108
- const { registerExactEvmScheme } = await import("@x402/evm/exact/client");
109
115
  const { wrapFetchWithPayment } = await import("@x402/fetch");
110
- const { privateKeyToAccount } = await import("viem/accounts");
111
116
  const client = new x402Client();
112
- registerExactEvmScheme(client, { signer: privateKeyToAccount(AGENT_KEY) });
117
+ if (AGENT_KEY) {
118
+ const { registerExactEvmScheme } = await import("@x402/evm/exact/client");
119
+ const { privateKeyToAccount } = await import("viem/accounts");
120
+ registerExactEvmScheme(client, { signer: privateKeyToAccount(AGENT_KEY) });
121
+ }
122
+ if (SOLANA_AGENT_KEY) {
123
+ const { registerExactSvmScheme } = await import("@x402/svm/exact/client");
124
+ registerExactSvmScheme(client, { signer: await solanaSigner() });
125
+ }
113
126
  return wrapFetchWithPayment(fetch, client);
114
127
  })();
115
128
  return payFetchPromise;
116
129
  }
117
130
 
131
+ // @solana/kit KeyPairSigner from SOLANA_AGENT_KEY — base58 64-byte secret key
132
+ // (Phantom / solana-keygen export) or a JSON byte array ([12,34,…]).
133
+ let solanaSignerPromise;
134
+ function solanaSigner() {
135
+ solanaSignerPromise ??= (async () => {
136
+ const { createKeyPairSignerFromBytes, getBase58Encoder } = await import("@solana/kit");
137
+ const raw = SOLANA_AGENT_KEY.trim();
138
+ const bytes = raw.startsWith("[")
139
+ ? Uint8Array.from(JSON.parse(raw))
140
+ : new Uint8Array(getBase58Encoder().encode(raw));
141
+ return createKeyPairSignerFromBytes(bytes);
142
+ })();
143
+ return solanaSignerPromise;
144
+ }
145
+
118
146
  function solvePow(challenge) {
119
147
  const leadingZeroBits = (buf) => {
120
148
  let total = 0;
@@ -133,8 +161,9 @@ function solvePow(challenge) {
133
161
  function walletRequiredText(tool) {
134
162
  return [
135
163
  `"${tool.slug}" costs ${tool.price}/call and requires a USDC wallet (it is not eligible for the proof-of-work tier).`,
136
- `To enable it: set the AGENT_KEY environment variable on this MCP server to the hex private key of a wallet`,
137
- `funded with USDC on Base. Payment is per call via the x402 protocol no signup or API key.`,
164
+ `To enable it: set AGENT_KEY on this MCP server to the hex private key of an EVM wallet funded with USDC`,
165
+ `on Base (or Polygon/Arbitrum), and/or SOLANA_AGENT_KEY to the base58 secret key of a Solana wallet funded`,
166
+ `with USDC on Solana. Payment is per call via the x402 protocol — no signup or API key.`,
138
167
  `Pricing and details: ${BASE}/tools/${tool.slug}`,
139
168
  ].join(" ");
140
169
  }
@@ -153,7 +182,7 @@ async function callEndpoint(tool, args = {}) {
153
182
  }
154
183
 
155
184
  let res;
156
- if (AGENT_KEY) {
185
+ if (HAS_WALLET) {
157
186
  const price = parseFloat(String(tool.price).replace(/[^0-9.]/g, "")) || 0;
158
187
  if (price > MAX_PER_CALL) {
159
188
  return {
@@ -171,7 +200,7 @@ async function callEndpoint(tool, args = {}) {
171
200
  res = await payFetch(url, init);
172
201
  // Count spend when the server confirms settlement (payment receipt header),
173
202
  // falling back to any 2xx — conservative in the buyer's favor.
174
- if (res.headers.get("x-payment-response") || res.ok) spentUsd += price;
203
+ if (res.headers.get("payment-response") || res.headers.get("x-payment-response") || res.ok) spentUsd += price;
175
204
  } else if (tool.computePayable) {
176
205
  // No wallet: pay with compute up front — solving before the call skips the
177
206
  // 402 round-trip entirely (challenges are single-use and tool-scoped).
@@ -379,20 +408,26 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
379
408
  const { privateKeyToAccount } = await import("viem/accounts");
380
409
  address = privateKeyToAccount(AGENT_KEY).address;
381
410
  }
411
+ let solanaAddress = null;
412
+ if (SOLANA_AGENT_KEY) {
413
+ try { solanaAddress = (await solanaSigner()).address; } catch { solanaAddress = "invalid SOLANA_AGENT_KEY"; }
414
+ }
382
415
  const computePayable = [...catalog.values()].filter((t) => t.computePayable).length;
383
416
  return {
384
417
  content: [{
385
418
  type: "text",
386
419
  text: JSON.stringify({
387
420
  service: BASE,
388
- mode: AGENT_KEY ? "usdc" : "proof-of-work",
421
+ mode: HAS_WALLET ? "usdc" : "proof-of-work",
389
422
  wallet: address,
423
+ solanaWallet: solanaAddress,
390
424
  network: pricingInfo?.payment?.network ?? "base",
425
+ networks: pricingInfo?.payment?.networks ?? undefined,
391
426
  tools: catalog.size,
392
427
  payableWithCompute: computePayable,
393
428
  walletOnly: catalog.size - computePayable,
394
429
  workflows: skillPacks.length,
395
- spendControls: AGENT_KEY
430
+ spendControls: HAS_WALLET
396
431
  ? {
397
432
  maxPerCallUsd: MAX_PER_CALL === Infinity ? "unlimited" : MAX_PER_CALL,
398
433
  sessionBudgetUsd: BUDGET === Infinity ? "unlimited" : BUDGET,
@@ -400,10 +435,10 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
400
435
  remainingUsd: BUDGET === Infinity ? "unlimited" : Number(Math.max(0, BUDGET - spentUsd).toFixed(6)),
401
436
  }
402
437
  : "n/a (proof-of-work mode spends CPU, not money)",
403
- note: AGENT_KEY
404
- ? "Every tool is available; each call is paid in USDC via x402 from the configured wallet, within the spend controls above."
405
- : `No AGENT_KEY configured: ${computePayable} pure-CPU tools are free via proof-of-work; the ${catalog.size - computePayable} network/browser/memory tools need a funded wallet (set AGENT_KEY).`,
406
- ecosystem: "Call top_x402_sellers to see which x402 sellers (any wallet, not just this host) are settling the most USDC on Base in the last 24h — discovers the live economy beyond this catalog.",
438
+ note: HAS_WALLET
439
+ ? "Every tool is available; each call is paid in USDC via x402 from the configured wallet(s) — EVM chains via AGENT_KEY, Solana via SOLANA_AGENT_KEY — within the spend controls above."
440
+ : `No wallet configured: ${computePayable} pure-CPU tools are free via proof-of-work; the ${catalog.size - computePayable} network/browser/memory tools need a funded wallet (set AGENT_KEY for Base/Polygon/Arbitrum and/or SOLANA_AGENT_KEY for Solana).`,
441
+ ecosystem: "Call top_x402_sellers to see which x402 sellers (any wallet, not just this host) are settling the most USDC (primarily on Base) in the last 24h — discovers the live economy beyond this catalog.",
407
442
  }, null, 2),
408
443
  }],
409
444
  };
@@ -479,9 +514,9 @@ const requested = (process.env.AGENT402_TOOLS || DEFAULT_CURATED.join(","))
479
514
  curated = requested.map((slug) => catalog.get(slug)).filter(Boolean);
480
515
  log(`catalog: ${catalog.size} tools from ${BASE}; ${curated.length} first-class, rest via search_tools/call_tool`);
481
516
  log(
482
- AGENT_KEY
483
- ? `payment: USDC via x402 (wallet configured; max/call ${MAX_PER_CALL === Infinity ? "unlimited" : `$${MAX_PER_CALL}`}, budget ${BUDGET === Infinity ? "unlimited" : `$${BUDGET}`})`
484
- : "payment: proof-of-work on eligible tools (no AGENT_KEY)"
517
+ HAS_WALLET
518
+ ? `payment: USDC via x402 (${[AGENT_KEY && "EVM", SOLANA_AGENT_KEY && "Solana"].filter(Boolean).join(" + ")} wallet configured; max/call ${MAX_PER_CALL === Infinity ? "unlimited" : `$${MAX_PER_CALL}`}, budget ${BUDGET === Infinity ? "unlimited" : `$${BUDGET}`})`
519
+ : "payment: proof-of-work on eligible tools (no AGENT_KEY / SOLANA_AGENT_KEY)"
485
520
  );
486
521
 
487
522
  await server.connect(new StdioServerTransport());
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "agent402-mcp",
3
- "version": "0.8.1",
3
+ "version": "0.10.0",
4
4
  "mcpName": "io.github.MikeyPetrillo/agent402",
5
- "author": "Mikey Petrillo <mike@agent402.tools> (https://github.com/MikeyPetrillo)",
5
+ "author": "Mike Petrillo <mike@agent402.tools> (https://github.com/MikeyPetrillo)",
6
6
  "homepage": "https://agent402.tools",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/MikeyPetrillo/Agent402.git"
10
10
  },
11
- "description": "Open-source MCP server exposing Agent402's 1,199 self-hostable tools + 39 multi-tool skill packs (security-audit, trend-analysis, structured-scrape, decode-blob, forecasting-bake-off) for AI agents browser, web search & answers, PDFs, OCR, images, live financial/crypto/macro data, SEC EDGAR filings, deterministic stats & forecasting, compression, payments. Free via proof-of-work, or pay per call in USDC via the x402 protocol.",
11
+ "description": "Open-source MCP server exposing Agent402.Tools' 1,338 self-hostable tools + 42 multi-tool skill packs (security-audit, trend-analysis, structured-scrape, decode-blob, forecasting-bake-off) for AI agents \u2014 browser, web search & answers, PDFs, OCR, images, LLM inference, image generation, code execution, TTS, STT, embeddings, live financial/crypto/macro data, SEC EDGAR filings, deterministic stats & forecasting, compression, payments. Free via proof-of-work, or pay per call in USDC via the x402 protocol.",
12
12
  "type": "module",
13
13
  "bin": {
14
14
  "agent402-mcp": "index.js"
@@ -30,24 +30,32 @@
30
30
  "llm-tools",
31
31
  "ai-tools",
32
32
  "claude",
33
+ "openai",
33
34
  "self-hosted",
34
35
  "agents",
35
36
  "ai",
36
37
  "payments",
37
38
  "usdc",
39
+ "base",
40
+ "solana",
38
41
  "http-402",
39
42
  "tools",
40
43
  "skill-packs",
41
44
  "mcp-prompts",
42
45
  "workflows",
43
- "proof-of-work"
46
+ "proof-of-work",
47
+ "agent402",
48
+ "micropayments",
49
+ "tool-discovery"
44
50
  ],
45
51
  "license": "MIT",
46
52
  "dependencies": {
47
53
  "@modelcontextprotocol/sdk": "^1.12.0",
54
+ "@solana/kit": "^5.1.0",
48
55
  "@x402/core": "2.14.0",
49
56
  "@x402/evm": "2.14.0",
50
57
  "@x402/fetch": "2.14.0",
58
+ "@x402/svm": "2.14.0",
51
59
  "viem": "^2.21.0"
52
60
  }
53
61
  }