@aifinpay/mcp 2.12.1 → 2.12.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
|
@@ -4,8 +4,8 @@ AiFinPay MCP server for persistent agent identity, Agent Passport resolution,
|
|
|
4
4
|
route discovery and non-signing settlement invoices. Canonical domain:
|
|
5
5
|
**aifinpay.io**.
|
|
6
6
|
|
|
7
|
-
Version **2.12.
|
|
8
|
-
and canonical skill 2.
|
|
7
|
+
Version **2.12.2** is prepared in this checkout, on the published agent 2.9.0
|
|
8
|
+
and canonical skill 2.11.0 (AiFinPay/skill 0490615, published 2026-10-22). The separate canonical producer's final immutable
|
|
9
9
|
source pin is a required handoff, not a moving-branch substitution.
|
|
10
10
|
The published baseline checked2026-10-04 was MCP2.5.0. Package publication and
|
|
11
11
|
real registry dependency/lock refresh remain release gates; a source-cohort
|
|
@@ -227,10 +227,13 @@ client missing from this table can be reported with its exact name.
|
|
|
227
227
|
## Link the agent to its owner's dashboard
|
|
228
228
|
|
|
229
229
|
The owner sees the agent's balance, payments and receipts at
|
|
230
|
-
https://dash.aifinpay.io → My Agents. There, **Claim via MCP**
|
|
231
|
-
one-time URL; pass it to `agent_claim_self
|
|
232
|
-
|
|
233
|
-
no
|
|
230
|
+
https://dash.aifinpay.io → My Agents. There, **Link an agent → Claim via MCP**
|
|
231
|
+
generates a one-time URL; pass it to `agent_claim_self`, which redeems it with
|
|
232
|
+
a POST to `/api/auth/claim`. Opening the URL in a browser, or pasting it into a
|
|
233
|
+
chat that has no AiFinPay MCP, links nothing; such an agent is linked by signed
|
|
234
|
+
message in My Agents instead, as is an account with 2FA on. The tool contacts
|
|
235
|
+
only AiFinPay origins, signs only the claim challenge for this agent's own
|
|
236
|
+
address, and moves no funds. The owner-selected payment family must be confirmed successfully;
|
|
234
237
|
the second wallet is best-effort. Use the selected wallet's Fund panel for
|
|
235
238
|
available networks and assets; binding does not activate a disabled network.
|
|
236
239
|
Offer this to the owner after `init` (step 4 above): from then on the owner
|
|
@@ -4,17 +4,25 @@ import type { ToolContext } from "../server.js";
|
|
|
4
4
|
* autonomously by signing a claim challenge with its own key.
|
|
5
5
|
*
|
|
6
6
|
* Flow (executed inside the tool, no copy-paste between UIs):
|
|
7
|
-
* 1.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* 3. Agent calls this tool with the magic_link_url
|
|
12
|
-
* 4. Tool
|
|
7
|
+
* 1. The owner opens dash.aifinpay.io → My Agents → Link an agent →
|
|
8
|
+
* Claim via MCP and generates a one-time URL (POST /api/me/claim-url),
|
|
9
|
+
* e.g. `https://dash.aifinpay.io/api/auth/verify?token=…`
|
|
10
|
+
* 2. The owner gives that URL to the agent: "link yourself to my account"
|
|
11
|
+
* 3. Agent calls this tool with the URL as magic_link_url
|
|
12
|
+
* 4. Tool POSTs the token to /api/auth/claim → server answers with a
|
|
13
|
+
* ten-minute agent-claim grant cookie (not a session)
|
|
13
14
|
* 5. Tool requests a challenge for the owner-selected payment family
|
|
14
15
|
* 6. Tool signs only that address's claim (EIP-191 or Ed25519)
|
|
15
16
|
* 7. Tool POSTs to /api/me/agents/claim → server verifies signature →
|
|
16
17
|
* agent attached to user's watchlist
|
|
17
18
|
*
|
|
19
|
+
* Step 4 used to GET the URL. The backend redeems a claim link on that GET
|
|
20
|
+
* only when the request carries no browser Sec-Fetch headers, so a runtime
|
|
21
|
+
* whose fetch adds them was sent to the confirm page and linked nothing.
|
|
22
|
+
* The POST route is told apart by its own path and the link's flow. A
|
|
23
|
+
* backend without it (404/405) still gets the GET, so this works against any
|
|
24
|
+
* deployment.
|
|
25
|
+
*
|
|
18
26
|
* Optional `label` field gives the agent a friendly name in the user's UI.
|
|
19
27
|
*
|
|
20
28
|
* Security model:
|
|
@@ -57,7 +65,6 @@ export declare function runAgentClaimSelf(ctx: ToolContext, args: Record<string,
|
|
|
57
65
|
text: string;
|
|
58
66
|
}[];
|
|
59
67
|
} | {
|
|
60
|
-
isError?: undefined;
|
|
61
68
|
content: {
|
|
62
69
|
type: string;
|
|
63
70
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-claim-self.d.ts","sourceRoot":"","sources":["../../src/tools/agent-claim-self.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD
|
|
1
|
+
{"version":3,"file":"agent-claim-self.d.ts","sourceRoot":"","sources":["../../src/tools/agent-claim-self.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,kBAAkB;IAE9B,IAAI;IACJ,WAAW;IAOX,WAAW;QACT,IAAI;QACJ,UAAU;YACR,cAAc;gBACZ,IAAI;gBACJ,WAAW;;YAKb,KAAK;gBACH,IAAI;gBACJ,WAAW;;;QAGf,QAAQ;;IAGV,WAAW;QAAI,YAAY;QAAS,aAAa;QAAS,eAAe;;IACzE,YAAY;QAAI,IAAI;;EAEvB;AAmGD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;GAqLtF"}
|
|
@@ -4,17 +4,25 @@ import { payChain } from "../pay-chains.js";
|
|
|
4
4
|
* autonomously by signing a claim challenge with its own key.
|
|
5
5
|
*
|
|
6
6
|
* Flow (executed inside the tool, no copy-paste between UIs):
|
|
7
|
-
* 1.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* 3. Agent calls this tool with the magic_link_url
|
|
12
|
-
* 4. Tool
|
|
7
|
+
* 1. The owner opens dash.aifinpay.io → My Agents → Link an agent →
|
|
8
|
+
* Claim via MCP and generates a one-time URL (POST /api/me/claim-url),
|
|
9
|
+
* e.g. `https://dash.aifinpay.io/api/auth/verify?token=…`
|
|
10
|
+
* 2. The owner gives that URL to the agent: "link yourself to my account"
|
|
11
|
+
* 3. Agent calls this tool with the URL as magic_link_url
|
|
12
|
+
* 4. Tool POSTs the token to /api/auth/claim → server answers with a
|
|
13
|
+
* ten-minute agent-claim grant cookie (not a session)
|
|
13
14
|
* 5. Tool requests a challenge for the owner-selected payment family
|
|
14
15
|
* 6. Tool signs only that address's claim (EIP-191 or Ed25519)
|
|
15
16
|
* 7. Tool POSTs to /api/me/agents/claim → server verifies signature →
|
|
16
17
|
* agent attached to user's watchlist
|
|
17
18
|
*
|
|
19
|
+
* Step 4 used to GET the URL. The backend redeems a claim link on that GET
|
|
20
|
+
* only when the request carries no browser Sec-Fetch headers, so a runtime
|
|
21
|
+
* whose fetch adds them was sent to the confirm page and linked nothing.
|
|
22
|
+
* The POST route is told apart by its own path and the link's flow. A
|
|
23
|
+
* backend without it (404/405) still gets the GET, so this works against any
|
|
24
|
+
* deployment.
|
|
25
|
+
*
|
|
18
26
|
* Optional `label` field gives the agent a friendly name in the user's UI.
|
|
19
27
|
*
|
|
20
28
|
* Security model:
|
|
@@ -29,15 +37,16 @@ export function agentClaimSelfTool() {
|
|
|
29
37
|
name: "agent_claim_self",
|
|
30
38
|
description: "Link this agent to its owner's AiFinPay dashboard, so the owner sees the agent's " +
|
|
31
39
|
"balance, payments and receipts. Offer this after creating a wallet. The owner " +
|
|
32
|
-
"generates a one-time URL at https://dash.aifinpay.io → My Agents →
|
|
33
|
-
"and
|
|
40
|
+
"generates a one-time URL at https://dash.aifinpay.io → My Agents → Link an agent → " +
|
|
41
|
+
"Claim via MCP and gives it to you; pass it here. Do not open the URL in a browser " +
|
|
42
|
+
"tool: that links nothing. The tool signs only an AiFinPay claim challenge for this " +
|
|
34
43
|
"agent's own address and moves no funds.",
|
|
35
44
|
inputSchema: {
|
|
36
45
|
type: "object",
|
|
37
46
|
properties: {
|
|
38
47
|
magic_link_url: {
|
|
39
48
|
type: "string",
|
|
40
|
-
description: "The one-time URL from My Agents → Claim via MCP. Looks like " +
|
|
49
|
+
description: "The one-time URL from My Agents → Link an agent → Claim via MCP. Looks like " +
|
|
41
50
|
"https://dash.aifinpay.io/api/auth/verify?token=… — single use, " +
|
|
42
51
|
"expires 15 minutes after it was generated.",
|
|
43
52
|
},
|
|
@@ -115,16 +124,44 @@ function challengeIsWellFormed(message, address) {
|
|
|
115
124
|
return false;
|
|
116
125
|
return /^[0-9a-f]{32}$/.test(message.slice(prefix.length));
|
|
117
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* The token of a one-time claim URL. Accepts the shape the dashboard hands
|
|
129
|
+
* out (`/api/auth/verify?token=<hex>`) and `/api/auth/claim/<hex>`. The token
|
|
130
|
+
* is sent in a POST body, never back in a URL.
|
|
131
|
+
*/
|
|
132
|
+
function claimToken(url) {
|
|
133
|
+
let parsed;
|
|
134
|
+
try {
|
|
135
|
+
parsed = new URL(url);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const fromQuery = parsed.pathname.replace(/\/+$/, "") === "/api/auth/verify" ? parsed.searchParams.get("token") : null;
|
|
141
|
+
const fromPath = parsed.pathname.match(/^\/api\/auth\/claim\/([^/]+)\/?$/)?.[1] ?? null;
|
|
142
|
+
const token = fromQuery ?? fromPath;
|
|
143
|
+
return token && /^[A-Za-z0-9_-]{1,256}$/.test(token) ? token : null;
|
|
144
|
+
}
|
|
145
|
+
/** Why the link gave no grant, without echoing the token or server text. */
|
|
146
|
+
function linkRefused(status, code) {
|
|
147
|
+
const text = code === "claim_link_2fa_account"
|
|
148
|
+
? "This AiFinPay account has two-factor sign-in on, so a one-time URL cannot link an agent. " +
|
|
149
|
+
"Ask the owner to link this wallet by signed message in My Agents (call agent_address for the address)."
|
|
150
|
+
: `The one-time URL gave no claim grant (HTTP ${status}). It works once and for 15 minutes; ` +
|
|
151
|
+
"ask the owner for a new one in My Agents → Link an agent → Claim via MCP.";
|
|
152
|
+
return { isError: true, content: [{ type: "text", text }] };
|
|
153
|
+
}
|
|
118
154
|
export async function runAgentClaimSelf(ctx, args) {
|
|
119
155
|
const magicLinkUrl = typeof args.magic_link_url === "string" ? args.magic_link_url : "";
|
|
120
156
|
const label = typeof args.label === "string" ? args.label : null;
|
|
121
|
-
|
|
157
|
+
const token = claimToken(magicLinkUrl);
|
|
158
|
+
if (!magicLinkUrl || !token) {
|
|
122
159
|
return {
|
|
123
160
|
isError: true,
|
|
124
161
|
content: [
|
|
125
162
|
{
|
|
126
163
|
type: "text",
|
|
127
|
-
text: "magic_link_url required — should look like https://aifinpay.io/api/auth/verify?token=…",
|
|
164
|
+
text: "magic_link_url required — should look like https://dash.aifinpay.io/api/auth/verify?token=…",
|
|
128
165
|
},
|
|
129
166
|
],
|
|
130
167
|
};
|
|
@@ -146,27 +183,41 @@ export async function runAgentClaimSelf(ctx, args) {
|
|
|
146
183
|
content: [{ type: "text", text: "magic_link_url is not a valid URL" }],
|
|
147
184
|
};
|
|
148
185
|
}
|
|
149
|
-
// ── 1.
|
|
186
|
+
// ── 1. Redeem the link for a claim grant ───────────────────────────
|
|
150
187
|
let setCookie = null;
|
|
151
188
|
try {
|
|
152
|
-
const res = await fetch(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
189
|
+
const res = await fetch(`${apiBase}/api/auth/claim`, {
|
|
190
|
+
method: "POST",
|
|
191
|
+
redirect: "error", // a redirect would leave the origin we vetted
|
|
192
|
+
headers: { "content-type": "application/json" },
|
|
193
|
+
body: JSON.stringify({ token }),
|
|
194
|
+
});
|
|
195
|
+
if (res.status === 404 || res.status === 405) {
|
|
196
|
+
// A backend from before /api/auth/claim: the URL itself is the claim.
|
|
197
|
+
const legacy = await fetch(magicLinkUrl, { redirect: "manual" });
|
|
198
|
+
setCookie = legacy.headers.get("set-cookie");
|
|
199
|
+
if (!setCookie)
|
|
200
|
+
return linkRefused(legacy.status, null);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
setCookie = res.headers.get("set-cookie");
|
|
204
|
+
if (!res.ok || !setCookie) {
|
|
205
|
+
let code = null;
|
|
206
|
+
try {
|
|
207
|
+
const body = (await res.json());
|
|
208
|
+
code = typeof body?.error === "string" ? body.error : null;
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
/* not JSON */
|
|
212
|
+
}
|
|
213
|
+
return linkRefused(res.status, code);
|
|
214
|
+
}
|
|
164
215
|
}
|
|
165
216
|
}
|
|
166
217
|
catch {
|
|
167
218
|
return {
|
|
168
219
|
isError: true,
|
|
169
|
-
content: [{ type: "text", text: "Failed to
|
|
220
|
+
content: [{ type: "text", text: "Failed to reach AiFinPay to redeem the link; no claim was completed." }],
|
|
170
221
|
};
|
|
171
222
|
}
|
|
172
223
|
// Some setups split multiple cookies; grab the session one we care about.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-claim-self.js","sourceRoot":"","sources":["../../src/tools/agent-claim-self.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"agent-claim-self.js","sourceRoot":"","sources":["../../src/tools/agent-claim-self.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aifinpay/mcp",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.2",
|
|
4
4
|
"mcpName": "io.github.daochild/aifinpay",
|
|
5
5
|
"description": "AiFinPay MCP: persistent local agent wallets, owner-configured EVM and Solana payment adapters, durable budgets and receipt recovery.",
|
|
6
6
|
"type": "module",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"bugs": "https://github.com/AiFinPay/sdk/issues",
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@aifinpay/agent": "^2.9.0",
|
|
80
|
-
"@aifinpay/skill": "^2.
|
|
80
|
+
"@aifinpay/skill": "^2.11.0",
|
|
81
81
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
82
82
|
"bs58": "^6.0.0",
|
|
83
83
|
"tweetnacl": "^1.0.3"
|
package/skills/SKILL.md
CHANGED
|
@@ -6,7 +6,7 @@ description: Pay for x402-gated APIs and sites as an agent (AIFP-1 on an owner-s
|
|
|
6
6
|
wallet, payment history, prepaid quotas and Agent Passport records through
|
|
7
7
|
the AiFinPay MCP server or SDK.
|
|
8
8
|
license: MIT
|
|
9
|
-
version: 2.
|
|
9
|
+
version: 2.11.0
|
|
10
10
|
author: AiFinPay Support
|
|
11
11
|
metadata:
|
|
12
12
|
hermes:
|
|
@@ -61,7 +61,7 @@ your language. There is no "install together" scenario.
|
|
|
61
61
|
|
|
62
62
|
## Version and release status
|
|
63
63
|
|
|
64
|
-
Release target: MCP **2.
|
|
64
|
+
Release target: MCP **2.12.1**, Node SDK **2.9.0**, Python **2.7.1**.
|
|
65
65
|
This skill describes that coordinated package cohort. Check the installed
|
|
66
66
|
versions before using its additional-network instructions; a release target
|
|
67
67
|
does not establish npm/PyPI publication or production network activation.
|
|
@@ -71,7 +71,7 @@ Published packages remain usable within their documented capabilities.
|
|
|
71
71
|
|
|
72
72
|
| Surface | Can it pay? |
|
|
73
73
|
|---|---|
|
|
74
|
-
| MCP `@aifinpay/mcp` 2.
|
|
74
|
+
| MCP `@aifinpay/mcp` 2.12.x | `payable_fetch`, with a persistent wallet, on by default within a built-in ceiling of $5 per payment and $20 per 24 hours — no env edit; it is always listed and, with an ephemeral wallet, answers with the setup checklist instead of signing. `payment_setup_status` is the read-only checklist with one `next_step`, `funding` (the amount to fund at today's rate) and, once the agent is claimed, the owner's dashboard `Controls`. Polygon is the default; other networks require explicit `AIFINPAY_PAY_CHAIN`. The merchant and backend must authorize and serve that network. `scope: "merchant"` buys a site-wide batch. On 2.11.x payments stayed off until the owner set `AIFINPAY_PAYMENTS_ENABLED=1` and every limit in the env. |
|
|
75
75
|
| Node `@aifinpay/agent` 2.8.x | `fetchPaid` with a v14 journal, gas cap and owner budgets. Select another network with `v14.chain`; select a pinned stablecoin with `v14.asset`. Native payments require an independent native/USD rate. |
|
|
76
76
|
| Python `aifinpay-agent` 2.7.x | `agent.fetch_paid(url, allowed_origins=…, max_amount_usd=…, daily_amount_usd=…)`; use explicit `chain` and the chain's native gas cap for another network, or a pinned stablecoin `asset`. `agent.recover_paid(journal_path)` recovers the original transaction. |
|
|
77
77
|
|
|
@@ -166,71 +166,74 @@ or event log alone does not prove a valid paid request.
|
|
|
166
166
|
|
|
167
167
|
# AiFinPay agent workflow
|
|
168
168
|
|
|
169
|
-
Use the tools actually returned by MCP tools/list. MCP 2.
|
|
169
|
+
Use the tools actually returned by MCP tools/list. MCP 2.12.1 exposes
|
|
170
170
|
agent_address, agent_reload, agent_claim_self, agent_history, agent_quota,
|
|
171
171
|
agent_passport_resolve, settlement_routes, settlement_invoice,
|
|
172
172
|
deployment_info, `payment_setup_status` and `payable_fetch`. `payable_fetch`
|
|
173
|
-
is listed from the first start
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
is listed from the first start and pays by default from a persistent wallet,
|
|
174
|
+
within the built-in ceiling; with an ephemeral wallet, or when the owner
|
|
175
|
+
switched payments off with `AIFINPAY_PAYMENTS_ENABLED=0`, it returns the same
|
|
176
|
+
checklist as `payment_setup_status` and signs nothing. With AIFINPAY_MODE=dev
|
|
177
|
+
it also exposes dev_payment_quote. Never tell a user a payment was sent
|
|
178
|
+
because a quote or invoice was created.
|
|
177
179
|
|
|
178
180
|
`settlement_routes` lists the AIFP-1 v1.4 routes first (Polygon and Base,
|
|
179
181
|
`live: true` when served) and the older splitter v1.3 routes under
|
|
180
182
|
`legacy_v13`. Only the v1.4 section says whether `payable_fetch` can pay; a
|
|
181
183
|
v1.3 route marked not live does not mean the network is disabled.
|
|
182
184
|
|
|
183
|
-
## First payment in
|
|
184
|
-
|
|
185
|
-
A fresh install reaches its first payment in
|
|
186
|
-
single tool call or command; signing happens only in step
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
(`
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
missing. Follow `next_step`; do not skip ahead.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
address.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
expected, not a refusal — say so, ask the owner for the restart, and stop.
|
|
228
|
-
After it, `payment_setup_status` reports `ready: true`. Funding, origins
|
|
229
|
-
and limits are the owner's decisions; never choose them yourself.
|
|
230
|
-
5. **Pay.** `payable_fetch({"url":"<origin><path>"})` (add
|
|
185
|
+
## First payment in four steps
|
|
186
|
+
|
|
187
|
+
A fresh install reaches its first payment in four steps. Each one is a
|
|
188
|
+
single tool call or command; signing happens only in the last step, and only
|
|
189
|
+
from a persistent wallet. Nobody edits the MCP client config to enable
|
|
190
|
+
payments: they are on from the first start, within the built-in ceiling ($5
|
|
191
|
+
per payment, $20 per 24 hours). Do not improvise around a missing step — no
|
|
192
|
+
key handling of your own, no funding of an ephemeral address.
|
|
193
|
+
|
|
194
|
+
1. **Init.** Call `payment_setup_status`. It returns the wallet (`persistent`
|
|
195
|
+
or ephemeral), `payments_enabled`, the limits in force with their source
|
|
196
|
+
(`default` or `env`), the balance when the RPC answers, `funding` (what a
|
|
197
|
+
persistent wallet needs, priced now), `dashboard` (whether the agent is
|
|
198
|
+
linked and, if so, the owner's Controls), `ready`, and `next_step` — the
|
|
199
|
+
one thing still missing. Follow `next_step`; do not skip ahead. If
|
|
200
|
+
`wallet.persistent` is false, run the exact command in `next_step` (it is
|
|
201
|
+
`npx @aifinpay/mcp init`, prefixed with `AIFINPAY_HOME=…` when the server
|
|
202
|
+
uses its own wallet directory — keep that prefix, or the server will not
|
|
203
|
+
see the keystore). Without a terminal init does not prompt: it generates
|
|
204
|
+
the passphrase, writes the keystore and prints one JSON document with
|
|
205
|
+
`addresses` and an `env` block. Put that `env` into the `aifinpay` server
|
|
206
|
+
entry of the MCP client config (the passphrase is only there — the output
|
|
207
|
+
is a secret, and a second run never reprints it), then call
|
|
208
|
+
`agent_reload`: it reads the keystore, switches this server to the
|
|
209
|
+
persistent wallet and turns the payment journal on in the same connection
|
|
210
|
+
— no restart. If init answers that a keystore already exists and cannot
|
|
211
|
+
be opened, do not delete or replace it: follow its `next_step` and start
|
|
212
|
+
a new wallet directory. Never fund an ephemeral address.
|
|
213
|
+
2. **Fund.** Tell the owner `addresses.evm` and the amount: the batch price
|
|
214
|
+
in the pay chain's native currency at today's rate plus the gas cap. Take
|
|
215
|
+
it from `payment_setup_status` — its `funding` field prices the smallest
|
|
216
|
+
batch now and adds the gas cap into `amount`. The rate moves (on
|
|
217
|
+
2026-10-19 one `$0.10` batch was 1.08 POL), so never quote a remembered
|
|
218
|
+
number; if `funding` has a `rate_error` and no `amount`, ask the owner to
|
|
219
|
+
fund "the batch price in POL at today's rate plus the gas cap" and name
|
|
220
|
+
no number. Funding is the owner's decision; never choose the amount
|
|
221
|
+
yourself.
|
|
222
|
+
3. **Link.** Offer the dashboard (see "After creating a wallet"): the owner
|
|
223
|
+
generates a one-time URL at https://dash.aifinpay.io → My Agents → Claim
|
|
224
|
+
via MCP and pastes it; call `agent_claim_self`. From then on the owner
|
|
225
|
+
sets the working limits in Controls and `payment_setup_status` shows them
|
|
226
|
+
in `dashboard`. The owner may skip this for a first test; the ceiling
|
|
227
|
+
still applies.
|
|
228
|
+
4. **Pay.** `payable_fetch({"url":"<origin><path>"})` (add
|
|
231
229
|
`"scope":"merchant"` for a site-wide batch) buys the batch and returns the
|
|
232
230
|
content with the receipt summary. Later requests reuse the batch.
|
|
233
231
|
|
|
232
|
+
If `payment_setup_status` reports `payments_enabled: false`, the owner set
|
|
233
|
+
`AIFINPAY_PAYMENTS_ENABLED=0` in the server's env: say so and stop — only the
|
|
234
|
+
owner removes it, and the server has to be restarted afterwards (env is read
|
|
235
|
+
at start; `agent_reload` does not read it).
|
|
236
|
+
|
|
234
237
|
## "Buy access for this site"
|
|
235
238
|
|
|
236
239
|
The owner can start with one sentence — "buy access for this site", "get me
|
|
@@ -252,17 +255,18 @@ into ratersapp.com", "купи доступ до цього сайту". Handle
|
|
|
252
255
|
separate, in the selected network's native currency. Use the display rules
|
|
253
256
|
in "Transaction display" below.
|
|
254
257
|
4. **Check readiness.** Call `payment_setup_status`. If it is not `ready`,
|
|
255
|
-
follow its `next_step` through "First payment in
|
|
256
|
-
persistent wallet first, then the owner's funding and
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
does not read them. Adding a site, raising a limit and funding the wallet
|
|
262
|
-
are the owner's decisions; never make them on your own initiative.
|
|
258
|
+
follow its `next_step` through "First payment in four steps" above: a
|
|
259
|
+
persistent wallet first, then the owner's funding — and stop until the
|
|
260
|
+
owner has done their part. No environment block is needed: without an
|
|
261
|
+
owner allowlist, MCP 2.12.1 pays only a merchant that verified this very
|
|
262
|
+
site with AiFinPay. Raising a limit and funding the wallet are the owner's
|
|
263
|
+
decisions; never make them on your own initiative.
|
|
263
264
|
5. **Buy.** `payable_fetch({"url":"<origin><path>","scope":"merchant"})`, where
|
|
264
265
|
the path is what the owner wants to read, or a standard resource from the
|
|
265
|
-
discovery document.
|
|
266
|
+
discovery document. If it answers "Not paid: merchant … has not verified
|
|
267
|
+
its site" or "is verified for X, not Y", nothing was paid: tell the owner
|
|
268
|
+
the site's AiFinPay merchant has not verified this site, and stop. Do not
|
|
269
|
+
look for another way to pay it.
|
|
266
270
|
6. **Report and reuse.** Give the amount, the transaction hash with its
|
|
267
271
|
explorer link, the receipt id and the remaining units. Later requests to any
|
|
268
272
|
path on that origin go through `payable_fetch` and spend the same batch, with
|
|
@@ -278,27 +282,39 @@ default `scope`.
|
|
|
278
282
|
|
|
279
283
|
## Paying with payable_fetch
|
|
280
284
|
|
|
281
|
-
|
|
282
|
-
|
|
285
|
+
Nothing has to be configured to pay. The MCP server pays by default from a
|
|
286
|
+
persistent wallet within a built-in ceiling — **$5 per payment, $20 per
|
|
287
|
+
rolling 24 hours**, gas capped at 0.3 POL on Polygon — and only to a merchant
|
|
288
|
+
that verified the very site being fetched with AiFinPay (on the hosted
|
|
289
|
+
gateway, any verified merchant). The payee is the merchant the AiFinPay quote
|
|
290
|
+
names, never an address a `402` claims. The day-to-day limits —
|
|
291
|
+
per-payment cap, daily cap, pause, allowed merchants — are the dashboard
|
|
292
|
+
**Controls** once the agent is claimed (see "After creating a wallet" below);
|
|
293
|
+
the backend enforces them on every quote and payment, with no env change and
|
|
294
|
+
no server restart. A payment has to pass both.
|
|
295
|
+
|
|
296
|
+
The env values are optional overrides the owner may set in the MCP client
|
|
297
|
+
config (read when the server starts; the client then restarts the server):
|
|
283
298
|
|
|
284
299
|
```json
|
|
285
300
|
{
|
|
286
|
-
"
|
|
301
|
+
"AIFINPAY_MAX_USD": "2",
|
|
302
|
+
"AIFINPAY_DAILY_USD": "10",
|
|
287
303
|
"AIFINPAY_GATEWAY_ORIGINS": "https://merchant.example",
|
|
288
|
-
"AIFINPAY_GATEWAY_PATH_MODE": "direct",
|
|
289
|
-
"AIFINPAY_MAX_USD": "5",
|
|
290
|
-
"AIFINPAY_DAILY_USD": "20",
|
|
291
304
|
"AIFINPAY_MAX_GAS_POL": "0.3"
|
|
292
305
|
}
|
|
293
306
|
```
|
|
294
307
|
|
|
295
|
-
`AIFINPAY_MAX_USD`
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
308
|
+
Every override only narrows. `AIFINPAY_MAX_USD` / `AIFINPAY_DAILY_USD` can
|
|
309
|
+
lower the ceiling, never raise it: a value above $5 / $20 stops the server at
|
|
310
|
+
start with a message that points to the dashboard, and is never silently
|
|
311
|
+
clipped. A higher limit is a dashboard decision, or the Node SDK with its own
|
|
312
|
+
budgets. `AIFINPAY_GATEWAY_ORIGINS` narrows the sites to exact https origins;
|
|
313
|
+
`AIFINPAY_GATEWAY_PATH_MODE` is inferred from the origin (`gateway` for
|
|
314
|
+
gateway.aifinpay.io, `direct` elsewhere) unless set. `AIFINPAY_PAYMENTS_ENABLED=0`
|
|
315
|
+
switches payments off. Never ask the owner to add any of these to pay; only
|
|
316
|
+
mention them when the owner asks for a different ceiling or a site allowlist.
|
|
317
|
+
The smallest batch is **$0.10 plus gas** on **Polygon**;
|
|
302
318
|
`AIFINPAY_MAX_USD` only has to be at or above the batch. The gas cap has to cover the
|
|
303
319
|
worst-case fee: at ~280 gwei that is about 0.10 POL for a POL payment and
|
|
304
320
|
0.21 POL for USDC, and a lower cap refuses before anything is signed. The fee
|
|
@@ -389,10 +405,11 @@ Once the agent is claimed, the dashboard is where the owner manages its
|
|
|
389
405
|
working limits: **Controls** on the agent's page sets the per-payment cap, the
|
|
390
406
|
daily cap, pause and the allowed sites, and the backend enforces that policy
|
|
391
407
|
on every `/v1/quote` and `/v1/pay` for the claimed agent — no env change, no
|
|
392
|
-
server restart
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
408
|
+
server restart; `payment_setup_status` reads them back as `dashboard`. The
|
|
409
|
+
MCP's local ceiling ($5 per payment and $20 per day, or the owner's
|
|
410
|
+
`AIFINPAY_MAX_USD` / `AIFINPAY_DAILY_USD`) stays underneath; it does not
|
|
411
|
+
replace the dashboard, and the dashboard does not replace it — a payment has
|
|
412
|
+
to pass both. Dashboard controls do not reach transactions sent
|
|
396
413
|
directly outside AiFinPay. After `agent_claim_self`, point the owner at
|
|
397
414
|
Controls rather than at the config file when they want to change a limit.
|
|
398
415
|
|