@moonpay/cli 0.3.3 → 0.3.5

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.
@@ -0,0 +1,208 @@
1
+ import { createRequire as __createRequire } from "module"; const require = __createRequire(import.meta.url);
2
+ import {
3
+ callTool,
4
+ createTool,
5
+ defineToolSchema,
6
+ loadWallet,
7
+ messageSign,
8
+ resolveBaseUrl,
9
+ schemas_default,
10
+ transactionSign,
11
+ walletCreate,
12
+ walletDelete,
13
+ walletImport,
14
+ walletList,
15
+ walletRetrieve
16
+ } from "./chunk-SQTD2GMD.js";
17
+
18
+ // src/mcp.ts
19
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
20
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
+
22
+ // src/tools/x402/request/tool.ts
23
+ import { Keypair, VersionedTransaction, VersionedMessage } from "@solana/web3.js";
24
+ import bs58 from "bs58";
25
+ import axios from "axios";
26
+ import { wrapAxiosWithPayment } from "@x402/axios";
27
+ import { x402Client } from "@x402/core/client";
28
+ import { ExactSvmScheme } from "@x402/svm";
29
+
30
+ // src/tools/x402/request/schema.ts
31
+ import { z } from "zod";
32
+ var x402RequestSchema = defineToolSchema({
33
+ name: "x402_request",
34
+ description: "Make an HTTP request to an x402-protected endpoint. Automatically handles payment when a 402 Payment Required response is received, signing the payment transaction with the local wallet.",
35
+ input: z.object({
36
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
37
+ url: z.string().url().describe(
38
+ "Full URL of the x402-protected endpoint (e.g., 'https://agents.moonpay.com/api/x402/tools/market_digest_retrieve')"
39
+ ),
40
+ body: z.record(z.any()).nullable().describe("Request body (for POST, PUT, PATCH)"),
41
+ params: z.record(z.any()).nullable().describe("Query parameters"),
42
+ wallet: z.string().describe("Wallet name or address to pay with")
43
+ }),
44
+ output: z.object({
45
+ status: z.number().describe("HTTP status code"),
46
+ data: z.any().describe("Response data"),
47
+ headers: z.record(z.string()).describe("Response headers")
48
+ })
49
+ });
50
+
51
+ // src/tools/x402/request/tool.ts
52
+ var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
53
+ function createLocalX402Client(walletAddress, secretKey) {
54
+ const keypair = Keypair.fromSecretKey(bs58.decode(secretKey));
55
+ const signer = {
56
+ address: walletAddress,
57
+ signTransactions: async (transactions) => {
58
+ return transactions.map((transaction) => {
59
+ const messageBytes = new Uint8Array(transaction.messageBytes);
60
+ const message = VersionedMessage.deserialize(messageBytes);
61
+ const numSigs = Object.keys(transaction.signatures).length;
62
+ const tx = new VersionedTransaction(
63
+ message,
64
+ new Array(numSigs).fill(new Uint8Array(64))
65
+ );
66
+ tx.sign([keypair]);
67
+ const signerIndex = message.staticAccountKeys.findIndex(
68
+ (key) => key.toBase58() === walletAddress
69
+ );
70
+ if (signerIndex === -1) {
71
+ throw new Error(
72
+ `Wallet ${walletAddress} is not a signer for this transaction`
73
+ );
74
+ }
75
+ return {
76
+ [walletAddress]: tx.signatures[signerIndex]
77
+ };
78
+ });
79
+ }
80
+ };
81
+ const client = new x402Client();
82
+ const svmScheme = new ExactSvmScheme(signer);
83
+ client.register(SOLANA_NETWORK, svmScheme);
84
+ client.registerV1("solana", svmScheme);
85
+ return wrapAxiosWithPayment(axios.create(), client);
86
+ }
87
+ var x402Request = createTool(
88
+ x402RequestSchema,
89
+ async ({ method, url, body, params, wallet: walletNameOrAddress }) => {
90
+ const storedWallet = loadWallet(walletNameOrAddress);
91
+ const client = createLocalX402Client(
92
+ storedWallet.address,
93
+ storedWallet.secretKey
94
+ );
95
+ let response;
96
+ switch (method) {
97
+ case "GET":
98
+ response = await client.get(url, { params });
99
+ break;
100
+ case "POST":
101
+ response = await client.post(url, body || {}, { params });
102
+ break;
103
+ case "PUT":
104
+ response = await client.put(url, body || {}, { params });
105
+ break;
106
+ case "PATCH":
107
+ response = await client.patch(url, body || {}, { params });
108
+ break;
109
+ case "DELETE":
110
+ response = await client.delete(url, { params });
111
+ break;
112
+ default:
113
+ throw new Error(`Unsupported HTTP method: ${method}`);
114
+ }
115
+ return {
116
+ status: response.status,
117
+ data: response.data,
118
+ headers: response.headers
119
+ };
120
+ }
121
+ );
122
+
123
+ // src/mcp.ts
124
+ var LOCAL_TOOLS = [
125
+ walletCreate,
126
+ walletImport,
127
+ walletList,
128
+ walletRetrieve,
129
+ walletDelete,
130
+ transactionSign,
131
+ messageSign,
132
+ x402Request
133
+ ];
134
+ var localToolMap = new Map(LOCAL_TOOLS.map((t) => [t.schema.name, t]));
135
+ function resolveRemoteSchema(schema) {
136
+ const input = schema.inputSchema;
137
+ if (input.$ref && input.definitions) {
138
+ const defName = input.$ref.replace("#/definitions/", "");
139
+ return input.definitions[defName] ?? input;
140
+ }
141
+ return input;
142
+ }
143
+ async function startMcpServer() {
144
+ const server = new McpServer({
145
+ name: "moonpay",
146
+ version: "1.0.0"
147
+ });
148
+ for (const tool of LOCAL_TOOLS) {
149
+ const shape = tool.schema.input.shape ?? {};
150
+ server.registerTool(
151
+ tool.schema.name,
152
+ { description: tool.schema.description, inputSchema: shape },
153
+ async (params) => {
154
+ const result = await tool.handler(params);
155
+ return {
156
+ content: [
157
+ { type: "text", text: JSON.stringify(result, null, 2) }
158
+ ]
159
+ };
160
+ }
161
+ );
162
+ }
163
+ for (const schema of schemas_default) {
164
+ if (localToolMap.has(schema.name)) continue;
165
+ const resolved = resolveRemoteSchema(schema);
166
+ server.registerTool(
167
+ schema.name,
168
+ {
169
+ description: schema.description,
170
+ inputSchema: {
171
+ type: "object",
172
+ properties: resolved.properties ?? {},
173
+ required: resolved.required ?? []
174
+ }
175
+ },
176
+ async (params) => {
177
+ const props = resolved.properties ?? {};
178
+ for (const [key, prop] of Object.entries(props)) {
179
+ if (params[key] === void 0) {
180
+ const nullable = Array.isArray(prop.type) ? prop.type.includes("null") : prop.anyOf?.some((t) => t.type === "null");
181
+ if (nullable) params[key] = null;
182
+ }
183
+ const isNum = prop.type === "number" || prop.type === "integer" || Array.isArray(prop.type) && prop.type.some(
184
+ (t) => t === "number" || t === "integer"
185
+ ) || prop.anyOf?.some(
186
+ (t) => t.type === "number" || t.type === "integer"
187
+ );
188
+ if (isNum && typeof params[key] === "string") {
189
+ params[key] = Number(params[key]);
190
+ }
191
+ }
192
+ const baseUrl = resolveBaseUrl();
193
+ const result = await callTool(baseUrl, schema.name, params);
194
+ return {
195
+ content: [
196
+ { type: "text", text: JSON.stringify(result, null, 2) }
197
+ ]
198
+ };
199
+ }
200
+ );
201
+ }
202
+ const transport = new StdioServerTransport();
203
+ await server.connect(transport);
204
+ }
205
+ export {
206
+ startMcpServer
207
+ };
208
+ //# sourceMappingURL=mcp-R3YBYDRT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp.ts","../src/tools/x402/request/tool.ts","../src/tools/x402/request/schema.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { callTool } from \"./client\";\nimport { resolveBaseUrl } from \"./auth\";\nimport type { Tool } from \"./tools/shared\";\nimport { walletCreate } from \"./tools/wallet/create/tool\";\nimport { walletImport } from \"./tools/wallet/import/tool\";\nimport { walletList } from \"./tools/wallet/list/tool\";\nimport { walletRetrieve } from \"./tools/wallet/retrieve/tool\";\nimport { walletDelete } from \"./tools/wallet/delete/tool\";\nimport { transactionSign } from \"./tools/transaction/sign/tool\";\nimport { messageSign } from \"./tools/message/sign/tool\";\nimport { x402Request } from \"./tools/x402/request/tool\";\nimport schemas from \"./generated/schemas.json\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst LOCAL_TOOLS: Tool<any>[] = [\n walletCreate,\n walletImport,\n walletList,\n walletRetrieve,\n walletDelete,\n transactionSign,\n messageSign,\n x402Request,\n];\n\nconst localToolMap = new Map(LOCAL_TOOLS.map((t) => [t.schema.name, t]));\n\n/**\n * Resolve a remote schema's $ref to the actual properties object.\n */\nfunction resolveRemoteSchema(schema: (typeof schemas)[number]) {\n const input = schema.inputSchema as any;\n if (input.$ref && input.definitions) {\n const defName = input.$ref.replace(\"#/definitions/\", \"\");\n return input.definitions[defName] ?? input;\n }\n return input;\n}\n\nexport async function startMcpServer() {\n const server = new McpServer({\n name: \"moonpay\",\n version: \"1.0.0\",\n });\n\n // Register local tools — pass Zod input shape directly\n for (const tool of LOCAL_TOOLS) {\n const shape = (tool.schema.input as any).shape ?? {};\n\n server.registerTool(\n tool.schema.name,\n { description: tool.schema.description, inputSchema: shape },\n async (params: Record<string, unknown>) => {\n const result = await tool.handler(params);\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify(result, null, 2) },\n ],\n };\n },\n );\n }\n\n // Register remote tools (skip if already registered as local)\n for (const schema of schemas) {\n if (localToolMap.has(schema.name)) continue;\n\n const resolved = resolveRemoteSchema(schema);\n\n server.registerTool(\n schema.name,\n {\n description: schema.description,\n inputSchema: {\n type: \"object\",\n properties: resolved.properties ?? {},\n required: resolved.required ?? [],\n } as any,\n },\n async (params: Record<string, unknown>) => {\n // Coerce types for remote tools\n const props = (resolved.properties ?? {}) as Record<string, any>;\n for (const [key, prop] of Object.entries(props)) {\n if (params[key] === undefined) {\n const nullable = Array.isArray(prop.type)\n ? prop.type.includes(\"null\")\n : prop.anyOf?.some((t: any) => t.type === \"null\");\n if (nullable) params[key] = null;\n }\n const isNum =\n prop.type === \"number\" ||\n prop.type === \"integer\" ||\n (Array.isArray(prop.type) &&\n prop.type.some(\n (t: string) => t === \"number\" || t === \"integer\",\n )) ||\n prop.anyOf?.some(\n (t: any) => t.type === \"number\" || t.type === \"integer\",\n );\n if (isNum && typeof params[key] === \"string\") {\n params[key] = Number(params[key]);\n }\n }\n\n const baseUrl = resolveBaseUrl();\n const result = await callTool(baseUrl, schema.name, params);\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify(result, null, 2) },\n ],\n };\n },\n );\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","import { Keypair, VersionedTransaction, VersionedMessage } from \"@solana/web3.js\";\nimport bs58 from \"bs58\";\nimport axios from \"axios\";\nimport { wrapAxiosWithPayment } from \"@x402/axios\";\nimport { x402Client } from \"@x402/core/client\";\nimport { ExactSvmScheme } from \"@x402/svm\";\nimport type { Address } from \"@solana/addresses\";\nimport type { SignatureDictionary } from \"@solana/signers\";\nimport type { Transaction } from \"@solana/transactions\";\nimport { createTool } from \"../../shared\";\nimport { loadWallet } from \"../../wallet/server\";\nimport { x402RequestSchema } from \"./schema\";\n\nconst SOLANA_NETWORK = \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\" as const;\n\nfunction createLocalX402Client(walletAddress: string, secretKey: string) {\n const keypair = Keypair.fromSecretKey(bs58.decode(secretKey));\n\n const signer = {\n address: walletAddress as Address,\n signTransactions: async (\n transactions: readonly Transaction[],\n ): Promise<readonly SignatureDictionary[]> => {\n return transactions.map((transaction) => {\n const messageBytes = new Uint8Array(transaction.messageBytes);\n const message = VersionedMessage.deserialize(messageBytes);\n const numSigs = Object.keys(transaction.signatures).length;\n const tx = new VersionedTransaction(\n message,\n new Array(numSigs).fill(new Uint8Array(64)),\n );\n\n tx.sign([keypair]);\n\n const signerIndex = message.staticAccountKeys.findIndex(\n (key) => key.toBase58() === walletAddress,\n );\n if (signerIndex === -1) {\n throw new Error(\n `Wallet ${walletAddress} is not a signer for this transaction`,\n );\n }\n\n return {\n [walletAddress]: tx.signatures[signerIndex],\n } as SignatureDictionary;\n });\n },\n };\n\n const client = new x402Client();\n const svmScheme = new ExactSvmScheme(signer);\n client.register(SOLANA_NETWORK, svmScheme);\n client.registerV1(\"solana\", svmScheme);\n\n return wrapAxiosWithPayment(axios.create(), client);\n}\n\nexport const x402Request = createTool(\n x402RequestSchema,\n async ({ method, url, body, params, wallet: walletNameOrAddress }) => {\n const storedWallet = loadWallet(walletNameOrAddress);\n const client = createLocalX402Client(\n storedWallet.address,\n storedWallet.secretKey,\n );\n\n let response;\n switch (method) {\n case \"GET\":\n response = await client.get(url, { params });\n break;\n case \"POST\":\n response = await client.post(url, body || {}, { params });\n break;\n case \"PUT\":\n response = await client.put(url, body || {}, { params });\n break;\n case \"PATCH\":\n response = await client.patch(url, body || {}, { params });\n break;\n case \"DELETE\":\n response = await client.delete(url, { params });\n break;\n default:\n throw new Error(`Unsupported HTTP method: ${method}`);\n }\n\n return {\n status: response.status,\n data: response.data,\n headers: response.headers as Record<string, string>,\n };\n },\n);\n","import { z } from \"zod\";\nimport { defineToolSchema } from \"../../shared\";\n\nexport const x402RequestSchema = defineToolSchema({\n name: \"x402_request\",\n description:\n \"Make an HTTP request to an x402-protected endpoint. Automatically handles payment when a 402 Payment Required response is received, signing the payment transaction with the local wallet.\",\n input: z.object({\n method: z\n .enum([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"])\n .describe(\"HTTP method\"),\n url: z\n .string()\n .url()\n .describe(\n \"Full URL of the x402-protected endpoint (e.g., 'https://agents.moonpay.com/api/x402/tools/market_digest_retrieve')\",\n ),\n body: z\n .record(z.any())\n .nullable()\n .describe(\"Request body (for POST, PUT, PATCH)\"),\n params: z.record(z.any()).nullable().describe(\"Query parameters\"),\n wallet: z.string().describe(\"Wallet name or address to pay with\"),\n }),\n output: z.object({\n status: z.number().describe(\"HTTP status code\"),\n data: z.any().describe(\"Response data\"),\n headers: z.record(z.string()).describe(\"Response headers\"),\n }),\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonpay/cli",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -20,9 +20,15 @@
20
20
  "test": "jest"
