@forgemeshlabs/x402-ads-mcp 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @forgemeshlabs/x402-ads-mcp
2
2
 
3
- **Machine-commerce intent analytics for your agent.** What autonomous agents probe, want, and abandon across the x402 ecosystem — as MCP tools.
3
+ **Install one middleware. Monetize unused 402 responses with recommendations, discovery, and machine commerce analytics.**
4
+
5
+ This is the MCP side of that network: what autonomous agents probe, want, and abandon across the x402 ecosystem — as tools for your agent.
4
6
 
5
7
  Wraps the [ForgeMesh x402 Ads & Intent Network](https://ads.forgemesh.io). Paid tools settle per call in USDC on Base mainnet over the [x402 protocol](https://x402.org) — no account, no API key; your wallet is the login. Publishers get reports on their own services **free**.
6
8
 
@@ -23,6 +25,18 @@ Wraps the [ForgeMesh x402 Ads & Intent Network](https://ads.forgemesh.io). Paid
23
25
 
24
26
  Both env vars are optional. With neither set, free tools work fully and paid tools return the x402 payment challenge (price, network, payTo) instead of settling — useful for inspection before spending anything.
25
27
 
28
+ ## Bonus: one-command publisher registration
29
+
30
+ This package doubles as the signup CLI for API operators (no MCP client needed):
31
+
32
+ ```bash
33
+ # read the terms first: https://ads.forgemesh.io/terms
34
+ WALLET_PRIVATE_KEY=0xYOUR_WALLET npx -y @forgemeshlabs/x402-ads-mcp register \
35
+ --url https://api.your-service.com --accept-terms
36
+ ```
37
+
38
+ One $0.10 USDC payment on Base; the paying wallet becomes your identity and your publisher key is printed once. Invalid requests are rejected **before** payment — you can't pay for a doomed registration.
39
+
26
40
  ## Tools
27
41
 
28
42
  | Tool | Price | What it returns |
@@ -48,6 +62,19 @@ Both env vars are optional. With neither set, free tools work fully and paid too
48
62
 
49
63
  Use a dedicated hot wallet holding only small working balances. The key never leaves your machine — payments are signed locally (EIP-3009) and settle on-chain.
50
64
 
65
+ Ready-made configs live in [`examples/`](./examples): a Claude Desktop `mcpServers` block and a commented env-var template.
66
+
67
+ ## Testing (safe by construction)
68
+
69
+ ```bash
70
+ npm test # smoke: MCP boots over stdio and lists its 7 tools
71
+ npm run test:free # free tools against the live network
72
+ npm run test:challenge # every paid tool returns an x402 challenge — no wallet, nothing can spend
73
+ npm run test:all # all of the above
74
+ ```
75
+
76
+ No test settles a payment. The challenge test deletes the payment env vars before loading, so it cannot move funds even if your shell has a wallet configured.
77
+
51
78
  ## The network in one sentence
52
79
 
53
80
  **We measure machine commerce, not API content** — publishers running the [`@forgemeshlabs/x402-ads`](https://www.npmjs.com/package/@forgemeshlabs/x402-ads) middleware contribute anonymized 402 probe metadata; this MCP sells the aggregate demand signal back to agents and builders.
package/glama.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://glama.ai/mcp/schemas/server.json",
3
3
  "name": "x402-ads-mcp",
4
4
  "version": "0.1.0",
5
- "description": "Machine-commerce intent analytics over x402: agent demand trends, category depth, and why-agents-didn't-buy funnels for the x402 ecosystem. Free network counters and recommendation previews; paid analytics settle in USDC on Base.",
5
+ "description": "Install one middleware. Monetize unused 402 responses with recommendations, discovery, and machine commerce analytics. MCP server for the ForgeMesh x402 Ads network.",
6
6
  "homepage": "https://ads.forgemesh.io",
7
7
  "repository": "https://github.com/forgemeshlabs/x402-ads-mcp",
8
8
  "maintainers": [
package/index.js CHANGED
@@ -266,8 +266,64 @@ async function main() {
266
266
  process.stdin.on("end", () => clearInterval(keepAlive));
267
267
  }
268
268
 
269
+ // `npx -y @forgemeshlabs/x402-ads-mcp register` — one-command publisher signup.
270
+ async function registerCli(argv) {
271
+ const args = { categories: [] };
272
+ for (let i = 0; i < argv.length; i++) {
273
+ if (argv[i] === "--url") args.service_url = argv[++i];
274
+ else if (argv[i] === "--name") args.name = argv[++i];
275
+ else if (argv[i] === "--category") args.categories.push(argv[++i]);
276
+ else if (argv[i] === "--contact") args.contact = argv[++i];
277
+ else if (argv[i] === "--accept-terms") args.terms_accepted = true;
278
+ }
279
+ if (!args.service_url || !args.terms_accepted) {
280
+ console.error("Usage: WALLET_PRIVATE_KEY=0x... x402-ads-mcp register --url https://api.your-service.com --accept-terms");
281
+ console.error(" [--name \"My API\"] [--category weather] [--contact you@example.com]");
282
+ console.error("");
283
+ console.error("Registers you as a publisher for one $0.10 USDC x402 payment on Base.");
284
+ console.error("The paying wallet becomes your identity; your key is printed once.");
285
+ console.error("--accept-terms is required — read them first: " + BASE_URL + "/terms");
286
+ process.exit(1);
287
+ }
288
+ const httpClient = walletClient();
289
+ if (!httpClient) {
290
+ console.error("WALLET_PRIVATE_KEY is required: a Base mainnet wallet holding at least $0.10 USDC.");
291
+ process.exit(1);
292
+ }
293
+ if (!args.name) delete args.name;
294
+ if (!args.contact) delete args.contact;
295
+ if (!args.categories.length) delete args.categories;
296
+
297
+ const url = BASE_URL + "/v1/publishers/register";
298
+ const init = { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(args) };
299
+ const res = await fetch(url, init);
300
+ if (res.status === 400) {
301
+ const body = await res.json().catch(() => ({}));
302
+ console.error("Rejected before payment (nothing was charged): " + (body.error || res.statusText));
303
+ process.exit(1);
304
+ }
305
+ if (res.status !== 402) throw new Error(`expected x402 challenge, got ${res.status}`);
306
+ let challengeBody;
307
+ try {
308
+ challengeBody = await res.clone().json();
309
+ } catch (_) {}
310
+ const paymentRequired = httpClient.getPaymentRequiredResponse((n) => res.headers.get(n), challengeBody);
311
+ const paymentPayload = await createChainTimedPaymentPayload(httpClient, paymentRequired);
312
+ const paidRes = await fetch(url, { ...init, headers: { ...init.headers, ...httpClient.encodePaymentSignatureHeader(paymentPayload) } });
313
+ const out = await paidRes.json().catch(() => ({}));
314
+ if (!paidRes.ok) throw new Error(`registration failed (${paidRes.status}): ${JSON.stringify(out).slice(0, 240)}`);
315
+ console.log("Registered: " + out.publisher_id);
316
+ console.log("");
317
+ console.log("Your publisher key (shown once — store it now):");
318
+ console.log(" " + out.publisher_key);
319
+ console.log("");
320
+ console.log("Next: set it as X402_ADS_PUBLISHER_KEY in your server env and mount the");
321
+ console.log("@forgemeshlabs/x402-ads middleware. Your own traffic reports are free.");
322
+ }
323
+
269
324
  if (require.main === module) {
270
- main().catch((error) => {
325
+ const run = process.argv[2] === "register" ? registerCli(process.argv.slice(3)) : main();
326
+ run.catch((error) => {
271
327
  console.error(error instanceof Error ? error.message : String(error));
272
328
  process.exit(1);
273
329
  });
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@forgemeshlabs/x402-ads-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "mcpName": "io.github.forgemeshlabs/x402-ads-mcp",
5
- "description": "Machine-commerce intent analytics over x402: what autonomous agents probe, want, and abandon across the x402 ecosystem trends, category demand, and why-agents-didn't-buy funnels, paid per call in USDC on Base. Free for publishers on their own traffic.",
5
+ "description": "Install one middleware. Monetize unused 402 responses with recommendations, discovery, and machine commerce analytics. MCP server: 7 tools for agent demand analytics, paid per call in USDC on Base; free for publishers on their own traffic.",
6
6
  "main": "index.js",
7
7
  "bin": {
8
8
  "x402-ads-mcp": "index.js"
@@ -18,7 +18,10 @@
18
18
  "scripts": {
19
19
  "start": "node index.js",
20
20
  "check": "node --check index.js",
21
- "test": "npm run check && node scripts/test-mcp.js"
21
+ "test": "node tests/smoke.test.js",
22
+ "test:free": "node tests/free-tools.test.js",
23
+ "test:challenge": "node tests/paid-challenge.test.js",
24
+ "test:all": "npm run check && npm test && npm run test:free && npm run test:challenge"
22
25
  },
23
26
  "engines": {
24
27
  "node": ">=18"
package/server.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "x402-ads-mcp",
3
3
  "version": "0.1.0",
4
- "description": "Machine-commerce intent analytics over x402: agent demand trends, category depth, and why-agents-didn't-buy funnels for the x402 ecosystem. Free network counters and recommendation previews; paid analytics settle in USDC on Base.",
4
+ "description": "Install one middleware. Monetize unused 402 responses with recommendations, discovery, and machine commerce analytics. MCP server for the ForgeMesh x402 Ads network.",
5
5
  "homepage": "https://ads.forgemesh.io",
6
6
  "repository": "https://github.com/forgemeshlabs/x402-ads-mcp",
7
7
  "transport": {