mpp32-mcp-server 1.2.3 → 1.2.4
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/CHANGELOG.md +15 -0
- package/README.md +55 -26
- package/dist/index.js +1 -1
- package/dist/x402-signers.js +20 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ All notable changes to `mpp32-mcp-server` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.2.4] - 2026-05-11
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
* **Self-payment now fails fast with a useful error.** When the wallet
|
|
12
|
+
derived from `MPP32_SOLANA_PRIVATE_KEY` (or `MPP32_PRIVATE_KEY`) is the
|
|
13
|
+
same address as a challenge's `payTo`, the signer used to construct the
|
|
14
|
+
transaction anyway and the facilitator surfaced an opaque "transaction
|
|
15
|
+
failed simulation" error a few seconds later. Both the SVM and EVM
|
|
16
|
+
signers now detect this case before signing and return:
|
|
17
|
+
`Refusing to sign an x402 payment to yourself: the wallet derived from
|
|
18
|
+
MPP32_SOLANA_PRIVATE_KEY (<addr>) is also the payment recipient (payTo)
|
|
19
|
+
for this service.` This happens most often when an operator uses their
|
|
20
|
+
own receiving wallet to test a paid endpoint they themselves run.
|
|
21
|
+
|
|
7
22
|
## [1.2.3] - 2026-05-11
|
|
8
23
|
|
|
9
24
|
### Fixed
|
package/README.md
CHANGED
|
@@ -9,7 +9,18 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
One install.
|
|
12
|
+
One install. Pay any x402 endpoint on Solana from your agent. Browse a federated index of thousands of machine payable APIs without setting up a single provider account.
|
|
13
|
+
|
|
14
|
+
## What works today
|
|
15
|
+
|
|
16
|
+
| Rail | Status | Network | Asset |
|
|
17
|
+
|:-----|:-------|:--------|:------|
|
|
18
|
+
| x402 | Production | Solana (mainnet) | USDC |
|
|
19
|
+
| x402 | Production | Base | USDC |
|
|
20
|
+
| Tempo | Envelope wired, gated off in production until the client flow is verified end to end | Ethereum L2 | pathUSD |
|
|
21
|
+
| ACP / AP2 / AGTP | Envelopes wired, gated off in production | Multi chain | per protocol |
|
|
22
|
+
|
|
23
|
+
The MCP server ships signers for both Solana and Base out of the box. When a paid call returns a 402, the server picks the network that matches the key you configured and settles the payment in one round trip.
|
|
13
24
|
|
|
14
25
|
## Why this beats running your own integrations
|
|
15
26
|
|
|
@@ -25,22 +36,10 @@ MPP32 replaces all of that with one MCP server. Your agent asks for a service by
|
|
|
25
36
|
* Track every call, every dollar settled, and every protocol used from a dashboard at mpp32.org.
|
|
26
37
|
* Get an automatic 20 percent or 40 percent discount on native services for holding M32 once your wallet is verified.
|
|
27
38
|
|
|
28
|
-
## Payment rails it speaks natively
|
|
29
|
-
|
|
30
|
-
| Rail | Settles in | Network |
|
|
31
|
-
|:-----|:-----------|:--------|
|
|
32
|
-
| x402 | USDC | Solana |
|
|
33
|
-
| Tempo | pathUSD | Ethereum L2 |
|
|
34
|
-
| ACP | Checkout session | Multi chain |
|
|
35
|
-
| AP2 | W3C verifiable credentials | Chain agnostic |
|
|
36
|
-
| AGTP | HMAC signed agent certificates | Chain agnostic |
|
|
37
|
-
|
|
38
|
-
Every native endpoint accepts all five. The server picks whichever your wallet is funded for and falls back gracefully if the first attempt fails.
|
|
39
|
-
|
|
40
39
|
## Install
|
|
41
40
|
|
|
42
41
|
```bash
|
|
43
|
-
npx mpp32-mcp-server
|
|
42
|
+
npx -y mpp32-mcp-server@latest
|
|
44
43
|
```
|
|
45
44
|
|
|
46
45
|
### Claude Desktop, Claude Code, Cursor, Windsurf
|
|
@@ -52,30 +51,56 @@ Drop this into the MCP servers section of your client config.
|
|
|
52
51
|
"mcpServers": {
|
|
53
52
|
"mpp32": {
|
|
54
53
|
"command": "npx",
|
|
55
|
-
"args": ["mpp32-mcp-server"],
|
|
54
|
+
"args": ["-y", "mpp32-mcp-server@latest"],
|
|
56
55
|
"env": {
|
|
57
56
|
"MPP32_AGENT_KEY": "mpp32_agent_…",
|
|
58
|
-
"MPP32_SOLANA_PRIVATE_KEY": "
|
|
57
|
+
"MPP32_SOLANA_PRIVATE_KEY": "<your base58 Solana secret key>"
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
Config file locations:
|
|
65
|
+
|
|
66
|
+
* **Claude Desktop (macOS):** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
67
|
+
* **Claude Desktop (Windows):** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
68
|
+
* **Cursor:** `~/.cursor/mcp.json`
|
|
69
|
+
* **Windsurf:** `~/.codeium/windsurf/mcp_config.json`
|
|
70
|
+
|
|
71
|
+
Fully quit and reopen the client after editing. The MCP child process inherits env vars from this file at launch.
|
|
72
|
+
|
|
73
|
+
Get an `MPP32_AGENT_KEY` at [mpp32.org/agent-console](https://mpp32.org/agent-console). No signup, no email, just click **Create Agent Session** and the form returns a key plus this exact config snippet ready to copy. With an agent key every call is attributed to your dashboard so you can see spend, success rate, and protocol breakdown. Without it the server still works but you only see native services and the calls stay anonymous.
|
|
74
|
+
|
|
75
|
+
`MPP32_SOLANA_PRIVATE_KEY` is only needed for paid services. Free services in the catalog work without any payment key.
|
|
76
|
+
|
|
77
|
+
### What format does `MPP32_SOLANA_PRIVATE_KEY` take?
|
|
78
|
+
|
|
79
|
+
A base58 encoded 64 byte Solana secret key. The same string that Phantom shows under **export private key** (not the seed phrase). If you have a `keypair.json` (the 64 byte array Solana CLI uses), convert it once with:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
node -e "console.log(require('bs58').encode(Buffer.from(JSON.parse(require('fs').readFileSync('keypair.json')))))"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Then paste the resulting string into the env block. Treat it like a password. It can spend any USDC and SOL in the wallet.
|
|
86
|
+
|
|
87
|
+
### Fund the wallet with both USDC and SOL
|
|
88
|
+
|
|
89
|
+
x402 settles the payment in USDC, but Solana itself charges a tiny native SOL fee on every transaction. A USDC only wallet will fail with `insufficient funds for rent` even though the USDC balance is plentiful. About `0.001 SOL` covers many calls.
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
Tip: call the `get_mpp32_diagnostics` tool from inside Claude. It probes the API, reports which env vars actually reached the MCP process, and prints `Ready to pay: YES` once everything is wired.
|
|
68
92
|
|
|
69
93
|
## Configuration
|
|
70
94
|
|
|
71
95
|
| Variable | When you need it | What it does |
|
|
72
96
|
|:---------|:-----------------|:-------------|
|
|
73
97
|
| `MPP32_AGENT_KEY` | Recommended | Session key from mpp32.org/agent-console. Unlocks the full federated catalog and dashboard tracking. Also accepted as `MPP32_API_KEY`. |
|
|
74
|
-
| `MPP32_SOLANA_PRIVATE_KEY` | Paid x402 calls | Solana key
|
|
75
|
-
| `MPP32_PRIVATE_KEY` | Paid
|
|
98
|
+
| `MPP32_SOLANA_PRIVATE_KEY` | Paid x402 calls on Solana | Base58 encoded Solana secret key. Used to sign USDC payments locally. Never leaves your machine. |
|
|
99
|
+
| `MPP32_PRIVATE_KEY` | Paid x402 calls on Base | 0x prefixed EVM private key. Used to sign USDC payments on Base when a provider only accepts EVM. |
|
|
100
|
+
| `MPP32_PREFERRED_NETWORK` | Optional override | When both keys are configured and the challenge advertises multiple networks, force one. Accepts `solana`, `base`, `evm`, or a full CAIP-2 string. |
|
|
76
101
|
| `MPP32_API_URL` | Custom deployments | Override the API base URL. Defaults to `https://mpp32.org`. |
|
|
77
102
|
|
|
78
|
-
Private keys stay on your machine. They sign payments locally and never travel to MPP32 servers. Provide
|
|
103
|
+
Private keys stay on your machine. They sign payments locally and never travel to MPP32 servers. Provide either or both for paid calls. If both are present and a challenge advertises both networks, EVM is preferred unless `MPP32_PREFERRED_NETWORK` is set; if only one key is configured, that network wins automatically.
|
|
79
104
|
|
|
80
105
|
## Tools your agent will see
|
|
81
106
|
|
|
@@ -111,15 +136,19 @@ Under the hood:
|
|
|
111
136
|
|
|
112
137
|
No payment logic in your code. No per provider keys to juggle.
|
|
113
138
|
|
|
139
|
+
### `get_mpp32_diagnostics`
|
|
140
|
+
|
|
141
|
+
Reports the MCP server version, which env vars actually reached the child process, the API URL it will hit, and a live API reachability probe. Prints `Ready to pay: YES` only when an agent key plus at least one signing key are detected and the API is reachable. Call this first if anything misbehaves. Also available as `debug_mpp32`.
|
|
142
|
+
|
|
114
143
|
### `get_solana_token_intelligence`
|
|
115
144
|
|
|
116
|
-
Real time analysis of any Solana token. Pulls live data from DexScreener, Jupiter, and CoinGecko and merges it into one report. Returns an alpha score from 0 to 100, rug risk, whale activity, smart money signals, 24 hour pump probability, projected ROI ranges, and full market data. Costs $0.008 per call, paid automatically through x402
|
|
145
|
+
Real time analysis of any Solana token. Pulls live data from DexScreener, Jupiter, and CoinGecko and merges it into one report. Returns an alpha score from 0 to 100, rug risk, whale activity, smart money signals, 24 hour pump probability, projected ROI ranges, and full market data. Costs $0.008 per call, paid automatically through x402 when a Solana key is set.
|
|
117
146
|
|
|
118
147
|
```json
|
|
119
148
|
{ "token": "BONK" }
|
|
120
149
|
```
|
|
121
150
|
|
|
122
|
-
M32 holders get tiered discounts (20 percent at 250k, 40 percent at 1M)
|
|
151
|
+
M32 holders will get tiered discounts (20 percent at 250k, 40 percent at 1M) once SIWS wallet signature verification ships. The discount path is gated off in production until then so it cannot be claimed by spoofing a wallet header.
|
|
123
152
|
|
|
124
153
|
## How discovery works
|
|
125
154
|
|
|
@@ -147,13 +176,13 @@ Sessions are scoped, revocable, and rotate cleanly. The key is hashed at rest on
|
|
|
147
176
|
|
|
148
177
|
## How payment verification actually works
|
|
149
178
|
|
|
150
|
-
x402 payments are verified on chain through the Solana facilitator
|
|
179
|
+
x402 payments are verified on chain through the Solana facilitator (for SVM) or the Base facilitator (for EVM). MPP32 never holds custody of funds. Every paid call settles directly from the caller's wallet to the provider's wallet.
|
|
151
180
|
|
|
152
|
-
|
|
181
|
+
Tempo, ACP, AP2, and AGTP envelopes are implemented in the proxy and tested against synthetic challenges, but the corresponding client signing flows are not yet exposed by this MCP. Those rails stay disabled in production until each has a verified end to end client flow. Treat the catalog as an x402 catalog today; the rest will light up as their clients land.
|
|
153
182
|
|
|
154
183
|
## For API providers
|
|
155
184
|
|
|
156
|
-
List your endpoint once and
|
|
185
|
+
List your endpoint once and receive payment over x402. MPP32 handles the payment negotiation, the on chain verification, the discovery listings via OpenAPI and A2A and MCP standards, the periodic health re check, and the analytics dashboard. Settlement lands in USDC on Solana or Base straight to your wallet.
|
|
157
186
|
|
|
158
187
|
Register at [mpp32.org/build](https://mpp32.org/build).
|
|
159
188
|
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { signX402Payment } from "./x402-signers.js";
|
|
6
|
-
const SERVER_VERSION = "1.2.
|
|
6
|
+
const SERVER_VERSION = "1.2.4";
|
|
7
7
|
// ── Env loading: trim and sanitize aggressively ─────────────────────────────
|
|
8
8
|
// Copy-paste from Claude Desktop / Cursor / Windsurf JSON config UIs frequently
|
|
9
9
|
// adds trailing \n, \r, NBSP, BOM, or wraps the value in literal quotes. Any
|
package/dist/x402-signers.js
CHANGED
|
@@ -129,6 +129,18 @@ export async function signX402PaymentSvm(requirements, rawKey, rpcUrlOverride, e
|
|
|
129
129
|
const mintAddress = deps.address(requirements.asset);
|
|
130
130
|
const recipientAddress = deps.address(requirements.payTo);
|
|
131
131
|
const feePayerAddress = deps.address(requirements.extra.feePayer);
|
|
132
|
+
// Self-payment guard. An SPL TransferChecked where source ATA == destination
|
|
133
|
+
// ATA is a no-op the Solana runtime rejects, and the resulting facilitator
|
|
134
|
+
// error is opaque ("transaction failed simulation"). This usually means the
|
|
135
|
+
// user configured the same wallet as both their MPP32_SOLANA_PRIVATE_KEY and
|
|
136
|
+
// the upstream payTo (e.g. calling their own listed service, or testing
|
|
137
|
+
// against the MPP32 oracle from the operator wallet). Catch it here with a
|
|
138
|
+
// clear, actionable message before we burn an RPC round-trip.
|
|
139
|
+
if (String(payerAddress) === String(recipientAddress)) {
|
|
140
|
+
throw new Error(`Refusing to sign an x402 payment to yourself: the wallet derived from MPP32_SOLANA_PRIVATE_KEY ` +
|
|
141
|
+
`(${String(payerAddress)}) is also the payment recipient (payTo) for this service. ` +
|
|
142
|
+
`Use a different wallet to call this endpoint, or fund a separate payer key.`);
|
|
143
|
+
}
|
|
132
144
|
// Derive both sides' associated token accounts (classic SPL Token program).
|
|
133
145
|
const [sourceAtaTuple, destinationAtaTuple] = await Promise.all([
|
|
134
146
|
deps.findAssociatedTokenPda({
|
|
@@ -203,6 +215,14 @@ export async function signX402PaymentEvm(requirements, rawKey, echoedVersion = 1
|
|
|
203
215
|
}
|
|
204
216
|
const { privateKeyToAccount } = await loadEvmDeps();
|
|
205
217
|
const account = privateKeyToAccount(keyHex);
|
|
218
|
+
// Self-payment guard (EVM). EIP-3009 transferWithAuthorization with
|
|
219
|
+
// from == to is rejected on-chain by USDC. Surfacing this here keeps the
|
|
220
|
+
// error message useful instead of an opaque facilitator failure.
|
|
221
|
+
if (account.address.toLowerCase() === recipientAddr.toLowerCase()) {
|
|
222
|
+
throw new Error(`Refusing to sign an x402 payment to yourself: the wallet derived from MPP32_PRIVATE_KEY ` +
|
|
223
|
+
`(${account.address}) is also the payment recipient (payTo) for this service. ` +
|
|
224
|
+
`Use a different wallet to call this endpoint, or fund a separate payer key.`);
|
|
225
|
+
}
|
|
206
226
|
const now = Math.floor(Date.now() / 1000);
|
|
207
227
|
const validAfter = BigInt(0);
|
|
208
228
|
const validBefore = BigInt(now + (requirements.maxTimeoutSeconds ?? 600));
|
package/package.json
CHANGED