21
21
  },
22
22
  "dependencies": {
23
+ "@modelcontextprotocol/sdk": "^1.26.0",
23
24
  "@solana/web3.js": "^1.98.4",
25
+ "@x402/axios": "^2.4.0",
26
+ "@x402/core": "^2.4.0",
27
+ "@x402/svm": "^2.4.0",
28
+ "axios": "^1.13.5",
24
29
  "bs58": "^6.0.0",
25
30
  "commander": "^12.1.0",
31
+ "tweetnacl": "^1.0.3",
26
32
  "zod": "^3.25.76"
27
33
  },
28
34
  "devDependencies": {
@@ -1,14 +1,25 @@
1
1
  ---
2
2
  name: moonpay-auth
3
- description: Authenticate and manage local wallets with MoonPay CLI. Use when you need to log in, check auth state, or manage wallets for signing transactions.
3
+ description: Set up the MoonPay CLI, authenticate, and manage local wallets. Use when commands fail, for login, or to create/import wallets.
4
4
  tags: [setup]
5
5
  ---
6
6
 
7
- # MoonPay auth
7
+ # MoonPay auth and setup
8
8
 
9
- ## Goal
9
+ ## Install
10
10
 
11
- Set up authentication and local wallet management for the MoonPay CLI (`mp`).
11
+ ```bash
12
+ npm i -g @moonpay/cli
13
+ ```
14
+
15
+ This installs the `mp` (and `moonpay`) binary globally.
16
+
17
+ ## Verify installation
18
+
19
+ ```bash
20
+ mp --version
21
+ mp --help
22
+ ```
12
23
 
13
24
  ## Auth commands
14
25
 
@@ -39,7 +50,6 @@ mp wallet list
39
50
 
40
51
  # Get wallet details (by name or address)
41
52
  mp wallet retrieve --wallet "my-wallet"
42
- mp wallet retrieve --wallet <address>
43
53
 
44
54
  # Delete a wallet (irreversible)
45
55
  mp wallet delete --wallet "my-wallet" --confirm
@@ -52,13 +62,37 @@ mp wallet delete --wallet "my-wallet" --confirm
52
62
  3. Run `mp wallet list` to see local wallets.
53
63
  4. If no wallets, create one: `mp wallet create --name "default"`.
54
64
 
55
- ## Notes
65
+ ## Config locations
66
+
67
+ - **Credentials:** `~/.config/moonpay/credentials.json` (OAuth tokens)
68
+ - **Config:** `~/.config/moonpay/config.json` (base URL, client ID)
69
+ - **Wallets:** `~/.config/moonpay/wallets/` (local keypairs, 0600 permissions)
70
+
71
+ ## Output formats
72
+
73
+ ```bash
74
+ mp -f json wallet list # Pretty JSON (default)
75
+ mp -f compact wallet list # Single-line JSON
76
+ mp -f table wallet list # ASCII table
77
+ ```
78
+
79
+ ## Environment for scripts/agents
80
+
81
+ If running `mp` from a script or agent subprocess, ensure PATH includes the npm global bin:
82
+
83
+ ```bash
84
+ export PATH="$(npm config get prefix)/bin:$PATH"
85
+ mp --version
86
+ ```
87
+
88
+ ## Troubleshooting
56
89
 
57
- - Credentials: `~/.config/moonpay/credentials.json`
58
- - Wallets: `~/.config/moonpay/wallets/`
90
+ - **"command not found"** — `npm i -g @moonpay/cli` and check PATH.
91
+ - **401 / auth errors** — Run `mp login`.
92
+ - **"fetch failed"** — Check network connectivity to agents.moonpay.com.
59
93
  - Tokens auto-refresh on expiry. If refresh fails, run `mp login` again.
60
94
 
61
95
  ## Related skills
62
96
 
63
- - **moonpay-env** — Environment and PATH setup.
64
97
  - **moonpay-swap-tokens** — Swap tokens using local wallets.
98
+ - **moonpay-check-wallet** — Check wallet balances.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: moonpay-check-wallet
3
- description: Check wallet balances and holdings. Use for "what's in my wallet", portfolio breakdown, token balances, and USD values.
3
+ description: Check wallet balances and holdings. Use for "what's in my wallet", portfolio breakdown, token balances, allocation percentages, and USD values.
4
4
  tags: [portfolio]
5
5
  ---
6
6
 
@@ -8,7 +8,7 @@ tags: [portfolio]
8
8
 
9
9
  ## Goal
10
10
 
11
- List all token balances held in a wallet with current USD values.
11
+ List all token balances in a wallet with USD values, allocation breakdown, and total portfolio value.
12
12
 
13
13
  ## Commands
14
14
 
@@ -19,27 +19,39 @@ mp token balance list --wallet <address> --chain solana
19
19
  # List balances for an EVM wallet
20
20
  mp token balance list --wallet 0x... --chain ethereum
21
21
  mp token balance list --wallet 0x... --chain base
22
+
23
+ # Find wallet address
24
+ mp wallet list
22
25
  ```
23
26
 
24
27
  ## Supported chains
25
28
 
26
29
  `solana`, `ethereum`, `base`, `polygon`, `arbitrum`, `optimism`
27
30
 
28
- ## Output handling
31
+ ## Workflow
29
32
 
30
- - Summarize top holdings by USD value.
31
- - Call out small dust balances separately.
32
- - Sum `balance.value` across items for total portfolio value.
33
+ 1. Run `mp wallet list` to find the user's wallet address.
34
+ 2. Run `mp token balance list --wallet <address> --chain solana`.
35
+ 3. Sort holdings by USD value descending.
36
+ 4. Calculate allocation percentages (each holding's USD / total USD).
37
+ 5. Present: top holdings, dust balances, total value.
33
38
 
34
39
  ## Example flow
35
40
 
36
- 1. User: "What's in my wallet?"
37
- 2. Run `mp wallet list` to find the user's wallet address.
38
- 3. Run `mp token balance list --wallet <address> --chain solana`.
39
- 4. Present holdings sorted by value.
41
+ 1. User: "What's in my wallet?" or "Generate a portfolio report."
42
+ 2. Run: `mp token balance list --wallet <address> --chain solana`
43
+ 3. Present:
44
+ - **Total value:** $168.05
45
+ - **SOL** — 0.61 ($51.87) — 30.9%
46
+ - **WBTC** — 0.00127 ($85.48) — 50.9%
47
+ - **USDC** — 29.81 ($29.81) — 17.7%
48
+ - **Dust:** none
49
+
50
+ ## Output formats
51
+
52
+ Use `mp -f table token balance list ...` for a quick table view, or `mp -f json ...` for programmatic processing.
40
53
 
41
54
  ## Related skills
42
55
 
43
56
  - **moonpay-auth** — Set up wallets if none exist.
44
- - **moonpay-portfolio-report** — Full report with allocation percentages.
45
- - **moonpay-rug-check** — Risk-check a token before buying.
57
+ - **moonpay-discover-tokens** — Research specific tokens in the portfolio.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: moonpay-discover-tokens
3
- description: Search for tokens and retrieve detailed market data. Use to find token addresses, check prices, volume, liquidity, and trading activity.
3
+ description: Search for tokens, check prices, get trading briefs, and evaluate risk. Use for token research, "is this token safe?", price checks, and market analysis.
4
4
  tags: [research]
5
5
  ---
6
6
 
@@ -8,26 +8,20 @@ tags: [research]
8
8
 
9
9
  ## Goal
10
10
 
11
- Search for tokens by name/symbol and retrieve detailed market data including price, volume, liquidity, and trading activity.
11
+ Search for tokens, retrieve market data, generate trading briefs, and assess risk — all from one skill.
12
12
 
13
13
  ## Commands
14
14
 
15
- ### Search for tokens
16
-
17
15
  ```bash
18
- mp token search --query "SOL" --chain solana
19
- mp token search --query "BONK" --chain solana --limit 3
20
- ```
21
-
22
- Returns matching tokens with market data (price, volume, liquidity, trades, buys/sells, unique wallets).
16
+ # Search by name or symbol
17
+ mp token search --query "BONK" --chain solana
23
18
 
24
- ### Retrieve token details
25
-
26
- ```bash
19
+ # Get full details for a specific token
27
20
  mp token retrieve --token <mint-address> --chain solana
28
- ```
29
21
 
30
- Returns token metadata (name, symbol, decimals, image) and market data.
22
+ # See what's trending
23
+ mp token trending list --chain solana
24
+ ```
31
25
 
32
26
  ## Supported chains
33
27
 
@@ -37,18 +31,46 @@ Returns token metadata (name, symbol, decimals, image) and market data.
37
31
 
38
32
  1. Search by name/symbol with `mp token search`.
39
33
  2. Use the returned address to get details with `mp token retrieve`.
40
- 3. Evaluate risk with **moonpay-rug-check** for unknown tokens.
41
- 4. Proceed to buy/swap if desired.
34
+ 3. Assess risk and generate a brief from the market data.
42
35
 
43
- ## Example flow
36
+ ## Trading brief format
44
37
 
38
+ When the user wants a brief or analysis, format the output like:
39
+
40
+ ```
41
+ BONK (DezX...pump) — mcap $850M, liq $12M, vol24 $45M
42
+ momentum: 1h +2.3%, 4h -0.5%, 24h +8.1%
43
+ activity: trades24 12,500, wallets24 3,200
44
+ note: healthy volume, broad wallet distribution
45
+ ```
46
+
47
+ ## Risk assessment
48
+
49
+ When the user asks "is this safe?" or wants to evaluate an unknown token, check these indicators from the market data:
50
+
51
+ 1. **Liquidity** — Under $10K is a red flag.
52
+ 2. **Volume pattern** — Sudden spikes with no context = suspicious.
53
+ 3. **Buy/sell ratio** — Extremely one-sided trading = dump risk.
54
+ 4. **Unique wallets** — Very few unique wallets = concentrated activity.
55
+ 5. **Market cap vs liquidity** — Huge mcap with tiny liquidity = inflated, hard to exit.
56
+ 6. **Price volatility** — Extreme short-term swings (>50% in 1h) = high risk.
57
+
58
+ Present a risk summary with traffic-light ratings. This is a heuristic check based on market data, not a smart contract audit — always recommend caution with unknown tokens.
59
+
60
+ ## Example flows
61
+
62
+ **Price check:**
45
63
  1. User: "What's the price of BONK?"
46
64
  2. Run: `mp token search --query "BONK" --chain solana`
47
65
  3. Present: name, symbol, price, 24h change, volume, liquidity.
48
66
 
67
+ **Risk check:**
68
+ 1. User: "Is BONK safe to buy?"
69
+ 2. Run: `mp token search --query "BONK" --chain solana` then `mp token retrieve --token <address> --chain solana`
70
+ 3. Present risk indicators with ratings.
71
+
49
72
  ## Related skills
50
73
 
51
- - **moonpay-token-brief** — Detailed trading brief for a specific token.
52
- - **moonpay-rug-check** — Risk assessment for unknown tokens.
53
- - **moonpay-swap-tokens** — Swap after research.
74
+ - **moonpay-swap-tokens** — Trade after research.
54
75
  - **moonpay-buy-crypto** — Buy with fiat after research.
76
+ - **moonpay-check-wallet** — Check your current holdings.
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: moonpay-mcp
3
+ description: Set up MoonPay as an MCP server for Claude Desktop or Claude Code. Provides all MoonPay CLI tools via the Model Context Protocol.
4
+ tags: [setup]
5
+ ---
6
+
7
+ # MoonPay MCP Setup
8
+
9
+ ## Goal
10
+
11
+ Configure the MoonPay CLI as an MCP server so Claude Desktop, Claude Code, or any MCP-compatible client can use all MoonPay tools directly.
12
+
13
+ ## Prerequisites
14
+
15
+ ```bash
16
+ npm i -g @moonpay/cli
17
+ mp login
18
+ ```
19
+
20
+ ## Claude Code setup
21
+
22
+ ```bash
23
+ claude mcp add moonpay -- mp mcp
24
+ ```
25
+
26
+ ## Claude Desktop setup
27
+
28
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "moonpay": {
34
+ "command": "mp",
35
+ "args": ["mcp"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ Then restart Claude Desktop.
42
+
43
+ ## What it provides
44
+
45
+ All MoonPay CLI tools are available as MCP tools:
46
+
47
+ - **Wallet management** — create, import, list, retrieve, delete wallets
48
+ - **Token operations** — search, retrieve, swap, buy, sell, limit orders, recurring orders
49
+ - **Market data** — token prices, trending, top traders, liquidity, holder data
50
+ - **DeFi** — lending deposits/withdrawals, yield recommendations
51
+ - **Fiat on/off-ramp** — buy crypto, virtual accounts, bank accounts
52
+ - **x402 payments** — paid API requests with automatic payment handling
53
+ - **Transaction signing** — sign transactions with local wallets
54
+
55
+ ## Verification
56
+
57
+ After setup, ask Claude: "What MoonPay tools do you have?" — it should list all available tools.
58
+
59
+ ## Auth
60
+
61
+ The MCP server uses the same credentials as the CLI (`~/.config/moonpay/credentials.json`). Run `mp login` to authenticate.
62
+
63
+ ## Related skills
64
+
65
+ - **moonpay-auth** — Login and wallet setup.
66
+ - **moonpay-discover-tokens** — Search and analyze tokens.
67
+ - **moonpay-swap-tokens** — Swap tokens.
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: moonpay-x402
3
+ description: Make paid API requests to x402-protected endpoints. Automatically handles payment with your local wallet.
4
+ tags: [payments, api]
5
+ ---
6
+
7
+ # x402 paid API requests
8
+
9
+ ## Goal
10
+
11
+ Make HTTP requests to x402-protected endpoints. The CLI automatically detects 402 Payment Required responses, builds and signs a Solana payment transaction with your local wallet, and retries the request with the payment proof.
12
+
13
+ ## Command
14
+
15
+ ```bash
16
+ mp x402 request \
17
+ --method POST \
18
+ --url <x402-endpoint-url> \
19
+ --body '<json-body>' \
20
+ --wallet <wallet-name-or-address>
21
+ ```
22
+
23
+ ## Available x402 endpoints
24
+
25
+ | Endpoint | Cost | Input |
26
+ |----------|------|-------|
27
+ | `https://agents.moonpay.com/api/x402/tools/market_digest_retrieve` | $0.01 | `{"chain": "solana"}` |
28
+ | `https://agents.moonpay.com/api/x402/tools/token_digest_retrieve` | $0.01 | `{"token": "<mint>", "chain": "solana"}` |
29
+ | `https://agents.moonpay.com/api/x402/tools/wallet_digest_retrieve` | $0.01 | `{"wallet": "<address>", "chain": "solana"}` |
30
+
31
+ ## Example flow
32
+
33
+ 1. User: "Get me a market digest for Solana."
34
+ 2. Run: `mp x402 request --method POST --url "https://agents.moonpay.com/api/x402/tools/market_digest_retrieve" --body '{"chain": "solana"}' --wallet my-wallet`
35
+ 3. The CLI handles the 402 payment flow automatically and returns the digest.
36
+
37
+ ## Notes
38
+
39
+ - Requires a local wallet with USDC to pay for requests.
40
+ - Payments are on Solana mainnet.
41
+ - If the tool request fails (status >= 400), the payment is not settled — you don't pay for errors.
42
+ - Use **moonpay-auth** to set up a local wallet first.
43
+
44
+ ## Related skills
45
+
46
+ - **moonpay-auth** — Create or import a local wallet.
47
+ - **moonpay-check-wallet** — Check your wallet balance before making paid requests.
@@ -1,57 +0,0 @@
1
- ---
2
- name: moonpay-env
3
- description: Ensure the MoonPay CLI environment is set up correctly. Use when commands fail due to PATH or config issues.
4
- tags: [setup]
5
- ---
6
-
7
- # MoonPay environment setup
8
-
9
- ## Install
10
-
11
- ```bash
12
- npm i -g @moonpay/cli
13
- ```
14
-
15
- This installs the `mp` (and `moonpay`) binary globally.
16
-
17
- ## Verify installation
18
-
19
- ```bash
20
- mp --version
21
- mp --help
22
- ```
23
-
24
- ## Config locations
25
-
26
- - **Credentials:** `~/.config/moonpay/credentials.json` (OAuth tokens)
27
- - **Config:** `~/.config/moonpay/config.json` (base URL, client ID)
28
- - **Wallets:** `~/.config/moonpay/wallets/` (local keypairs, 0600 permissions)
29
-
30
- ## Environment for scripts/agents
31
-
32
- If running `mp` from a script or agent subprocess, ensure PATH includes the npm global bin:
33
-
34
- ```bash
35
- export PATH="$(npm config get prefix)/bin:$PATH"
36
- mp --version
37
- ```
38
-
39
- ## Output formats
40
-
41
- The CLI supports three output formats via `-f`:
42
-
43
- ```bash
44
- mp -f json wallet list # Pretty JSON (default)
45
- mp -f compact wallet list # Single-line JSON
46
- mp -f table wallet list # ASCII table
47
- ```
48
-
49
- ## Troubleshooting
50
-
51
- - **"command not found"** — `npm i -g @moonpay/cli` and check PATH.
52
- - **401 / auth errors** — Run `mp login`.
53
- - **"fetch failed"** — Check network connectivity to agents.moonpay.com.
54
-
55
- ## Related skills
56
-
57
- - **moonpay-auth** — Login, logout, wallet management.