@silencelaboratories/pay-mcp-client 1.0.0

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.
Files changed (3) hide show
  1. package/README.md +76 -0
  2. package/build/index.js +209 -0
  3. package/package.json +27 -0
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Pay MCP Client
2
+
3
+ Model Context Protocol (MCP) client for AI-powered payment operations. Connects LLMs to the Pay Server for payment operations.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ npm install
9
+ npm run build
10
+ npm start
11
+ ```
12
+
13
+ ## Cursor Configuration
14
+
15
+ Add to `~/.cursor/mcp.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "wallet-mcp-server": {
21
+ "command": "node",
22
+ "args": ["/path/to/mcp-server/build/index.js"],
23
+ "env": {
24
+ "WALLET_API_URL": "http://localhost:3001"
25
+ }
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## Available Tools
32
+
33
+ ### Utility Tools
34
+
35
+ | Tool | Description |
36
+ |------|-------------|
37
+ | `get_time` | Get current date and time |
38
+ | `add` | Add two numbers together |
39
+
40
+ ### Wallet Tools
41
+
42
+ | Tool | Description | Parameters |
43
+ |------|-------------|------------|
44
+ | `get_eth_balance` | Get ETH balance for wallet | `token` |
45
+ | `sign_eth_transaction` | Sign and broadcast ETH transaction | `token`, `recipientAddress`, `amount` |
46
+ | `get_transaction_history` | Get transaction history | `token` |
47
+
48
+ ### Supplier Tools
49
+
50
+ | Tool | Description | Parameters |
51
+ |------|-------------|------------|
52
+ | `get_suppliers` | Get list of available suppliers | - |
53
+ | `get_supplier` | Get supplier details by ID | `supplierId` |
54
+ | `pay_supplier` | Pay a supplier by ID | `token`, `supplierId`, `amount` |
55
+
56
+ ## Token Format
57
+
58
+ The bearer token is 168 characters:
59
+ - `ephSk` (64 chars): Ephemeral secret key hex
60
+ - `keyId` (64 chars): MPC key ID
61
+ - `address` (40 chars): Wallet address (without 0x)
62
+
63
+ ## Example Usage
64
+
65
+ Once connected to Cursor, you can use natural language:
66
+
67
+ - "What's my ETH balance?" (provide token)
68
+ - "Send 0.001 ETH to 0x..." (provide token)
69
+ - "Show my transaction history" (provide token)
70
+ - "List available suppliers"
71
+ - "Pay Amazon 0.01 ETH" (provide token)
72
+
73
+ ## Dependencies
74
+
75
+ - `@modelcontextprotocol/sdk` - MCP SDK
76
+ - Requires `wallet-api` running on `http://localhost:3001`
package/build/index.js ADDED
@@ -0,0 +1,209 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { z } from "zod";
4
+ const server = new McpServer({
5
+ name: "@silencelaboratories/pay-mcp-client",
6
+ version: "1.0.0",
7
+ });
8
+ const WALLET_API_URL = process.env.WALLET_API_URL || "http://localhost:3001";
9
+ async function callWalletApi(endpoint, method, token, body) {
10
+ const url = `${WALLET_API_URL}${endpoint}`;
11
+ const headers = {
12
+ "Content-Type": "application/json",
13
+ };
14
+ if (token) {
15
+ headers.Authorization = `Bearer ${token}`;
16
+ }
17
+ const response = await fetch(url, {
18
+ method,
19
+ headers,
20
+ body: body ? JSON.stringify(body) : undefined,
21
+ });
22
+ return response.json();
23
+ }
24
+ // Tool 1: get_eth_balance - get ETH balance for wallet
25
+ server.tool("get_eth_balance", "Get ETH balance for the wallet associated with the token", {
26
+ token: z.string().describe("Bearer token (168 chars: ephSk + keyId + address)"),
27
+ }, async ({ token }) => {
28
+ try {
29
+ const result = await callWalletApi("/api/balance/eth", "GET", token);
30
+ return {
31
+ content: [
32
+ {
33
+ type: "text",
34
+ text: JSON.stringify(result),
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ catch (error) {
40
+ return {
41
+ content: [
42
+ {
43
+ type: "text",
44
+ text: JSON.stringify({ success: false, error: error.message }),
45
+ },
46
+ ],
47
+ };
48
+ }
49
+ });
50
+ // Tool 2: sign_eth_transaction - sign and broadcast ETH transaction
51
+ server.tool("sign_eth_transaction", "Sign and broadcast an ETH transaction using MPC signing", {
52
+ token: z.string().describe("Bearer token (168 chars: ephSk + keyId + address)"),
53
+ recipientAddress: z.string().describe("Recipient wallet address"),
54
+ amount: z.string().describe("Amount in ETH (e.g., '0.001')"),
55
+ }, async ({ token, recipientAddress, amount }) => {
56
+ try {
57
+ const result = await callWalletApi("/api/sign/eth", "POST", token, {
58
+ recipientAddress,
59
+ amount,
60
+ });
61
+ return {
62
+ content: [
63
+ {
64
+ type: "text",
65
+ text: JSON.stringify(result),
66
+ },
67
+ ],
68
+ };
69
+ }
70
+ catch (error) {
71
+ return {
72
+ content: [
73
+ {
74
+ type: "text",
75
+ text: JSON.stringify({ success: false, error: error.message }),
76
+ },
77
+ ],
78
+ };
79
+ }
80
+ });
81
+ // Tool 3: get_transaction_history - get transaction history for wallet
82
+ server.tool("get_transaction_history", "Get transaction history for the wallet associated with the token", {
83
+ token: z.string().describe("Bearer token (168 chars: ephSk + keyId + address)"),
84
+ }, async ({ token }) => {
85
+ try {
86
+ const result = await callWalletApi("/api/transactions/eth", "GET", token);
87
+ return {
88
+ content: [
89
+ {
90
+ type: "text",
91
+ text: JSON.stringify(result),
92
+ },
93
+ ],
94
+ };
95
+ }
96
+ catch (error) {
97
+ return {
98
+ content: [
99
+ {
100
+ type: "text",
101
+ text: JSON.stringify({ success: false, error: error.message }),
102
+ },
103
+ ],
104
+ };
105
+ }
106
+ });
107
+ // Tool 4: get_suppliers - get list of available suppliers
108
+ server.tool("get_suppliers", "Get list of available suppliers/merchants that can receive payments", {}, async () => {
109
+ try {
110
+ const result = await callWalletApi("/api/suppliers", "GET");
111
+ return {
112
+ content: [
113
+ {
114
+ type: "text",
115
+ text: JSON.stringify(result),
116
+ },
117
+ ],
118
+ };
119
+ }
120
+ catch (error) {
121
+ return {
122
+ content: [
123
+ {
124
+ type: "text",
125
+ text: JSON.stringify({ success: false, error: error.message }),
126
+ },
127
+ ],
128
+ };
129
+ }
130
+ });
131
+ // Tool 5: get_supplier - get specific supplier by ID
132
+ server.tool("get_supplier", "Get details of a specific supplier by ID", {
133
+ supplierId: z.string().describe("Supplier ID (e.g., 'amazon', 'gemini', 'apollo')"),
134
+ }, async ({ supplierId }) => {
135
+ try {
136
+ const result = await callWalletApi(`/api/suppliers/${supplierId}`, "GET");
137
+ return {
138
+ content: [
139
+ {
140
+ type: "text",
141
+ text: JSON.stringify(result),
142
+ },
143
+ ],
144
+ };
145
+ }
146
+ catch (error) {
147
+ return {
148
+ content: [
149
+ {
150
+ type: "text",
151
+ text: JSON.stringify({ success: false, error: error.message }),
152
+ },
153
+ ],
154
+ };
155
+ }
156
+ });
157
+ // Tool 6: pay_supplier - pay a supplier by ID
158
+ server.tool("pay_supplier", "Pay a supplier/merchant by their ID using MPC signing", {
159
+ token: z.string().describe("Bearer token (168 chars: ephSk + keyId + address)"),
160
+ supplierId: z.string().describe("Supplier ID (e.g., 'amazon', 'gemini', 'apollo')"),
161
+ amount: z.string().describe("Amount in ETH (e.g., '0.001')"),
162
+ }, async ({ token, supplierId, amount }) => {
163
+ try {
164
+ // First get the supplier address
165
+ const supplierResult = await callWalletApi(`/api/suppliers/${supplierId}`, "GET");
166
+ if (!supplierResult.success) {
167
+ return {
168
+ content: [
169
+ {
170
+ type: "text",
171
+ text: JSON.stringify({ success: false, error: `Supplier '${supplierId}' not found` }),
172
+ },
173
+ ],
174
+ };
175
+ }
176
+ // Then sign and send the transaction
177
+ const result = await callWalletApi("/api/sign/eth", "POST", token, {
178
+ recipientAddress: supplierResult.supplier.address,
179
+ amount,
180
+ });
181
+ return {
182
+ content: [
183
+ {
184
+ type: "text",
185
+ text: JSON.stringify({
186
+ ...result,
187
+ supplier: supplierResult.supplier.name,
188
+ }),
189
+ },
190
+ ],
191
+ };
192
+ }
193
+ catch (error) {
194
+ return {
195
+ content: [
196
+ {
197
+ type: "text",
198
+ text: JSON.stringify({ success: false, error: error.message }),
199
+ },
200
+ ],
201
+ };
202
+ }
203
+ });
204
+ async function main() {
205
+ const transport = new StdioServerTransport();
206
+ await server.connect(transport);
207
+ console.error("Wallet MCP Server running on stdio");
208
+ }
209
+ main().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@silencelaboratories/pay-mcp-client",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "build/index.js",
6
+ "files": [
7
+ "build"
8
+ ],
9
+ "bin": {
10
+ "pay-mcp-client": "build/index.js"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "start": "node build/index.js",
18
+ "dev": "tsc && node build/index.js"
19
+ },
20
+ "dependencies": {
21
+ "@modelcontextprotocol/sdk": "^1.12.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^22.0.0",
25
+ "typescript": "^5.7.0"
26
+ }
27
+ }