@arispay/payagent-mcp 2.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Polar Industries Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # @arispay/payagent-mcp
2
+
3
+ MCP server for [ArisPay](https://arispay.app)-delegated x402 USDC payments. Lets AI agents call paid APIs and settle HTTP 402 challenges with USDC on Base — no private keys ever live in this process.
4
+
5
+ Works with Claude Desktop, Cursor, Windsurf, or any MCP client. A thin wrapper around the [`payagent`](https://www.npmjs.com/package/payagent) SDK.
6
+
7
+ ## Setup
8
+
9
+ 1. Provision an agent at [payagent.arispay.app](https://payagent.arispay.app). You'll get:
10
+ - A CDP-managed wallet address to fund with USDC on Base
11
+ - An `ARISPAY_AGENT_KEY` (returned exactly once — store it securely)
12
+ 2. Fund the wallet with USDC on Base.
13
+ 3. Add the MCP server to your client config:
14
+
15
+ ### Claude Desktop
16
+
17
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "arispay": {
23
+ "command": "npx",
24
+ "args": ["-y", "@arispay/payagent-mcp"],
25
+ "env": {
26
+ "ARISPAY_AGENT_KEY": "ap_live_...",
27
+ "PAYAGENT_WALLET": "0x..."
28
+ }
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### Cursor
35
+
36
+ Edit `.cursor/mcp.json` in your project:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "arispay": {
42
+ "command": "npx",
43
+ "args": ["-y", "@arispay/payagent-mcp"],
44
+ "env": {
45
+ "ARISPAY_AGENT_KEY": "ap_live_...",
46
+ "PAYAGENT_WALLET": "0x..."
47
+ }
48
+ }
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### Windsurf
54
+
55
+ Edit `~/.codeium/windsurf/mcp_config.json` with the same pattern.
56
+
57
+ ## Environment Variables
58
+
59
+ | Variable | Required | Default | Description |
60
+ |----------|----------|---------|-------------|
61
+ | `ARISPAY_AGENT_KEY` | Yes | — | Agent-scoped API key from `payagent.arispay.app` |
62
+ | `ARISPAY_URL` | No | `https://api.arispay.app` | ArisPay API base URL |
63
+ | `PAYAGENT_WALLET` | No | — | Wallet address (for `check_wallet` tool output) |
64
+
65
+ ## Tools
66
+
67
+ ### `pay_api`
68
+
69
+ Make an HTTP request to a paid API. Automatically handles HTTP 402 payment challenges via ArisPay-delegated signing.
70
+
71
+ **Parameters:**
72
+ - `url` (string, required) — The API endpoint URL
73
+ - `method` (string, default: "GET") — HTTP method
74
+ - `headers` (object, optional) — Additional HTTP headers
75
+ - `body` (string, optional) — Request body
76
+
77
+ Spend caps (`maxPerTx`, `maxDaily`, `maxMonthly`, `allowedDomains`) are set on the agent at provisioning time and enforced server-side by ArisPay. There is no client-side budget parameter — attempts that exceed the delegation return a `PaymentRejectedError`.
78
+
79
+ **Example prompt:** "Use pay_api to fetch https://api.example.com/premium-data"
80
+
81
+ ### `check_wallet`
82
+
83
+ Report the configured agent, and — if `PAYAGENT_WALLET` is set — the on-chain USDC balance on Base.
84
+
85
+ **Parameters:** None
86
+
87
+ **Example prompt:** "Check my agent wallet"
88
+
89
+ Full delegation limits and spend history live at [payagent.arispay.app](https://payagent.arispay.app).
90
+
91
+ ## How It Works
92
+
93
+ 1. Agent calls `pay_api` with a URL.
94
+ 2. If the server returns HTTP 402, `payagent` asks ArisPay to sign via CDP.
95
+ 3. ArisPay validates the request against the agent's delegation limits and signs.
96
+ 4. `payagent` retries with the signed `X-PAYMENT` header; the seller's facilitator settles on-chain.
97
+
98
+ No private key lives in this process. The signing key is held by Coinbase CDP; ArisPay enforces limits before signing. If a payment breaches the delegation, it's rejected before any on-chain action.
99
+
100
+ ## Install
101
+
102
+ ```bash
103
+ npm install @arispay/payagent-mcp
104
+ ```
105
+
106
+ Or invoke directly via `npx @arispay/payagent-mcp` from an MCP client config — no pre-install required.
107
+
108
+ ## Related
109
+
110
+ - [payagent](https://www.npmjs.com/package/payagent) — the SDK for programmatic use
111
+ - [x402 protocol](https://github.com/coinbase/x402) — HTTP 402 payment standard
112
+
113
+ ## License
114
+
115
+ MIT
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { z } from "zod";
7
+ import { payFetchDelegated, getUSDCBalance, formatUSDC } from "payagent";
8
+ var arispayUrl = process.env.ARISPAY_URL ?? "https://api.arispay.app";
9
+ var agentKey = process.env.ARISPAY_AGENT_KEY;
10
+ var walletAddress = process.env.PAYAGENT_WALLET;
11
+ if (!agentKey) {
12
+ console.error(
13
+ "Error: ARISPAY_AGENT_KEY environment variable is required.\nProvision an agent at https://payagent.arispay.app to get a key."
14
+ );
15
+ process.exit(1);
16
+ }
17
+ var fetch402 = payFetchDelegated({
18
+ arispayUrl,
19
+ apiKey: agentKey
20
+ });
21
+ var server = new McpServer({
22
+ name: "payagent",
23
+ version: "2.0.0"
24
+ });
25
+ server.tool(
26
+ "pay_api",
27
+ {
28
+ url: z.string().describe("The full URL of the API endpoint to call"),
29
+ method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).default("GET").describe("HTTP method"),
30
+ headers: z.record(z.string(), z.string()).optional().describe("Additional HTTP headers to include"),
31
+ body: z.string().optional().describe("Request body (for POST/PUT/PATCH)")
32
+ },
33
+ async ({ url, method, headers, body }) => {
34
+ try {
35
+ const response = await fetch402(url, {
36
+ method,
37
+ headers,
38
+ body
39
+ });
40
+ const responseBody = await response.text();
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text",
45
+ text: [
46
+ `HTTP ${response.status}`,
47
+ "",
48
+ responseBody
49
+ ].join("\n")
50
+ }
51
+ ]
52
+ };
53
+ } catch (err) {
54
+ return {
55
+ content: [
56
+ {
57
+ type: "text",
58
+ text: `Error: ${err instanceof Error ? err.message : String(err)}`
59
+ }
60
+ ],
61
+ isError: true
62
+ };
63
+ }
64
+ }
65
+ );
66
+ server.tool(
67
+ "check_wallet",
68
+ {},
69
+ async () => {
70
+ const lines = [
71
+ `ArisPay URL: ${arispayUrl}`,
72
+ `Agent key: ${agentKey.slice(0, 10)}\u2026`
73
+ ];
74
+ if (walletAddress) {
75
+ lines.push(`Wallet: ${walletAddress}`);
76
+ try {
77
+ const raw = await getUSDCBalance(walletAddress, "base");
78
+ lines.push(`Balance: ${formatUSDC(raw)} USDC on Base`);
79
+ } catch (err) {
80
+ lines.push(`Balance: unavailable (${err instanceof Error ? err.message : String(err)})`);
81
+ }
82
+ } else {
83
+ lines.push("", "Set PAYAGENT_WALLET=0x\u2026 in env to include on-chain balance.");
84
+ }
85
+ lines.push("", "Delegation limits + full spend history: https://payagent.arispay.app");
86
+ return {
87
+ content: [{ type: "text", text: lines.join("\n") }]
88
+ };
89
+ }
90
+ );
91
+ async function main() {
92
+ const transport = new StdioServerTransport();
93
+ await server.connect(transport);
94
+ }
95
+ main().catch((err) => {
96
+ console.error("Fatal:", err);
97
+ process.exit(1);
98
+ });
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * payagent-mcp — MCP server that lets AI agents pay for APIs.\n *\n * Thin wrapper around `payagent`'s delegated signing path. No private keys\n * touch this process — ArisPay holds a Coinbase CDP-managed wallet and\n * enforces spend limits server-side.\n *\n * Configuration via environment variables:\n * - ARISPAY_URL: ArisPay API base URL (default: https://api.arispay.app)\n * - ARISPAY_AGENT_KEY: The agent-scoped API key returned by createX402Agent (required)\n * - PAYAGENT_WALLET: Optional wallet address for `check_wallet` tool output\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { payFetchDelegated, getUSDCBalance, formatUSDC } from 'payagent';\n\n// ── Config from env ─────────────────────────────────\n\nconst arispayUrl = process.env.ARISPAY_URL ?? 'https://api.arispay.app';\nconst agentKey = process.env.ARISPAY_AGENT_KEY;\nconst walletAddress = process.env.PAYAGENT_WALLET;\n\nif (!agentKey) {\n console.error(\n 'Error: ARISPAY_AGENT_KEY environment variable is required.\\n' +\n 'Provision an agent at https://payagent.arispay.app to get a key.',\n );\n process.exit(1);\n}\n\nconst fetch402 = payFetchDelegated({\n arispayUrl,\n apiKey: agentKey,\n});\n\n// ── MCP Server ──────────────────────────────────────\n\nconst server = new McpServer({\n name: 'payagent',\n version: '2.0.0',\n});\n\nserver.tool(\n 'pay_api',\n {\n url: z.string().describe('The full URL of the API endpoint to call'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])\n .default('GET')\n .describe('HTTP method'),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Additional HTTP headers to include'),\n body: z\n .string()\n .optional()\n .describe('Request body (for POST/PUT/PATCH)'),\n },\n async ({ url, method, headers, body }) => {\n try {\n const response = await fetch402(url, {\n method,\n headers,\n body,\n });\n const responseBody = await response.text();\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `HTTP ${response.status}`,\n '',\n responseBody,\n ].join('\\n'),\n },\n ],\n };\n } catch (err) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n isError: true,\n };\n }\n },\n);\n\nserver.tool(\n 'check_wallet',\n {},\n async () => {\n const lines = [\n `ArisPay URL: ${arispayUrl}`,\n `Agent key: ${agentKey.slice(0, 10)}…`,\n ];\n\n if (walletAddress) {\n lines.push(`Wallet: ${walletAddress}`);\n try {\n const raw = await getUSDCBalance(walletAddress, 'base');\n lines.push(`Balance: ${formatUSDC(raw)} USDC on Base`);\n } catch (err) {\n lines.push(`Balance: unavailable (${err instanceof Error ? err.message : String(err)})`);\n }\n } else {\n lines.push('', 'Set PAYAGENT_WALLET=0x… in env to include on-chain balance.');\n }\n\n lines.push('', 'Delegation limits + full spend history: https://payagent.arispay.app');\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n },\n);\n\n// ── Start ───────────────────────────────────────────\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error('Fatal:', err);\n process.exit(1);\n});\n"],"mappings":";;;AAYA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;AAClB,SAAS,mBAAmB,gBAAgB,kBAAkB;AAI9D,IAAM,aAAa,QAAQ,IAAI,eAAe;AAC9C,IAAM,WAAW,QAAQ,IAAI;AAC7B,IAAM,gBAAgB,QAAQ,IAAI;AAElC,IAAI,CAAC,UAAU;AACb,UAAQ;AAAA,IACN;AAAA,EAEF;AACA,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,WAAW,kBAAkB;AAAA,EACjC;AAAA,EACA,QAAQ;AACV,CAAC;AAID,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAED,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,KAAK,EAAE,OAAO,EAAE,SAAS,0CAA0C;AAAA,IACnE,QAAQ,EACL,KAAK,CAAC,OAAO,QAAQ,OAAO,UAAU,OAAO,CAAC,EAC9C,QAAQ,KAAK,EACb,SAAS,aAAa;AAAA,IACzB,SAAS,EACN,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAC7B,SAAS,EACT,SAAS,oCAAoC;AAAA,IAChD,MAAM,EACH,OAAO,EACP,SAAS,EACT,SAAS,mCAAmC;AAAA,EACjD;AAAA,EACA,OAAO,EAAE,KAAK,QAAQ,SAAS,KAAK,MAAM;AACxC,QAAI;AACF,YAAM,WAAW,MAAM,SAAS,KAAK;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,YAAM,eAAe,MAAM,SAAS,KAAK;AAEzC,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,cACJ,QAAQ,SAAS,MAAM;AAAA,cACvB;AAAA,cACA;AAAA,YACF,EAAE,KAAK,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAClE;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA,CAAC;AAAA,EACD,YAAY;AACV,UAAM,QAAQ;AAAA,MACZ,gBAAgB,UAAU;AAAA,MAC1B,gBAAgB,SAAS,MAAM,GAAG,EAAE,CAAC;AAAA,IACvC;AAEA,QAAI,eAAe;AACjB,YAAM,KAAK,gBAAgB,aAAa,EAAE;AAC1C,UAAI;AACF,cAAM,MAAM,MAAM,eAAe,eAAe,MAAM;AACtD,cAAM,KAAK,gBAAgB,WAAW,GAAG,CAAC,eAAe;AAAA,MAC3D,SAAS,KAAK;AACZ,cAAM,KAAK,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG;AAAA,MAC7F;AAAA,IACF,OAAO;AACL,YAAM,KAAK,IAAI,kEAA6D;AAAA,IAC9E;AAEA,UAAM,KAAK,IAAI,sEAAsE;AAErF,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;AAIA,eAAe,OAAO;AACpB,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,UAAU,GAAG;AAC3B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@arispay/payagent-mcp",
3
+ "version": "2.0.0",
4
+ "description": "MCP server for ArisPay-delegated x402 USDC payments. Use with Claude Desktop, Cursor, or any MCP client — no private keys in your process.",
5
+ "type": "module",
6
+ "bin": {
7
+ "payagent-mcp": "dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "arispay",
22
+ "mcp",
23
+ "mcp-server",
24
+ "model-context-protocol",
25
+ "ai-agent",
26
+ "http-402",
27
+ "x402",
28
+ "payment",
29
+ "usdc",
30
+ "stablecoin",
31
+ "claude",
32
+ "cursor",
33
+ "windsurf",
34
+ "agent-tool",
35
+ "delegated-custody"
36
+ ],
37
+ "engines": {
38
+ "node": ">=18"
39
+ },
40
+ "author": "Polar Industries Ltd",
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/stevemilton/payagent-mcp.git"
45
+ },
46
+ "homepage": "https://github.com/stevemilton/payagent-mcp#readme",
47
+ "dependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.12.1",
49
+ "payagent": "^2.0.0",
50
+ "zod": "^3.25.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^22.0.0",
54
+ "tsup": "^8.0.0",
55
+ "typescript": "^5.7.0"
56
+ }
57
+ }