@nonagon-link/mcp 0.3.0 → 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 +39 -17
- package/dist/server.js +8 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @nonagon-link/mcp
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) server for [NONAGON LINK](https://
|
|
3
|
+
MCP (Model Context Protocol) server for [NONAGON LINK](https://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
|
|
|
@@ -52,9 +52,9 @@ Use `currency` together with `maxPrice` to set a budget; the tool rejects an unq
|
|
|
52
52
|
| Solana mainnet | Polygon (`eip155:137`), Ethereum (`eip155:1`) | JPYC |
|
|
53
53
|
| Solana devnet | Sepolia (`eip155:11155111`) | TEST_JPYSC (test token) |
|
|
54
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 (
|
|
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` (
|
|
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
|
+
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 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,31 +125,42 @@ 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.
|
|
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",
|
|
121
|
-
"NONAGON_PAY_TO": "
|
|
132
|
+
"NONAGON_PAY_TO": "8yXpNyyPg9iGdMST8BRyz7HEJVbQG81VP6kHBCKXrdH8"
|
|
122
133
|
}
|
|
123
134
|
}
|
|
124
135
|
}
|
|
125
136
|
}
|
|
126
137
|
```
|
|
127
138
|
|
|
128
|
-
> **Always pin an exact version** (`@nonagon-link/mcp@0.3.
|
|
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
|
-
> **Set `NONAGON_PAY_TO`** to the NONAGON LINK
|
|
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.
|
|
142
|
+
|
|
143
|
+
### NONAGON LINK payees
|
|
144
|
+
|
|
145
|
+
The `payTo` values NONAGON LINK uses (public: they appear in every 402). Put them in the allow-lists:
|
|
146
|
+
|
|
147
|
+
| Environment | `NONAGON_PAY_TO` (Solana USDC) | `NONAGON_EVM_PAY_TO` (JPYC / EVM USDC) |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| Production (Solana mainnet; Ethereum / Polygon / Base) | `8yXpNyyPg9iGdMST8BRyz7HEJVbQG81VP6kHBCKXrdH8` | `0x7b689c9b29e5e51700f19d4bb02b382fb418f34d` |
|
|
150
|
+
| Testing (Solana devnet; Sepolia / Amoy / Base Sepolia) | `6JdW8xNvXrghY7acKXzMn2pJoK88g6nnAVU3YNo1YiF8` | `0xcaeb3ef5dcea1557765323379a292fc6b4011831` |
|
|
151
|
+
|
|
152
|
+
The current values are also listed at https://nnglink.ai/docs/mcp.
|
|
131
153
|
|
|
132
154
|
For stricter isolation, install once and reference the binary directly:
|
|
133
155
|
|
|
134
156
|
```bash
|
|
135
|
-
npm install -g @nonagon-link/mcp@0.3.
|
|
157
|
+
npm install -g @nonagon-link/mcp@0.3.2
|
|
136
158
|
```
|
|
137
159
|
|
|
138
160
|
```json
|
|
139
161
|
{
|
|
140
162
|
"mcpServers": {
|
|
141
|
-
"nonagon-link": { "command": "nonagon-mcp", "env": { "NONAGON_PRIVATE_KEY": "...", "NONAGON_PAY_TO": "
|
|
163
|
+
"nonagon-link": { "command": "nonagon-mcp", "env": { "NONAGON_PRIVATE_KEY": "...", "NONAGON_PAY_TO": "8yXpNyyPg9iGdMST8BRyz7HEJVbQG81VP6kHBCKXrdH8" } }
|
|
142
164
|
}
|
|
143
165
|
}
|
|
144
166
|
```
|
|
@@ -149,12 +171,12 @@ npm install -g @nonagon-link/mcp@0.3.0
|
|
|
149
171
|
|---|---|---|
|
|
150
172
|
| `NONAGON_PRIVATE_KEY` | ✅ | Agent's Solana secret key (Base58). Used to sign USDC payments |
|
|
151
173
|
| `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 =
|
|
174
|
+
| `NONAGON_PAY_TO` | For Solana `pay_and_call` | Comma-separated Solana addresses allowed as 402 `payTo` (platform wallet). **Unset = every Solana USDC payment is refused** (EVM payments are governed by `NONAGON_EVM_PAY_TO`) |
|
|
153
175
|
| `NONAGON_USDC_MINT` | — | Override USDC mint **only for unknown `NONAGON_NETWORK`**. Known mainnet/devnet always use the built-in USDC mint |
|
|
154
176
|
| `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 =
|
|
157
|
-
| `MCP_MAX_PAYMENT_JPY_CAP` | — | Raise the `maxPaymentJpy` ceiling (100–1000, decimal notation, at most 4 decimals). Default 100 |
|
|
177
|
+
| `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. Requires `NONAGON_NETWORK` to be Solana mainnet or devnet (otherwise the server refuses to start). Validated at startup; the value is never logged or returned |
|
|
178
|
+
| `NONAGON_EVM_PAY_TO` | For JPYC / EVM USDC | Comma-separated EVM addresses allowed as the EVM 402 `payTo` (NONAGON LINK EVM treasury). **Unset = every EVM payment is refused** (Solana USDC payments are governed by `NONAGON_PAY_TO`) |
|
|
179
|
+
| `MCP_MAX_PAYMENT_JPY_CAP` | — | Raise the `maxPaymentJpy` ceiling (100–1000, decimal notation, at most 4 decimals; below 100 the server does not start). Default 100. Ethereum JPYC listings need 300 or more |
|
|
158
180
|
| `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 |
|
|
159
181
|
| `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 |
|
|
160
182
|
| `MCP_AUTH_TOKEN` | HTTP mode only | Bearer token for Streamable HTTP transport (32-byte random, base64url or hex) |
|
|
@@ -174,8 +196,8 @@ npm install -g @nonagon-link/mcp@0.3.0
|
|
|
174
196
|
|
|
175
197
|
## Documentation
|
|
176
198
|
|
|
177
|
-
- Setup & verification guide: https://
|
|
178
|
-
- Agent developer guide: https://
|
|
199
|
+
- Setup & verification guide: https://nnglink.ai/docs/mcp
|
|
200
|
+
- Agent developer guide: https://nnglink.ai/docs/agent
|
|
179
201
|
|
|
180
202
|
## License
|
|
181
203
|
|
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:
|
|
78
|
-
//
|
|
77
|
+
minAmount: 1000000000000000000n,
|
|
78
|
+
// 1 JPYC
|
|
79
79
|
maxAmount: 1000000000000000000000n,
|
|
80
80
|
// 1000 JPYC
|
|
81
|
-
listingPriceRange: [
|
|
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
|
|
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:
|
|
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:
|
|
147
|
+
pinEvidence: JPYC_POLYGON_EVIDENCE,
|
|
146
148
|
...JPYC_POLYGON_RANGE
|
|
147
149
|
}
|
|
148
150
|
},
|