@nonagon-link/mcp 0.2.0 → 0.3.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 +118 -14
  2. package/dist/server.js +3222 -316
  3. package/package.json +15 -7
package/README.md CHANGED
@@ -1,20 +1,109 @@
1
1
  # @nonagon-link/mcp
2
2
 
3
- MCP (Model Context Protocol) server for [NONAGON LINK](https://app.nnglink.ai) — lets AI agents discover paid APIs and pay for them with USDC over the [x402 protocol](https://www.x402.org) (Solana).
3
+ MCP (Model Context Protocol) server for [NONAGON LINK](https://app.nnglink.ai) — lets AI agents discover paid APIs and pay for them over the [x402 protocol](https://www.x402.org) with **USDC on Solana**, and — when you configure an EVM wallet — with the **official JPYC** on Polygon / Ethereum (**TEST_JPYSC** on Sepolia for testing), and — only when you also set an EVM USDC cap — with **EVM USDC**. A 402 that asks for any other asset, a different network, or a `payTo` outside your allow-list is rejected without signing.
4
4
 
5
5
  ## Tools
6
6
 
7
7
  | Tool | Description |
8
8
  |---|---|
9
- | `search_listings` | Search the NONAGON LINK API catalog by keyword |
10
- | `pay_and_call` | Call a paid API endpoint, automatically handling the x402 payment flow (402 → sign → retry). On success, returns a `paymentInfo` summary (`amountUsdc`, `txSignature`, `network`, `payer`, `paidAt`) so the agent can track its spending |
9
+ | `search_listings` | Search and compare paid APIs by keyword, network, currency, budget, MCP payment compatibility, health, and settled-payment rating evidence |
10
+ | `pay_and_call` | Call a paid API endpoint, automatically handling the x402 payment flow (402 → sign → retry). Every response carries `paymentStatus` (`paid` / `not_paid` / `unknown` — see [Payment status](#payment-status)). When paid, `paymentInfo` has `currency` (`USDC`, `JPYC`, or `TEST_JPYSC`), `amount` in that currency, `amountUsdc` (USDC on Solana or EVM; `null` for yen tokens), `txSignature`, `network`, `payer`, and `paidAt`. `txSignature` is **the tx the payee reported; the MCP does not verify it on-chain**. For USDC on Solana, `payer` is the paying wallet as reported in the `PAYMENT-RESPONSE` header (the counterparty's claim); for EVM payments (JPYC and EVM USDC), `amount`, `network` and `payer` are the values this server actually signed |
11
11
  | `get_active_tokens` | List active access tokens for this session (masked summary only). Note: standard inline payments via `pay_and_call` do **not** issue an access token, so this list can be empty even after a successful payment — use `get_payment_history` / `get_spending` to review spending |
12
- | `get_payment_history` | List this wallet's recent payments (inline payments included). Requires `NONAGON_LINK_BASE_URL` |
13
- | `get_spending` | Aggregate this wallet's spending by period (`day`/`week`/`month`/`all`), with a per-currency breakdown. Requires `NONAGON_LINK_BASE_URL` |
12
+ | `get_payment_history` | List this server's recent payments (inline payments included). With an EVM wallet configured, the Solana wallet's and the EVM wallet's payments are merged into one list and each row says which `wallet` paid. Requires `NONAGON_LINK_BASE_URL` |
13
+ | `get_spending` | Aggregate spending by period (`day`/`week`/`month`/`all`), with a per-currency breakdown. With an EVM wallet configured, also returns per-wallet results and an `assets` list (one entry per wallet × currency; amounts are never added across wallets or currencies). Requires `NONAGON_LINK_BASE_URL` |
14
14
 
15
- > `get_payment_history` and `get_spending` authenticate to NONAGON LINK on your behalf using the same Solana key (`NONAGON_PRIVATE_KEY`) via the standard agent challenge/verify flow. The resulting access token is held in memory only and is never logged or returned to the model.
15
+ > `get_payment_history` and `get_spending` authenticate to NONAGON LINK on your behalf via the standard agent challenge/verify flow: with the Solana key (`NONAGON_PRIVATE_KEY`), and — when `NONAGON_EVM_PRIVATE_KEY` is set — separately with the EVM key, which signs only a fixed EIP-712 `AgentChallenge` message (`purpose: "agent-challenge"` and the server's UUID nonce) on a network of this server's family. The access tokens are held in memory per wallet only and are never logged or returned to the model.
16
16
  >
17
- > These two tools report activity for the **server's wallet** (`NONAGON_PRIVATE_KEY`), which is process-wide. In HTTP mode (`--transport http`), every client connected to the same server shares that one wallet, so they all see the same payment history and spending. This matches the one-wallet-per-server model — run a separate server per wallet if you need isolation.
17
+ > With an EVM wallet the response also has `wallets` (one entry per wallet with `status: "ok"` or `status: "error"` and a fixed `error.kind` / `error.message`). If one wallet fails, the other wallet's result is still returned with `partial: true` (in `get_payment_history`, `pagination.total` is then `null`); if both fail the tool returns an error. In `get_spending`, the top-level `total` / `count` / `byStatus` / `byCurrency` / `period` / `from` keep meaning the **Solana** wallet (`total` / `count` / `byStatus` are the server's USDC-only headline); read `assets` or `wallets[].byCurrency` for JPYC and for the EVM wallet. Each wallet has a 20-second deadline per call. If EVM agent authentication fails (not enabled on the server, sanctions, revoked agent, rate limits), the server is not asked again for that wallet for 60 seconds (10 minutes when the cause will not clear quickly: not enabled, sanctions, or an API 401 whose server code is `AGENT_REVOKED`), so the Solana side keeps working. An attempt stopped by the 20-second deadline before the server answered does not start this wait (once the server's status has arrived, the wait follows that status; this includes an unreadable 400 that is still the latest answer when the deadline stops a later network's request; once a later network answers, with 200 or with "not enabled", the earlier 400 no longer sets the wait), so a consistently slow server can see one attempt per call; EVM calls for the same wallet still run one at a time, so at most one attempt is in flight. With an EVM wallet each call uses two of the per-IP agent-token requests (about 30 calls per minute per IP).
18
+ >
19
+ > These two tools report activity for the **server's wallets** (`NONAGON_PRIVATE_KEY`, and `NONAGON_EVM_PRIVATE_KEY` when set), which are process-wide. In HTTP mode (`--transport http`), every client connected to the same server shares those wallets, so they all see the same payment history and spending. This matches the one-wallet-per-server model — run a separate server per wallet if you need isolation. The EVM wallet's history includes every payment made with that key, also outside this server.
20
+
21
+ ### `search_listings` inputs
22
+
23
+ | Input | Values / default | Purpose |
24
+ |---|---|---|
25
+ | `q` | string, up to 200 characters | Match listing names and descriptions |
26
+ | `category` | string, up to 40 characters | Filter by category |
27
+ | `chain` | `solana` or `ethereum` | Filter by payment chain |
28
+ | `networkId` | CAIP-2 `solana:<genesis>` or `eip155:<chainId>` | Filter by an exact payment network |
29
+ | `currency` | `USDC`, `JPYC`, or `TEST_JPYSC` | Filter by payment asset; required with `maxPrice`. SBI JPYSC is a separate, unsupported asset. |
30
+ | `maxPrice` | greater than 0 and at most 1000 | Maximum price per call, denominated in `currency` |
31
+ | `health` | `healthy`, `unhealthy`, or `unknown` | Filter by the most recent bounded upstream probe; results become unknown after 45 minutes |
32
+ | `minRatingCount` | integer from 1 to 1,000,000 | Require at least this many settled-payment ratings |
33
+ | `payableViaMcpOnly` | boolean; default `false` | Keep only listings this server can actually pay and call: USDC on its Solana `NONAGON_NETWORK` and, with an EVM wallet configured, JPYC / TEST_JPYSC priced at or below the yen cap, plus EVM USDC priced at or below `MCP_MAX_PAYMENT_EVM_USDC_CAP` when that cap is set |
34
+ | `sort` | `updated_at`, `price_usdc`, `name`, `rating_score`, `rating_count`, `uptime_percent`, or `decision_readiness`; default `decision_readiness` | Choose the catalog ordering |
35
+ | `order` | `asc` or `desc`; default `desc` | Choose the direction; `decision_readiness` always remains highest first |
36
+ | `limit` | integer from 1 to 10; default `5` | Limit the number of returned listings |
37
+
38
+ For GET listings, `search_listings` returns both `parameters` and `querySchema`. Validate the complete query object against `querySchema` before paying: individual `parameters` cannot express rules such as exactly one of `tweet_id` or `url`. The schema is supplied by the provider and is returned only if it fits the MCP safety limits. If a saved schema cannot be exposed, `querySchema` is `null` and `decisionGaps` includes `query_schema_unavailable`. An OpenAPI fetch failure instead reports `openapi_unavailable`; the tool does not infer missing constraints from a description.
39
+
40
+ For proxy listings, `search_listings` also returns an opaque signed `funnelAttribution` value. Pass it unchanged to the optional `funnelAttribution` input of `pay_and_call`; the tool forwards it as `X-Nonagon-Funnel-Attribution` so discovery, payment, and upstream outcome remain one privacy-safe server-side flow. It contains no wallet, IP, request payload, query value, or API key.
41
+
42
+ `ratingScore` (1–5 or `null`) and `ratingCount` (0 for unrated) summarize ratings tied to settled payments; `ratingBasis` is `settled_payment`. A provider can still buy through a separate wallet, so these ratings are one signal for purchase decisions, not a guarantee of data quality. The score and count remain available when a listing's OpenAPI document cannot be fetched.
43
+
44
+ Use `currency` together with `maxPrice` to set a budget; the tool rejects an unqualified price because USDC, JPYC, and the Sepolia test token are different units. `payableViaMcpOnly: true` returns only listings `pay_and_call` can pay and call on this server (it skips listings whose OpenAPI cannot be resolved or whose method cannot be called). It keeps your `chain` / `networkId` / `currency` / `maxPrice`. Within one currency and network the catalog order is kept as-is; when several currencies or networks are payable, results interleave them one listing at a time (not a single overall ranking — `ranking` says so). `total` counts matching listings before unpayable ones are removed. A yen listing priced above the cap reports `payableViaMcp: false` with the decision gap `mcp_payment_limit_too_low`. `health: "healthy"` requires a successful upstream probe within 45 minutes, and `minRatingCount` requires settled-payment rating evidence. The default `decision_readiness` order prioritizes current health, provider-supplied metadata completeness, rating evidence, and recency. This order measures how much can be inspected before purchase. It does not establish response correctness, data freshness, or provider trustworthiness; check each result's `decisionGaps`, `upstreamHealth`, `ratingCount`, response schema/sample, and coverage before paying.
45
+
46
+ ### Paying in JPYC (EVM)
47
+
48
+ `pay_and_call` pays yen-denominated listings with the official JPYC via EIP-3009 `transferWithAuthorization` (gas is paid by NONAGON LINK; your wallet only needs the token balance — no approve, no ETH/POL).
49
+
50
+ | This server's `NONAGON_NETWORK` | EVM networks paid | Asset |
51
+ |---|---|---|
52
+ | Solana mainnet | Polygon (`eip155:137`), Ethereum (`eip155:1`) | JPYC |
53
+ | Solana devnet | Sepolia (`eip155:11155111`) | TEST_JPYSC (test token) |
54
+
55
+ 1. Set `NONAGON_EVM_PRIVATE_KEY` to a **dedicated EVM wallet with a small balance** (`0x` + 64 hex). It is only used to sign typed data (the signer cannot sign transactions).
56
+ 2. Set `NONAGON_EVM_PAY_TO` to the NONAGON LINK EVM treasury (from the operator or official docs — never copy it from an untrusted 402). Unset = every EVM payment is refused.
57
+ 3. Pass `maxPaymentJpy` to `pay_and_call` (at most 4 decimals). Without it a yen 402 is not signed: the tool returns `PAYMENT_EXCEEDS_LIMIT` with `max: null` and the required amount. The ceiling is 100 by default; raise it with `MCP_MAX_PAYMENT_JPY_CAP` (up to 1000). Polygon JPYC listings start at 10 and Ethereum JPYC listings start at 300, so Ethereum ones need a cap of 300 or more.
58
+
59
+ Before signing, the server checks that the 402's network, asset (the pinned JPYC contract), EIP-712 domain, amount range, `exact` + `eip3009` method, `maxTimeoutSeconds` (≤ 300) and `payTo` all match; otherwise it returns `PAYMENT_REQUIREMENT_REJECTED` without signing. Without an EVM wallet a JPYC listing returns `EVM_WALLET_NOT_CONFIGURED`. EVM USDC is covered in [Paying in EVM USDC](#paying-in-evm-usdc).
60
+
61
+ Every option a 402 offers is checked, not just the one that would be paid. If a 402 also offers an option this server does not handle (another network or scheme), `pay_and_call` refuses the whole 402 with `PAYMENT_REQUIREMENT_REJECTED` and `reason: "candidate"` (`paymentStatus: "not_paid"`) instead of silently paying one of the other options. This applies to every configuration, including Solana-only servers: a 402 offering Solana USDC together with an unhandled option is refused too. NONAGON LINK listings offer exactly one option, so they are not affected.
62
+
63
+ `search_listings` reports a JPYC / TEST_JPYSC listing as `payableViaMcp: true` only when its price is inside the asset's allowed range and at or below your yen cap. A price outside the asset's range reports `mcp_payment_unsupported` (`pay_and_call` would refuse it); a price inside the range but above the cap reports `mcp_payment_limit_too_low`.
64
+
65
+ ### Paying in EVM USDC
66
+
67
+ EVM USDC listings are priced 2–10 USDC, about 100 times the Solana USDC listings (0.001–0.1 USDC), so EVM USDC is **off by default** and has its own limits. Nothing changes for an existing configuration: without the new cap, an EVM USDC 402 is never signed, even with `MCP_MAX_PAYMENT_USDC_CAP=10` and an EVM wallet. It is paid the same way as JPYC (EIP-3009 `transferWithAuthorization`; gas is paid by NONAGON LINK, your wallet only needs USDC — no approve, no ETH/POL).
68
+
69
+ | This server's `NONAGON_NETWORK` | EVM USDC networks paid |
70
+ |---|---|
71
+ | Solana mainnet | Ethereum (`eip155:1`), Polygon (`eip155:137`), Base (`eip155:8453`) |
72
+ | Solana devnet | Sepolia (`eip155:11155111`), Polygon Amoy (`eip155:80002`), Base Sepolia (`eip155:84532`) |
73
+
74
+ This MCP server does not know which of these networks NONAGON LINK has enabled and does not check: once EVM USDC is set up, it signs **any host's** EVM USDC 402 on a network listed here, as long as the 402 matches the pinned USDC asset, your `NONAGON_EVM_PAY_TO` allowlist and your caps. NONAGON LINK's own listings only use the networks NONAGON LINK has enabled, so a 402 on another listed network can only come from a different host (see the known limitation below).
75
+
76
+ Three settings are needed, plus one argument per call:
77
+
78
+ 1. `NONAGON_EVM_PRIVATE_KEY` — the dedicated EVM wallet (same as for JPYC).
79
+ 2. `NONAGON_EVM_PAY_TO` — the NONAGON LINK EVM treasury (same as for JPYC).
80
+ 3. `MCP_MAX_PAYMENT_EVM_USDC_CAP` — the most this server may pay per EVM USDC call, written in decimal notation with at most 6 fractional digits. The allowed range comes from the pinned USDC price range of this server's network family (2–10 USDC today). Unset or empty = EVM USDC is never paid. In the `.mcpb` settings this is "EVM USDC payment cap".
81
+ 4. Pass `maxPaymentEvmUsdc` (USDC, at most 6 decimals, at most the cap) to `pay_and_call`. `maxPaymentUsdc` applies to Solana USDC only and is never used for EVM USDC.
82
+
83
+ | Situation | Response (`paymentStatus: "not_paid"`, nothing signed) |
84
+ |---|---|
85
+ | Cap not set | `EVM_NOT_SUPPORTED` with `reason: "evm_usdc_not_enabled"` and a hint naming the settings (only when setting them would make the 402 payable) |
86
+ | Cap set, no EVM wallet | `EVM_WALLET_NOT_CONFIGURED` with `currency: "USDC"` |
87
+ | `maxPaymentEvmUsdc` missing or too low | `PAYMENT_EXCEEDS_LIMIT` with `currency: "USDC"`, `network`, `required`, `max` (`null` when missing). It has no `requiredUsdc` / `maxPaymentUsdc` — raising `maxPaymentUsdc` does not help. When the price is above `MCP_MAX_PAYMENT_EVM_USDC_CAP`, the hint asks you to raise the cap (and restart the server) instead, because `maxPaymentEvmUsdc` cannot exceed it |
88
+ | Wrong network / asset / domain / amount / validity / `payTo` | `PAYMENT_REQUIREMENT_REJECTED` (same checks as JPYC) |
89
+
90
+ The cap is checked again right before signing, so a call that bypasses the tool's input validation still cannot sign above it. `search_listings` reports an EVM USDC listing as `payableViaMcp: true` only when the cap is set and its price is inside the pinned range and at or below the cap; above the cap it reports `mcp_payment_limit_too_low` (on a USDC row this gap always refers to the EVM USDC cap). When `payableViaMcpOnly` filters can only match EVM USDC and EVM USDC is not set up, the search returns an error naming the settings.
91
+
92
+ **There is no session or daily total limit.** Each call is limited separately, and only your wallet balance stops repeated calls. With every cap raised to its maximum, one call can pay up to 10 USDC (EVM USDC), 10 USDC (Solana USDC) or 1000 JPYC. Keep each cap as low as you need and the wallets small.
93
+
94
+ **Known limitation: a signed authorization can be executed by a third party.** If a prompt steers the agent to call an untrusted `proxyUrl` whose host returns a 402 with the NONAGON LINK treasury as `payTo`, that host can execute the signed EIP-3009 authorization itself. The money can only be sent to the treasury address set in `NONAGON_EVM_PAY_TO`, but you receive no service and no payment record is created; you can lose up to your EVM USDC cap per call. The same applies to a 402 on a listed network NONAGON LINK has not enabled. In both cases the USDC reaches the treasury address, whose key NONAGON LINK holds, so NONAGON LINK can recover it; but without a payment record it cannot be matched to your call automatically, and there is no documented procedure yet for matching such a deposit to you and refunding it. Do not `pay_and_call` URLs you do not trust, and keep `MCP_MAX_PAYMENT_EVM_USDC_CAP` as low as you need. A structural fix (switching to an authorization only the recipient can execute, or matching and refunding such deposits) is tracked separately.
95
+
96
+ `MCP_MAX_PAYMENT_USDC_CAP` and `MCP_MAX_PAYMENT_JPY_CAP` are now validated the same way as the EVM USDC cap: plain decimal notation only (`0.5`, `10`, `300.5`). Exponent (`1e1`), hex, sign, surrounding spaces, `.5` / `5.` and too many fractional digits stop the server at startup with a message saying how to write the value.
97
+
98
+ ### Payment status
99
+
100
+ | `paymentStatus` | Meaning | What to do |
101
+ |---|---|---|
102
+ | `not_paid` | No payment was sent (rejected 402, limit exceeded, not configured, error before signing) | Fix the cause and retry |
103
+ | `paid` | The paid request's response carried a successful receipt (even if the API itself then returned an error) | Retrying is a new payment |
104
+ | `unknown` | A signed payment was sent but the result is not confirmed (timeout, connection loss, error response, missing receipt). The response body is **not** trusted — the host could claim anything | **Do not retry automatically** (a retry signs a new authorization and can pay twice). For EVM payments (JPYC and EVM USDC) the response includes `authorization` (`network`, `asset`, `from`, `nonce`, `validBefore`): call `authorizationState(from, nonce)` on the token contract. It can never execute only after `validBefore` has passed and `authorizationState` is `false`. `reportedTransaction`, if any, is the host's unverified claim |
105
+
106
+ Payments made with the EVM wallet appear in `get_payment_history` / `get_spending` as the `ethereum` wallet. For an EVM payment, **a missing history row does not prove the authorization was not executed** (the server may not have recorded a failed payment, and anyone holding the authorization can execute it): when `paymentStatus` is `unknown`, check `authorizationState` as described above instead of retrying after looking at the history.
18
107
 
19
108
  ## Quick start (Claude Code / Claude Desktop)
20
109
 
@@ -25,28 +114,31 @@ Add to your MCP client config (e.g. `.claude/settings.json` or `claude_desktop_c
25
114
  "mcpServers": {
26
115
  "nonagon-link": {
27
116
  "command": "npx",
28
- "args": ["-y", "--ignore-scripts", "@nonagon-link/mcp@0.2.0"],
117
+ "args": ["-y", "--ignore-scripts", "@nonagon-link/mcp@0.3.0"],
29
118
  "env": {
30
119
  "NONAGON_PRIVATE_KEY": "<Base58 Solana secret key>",
31
- "NONAGON_LINK_BASE_URL": "https://api.nnglink.ai"
120
+ "NONAGON_LINK_BASE_URL": "https://api.nnglink.ai",
121
+ "NONAGON_PAY_TO": "<402 payTo — NONAGON LINK platform wallet>"
32
122
  }
33
123
  }
34
124
  }
35
125
  }
36
126
  ```
37
127
 
38
- > **Always pin an exact version** (`@nonagon-link/mcp@0.2.0`). Never use an unversioned `@nonagon-link/mcp` — your private key is passed to the process environment, so an unpinned install would expose it to whatever the latest published version is. `--ignore-scripts` additionally prevents dependency install scripts from running with your environment.
128
+ > **Always pin an exact version** (`@nonagon-link/mcp@0.3.0`). Never use an unversioned `@nonagon-link/mcp` — your private key is passed to the process environment, so an unpinned install would expose it to whatever the latest published version is. `--ignore-scripts` additionally prevents dependency install scripts from running with your environment.
129
+ >
130
+ > **Set `NONAGON_PAY_TO`** to the NONAGON LINK platform wallet. Obtain the platform wallet from the operator or official docs — do not copy `payTo` from an untrusted 402. Unset = `pay_and_call` denies every payment.
39
131
 
40
132
  For stricter isolation, install once and reference the binary directly:
41
133
 
42
134
  ```bash
43
- npm install -g @nonagon-link/mcp@0.2.0
135
+ npm install -g @nonagon-link/mcp@0.3.0
44
136
  ```
45
137
 
46
138
  ```json
47
139
  {
48
140
  "mcpServers": {
49
- "nonagon-link": { "command": "nonagon-mcp", "env": { "NONAGON_PRIVATE_KEY": "..." } }
141
+ "nonagon-link": { "command": "nonagon-mcp", "env": { "NONAGON_PRIVATE_KEY": "...", "NONAGON_PAY_TO": "<402 payTo>" } }
50
142
  }
51
143
  }
52
144
  ```
@@ -56,15 +148,27 @@ npm install -g @nonagon-link/mcp@0.2.0
56
148
  | Variable | Required | Description |
57
149
  |---|---|---|
58
150
  | `NONAGON_PRIVATE_KEY` | ✅ | Agent's Solana secret key (Base58). Used to sign USDC payments |
59
- | `NONAGON_NETWORK` | — | CAIP-2 network id. Defaults to Solana mainnet |
151
+ | `NONAGON_NETWORK` | — | CAIP-2 network id. Defaults to Solana mainnet. 402 `network` must match |
152
+ | `NONAGON_PAY_TO` | For `pay_and_call` | Comma-separated Solana addresses allowed as 402 `payTo` (platform wallet). **Unset = deny all payments** |
153
+ | `NONAGON_USDC_MINT` | — | Override USDC mint **only for unknown `NONAGON_NETWORK`**. Known mainnet/devnet always use the built-in USDC mint |
154
+ | `MCP_MAX_PAYMENT_USDC_CAP` | — | Raise the `maxPaymentUsdc` (Solana USDC) ceiling (0.1–10, decimal notation, at most 6 decimals). Default 0.100. Does not affect EVM USDC |
155
+ | `NONAGON_EVM_PRIVATE_KEY` | For JPYC / EVM USDC / EVM history | EVM wallet key (`0x` + 64 hex) used to sign EVM payments (JPYC; EVM USDC when `MCP_MAX_PAYMENT_EVM_USDC_CAP` is set) and the EIP-712 `AgentChallenge` that reads the EVM wallet's payment history and spending. Unset = Solana USDC only. Validated at startup; the value is never logged or returned |
156
+ | `NONAGON_EVM_PAY_TO` | For JPYC / EVM USDC | Comma-separated EVM addresses allowed as the EVM 402 `payTo` (NONAGON LINK EVM treasury). **Unset = deny all EVM payments** |
157
+ | `MCP_MAX_PAYMENT_JPY_CAP` | — | Raise the `maxPaymentJpy` ceiling (100–1000, decimal notation, at most 4 decimals). Default 100 |
158
+ | `MCP_MAX_PAYMENT_EVM_USDC_CAP` | For EVM USDC | The `maxPaymentEvmUsdc` ceiling and the switch for EVM USDC (range from the pinned USDC prices of the network family — 2–10 today; decimal notation, at most 6 decimals). **Unset = EVM USDC is never paid**. Requires `NONAGON_NETWORK` to be Solana mainnet or devnet |
60
159
  | `NONAGON_LINK_BASE_URL` | For `search_listings` / `get_payment_history` / `get_spending` | NONAGON LINK API base URL (e.g. `https://api.nnglink.ai`). `https` only; `http` allowed for `localhost` in local development. `pay_and_call` does not require it |
61
160
  | `MCP_AUTH_TOKEN` | HTTP mode only | Bearer token for Streamable HTTP transport (32-byte random, base64url or hex) |
62
161
  | `LOG_LEVEL` | — | pino log level. Defaults to `info` |
63
162
 
64
163
  ## Security notes
65
164
 
66
- - **Use a dedicated wallet with a small balance.** The private key in `env` authorizes real USDC payments. Do not reuse your main wallet.
165
+ - **Payments are USDC on the configured Solana network, plus the official JPYC (TEST_JPYSC on Sepolia) when an EVM wallet is configured, plus EVM USDC only when `MCP_MAX_PAYMENT_EVM_USDC_CAP` is also set.** Set `NONAGON_PAY_TO` (and `NONAGON_EVM_PAY_TO` for EVM payments) to the NONAGON LINK wallets or `pay_and_call` will refuse the 402.
166
+ - **Use dedicated wallets with small balances.** The private keys in `env` authorize real payments. Do not reuse your main wallets. In HTTP mode every client shares the server's wallets.
167
+ - **A signed EVM authorization (JPYC or EVM USDC) can be executed by whoever receives it.** EIP-3009 `transferWithAuthorization` does not restrict who submits it, so the host you call (any HTTPS host) or anyone who sees the authorization can execute it on-chain without NONAGON LINK. The recipient is fixed to your `NONAGON_EVM_PAY_TO` allow-list (the NONAGON LINK treasury), so funds can only move there — but in that case no service is delivered and no payment record is created. This is a known limitation; keep the EVM wallet balance small, and when `paymentStatus` is `unknown` use `authorization` to check on-chain whether it was executed.
168
+ - Values made by the host you call (rejection reasons, error messages, receipt claims, response headers) and by providers (listing and OpenAPI text) are returned with control characters and invisible characters removed (bidi controls, zero-width characters, Unicode tag characters, variation selectors and other default-ignorable characters, line/paragraph separators) and cut to a length limit. The API response body itself (`data` / `details`) is returned unchanged.
169
+ - The signing libraries (`viem`, `@x402/*` including `@x402/core`, `@solana/kit`, and the `@solana-program/*` packages that `@x402/svm` uses) are declared as exact versions, the same versions the `.mcpb` bundle ships. This holds for a standalone install (`npx` / `-g`).
67
170
  - The private key is never written to logs; log output is redacted and URLs are masked. Access tokens are only ever shown masked.
171
+ - **Set `NONAGON_LINK_BASE_URL` only to the official NONAGON LINK URL.** The agent challenge is unauthenticated, so a malicious base URL could have this server sign a nonce it obtained from the real server and get an agent token for your wallet (read your payment history, post ratings — not pay). This applies to the Solana and the EVM wallet alike. When an EVM key is set and the base URL host is neither `nnglink.ai` (or a subdomain) nor `localhost` / `127.0.0.1`, the server logs a one-line warning at startup (host only; the key is never printed).
68
172
  - stdio transport is the default and recommended mode. HTTP mode (`--transport http`) binds to `127.0.0.1` only and requires `MCP_AUTH_TOKEN`.
69
173
  - The MCP `serverInfo.version` reported over the protocol is independent of this npm package's version.
70
174