@moonpay/cli 0.3.4 → 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.4",
3
+ "version": "0.3.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -20,6 +20,7 @@
20
20
  "test": "jest"
21
21
  },
22
22
  "dependencies": {
23
+ "@modelcontextprotocol/sdk": "^1.26.0",
23
24
  "@solana/web3.js": "^1.98.4",
24
25
  "@x402/axios": "^2.4.0",
25
26
  "@x402/core": "^2.4.0",
@@ -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.