agora-pay-mcp 0.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 (3) hide show
  1. package/README.md +49 -0
  2. package/index.js +106 -0
  3. package/package.json +28 -0
package/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # agora-pay-mcp
2
+
3
+ **Give any AI agent a wallet, a budget, and street-smarts on Arc — in one config line.**
4
+
5
+ An [MCP](https://modelcontextprotocol.io) server that lets **Claude, Cursor, Codex, or any custom agent**
6
+ autonomously discover and **pay per-call** for services in **USDC on Arc** (as little as `$0.000001`), with a
7
+ **hard budget cap** it can never exceed and an **on-chain trust check** before it spends. No account, no
8
+ subscription, no API keys.
9
+
10
+ ## Install (one line)
11
+
12
+ **Claude Desktop / Claude Code / Cursor** — add to your MCP config:
13
+
14
+ ```json
15
+ {
16
+ "mcpServers": {
17
+ "agora-pay": { "command": "npx", "args": ["-y", "agora-pay-mcp"] }
18
+ }
19
+ }
20
+ ```
21
+
22
+ That's it. Point it at your own Agora gateway with `"env": { "AGORA_URL": "https://your-gateway" }` — it
23
+ defaults to the hosted demo at `https://agora-j52a.onrender.com`.
24
+
25
+ ## The tools your agent gets
26
+
27
+ | Tool | What it does |
28
+ | --- | --- |
29
+ | `open_tab(capUsdc)` | Open a **budget-capped** wallet. The cap is a hard limit — the agent can never overspend. |
30
+ | `list_services()` | Discover services with **price + TRUST verdict** (TRUSTED / NEUTRAL / RISKY / AVOID). |
31
+ | `check_trust(target)` | On-chain trust profile of a service **before** paying it. |
32
+ | `call_service(service, input)` | Pay per-call over x402; charged only if the service delivers. Returns result + tx + remaining budget. |
33
+ | `get_bill()` | Budget, spent, remaining, and every call. |
34
+
35
+ ## Try it
36
+
37
+ > Ask your agent: *"You have a $0.05 budget on Agora. Get me the live price of Bitcoin — but check the
38
+ > service's trust first, and don't overspend."*
39
+
40
+ The agent opens a tab, lists services, checks the price oracle's trust (TRUSTED), pays `$0.0001`, returns the
41
+ real BTC price, and tells you it has `$0.0499` left — every payment settled in USDC on Arc.
42
+
43
+ ## Why it's different
44
+ - **Sub-cent, account-free payments** — below `$0.01`, cards/Stripe are structurally impossible (min fee ~$0.30). This isn't.
45
+ - **Trust with skin in the game** — verdicts come from an on-chain reputation + slashable-bond graph, not an opinion.
46
+ - **The agent decides** — cost vs. value, which providers to trust, when it's out of budget.
47
+
48
+ Part of [Agora](https://github.com/Ritik200238/agora) — the economy real AI agents plug into.
49
+ MIT.
package/index.js ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ // agora-pay MCP server — gives ANY AI agent (Claude, Cursor, Codex, custom) a budget-capped wallet and a
3
+ // trust-checked, pay-per-use marketplace on Arc, in one config line. The agent decides what's worth paying
4
+ // for; the tab enforces a hard budget it can never exceed; every call settles in USDC on Arc.
5
+ //
6
+ // Config (Claude Desktop / Cursor / Claude Code):
7
+ // { "mcpServers": { "agora-pay": { "command": "npx", "args": ["-y", "agora-pay-mcp"] } } }
8
+ // Point it at any Agora gateway with AGORA_URL (defaults to the hosted demo).
9
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import { z } from "zod";
12
+
13
+ const AGORA_URL = (process.env.AGORA_URL || "https://agora-j52a.onrender.com").replace(/\/$/, "");
14
+ let activeTab = null;
15
+
16
+ async function api(method, path, body) {
17
+ const r = await fetch(AGORA_URL + path, {
18
+ method,
19
+ headers: body ? { "content-type": "application/json" } : undefined,
20
+ body: body ? JSON.stringify(body) : undefined,
21
+ });
22
+ const txt = await r.text();
23
+ let data;
24
+ try {
25
+ data = JSON.parse(txt);
26
+ } catch {
27
+ data = txt;
28
+ }
29
+ return { status: r.status, data };
30
+ }
31
+ const out = (o) => ({ content: [{ type: "text", text: typeof o === "string" ? o : JSON.stringify(o, null, 2) }] });
32
+
33
+ const server = new McpServer({ name: "agora-pay", version: "0.1.0" });
34
+
35
+ server.tool(
36
+ "open_tab",
37
+ "Open a budget-capped wallet (a 'tab') on Agora so you can pay per-call for services on Arc in USDC. The cap is a HARD limit — you can never spend more than capUsdc total. Do this first, before calling services.",
38
+ { capUsdc: z.number().describe("total budget in USDC for this tab (0.001–5), e.g. 0.05") },
39
+ async ({ capUsdc }) => {
40
+ const { status, data } = await api("POST", "/x402/tab", { capUsdc });
41
+ if (status !== 200) return out({ error: data?.error || data });
42
+ activeTab = data.tabId;
43
+ return out({ tabId: data.tabId, budgetUsdc: data.capUsdc, note: "Hard spending cap. Every call settles in USDC on Arc." });
44
+ }
45
+ );
46
+
47
+ server.tool(
48
+ "list_services",
49
+ "Discover services you can pay for on Agora. Each has a price and a TRUST verdict (TRUSTED / NEUTRAL / RISKY / AVOID) from its on-chain track record. Before paying, weigh price vs. value for your task, and prefer TRUSTED services — avoid RISKY/AVOID unless the user insists.",
50
+ {},
51
+ async () => {
52
+ const { data } = await api("GET", "/x402/services");
53
+ const services = (data.services || []).map((s) => ({
54
+ id: s.id,
55
+ kind: s.kind,
56
+ priceUsdc: s.priceUsdc,
57
+ trust: s.verdict,
58
+ desc: s.desc || s.name,
59
+ example: s.example,
60
+ }));
61
+ return out({ services, settlement: data.settlement, tip: "Only pay when the result is worth the price for your task." });
62
+ }
63
+ );
64
+
65
+ server.tool(
66
+ "check_trust",
67
+ "Get the on-chain trust profile + verdict for a service BEFORE you pay it: price, success rate, and a TRUSTED/AVOID verdict. Use this when unsure about a service.",
68
+ { target: z.string().describe("a service id (e.g. svc_… or a built-in like 'price')") },
69
+ async ({ target }) => {
70
+ const { status, data } = await api("GET", "/x402/services/" + encodeURIComponent(target));
71
+ if (status !== 200) return out({ error: "no trust record for '" + target + "'" });
72
+ return out(data);
73
+ }
74
+ );
75
+
76
+ server.tool(
77
+ "call_service",
78
+ "Pay for and call a service. The price is deducted from your tab (never exceeding the cap), and you are only charged if the service actually delivers. Returns the result, what you paid, the on-chain tx, and your remaining budget.",
79
+ {
80
+ service: z.string().describe("the service id to call"),
81
+ input: z.record(z.string(), z.any()).optional().describe("the input object the service expects, e.g. { asset: 'bitcoin' }"),
82
+ tabId: z.string().optional().describe("tab to pay from; defaults to your open tab"),
83
+ },
84
+ async ({ service, input, tabId }) => {
85
+ const tab = tabId || activeTab;
86
+ if (!tab) return out({ error: "open a tab first with open_tab" });
87
+ const { status, data } = await api("POST", `/x402/tab/${tab}/call`, { service, input: input || {} });
88
+ if (status !== 200) return out({ error: data?.error || data, charged: data?.charged });
89
+ return out({ result: data.result, paidUsdc: data.paidUsdc, tx: data.tx, remainingBudgetUsdc: data.tab?.remainingUsdc });
90
+ }
91
+ );
92
+
93
+ server.tool(
94
+ "get_bill",
95
+ "See your tab's spending so far: budget, spent, remaining, and each call you made.",
96
+ { tabId: z.string().optional().describe("defaults to your open tab") },
97
+ async ({ tabId }) => {
98
+ const tab = tabId || activeTab;
99
+ if (!tab) return out({ error: "no open tab — call open_tab first" });
100
+ const { data } = await api("GET", "/x402/tab/" + tab);
101
+ return out(data);
102
+ }
103
+ );
104
+
105
+ await server.connect(new StdioServerTransport());
106
+ console.error(`agora-pay MCP server running · gateway ${AGORA_URL}`);
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "agora-pay-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Give any AI agent a budget-capped wallet + a trust-checked pay-per-use marketplace on Arc — one config line. USDC nanopayments over x402.",
5
+ "type": "module",
6
+ "bin": { "agora-pay-mcp": "index.js" },
7
+ "main": "index.js",
8
+ "files": ["index.js", "README.md"],
9
+ "engines": { "node": ">=18" },
10
+ "keywords": [
11
+ "mcp",
12
+ "model-context-protocol",
13
+ "ai-agents",
14
+ "x402",
15
+ "usdc",
16
+ "arc",
17
+ "circle",
18
+ "nanopayments",
19
+ "agent-payments",
20
+ "pay-per-use"
21
+ ],
22
+ "license": "MIT",
23
+ "repository": { "type": "git", "url": "https://github.com/Ritik200238/agora" },
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.29.0",
26
+ "zod": "^4.4.3"
27
+ }
28
+ }