@aifinpay/mcp 0.1.0-alpha.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 ADDED
@@ -0,0 +1,96 @@
1
+ # @aifinpay/mcp
2
+
3
+ MCP server exposing AiFinPay's autonomous x402 payment loop as
4
+ agent-callable tools. Drop it into Claude Desktop, MCP Inspector, or any
5
+ MCP-aware agent runtime — your agent can now buy services autonomously.
6
+
7
+ ## Tools
8
+
9
+ | Tool | What it does |
10
+ |---|---|
11
+ | `payable_fetch(url, opts?)` | Fetch any URL. On 402, auto-detect facilitator, sign, retry. |
12
+ | `agent_address()` | Return the agent's Solana base58 pubkey (so you know where to fund). |
13
+ | `agent_quote(url)` | Inspect a 402 challenge without paying. Shows the merchant's quoted amount + facilitator flavor. |
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ # Globally — usable as `npx @aifinpay/mcp` from any client config
19
+ npm install -g @aifinpay/mcp
20
+ ```
21
+
22
+ ## Use with Claude Desktop
23
+
24
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "aifinpay": {
30
+ "command": "npx",
31
+ "args": ["@aifinpay/mcp"],
32
+ "env": {
33
+ "AIFINPAY_AGENT_SECRET": "<base58 secret — see below>",
34
+ "AIFINPAY_MAX_USD": "0.50"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ Restart Claude Desktop. Now Claude can call `payable_fetch`, `agent_address`,
42
+ and `agent_quote` like any other tool.
43
+
44
+ ## First run — generating an agent
45
+
46
+ If `AIFINPAY_AGENT_SECRET` is not set, the server generates an ephemeral
47
+ keypair and **prints it to stderr** at startup:
48
+
49
+ ```
50
+ [warn] no AIFINPAY_AGENT_SECRET set — generated EPHEMERAL agent.
51
+ address: 9HucVaL5yinJ4MfBKCFnz5QJBGwK33bfSQKw15pSe3Ch
52
+ secret: 2vfeWAYfkpTNGSgDpBonzmjkckrTKa5GTnhhztY141YcSKYrqCvtojVukQAQiJbbRLgdcfEdyqHbRMsUft6Pb7nD
53
+ >> Save this secret to AIFINPAY_AGENT_SECRET to keep the agent across restarts.
54
+ ```
55
+
56
+ Save the secret to `AIFINPAY_AGENT_SECRET` in your client config so the
57
+ agent identity (and any funded Seat) persists across restarts.
58
+
59
+ ## Environment variables
60
+
61
+ | Var | Default | Purpose |
62
+ |---|---|---|
63
+ | `AIFINPAY_AGENT_SECRET` | — | Base58 secret. If absent → ephemeral agent printed to stderr. |
64
+ | `AIFINPAY_BASE_URL` | `https://aifinpay.company` | Backend URL for nonce + funding probes. |
65
+ | `AIFINPAY_TIMEOUT_MS` | `30000` | Request timeout. |
66
+ | `AIFINPAY_MAX_USD` | — | Hard cap per single payment. Strongly recommended. |
67
+
68
+ ## Programmatic use
69
+
70
+ ```ts
71
+ import { createServer, loadConfigFromEnv } from "@aifinpay/mcp";
72
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
73
+
74
+ const { server } = createServer({
75
+ ...loadConfigFromEnv(),
76
+ agentSecretB58: "your-secret-here",
77
+ maxAmountUsd: 0.10,
78
+ });
79
+ await server.connect(new StdioServerTransport());
80
+ ```
81
+
82
+ ## How `payable_fetch` works
83
+
84
+ 1. Sends the request unauthenticated.
85
+ 2. On `402`, the underlying [`@aifinpay/agent`](../node) SDK detects the
86
+ facilitator flavor (AiFinPay native, Coinbase x402, …).
87
+ 3. Signs a payment payload and retries.
88
+ 4. Returns `{ status, ok, headers, body }` to the agent.
89
+
90
+ The flow is identical to calling `agent.pay(url)` directly — this
91
+ package just wraps it as an MCP tool surface so LLM agents can call it
92
+ without writing payment code.
93
+
94
+ ## License
95
+
96
+ MIT.
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * stdio entry point — run `npx @aifinpay/mcp` to start the MCP server
4
+ * in stdio mode. Compatible with Claude Desktop, MCP Inspector, and any
5
+ * MCP-aware agent runtime.
6
+ *
7
+ * Configure via env:
8
+ * AIFINPAY_AGENT_SECRET base58 secret (load existing identity)
9
+ * AIFINPAY_BASE_URL default https://aifinpay.company
10
+ * AIFINPAY_TIMEOUT_MS default 30000
11
+ * AIFINPAY_MAX_USD hard cap per single payment (no default)
12
+ */
13
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
+ import { createServer, loadConfigFromEnv } from "../dist/index.js";
15
+
16
+ const { server } = createServer(loadConfigFromEnv());
17
+ const transport = new StdioServerTransport();
18
+ await server.connect(transport);
@@ -0,0 +1,16 @@
1
+ /** Runtime configuration loaded from env. */
2
+ export interface McpConfig {
3
+ /** Base58 secret to load the agent identity. If absent, a fresh keypair is
4
+ * generated AND printed to stderr at startup with a "save this!" warning. */
5
+ agentSecretB58?: string;
6
+ /** Custom AiFinPay backend URL. Defaults to production. */
7
+ baseUrl?: string;
8
+ /** Request timeout in ms. */
9
+ timeoutMs?: number;
10
+ /** Hard cap on a single payment to prevent runaway agents. */
11
+ maxAmountUsd?: number;
12
+ /** Optional log destination (defaults to stderr). */
13
+ logFn?: (level: "info" | "warn" | "error", msg: string) => void;
14
+ }
15
+ export declare function loadConfigFromEnv(): McpConfig;
16
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,MAAM,WAAW,SAAS;IACxB;kFAC8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,qDAAqD;IACrD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjE;AAED,wBAAgB,iBAAiB,IAAI,SAAS,CAW7C"}
package/dist/config.js ADDED
@@ -0,0 +1,13 @@
1
+ export function loadConfigFromEnv() {
2
+ return {
3
+ agentSecretB58: process.env.AIFINPAY_AGENT_SECRET || undefined,
4
+ baseUrl: process.env.AIFINPAY_BASE_URL || undefined,
5
+ timeoutMs: process.env.AIFINPAY_TIMEOUT_MS
6
+ ? Number(process.env.AIFINPAY_TIMEOUT_MS)
7
+ : undefined,
8
+ maxAmountUsd: process.env.AIFINPAY_MAX_USD
9
+ ? Number(process.env.AIFINPAY_MAX_USD)
10
+ : undefined,
11
+ };
12
+ }
13
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAmBA,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,SAAS;QAC9D,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,SAAS;QACnD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;YACxC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YACzC,CAAC,CAAC,SAAS;QACb,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;YACxC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACtC,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @aifinpay/mcp — MCP server exposing AiFinPay's autonomous x402 payment
3
+ * loop as agent-callable tools.
4
+ *
5
+ * Tools:
6
+ * - payable_fetch(url, opts?) — fetch any URL, auto-pay on 402
7
+ * - agent_address() — show pubkey to fund
8
+ * - agent_quote(url) — inspect 402 cost before paying
9
+ *
10
+ * Quick start (stdio transport for Claude Desktop / MCP-aware runtimes):
11
+ *
12
+ * $ npx @aifinpay/mcp
13
+ *
14
+ * Or programmatically:
15
+ *
16
+ * import { createServer } from "@aifinpay/mcp";
17
+ * import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ *
19
+ * const { server } = createServer({ agentSecretB58: process.env.SECRET });
20
+ * await server.connect(new StdioServerTransport());
21
+ */
22
+ export { createServer } from "./server.js";
23
+ export type { ToolContext } from "./server.js";
24
+ export type { McpConfig } from "./config.js";
25
+ export { loadConfigFromEnv } from "./config.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @aifinpay/mcp — MCP server exposing AiFinPay's autonomous x402 payment
3
+ * loop as agent-callable tools.
4
+ *
5
+ * Tools:
6
+ * - payable_fetch(url, opts?) — fetch any URL, auto-pay on 402
7
+ * - agent_address() — show pubkey to fund
8
+ * - agent_quote(url) — inspect 402 cost before paying
9
+ *
10
+ * Quick start (stdio transport for Claude Desktop / MCP-aware runtimes):
11
+ *
12
+ * $ npx @aifinpay/mcp
13
+ *
14
+ * Or programmatically:
15
+ *
16
+ * import { createServer } from "@aifinpay/mcp";
17
+ * import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ *
19
+ * const { server } = createServer({ agentSecretB58: process.env.SECRET });
20
+ * await server.connect(new StdioServerTransport());
21
+ */
22
+ export { createServer } from "./server.js";
23
+ export { loadConfigFromEnv } from "./config.js";
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { Agent } from "@aifinpay/agent";
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import type { McpConfig } from "./config.js";
4
+ /**
5
+ * Build an MCP server that wraps the AiFinPay agent SDK as MCP tools.
6
+ *
7
+ * Returned server is unstarted — caller wires up a transport (stdio, SSE,
8
+ * etc.) via the official `@modelcontextprotocol/sdk` package.
9
+ */
10
+ export declare function createServer(config?: McpConfig): {
11
+ server: Server<{
12
+ method: string;
13
+ params?: {
14
+ [x: string]: unknown;
15
+ _meta?: {
16
+ [x: string]: unknown;
17
+ progressToken?: string | number | undefined;
18
+ "io.modelcontextprotocol/related-task"?: {
19
+ taskId: string;
20
+ } | undefined;
21
+ } | undefined;
22
+ } | undefined;
23
+ }, {
24
+ method: string;
25
+ params?: {
26
+ [x: string]: unknown;
27
+ _meta?: {
28
+ [x: string]: unknown;
29
+ progressToken?: string | number | undefined;
30
+ "io.modelcontextprotocol/related-task"?: {
31
+ taskId: string;
32
+ } | undefined;
33
+ } | undefined;
34
+ } | undefined;
35
+ }, {
36
+ [x: string]: unknown;
37
+ _meta?: {
38
+ [x: string]: unknown;
39
+ progressToken?: string | number | undefined;
40
+ "io.modelcontextprotocol/related-task"?: {
41
+ taskId: string;
42
+ } | undefined;
43
+ } | undefined;
44
+ }>;
45
+ agent: Agent;
46
+ };
47
+ export interface ToolContext {
48
+ agent: Agent;
49
+ config: McpConfig;
50
+ log: (level: "info" | "warn" | "error", msg: string) => void;
51
+ }
52
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAKnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAW7C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,SAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4ElD;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9D"}
package/dist/server.js ADDED
@@ -0,0 +1,84 @@
1
+ import { Agent } from "@aifinpay/agent";
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
+ import { payableFetchTool, runPayableFetch } from "./tools/payable-fetch.js";
5
+ import { agentAddressTool, runAgentAddress } from "./tools/agent-address.js";
6
+ import { agentQuoteTool, runAgentQuote } from "./tools/agent-quote.js";
7
+ import { payWithSplitTool, runPayWithSplit, quoteSplitTool, runQuoteSplit, } from "./tools/pay-with-split.js";
8
+ /**
9
+ * Build an MCP server that wraps the AiFinPay agent SDK as MCP tools.
10
+ *
11
+ * Returned server is unstarted — caller wires up a transport (stdio, SSE,
12
+ * etc.) via the official `@modelcontextprotocol/sdk` package.
13
+ */
14
+ export function createServer(config = {}) {
15
+ const log = config.logFn ?? defaultLog;
16
+ // Agent identity: load from env secret if provided, else generate one
17
+ // and print to stderr so the human knows what to fund.
18
+ const agent = config.agentSecretB58
19
+ ? Agent.fromSecretB58(config.agentSecretB58, {
20
+ baseUrl: config.baseUrl,
21
+ timeoutMs: config.timeoutMs,
22
+ })
23
+ : (() => {
24
+ const a = Agent.new({
25
+ baseUrl: config.baseUrl,
26
+ timeoutMs: config.timeoutMs,
27
+ });
28
+ log("warn", `[aifinpay-mcp] no AIFINPAY_AGENT_SECRET set — generated EPHEMERAL agent.\n` +
29
+ ` address: ${a.address}\n` +
30
+ ` secret: ${a.secretB58}\n` +
31
+ ` >> Save this secret to AIFINPAY_AGENT_SECRET to keep the agent across restarts.`);
32
+ return a;
33
+ })();
34
+ log("info", `[aifinpay-mcp] agent address: ${agent.address}`);
35
+ const server = new Server({
36
+ name: "@aifinpay/mcp",
37
+ version: "0.1.0-alpha.2",
38
+ }, {
39
+ capabilities: {
40
+ tools: {},
41
+ },
42
+ });
43
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
44
+ return {
45
+ tools: [
46
+ payableFetchTool(),
47
+ agentAddressTool(),
48
+ agentQuoteTool(),
49
+ payWithSplitTool(),
50
+ quoteSplitTool(),
51
+ ],
52
+ };
53
+ });
54
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
55
+ const { name, arguments: args } = request.params;
56
+ const ctx = { agent, config, log };
57
+ switch (name) {
58
+ case "payable_fetch":
59
+ return runPayableFetch(ctx, args ?? {});
60
+ case "agent_address":
61
+ return runAgentAddress(ctx, args ?? {});
62
+ case "agent_quote":
63
+ return runAgentQuote(ctx, args ?? {});
64
+ case "pay_with_split":
65
+ return runPayWithSplit(ctx, args ?? {});
66
+ case "quote_split":
67
+ return runQuoteSplit(ctx, args ?? {});
68
+ default:
69
+ return {
70
+ isError: true,
71
+ content: [
72
+ { type: "text", text: `unknown tool: ${name}` },
73
+ ],
74
+ };
75
+ }
76
+ });
77
+ return { server, agent };
78
+ }
79
+ function defaultLog(level, msg) {
80
+ // MCP stdio servers MUST NOT write to stdout — the transport owns it.
81
+ // stderr is safe.
82
+ process.stderr.write(`[${level}] ${msg}\n`);
83
+ }
84
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ToolContext } from "../server.js";
2
+ export declare function agentAddressTool(): {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: string;
7
+ properties: {};
8
+ };
9
+ };
10
+ export declare function runAgentAddress(ctx: ToolContext, _args: Record<string, unknown>): Promise<{
11
+ content: {
12
+ type: string;
13
+ text: string;
14
+ }[];
15
+ }>;
16
+ //# sourceMappingURL=agent-address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-address.d.ts","sourceRoot":"","sources":["../../src/tools/agent-address.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAgB,gBAAgB;;;;;;;EAW/B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAU/B"}
@@ -0,0 +1,22 @@
1
+ export function agentAddressTool() {
2
+ return {
3
+ name: "agent_address",
4
+ description: "Return the agent's Solana base58 public key (its on-chain identity). " +
5
+ "Send funds to this address to enable payments via payable_fetch.",
6
+ inputSchema: {
7
+ type: "object",
8
+ properties: {},
9
+ },
10
+ };
11
+ }
12
+ export async function runAgentAddress(ctx, _args) {
13
+ return {
14
+ content: [
15
+ {
16
+ type: "text",
17
+ text: ctx.agent.address,
18
+ },
19
+ ],
20
+ };
21
+ }
22
+ //# sourceMappingURL=agent-address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-address.js","sourceRoot":"","sources":["../../src/tools/agent-address.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,uEAAuE;YACvE,kEAAkE;QACpE,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAgB,EAChB,KAA8B;IAE9B,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO;aACxB;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { ToolContext } from "../server.js";
2
+ export declare function agentQuoteTool(): {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: string;
7
+ properties: {
8
+ url: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ method: {
13
+ type: string;
14
+ enum: string[];
15
+ default: string;
16
+ };
17
+ };
18
+ required: string[];
19
+ };
20
+ };
21
+ export declare function runAgentQuote(ctx: ToolContext, args: Record<string, unknown>): Promise<{
22
+ isError: boolean;
23
+ content: {
24
+ type: string;
25
+ text: string;
26
+ }[];
27
+ } | {
28
+ content: {
29
+ type: string;
30
+ text: string;
31
+ }[];
32
+ }>;
33
+ //# sourceMappingURL=agent-quote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-quote.d.ts","sourceRoot":"","sources":["../../src/tools/agent-quote.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;EAoB7B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;GA2D9B"}
@@ -0,0 +1,78 @@
1
+ import { detectFacilitator } from "@aifinpay/agent";
2
+ export function agentQuoteTool() {
3
+ return {
4
+ name: "agent_quote",
5
+ description: "Inspect a 402 challenge for a URL WITHOUT paying. Returns the detected " +
6
+ "facilitator flavor and the merchant's quoted amount + fee preview. " +
7
+ "Use before payable_fetch to decide whether the cost is acceptable.",
8
+ inputSchema: {
9
+ type: "object",
10
+ properties: {
11
+ url: { type: "string", description: "Target URL (https)." },
12
+ method: {
13
+ type: "string",
14
+ enum: ["GET", "POST"],
15
+ default: "GET",
16
+ },
17
+ },
18
+ required: ["url"],
19
+ },
20
+ };
21
+ }
22
+ export async function runAgentQuote(ctx, args) {
23
+ const url = String(args.url ?? "");
24
+ if (!url)
25
+ return errorResult("missing required arg: url");
26
+ const method = String(args.method ?? "GET").toUpperCase();
27
+ const resp = await ctx.agent.fetchImpl(url, { method });
28
+ if (resp.status !== 402) {
29
+ return {
30
+ content: [
31
+ {
32
+ type: "text",
33
+ text: JSON.stringify({
34
+ status: resp.status,
35
+ note: resp.status === 200
36
+ ? "no payment required — you can hit this without paying"
37
+ : `unexpected status ${resp.status} on initial probe`,
38
+ }, null, 2),
39
+ },
40
+ ],
41
+ };
42
+ }
43
+ try {
44
+ const facilitator = await detectFacilitator(resp);
45
+ let bodyPreview = null;
46
+ try {
47
+ bodyPreview = await resp.clone().json();
48
+ }
49
+ catch {
50
+ bodyPreview = (await resp.clone().text()).slice(0, 500);
51
+ }
52
+ return {
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: JSON.stringify({
57
+ facilitator: facilitator.name,
58
+ status: 402,
59
+ note: "fee-on-top engine not yet wired — quote shows merchant terms only. " +
60
+ "AiFinPay fee will be added on top at payment time.",
61
+ merchant_terms: bodyPreview,
62
+ }, null, 2),
63
+ },
64
+ ],
65
+ };
66
+ }
67
+ catch (e) {
68
+ const err = e;
69
+ return errorResult(`could not detect facilitator: ${err.message}`);
70
+ }
71
+ }
72
+ function errorResult(...lines) {
73
+ return {
74
+ isError: true,
75
+ content: lines.map((line) => ({ type: "text", text: line })),
76
+ };
77
+ }
78
+ //# sourceMappingURL=agent-quote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-quote.js","sourceRoot":"","sources":["../../src/tools/agent-quote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import type { ToolContext } from "../server.js";
2
+ export declare function payWithSplitTool(): {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: string;
7
+ properties: {
8
+ chain: {
9
+ type: string;
10
+ enum: string[];
11
+ description: string;
12
+ };
13
+ merchant_wallet: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ merchant_amount: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ order_id: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ fee_recipient: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ };
30
+ required: string[];
31
+ };
32
+ };
33
+ export declare function runPayWithSplit(ctx: ToolContext, args: Record<string, unknown>): Promise<{
34
+ isError: boolean;
35
+ content: {
36
+ type: string;
37
+ text: string;
38
+ }[];
39
+ } | {
40
+ content: {
41
+ type: string;
42
+ text: string;
43
+ }[];
44
+ }>;
45
+ export declare function quoteSplitTool(): {
46
+ name: string;
47
+ description: string;
48
+ inputSchema: {
49
+ type: string;
50
+ properties: {
51
+ chain: {
52
+ type: string;
53
+ enum: string[];
54
+ };
55
+ merchant_amount: {
56
+ type: string;
57
+ description: string;
58
+ };
59
+ };
60
+ required: string[];
61
+ };
62
+ };
63
+ export declare function runQuoteSplit(ctx: ToolContext, args: Record<string, unknown>): Promise<{
64
+ isError: boolean;
65
+ content: {
66
+ type: string;
67
+ text: string;
68
+ }[];
69
+ } | {
70
+ content: {
71
+ type: string;
72
+ text: string;
73
+ }[];
74
+ }>;
75
+ //# sourceMappingURL=pay-with-split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pay-with-split.d.ts","sourceRoot":"","sources":["../../src/tools/pay-with-split.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAgB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C/B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;GAkC9B;AAED,wBAAgB,cAAc;;;;;;;;;;;;;;;;;EAqB7B;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;GAkB9B"}
@@ -0,0 +1,117 @@
1
+ export function payWithSplitTool() {
2
+ return {
3
+ name: "pay_with_split",
4
+ description: "Get on-chain instructions for a fee-on-top atomic 3-way payment. " +
5
+ "The merchant receives the FULL quoted price; AiFinPay protocol fee " +
6
+ "(1%) and creator/referral fee (0.01%) are added ON TOP. The agent " +
7
+ "executes the returned instructions with their chain SDK of choice. " +
8
+ "Returns 503 with onboarding message if the splitter is not yet " +
9
+ "deployed on the requested chain.",
10
+ inputSchema: {
11
+ type: "object",
12
+ properties: {
13
+ chain: {
14
+ type: "string",
15
+ enum: ["solana", "polygon"],
16
+ description: "Chain to settle on.",
17
+ },
18
+ merchant_wallet: {
19
+ type: "string",
20
+ description: "Recipient — Solana base58 pubkey or Polygon 0x address.",
21
+ },
22
+ merchant_amount: {
23
+ type: "string",
24
+ description: "Merchant's quoted price in chain units (lamports for Solana, " +
25
+ "wei for Polygon). Use a string to preserve precision.",
26
+ },
27
+ order_id: {
28
+ type: "string",
29
+ description: "Off-chain reference (max 64 chars).",
30
+ },
31
+ fee_recipient: {
32
+ type: "string",
33
+ description: "Optional — receives the IP-creator fee. Omit to route the " +
34
+ "creator slot to AiFinPay treasury.",
35
+ },
36
+ },
37
+ required: ["chain", "merchant_wallet", "merchant_amount", "order_id"],
38
+ },
39
+ };
40
+ }
41
+ export async function runPayWithSplit(ctx, args) {
42
+ const chain = args.chain;
43
+ if (chain !== "solana" && chain !== "polygon") {
44
+ return errorResult("chain must be 'solana' or 'polygon'");
45
+ }
46
+ const merchantWallet = String(args.merchant_wallet ?? "");
47
+ const merchantAmount = String(args.merchant_amount ?? "");
48
+ const orderId = String(args.order_id ?? "");
49
+ if (!merchantWallet || !merchantAmount || !orderId) {
50
+ return errorResult("merchant_wallet, merchant_amount, and order_id are all required");
51
+ }
52
+ const feeRecipient = typeof args.fee_recipient === "string" && args.fee_recipient
53
+ ? args.fee_recipient
54
+ : undefined;
55
+ try {
56
+ const invoice = await ctx.agent.payWithSplitInvoice({
57
+ chain,
58
+ merchantWallet,
59
+ merchantAmount,
60
+ orderId,
61
+ feeRecipient,
62
+ });
63
+ return {
64
+ content: [{ type: "text", text: JSON.stringify(invoice, null, 2) }],
65
+ };
66
+ }
67
+ catch (e) {
68
+ const err = e;
69
+ return errorResult(`${err.constructor.name}: ${err.message}`);
70
+ }
71
+ }
72
+ export function quoteSplitTool() {
73
+ return {
74
+ name: "quote_split",
75
+ description: "Pure-view: compute the fee-on-top breakdown (merchant + treasury + " +
76
+ "creator + total) for a given merchant amount. No payment, no auth. " +
77
+ "Use this BEFORE pay_with_split to decide whether the cost is " +
78
+ "acceptable.",
79
+ inputSchema: {
80
+ type: "object",
81
+ properties: {
82
+ chain: { type: "string", enum: ["solana", "polygon"] },
83
+ merchant_amount: {
84
+ type: "string",
85
+ description: "Merchant's quoted price (lamports for Solana, wei for Polygon).",
86
+ },
87
+ },
88
+ required: ["chain", "merchant_amount"],
89
+ },
90
+ };
91
+ }
92
+ export async function runQuoteSplit(ctx, args) {
93
+ const chain = args.chain;
94
+ if (chain !== "solana" && chain !== "polygon") {
95
+ return errorResult("chain must be 'solana' or 'polygon'");
96
+ }
97
+ const merchantAmount = String(args.merchant_amount ?? "");
98
+ if (!merchantAmount)
99
+ return errorResult("merchant_amount required");
100
+ try {
101
+ const quote = await ctx.agent.quoteSplit({ chain, merchantAmount });
102
+ return {
103
+ content: [{ type: "text", text: JSON.stringify(quote, null, 2) }],
104
+ };
105
+ }
106
+ catch (e) {
107
+ const err = e;
108
+ return errorResult(`${err.constructor.name}: ${err.message}`);
109
+ }
110
+ }
111
+ function errorResult(...lines) {
112
+ return {
113
+ isError: true,
114
+ content: lines.map((line) => ({ type: "text", text: line })),
115
+ };
116
+ }
117
+ //# sourceMappingURL=pay-with-split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pay-with-split.js","sourceRoot":"","sources":["../../src/tools/pay-with-split.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { ToolContext } from "../server.js";
2
+ export declare function payableFetchTool(): {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: string;
7
+ properties: {
8
+ url: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ method: {
13
+ type: string;
14
+ enum: string[];
15
+ default: string;
16
+ };
17
+ body: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ headers: {
22
+ type: string;
23
+ additionalProperties: {
24
+ type: string;
25
+ };
26
+ description: string;
27
+ };
28
+ max_amount_usd: {
29
+ type: string;
30
+ description: string;
31
+ };
32
+ facilitator: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ };
37
+ required: string[];
38
+ };
39
+ };
40
+ export declare function runPayableFetch(ctx: ToolContext, args: Record<string, unknown>): Promise<{
41
+ isError: boolean;
42
+ content: {
43
+ type: string;
44
+ text: string;
45
+ }[];
46
+ } | {
47
+ content: {
48
+ type: string;
49
+ text: string;
50
+ }[];
51
+ }>;
52
+ //# sourceMappingURL=payable-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payable-fetch.d.ts","sourceRoot":"","sources":["../../src/tools/payable-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAgB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0C/B;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;GA0D9B"}
@@ -0,0 +1,93 @@
1
+ export function payableFetchTool() {
2
+ return {
3
+ name: "payable_fetch",
4
+ description: "Fetch a URL that may require payment (HTTP 402). The agent automatically " +
5
+ "detects the x402 facilitator flavor, signs a payment, and retries. Returns " +
6
+ "the response status, headers, and body. Use this whenever an external " +
7
+ "service charges per-call and you want to pay autonomously.",
8
+ inputSchema: {
9
+ type: "object",
10
+ properties: {
11
+ url: { type: "string", description: "Target URL (https)." },
12
+ method: {
13
+ type: "string",
14
+ enum: ["GET", "POST", "PUT", "PATCH", "DELETE"],
15
+ default: "GET",
16
+ },
17
+ body: {
18
+ type: "string",
19
+ description: "Request body (string). Set Content-Type via headers if non-JSON.",
20
+ },
21
+ headers: {
22
+ type: "object",
23
+ additionalProperties: { type: "string" },
24
+ description: "Extra request headers.",
25
+ },
26
+ max_amount_usd: {
27
+ type: "number",
28
+ description: "Refuse to pay if the facilitator wants more than this. " +
29
+ "Defaults to AIFINPAY_MAX_USD env or no cap.",
30
+ },
31
+ facilitator: {
32
+ type: "string",
33
+ description: "Force a facilitator: 'aifinpay' | 'coinbase-x402'. Default 'auto'.",
34
+ },
35
+ },
36
+ required: ["url"],
37
+ },
38
+ };
39
+ }
40
+ export async function runPayableFetch(ctx, args) {
41
+ const url = String(args.url ?? "");
42
+ if (!url)
43
+ return errorResult("missing required arg: url");
44
+ const method = String(args.method ?? "GET").toUpperCase();
45
+ const body = args.body ? String(args.body) : undefined;
46
+ const headers = typeof args.headers === "object" && args.headers !== null
47
+ ? args.headers
48
+ : undefined;
49
+ const maxAmountUsd = typeof args.max_amount_usd === "number"
50
+ ? args.max_amount_usd
51
+ : ctx.config.maxAmountUsd;
52
+ try {
53
+ const resp = await ctx.agent.pay(url, {
54
+ method,
55
+ body,
56
+ headers,
57
+ options: {
58
+ maxAmountUsd,
59
+ facilitator: typeof args.facilitator === "string"
60
+ ? args.facilitator
61
+ : undefined,
62
+ },
63
+ });
64
+ const respHeaders = {};
65
+ resp.headers.forEach((v, k) => (respHeaders[k] = v));
66
+ const text = await resp.text();
67
+ return {
68
+ content: [
69
+ {
70
+ type: "text",
71
+ text: JSON.stringify({
72
+ status: resp.status,
73
+ ok: resp.ok,
74
+ headers: respHeaders,
75
+ body: text,
76
+ }, null, 2),
77
+ },
78
+ ],
79
+ };
80
+ }
81
+ catch (e) {
82
+ const err = e;
83
+ return errorResult(`${err.constructor.name}: ${err.message}`, `Tip: ensure agent ${ctx.agent.address} has a funded Seat PDA. ` +
84
+ `Read more: https://aifinpay.company/docs`);
85
+ }
86
+ }
87
+ function errorResult(...lines) {
88
+ return {
89
+ isError: true,
90
+ content: lines.map((line) => ({ type: "text", text: line })),
91
+ };
92
+ }
93
+ //# sourceMappingURL=payable-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payable-fetch.js","sourceRoot":"","sources":["../../src/tools/payable-fetch.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@aifinpay/mcp",
3
+ "version": "0.1.0-alpha.2",
4
+ "description": "MCP server exposing AiFinPay's autonomous x402 payment loop as agent tools",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "aifinpay-mcp": "bin/aifinpay-mcp.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "bin",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc -p tsconfig.json",
25
+ "test": "vitest run",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "keywords": [
29
+ "x402",
30
+ "ai-agent",
31
+ "mcp",
32
+ "model-context-protocol",
33
+ "payments",
34
+ "non-custodial",
35
+ "autonomous"
36
+ ],
37
+ "author": "CoinSecurities (SECCO) <contact@aifinpay.company>",
38
+ "license": "MIT",
39
+ "homepage": "https://github.com/AiFinPay/sdk#readme",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/AiFinPay/sdk.git",
43
+ "directory": "mcp"
44
+ },
45
+ "bugs": "https://github.com/AiFinPay/sdk/issues",
46
+ "dependencies": {
47
+ "@aifinpay/agent": "^0.2.0-alpha.2",
48
+ "@modelcontextprotocol/sdk": "^1.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.0.0",
52
+ "typescript": "^5.4.0",
53
+ "vitest": "^4.1.5"
54
+ },
55
+ "engines": {
56
+ "node": ">=18"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }