@nonagon-link/mcp 0.3.1 → 0.3.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
@@ -54,7 +54,7 @@ Use `currency` together with `maxPrice` to set a budget; the tool rejects an unq
54
54
 
55
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). It works only when `NONAGON_NETWORK` is Solana mainnet or devnet, which selects the EVM networks in the table above; with any other network the server refuses to start.
56
56
  2. Set `NONAGON_EVM_PAY_TO` to the NONAGON LINK EVM treasury (see [NONAGON LINK payees](#nonagon-link-payees) — 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` (100–1000; below 100 the server does not start). Polygon JPYC listings start at 10 and Ethereum JPYC listings start at 300, so Ethereum ones need a cap of 300 or more.
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` (100–1000; below 100 the server does not start). Polygon JPYC listings start at 1 and Ethereum JPYC listings start at 300, so Ethereum ones need a cap of 300 or more. Payments from 1 Polygon JPYC are supported from 0.3.2; 0.3.1 and earlier require at least 10.
58
58
 
59
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
60
 
@@ -97,11 +97,22 @@ The cap is checked again right before signing, so a call that bypasses the tool'
97
97
 
98
98
  ### Payment status
99
99
 
100
+ NONAGON LINK can reject an unsigned request before issuing a nonce: payment-option policy is checked first (`409 PAYMENT_OPTION_DISABLED` / `503 PAYMENT_OPTIONS_UNAVAILABLE`), then EVM native readiness. Gas uses POL on Polygon or ETH on Ethereum / Base, separately from USDC / JPYC. A readiness snapshot does not reserve a USD budget or guarantee a later settlement.
101
+
102
+ | HTTP | Code | Fixed message |
103
+ |---|---|---|
104
+ | 503 | `EVM_NATIVE_BALANCE_INSUFFICIENT` | Native gas balance is insufficient |
105
+ | 503 | `EVM_NATIVE_READINESS_UNAVAILABLE` | Native gas readiness is unavailable |
106
+ | 503 | `EVM_GAS_LIMIT_EXCEEDED` | Estimated gas exceeds the supported limit |
107
+ | 503 | `EVM_TRANSACTION_ESTIMATE_UNAVAILABLE` | Gas estimation is unavailable |
108
+
109
+ Existing `GAS_LIMIT_EXCEEDED` is the USD per-transaction cap, distinct from the EVM gas quantity limit. `GAS_ESTIMATE_UNAVAILABLE`, `DAILY_GAS_CAP`, `GAS_BUDGET_UNAVAILABLE`, `TX_TIMEOUT`, `TX_FAILED` and `EVM_SETTLE_FAILED` remain. The MCP classifies a request that sent no signed payment as `not_paid`; after submission it does not infer non-payment from any HTTP status or error code, including these 503 errors.
110
+
100
111
  | `paymentStatus` | Meaning | What to do |
101
112
  |---|---|---|
102
113
  | `not_paid` | No payment was sent (rejected 402, limit exceeded, not configured, error before signing) | Fix the cause and retry |
103
114
  | `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 |
115
+ | `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: independently check its receipt on the saved network and require `transactionHash` to equal the requested hash before reading status. A missing / different-hash receipt does not prove non-payment. Keep the original authorization lookup fields and check again after `validBefore`; a false state before expiry is insufficient. Do not reuse the authorization or automatically create another payment |
105
116
 
106
117
  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.
107
118
 
@@ -114,7 +125,7 @@ Add to your MCP client config (e.g. `.claude/settings.json` or `claude_desktop_c
114
125
  "mcpServers": {
115
126
  "nonagon-link": {
116
127
  "command": "npx",
117
- "args": ["-y", "--ignore-scripts", "@nonagon-link/mcp@0.3.1"],
128
+ "args": ["-y", "--ignore-scripts", "@nonagon-link/mcp@0.3.2"],
118
129
  "env": {
119
130
  "NONAGON_PRIVATE_KEY": "<Base58 Solana secret key>",
120
131
  "NONAGON_LINK_BASE_URL": "https://api.nnglink.ai",
@@ -125,7 +136,7 @@ Add to your MCP client config (e.g. `.claude/settings.json` or `claude_desktop_c
125
136
  }
126
137
  ```
127
138
 
128
- > **Always pin an exact version** (`@nonagon-link/mcp@0.3.1`). 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.
139
+ > **Always pin an exact version** (`@nonagon-link/mcp@0.3.2`). 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
140
  >
130
141
  > **Set `NONAGON_PAY_TO`** to the NONAGON LINK Solana platform wallet (see [NONAGON LINK payees](#nonagon-link-payees)) — do not copy `payTo` from an untrusted 402. Unset = every **Solana USDC** payment is refused. EVM payments (JPYC, EVM USDC) are allowed separately by `NONAGON_EVM_PAY_TO`; unset, every EVM payment is refused.
131
142
 
@@ -143,7 +154,7 @@ The current values are also listed at https://nnglink.ai/docs/mcp.
143
154
  For stricter isolation, install once and reference the binary directly:
144
155
 
145
156
  ```bash
146
- npm install -g @nonagon-link/mcp@0.3.1
157
+ npm install -g @nonagon-link/mcp@0.3.2
147
158
  ```
148
159
 
149
160
  ```json
package/dist/server.js CHANGED
@@ -74,11 +74,11 @@ var YEN_TOKEN_FULL_RANGE = {
74
74
  listingPriceRange: [0.1, 1e3]
75
75
  };
76
76
  var JPYC_POLYGON_RANGE = {
77
- minAmount: 10000000000000000000n,
78
- // 10 JPYC
77
+ minAmount: 1000000000000000000n,
78
+ // 1 JPYC
79
79
  maxAmount: 1000000000000000000000n,
80
80
  // 1000 JPYC
81
- listingPriceRange: [10, 1e3],
81
+ listingPriceRange: [1, 1e3],
82
82
  recordableAmountRange: [0.1, 1e3]
83
83
  };
84
84
  var JPYC_ETH_MAINNET_RANGE = {
@@ -90,7 +90,9 @@ var JPYC_ETH_MAINNET_RANGE = {
90
90
  };
91
91
  var MAINNET_JPYC_ADDRESS = "0xe7c3d8c9a439fede00d2600032d5db0be71c3c29";
92
92
  var SEPOLIA_TEST_JPYSC_ADDRESS = "0x307cba674f0fe9a5a5b084dd58006eb604a24025";
93
- var JPYC_OFFICIAL_EVIDENCE = "issue #1705 \u8981\u4EF6\u4ED8\u9332 A (2026-07-15 \u30AA\u30F3\u30C1\u30A7\u30FC\u30F3\u691C\u8A3C: impl 0xafac17fc..d2e \u306B EIP-3009 selector e3ee160e \u5B9F\u5728 / name=JPY Coin / decimals=18)\u3002domain version \u306F PR2 \u5B9F\u8A3C\u78BA\u5B9A\u30BF\u30B9\u30AF\u3067 tx hash \u306B\u66F4\u65B0";
93
+ var JPYC_APPENDIX_A_EVIDENCE = "issue #1705 \u8981\u4EF6\u4ED8\u9332 A (2026-07-15 \u30AA\u30F3\u30C1\u30A7\u30FC\u30F3\u691C\u8A3C: impl 0xafac17fc..d2e \u306B EIP-3009 selector e3ee160e \u5B9F\u5728 / name=JPY Coin / decimals=18)";
94
+ var JPYC_ETH_MAINNET_EVIDENCE = `${JPYC_APPENDIX_A_EVIDENCE}\u3002domain version \u306F Ethereum mainnet \u306E\u5B9F tx \u3067\u672A\u89B3\u6E2C`;
95
+ var JPYC_POLYGON_EVIDENCE = `${JPYC_APPENDIX_A_EVIDENCE}\u3002domain { JPY Coin, 1 } \u306F 2026-10-05 \u672C\u756A Polygon \u5B9F tx 0xb8e87e92c2000b7922aa115f14b7a0aaf7a1699444d6ecd15a8ab50801f086b4 (block 94995641, transferWithAuthorization \u6210\u529F / 10 JPYC / issue #2056) \u3067\u5B9F\u8A3C`;
94
96
  var EVM_ASSET_PINS = {
95
97
  "eip155:1": {
96
98
  usdc: {
@@ -106,7 +108,7 @@ var EVM_ASSET_PINS = {
106
108
  eip712: { name: "JPY Coin", version: "1" },
107
109
  decimals: 18,
108
110
  currency: "JPYC",
109
- pinEvidence: JPYC_OFFICIAL_EVIDENCE,
111
+ pinEvidence: JPYC_ETH_MAINNET_EVIDENCE,
110
112
  ...JPYC_ETH_MAINNET_RANGE
111
113
  }
112
114
  },
@@ -142,7 +144,7 @@ var EVM_ASSET_PINS = {
142
144
  eip712: { name: "JPY Coin", version: "1" },
143
145
  decimals: 18,
144
146
  currency: "JPYC",
145
- pinEvidence: JPYC_OFFICIAL_EVIDENCE,
147
+ pinEvidence: JPYC_POLYGON_EVIDENCE,
146
148
  ...JPYC_POLYGON_RANGE
147
149
  }
148
150
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonagon-link/mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "NONAGON LINK MCP server — let AI agents discover and pay for APIs with USDC (x402)",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",