cryptoiz-mcp 4.16.6 → 4.16.8
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 +5 -100
- package/index.js +154 -445
- package/package.json +21 -53
- package/setup.js +51 -132
package/README.md
CHANGED
|
@@ -1,100 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g cryptoiz-mcp
|
|
9
|
-
npx cryptoiz-mcp-setup YOUR_SOLANA_PRIVATE_KEY
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
Auto-detects OS, finds Claude Desktop config (including Windows MSIX), writes correct config. Restart Claude Desktop and type `get_status`.
|
|
13
|
-
|
|
14
|
-
## Prerequisites
|
|
15
|
-
|
|
16
|
-
1. **Node.js** v18+ from nodejs.org
|
|
17
|
-
2. **Claude Desktop** from claude.ai/download
|
|
18
|
-
3. **Solana wallet** with $1-5 USDC (no SOL needed, Dexter sponsors gas)
|
|
19
|
-
|
|
20
|
-
## Tools and Pricing
|
|
21
|
-
|
|
22
|
-
| Tool | Price | Data |
|
|
23
|
-
|------|-------|------|
|
|
24
|
-
| get_whale_alpha | $0.05 | 20 smart money whale/dolphin signals |
|
|
25
|
-
| get_whale_divergence | $0.02 | 20 divergence signals (3 types) |
|
|
26
|
-
| get_whale_accumulation | $0.02 | Tokens in accumulation phase |
|
|
27
|
-
| get_whale_neutral | $0.02 | Tokens in neutral phase |
|
|
28
|
-
| get_whale_distribution | $0.02 | Tokens in distribution phase |
|
|
29
|
-
| get_btc_regime | $0.01 | BTC macro + Fear/Greed + technicals |
|
|
30
|
-
| get_btc_futures_signal | $0.03 | MTF BTC futures scalping signal (4h regime + 5m entry) |
|
|
31
|
-
| get_token_ca | FREE | Contract address lookup |
|
|
32
|
-
| get_status | FREE | Server health check |
|
|
33
|
-
|
|
34
|
-
## Manual Config (if auto-installer fails)
|
|
35
|
-
|
|
36
|
-
### macOS
|
|
37
|
-
Config: ~/Library/Application Support/Claude/claude_desktop_config.json
|
|
38
|
-
|
|
39
|
-
```json
|
|
40
|
-
{
|
|
41
|
-
"mcpServers": {
|
|
42
|
-
"cryptoiz": {
|
|
43
|
-
"command": "npx",
|
|
44
|
-
"args": ["-y", "cryptoiz-mcp"],
|
|
45
|
-
"env": {
|
|
46
|
-
"SVM_PRIVATE_KEY": "your-base58-private-key"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Windows
|
|
54
|
-
IMPORTANT: npx does NOT work on Windows. Use absolute paths.
|
|
55
|
-
|
|
56
|
-
Config location depends on install type:
|
|
57
|
-
- MSIX (most common): %LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json
|
|
58
|
-
- Standard: %APPDATA%\Claude\claude_desktop_config.json
|
|
59
|
-
|
|
60
|
-
Check: run `dir "$env:LOCALAPPDATA\Packages\Claude*"` in PowerShell. If folder exists = MSIX.
|
|
61
|
-
|
|
62
|
-
```json
|
|
63
|
-
{
|
|
64
|
-
"mcpServers": {
|
|
65
|
-
"cryptoiz": {
|
|
66
|
-
"command": "C:\\Program Files\\nodejs\\node.exe",
|
|
67
|
-
"args": ["C:\\Users\\YOUR_USERNAME\\AppData\\Roaming\\npm\\node_modules\\cryptoiz-mcp\\index.js"],
|
|
68
|
-
"env": {
|
|
69
|
-
"SVM_PRIVATE_KEY": "your-base58-private-key"
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Troubleshooting
|
|
77
|
-
|
|
78
|
-
**"No servers added" after setup:**
|
|
79
|
-
Config written to wrong path. Windows MSIX reads from LocalAppData, not AppData. Copy:
|
|
80
|
-
```powershell
|
|
81
|
-
copy "$env:APPDATA\Claude\claude_desktop_config.json" "$env:LOCALAPPDATA\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json"
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**"spawn npx ENOENT" on Windows:**
|
|
85
|
-
Use absolute paths, not npx. See Windows config above.
|
|
86
|
-
|
|
87
|
-
**Server disconnected:**
|
|
88
|
-
Check logs: Get-Content "$env:APPDATA\Claude\logs\mcp-server-cryptoiz.log" -Tail 30
|
|
89
|
-
|
|
90
|
-
## Security
|
|
91
|
-
|
|
92
|
-
Private key stored only in local config. Never sent to CryptoIZ. Gas sponsored by Dexter. Use a dedicated wallet.
|
|
93
|
-
|
|
94
|
-
## Links
|
|
95
|
-
|
|
96
|
-
- Guide: https://cryptoiz.org/McpLanding
|
|
97
|
-
- Platform: https://cryptoiz.org
|
|
98
|
-
- Dexter: https://dexter.cash/sellers/DsKmdkYx49Xc1WhqMUAztwhdYPTqieyC98VmnnJdgpXX
|
|
99
|
-
- Twitter: @cryptoiz_IDN
|
|
100
|
-
- npm: https://www.npmjs.com/package/cryptoiz-mcp
|
|
1
|
+
# cryptoiz-mcp
|
|
2
|
+
|
|
3
|
+
CryptoIZ MCP Server - Solana DEX whale intelligence via Claude Desktop.
|
|
4
|
+
|
|
5
|
+
Setup: https://cryptoiz.org/McpLanding
|
package/index.js
CHANGED
|
@@ -1,445 +1,154 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
var
|
|
50
|
-
var
|
|
51
|
-
var
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
var
|
|
83
|
-
var
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
var
|
|
95
|
-
var
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
var
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
var
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
var
|
|
111
|
-
var
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
var
|
|
118
|
-
|
|
119
|
-
var
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
async function
|
|
150
|
-
var
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
var keys = [
|
|
156
|
-
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
157
|
-
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
158
|
-
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
159
|
-
];
|
|
160
|
-
var data = Buffer.alloc(9);
|
|
161
|
-
data.writeUInt8(3, 0);
|
|
162
|
-
var lo = amount & 0xFFFFFFFF;
|
|
163
|
-
var hi = Math.floor(amount / 0x100000000) & 0xFFFFFFFF;
|
|
164
|
-
data.writeUInt32LE(lo, 1);
|
|
165
|
-
data.writeUInt32LE(hi, 5);
|
|
166
|
-
var transferIx = {
|
|
167
|
-
programId: tokenProgramPk,
|
|
168
|
-
keys: keys,
|
|
169
|
-
data: data,
|
|
170
|
-
};
|
|
171
|
-
var bhResult = await conn.getLatestBlockhash('confirmed');
|
|
172
|
-
var tx = new Transaction({
|
|
173
|
-
feePayer: kp.publicKey,
|
|
174
|
-
blockhash: bhResult.blockhash,
|
|
175
|
-
lastValidBlockHeight: bhResult.lastValidBlockHeight,
|
|
176
|
-
});
|
|
177
|
-
tx.add(transferIx);
|
|
178
|
-
tx.sign(kp);
|
|
179
|
-
var rawTx = tx.serialize();
|
|
180
|
-
var sig = await conn.sendRawTransaction(rawTx, { skipPreflight: false });
|
|
181
|
-
await conn.confirmTransaction({
|
|
182
|
-
signature: sig,
|
|
183
|
-
blockhash: bhResult.blockhash,
|
|
184
|
-
lastValidBlockHeight: bhResult.lastValidBlockHeight
|
|
185
|
-
}, 'confirmed');
|
|
186
|
-
return sig;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// ===== Headers helper: every gateway request carries x-client-version =====
|
|
190
|
-
function clientHeaders(extra) {
|
|
191
|
-
// Strip leading 'v' for cleanliness — gateway accepts both
|
|
192
|
-
var v = VERSION.replace(/^v/i, '');
|
|
193
|
-
var h = { 'x-client-version': v };
|
|
194
|
-
if (extra) {
|
|
195
|
-
for (var k in extra) { if (Object.prototype.hasOwnProperty.call(extra, k)) h[k] = extra[k]; }
|
|
196
|
-
}
|
|
197
|
-
return h;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// ===== TOOL CALL HANDLER =====
|
|
201
|
-
async function callTool(toolName, args) {
|
|
202
|
-
var queryParts = [];
|
|
203
|
-
|
|
204
|
-
// Use per-tool endpoint if available, otherwise gateway
|
|
205
|
-
var baseUrl = TOOL_ENDPOINTS[toolName] || GATEWAY;
|
|
206
|
-
|
|
207
|
-
if (!TOOL_ENDPOINTS[toolName]) {
|
|
208
|
-
// Free tools go to gateway with tool param
|
|
209
|
-
queryParts.push('tool=' + toolName);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Handle timeframe for divergence tools (new and old name)
|
|
213
|
-
if ((toolName === 'get_whale_divergence' || toolName === 'get_divergence') && args && args.timeframe) {
|
|
214
|
-
queryParts.push('tf=' + args.timeframe);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
if ((toolName === 'get_token_ca') && args && args.name) {
|
|
218
|
-
queryParts.push('name=' + encodeURIComponent(args.name));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
var url = queryParts.length > 0 ? baseUrl + '?' + queryParts.join('&') : baseUrl;
|
|
222
|
-
|
|
223
|
-
// Step 1: Fetch gateway — expect 402 or 200 (free tools)
|
|
224
|
-
var resp1 = await fetch(url, { headers: clientHeaders() });
|
|
225
|
-
if (resp1.status === 200) {
|
|
226
|
-
var data200 = await resp1.json();
|
|
227
|
-
maybeNotifyUpdate(data200, resp1.headers);
|
|
228
|
-
return data200;
|
|
229
|
-
}
|
|
230
|
-
if (resp1.status !== 402) {
|
|
231
|
-
var errText = await resp1.text();
|
|
232
|
-
throw new Error('Gateway error ' + resp1.status + ': ' + errText);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Step 2: Parse 402 response — try V2 header first, fallback to body
|
|
236
|
-
var paymentRequirements = null;
|
|
237
|
-
var useV2 = false;
|
|
238
|
-
|
|
239
|
-
var prHeader = resp1.headers.get('payment-required');
|
|
240
|
-
if (prHeader) {
|
|
241
|
-
try {
|
|
242
|
-
var prDecoded = Buffer.from(prHeader, 'base64').toString('utf8');
|
|
243
|
-
var prArray = JSON.parse(prDecoded);
|
|
244
|
-
if (Array.isArray(prArray) && prArray.length > 0) {
|
|
245
|
-
paymentRequirements = prArray[0];
|
|
246
|
-
useV2 = true;
|
|
247
|
-
}
|
|
248
|
-
} catch(e) {
|
|
249
|
-
console.error('[cryptoiz-mcp] Failed to parse PAYMENT-REQUIRED header:', e.message);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Fallback: read from body (V1 compat)
|
|
254
|
-
if (!paymentRequirements) {
|
|
255
|
-
var body402 = await resp1.json();
|
|
256
|
-
if (body402.accepts && body402.accepts.length > 0) {
|
|
257
|
-
paymentRequirements = body402.accepts[0];
|
|
258
|
-
} else {
|
|
259
|
-
throw new Error('402 response missing payment requirements');
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
var amount = parseInt(paymentRequirements.maxAmountRequired || paymentRequirements.amount || '10000');
|
|
264
|
-
var displayAmount = (amount / 1000000).toFixed(4);
|
|
265
|
-
var hasFeePayer = paymentRequirements.extra && paymentRequirements.extra.feePayer;
|
|
266
|
-
|
|
267
|
-
console.error('[cryptoiz-mcp] Payment required: ' + displayAmount + ' USDC for ' + toolName + (hasFeePayer ? ' (V2 Dexter)' : ' (V1 self-pay)'));
|
|
268
|
-
|
|
269
|
-
// Step 3: Build and send payment
|
|
270
|
-
var paymentHeader = '';
|
|
271
|
-
var headerName = '';
|
|
272
|
-
|
|
273
|
-
if (useV2 && paymentRequirements.extra && paymentRequirements.extra.feePayer) {
|
|
274
|
-
var v2FeePayer = paymentRequirements.extra.feePayer;
|
|
275
|
-
console.error('[cryptoiz-mcp] V2 mode: 4-ix tx (Limit+Price+TransferChecked+Memo), feePayer=' + v2FeePayer.substring(0, 8) + '...');
|
|
276
|
-
try {
|
|
277
|
-
var txB64 = await buildV2PaymentPayload(amount, v2FeePayer);
|
|
278
|
-
var v2Payload = {
|
|
279
|
-
x402Version: 2,
|
|
280
|
-
accepted: {
|
|
281
|
-
scheme: paymentRequirements.scheme || 'exact',
|
|
282
|
-
network: paymentRequirements.network || 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
|
|
283
|
-
},
|
|
284
|
-
payload: {
|
|
285
|
-
transaction: txB64,
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
paymentHeader = Buffer.from(JSON.stringify(v2Payload)).toString('base64');
|
|
289
|
-
headerName = 'payment-signature';
|
|
290
|
-
console.error('[cryptoiz-mcp] V2 tx ready, sending via payment-signature header');
|
|
291
|
-
} catch(e) {
|
|
292
|
-
console.error('[cryptoiz-mcp] V2 build failed: ' + e.message + ', falling back to V1');
|
|
293
|
-
useV2 = false;
|
|
294
|
-
}
|
|
295
|
-
} else {
|
|
296
|
-
useV2 = false;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (!useV2) {
|
|
300
|
-
console.error('[cryptoiz-mcp] V1 mode: sending USDC on-chain...');
|
|
301
|
-
var sig = await sendUSDC(amount);
|
|
302
|
-
console.error('[cryptoiz-mcp] V1 TX confirmed: ' + sig);
|
|
303
|
-
var v1Payload = { signature: sig };
|
|
304
|
-
paymentHeader = Buffer.from(JSON.stringify(v1Payload)).toString('base64');
|
|
305
|
-
headerName = 'x-payment';
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// Step 4: Retry with payment header
|
|
309
|
-
var headers2obj = {};
|
|
310
|
-
headers2obj[headerName] = paymentHeader;
|
|
311
|
-
var resp2 = await fetch(url, { headers: clientHeaders(headers2obj) });
|
|
312
|
-
|
|
313
|
-
// V2 settle failed? Auto-fallback to V1
|
|
314
|
-
if (resp2.status !== 200 && useV2) {
|
|
315
|
-
var v2ErrBody = await resp2.text();
|
|
316
|
-
console.error('[cryptoiz-mcp] V2 settle failed (' + resp2.status + '): ' + v2ErrBody.substring(0, 200));
|
|
317
|
-
console.error('[cryptoiz-mcp] Auto-fallback to V1 (sendUSDC on-chain)...');
|
|
318
|
-
try {
|
|
319
|
-
var fallbackSig = await sendUSDC(amount);
|
|
320
|
-
console.error('[cryptoiz-mcp] V1 fallback TX confirmed: ' + fallbackSig);
|
|
321
|
-
var v1FallbackPayload = { signature: fallbackSig };
|
|
322
|
-
var v1FallbackHeader = Buffer.from(JSON.stringify(v1FallbackPayload)).toString('base64');
|
|
323
|
-
resp2 = await fetch(url, { headers: clientHeaders({ 'x-payment': v1FallbackHeader }) });
|
|
324
|
-
} catch(fallbackErr) {
|
|
325
|
-
console.error('[cryptoiz-mcp] V1 fallback also failed: ' + fallbackErr.message);
|
|
326
|
-
throw new Error('V2 failed (' + v2ErrBody.substring(0, 100) + '), V1 fallback also failed: ' + fallbackErr.message);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (resp2.status !== 200) {
|
|
331
|
-
var errBody = await resp2.text();
|
|
332
|
-
throw new Error('Payment failed (' + resp2.status + '): ' + errBody);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
var receipt = resp2.headers.get('payment-response') || resp2.headers.get('x-payment-response');
|
|
336
|
-
if (receipt) {
|
|
337
|
-
try {
|
|
338
|
-
var receiptData = JSON.parse(Buffer.from(receipt, 'base64').toString('utf8'));
|
|
339
|
-
console.error('[cryptoiz-mcp] Payment receipt: TX=' + (receiptData.transaction || 'n/a') + ' via ' + (receiptData.version || 'unknown'));
|
|
340
|
-
} catch(e) {
|
|
341
|
-
// ignore receipt parse errors
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
var data = await resp2.json();
|
|
346
|
-
maybeNotifyUpdate(data, resp2.headers);
|
|
347
|
-
return data;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// ===== MCP SERVER SETUP =====
|
|
351
|
-
var TOOLS = [
|
|
352
|
-
{
|
|
353
|
-
name: 'get_whale_alpha',
|
|
354
|
-
description: 'Get top 20 smart money alpha signals from CryptoIZ Solana DEX scanner. Shows whale/dolphin accumulation patterns, entry timing, and risk scores. Cost: $0.05 USDC.',
|
|
355
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
name: 'get_whale_divergence',
|
|
359
|
-
description: 'Get divergence signals - hidden accumulation, breakout accumulation, classic divergence between price and whale activity. Cost: $0.02 USDC.',
|
|
360
|
-
inputSchema: {
|
|
361
|
-
type: 'object',
|
|
362
|
-
properties: {
|
|
363
|
-
timeframe: { type: 'string', description: 'Timeframe: 4h (default) or 1d', enum: ['4h', '1d'] },
|
|
364
|
-
},
|
|
365
|
-
required: [],
|
|
366
|
-
},
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
name: 'get_whale_accumulation',
|
|
370
|
-
description: 'Get tokens in accumulation phase with holder tier analysis (whale/dolphin/shrimp deltas). Smart money is entering these tokens. Cost: $0.02 USDC.',
|
|
371
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
372
|
-
},
|
|
373
|
-
{
|
|
374
|
-
name: 'get_whale_neutral',
|
|
375
|
-
description: 'Get tokens in neutral phase - no clear accumulation or distribution. Watch for phase transitions. Cost: $0.02 USDC.',
|
|
376
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
name: 'get_whale_distribution',
|
|
380
|
-
description: 'Get tokens in distribution phase - whale selling detected. Smart money is exiting. Consider closing positions or avoiding. Cost: $0.02 USDC.',
|
|
381
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
name: 'get_btc_regime',
|
|
385
|
-
description: 'Get Bitcoin macro regime, fear/greed index, futures signals, and technicals (RSI, EMA, MACD). Cost: $0.01 USDC.',
|
|
386
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
387
|
-
},
|
|
388
|
-
{
|
|
389
|
-
name: 'get_btc_futures_signal',
|
|
390
|
-
description: 'BTC futures scalping signal (35x leverage). Multi-timeframe: 4h regime filter (bull/bear) + 5m RSI entry trigger. Returns direction, entry, TP, SL, leverage recommendation, conviction score. Backtested 54% WR, PF 1.67, Sharpe 5.0 on 90d. Cost: $0.03 USDC.',
|
|
391
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
name: 'get_token_ca',
|
|
395
|
-
description: 'Look up a Solana token contract address by name. FREE - no payment required.',
|
|
396
|
-
inputSchema: {
|
|
397
|
-
type: 'object',
|
|
398
|
-
properties: {
|
|
399
|
-
name: { type: 'string', description: 'Token name to search for' },
|
|
400
|
-
},
|
|
401
|
-
required: ['name'],
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
name: 'get_status',
|
|
406
|
-
description: 'Check CryptoIZ MCP server status, available tools, and pricing. FREE.',
|
|
407
|
-
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
408
|
-
},
|
|
409
|
-
];
|
|
410
|
-
|
|
411
|
-
var server = new Server(
|
|
412
|
-
{ name: 'cryptoiz-mcp', version: VERSION },
|
|
413
|
-
{ capabilities: { tools: {} } }
|
|
414
|
-
);
|
|
415
|
-
|
|
416
|
-
server.setRequestHandler(ListToolsRequestSchema, async function() {
|
|
417
|
-
return { tools: TOOLS };
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
server.setRequestHandler(CallToolRequestSchema, async function(request) {
|
|
421
|
-
var toolName = request.params.name;
|
|
422
|
-
var args = request.params.arguments || {};
|
|
423
|
-
try {
|
|
424
|
-
var result = await callTool(toolName, args);
|
|
425
|
-
return {
|
|
426
|
-
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
427
|
-
};
|
|
428
|
-
} catch(e) {
|
|
429
|
-
return {
|
|
430
|
-
content: [{ type: 'text', text: 'Error: ' + e.message }],
|
|
431
|
-
isError: true,
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
async function main() {
|
|
437
|
-
var transport = new StdioServerTransport();
|
|
438
|
-
await server.connect(transport);
|
|
439
|
-
console.error('[cryptoiz-mcp] ' + VERSION + ' running on stdio (x402 V2 Dexter + V1 compat)');
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
main().catch(function(e) {
|
|
443
|
-
console.error('[cryptoiz-mcp] Fatal:', e.message);
|
|
444
|
-
process.exit(1);
|
|
445
|
-
});
|
|
1
|
+
'use strict';
|
|
2
|
+
var VERSION = 'v4.16.8';
|
|
3
|
+
var GATEWAY = 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-x402-gateway';
|
|
4
|
+
var TOOL_ENDPOINTS = {
|
|
5
|
+
get_whale_alpha: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-alpha-scanner',
|
|
6
|
+
get_whale_divergence: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-divergence',
|
|
7
|
+
get_whale_accumulation: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-accumulation',
|
|
8
|
+
get_whale_neutral: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-neutral',
|
|
9
|
+
get_whale_distribution: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-distribution',
|
|
10
|
+
get_btc_regime: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-btc-regime',
|
|
11
|
+
get_btc_futures_signal: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-btc-futures',
|
|
12
|
+
get_token_ca: GATEWAY,
|
|
13
|
+
get_status: GATEWAY,
|
|
14
|
+
};
|
|
15
|
+
var RECIPIENT = 'DsKmdkYx49Xc1WhqMUAztwhdYPTqieyC98VmnnJdgpXX';
|
|
16
|
+
var USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
17
|
+
var SOL_RPC = 'https://api.mainnet-beta.solana.com';
|
|
18
|
+
var TOKEN_PROGRAM = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';
|
|
19
|
+
var ATA_PROGRAM = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';
|
|
20
|
+
var MEMO_PROGRAM = 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr';
|
|
21
|
+
|
|
22
|
+
var _updateNotified = false;
|
|
23
|
+
function notifyUpdate(data, headers) {
|
|
24
|
+
if (_updateNotified) return;
|
|
25
|
+
if (!headers || headers.get('x-update-available') !== '1') return;
|
|
26
|
+
_updateNotified = true;
|
|
27
|
+
var latest = (data && data.version_latest) || '?';
|
|
28
|
+
var cmd = (data && data.update_command) || 'npm install -g cryptoiz-mcp@latest';
|
|
29
|
+
console.error('[cryptoiz-mcp] UPDATE: ' + VERSION + ' -> ' + latest + ' | Run: ' + cmd);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var Connection = require('@solana/web3.js').Connection;
|
|
33
|
+
var PublicKey = require('@solana/web3.js').PublicKey;
|
|
34
|
+
var Transaction = require('@solana/web3.js').Transaction;
|
|
35
|
+
var Keypair = require('@solana/web3.js').Keypair;
|
|
36
|
+
var _bs58mod = require('bs58'); var bs58 = _bs58mod.default || _bs58mod;
|
|
37
|
+
var Server = require('@modelcontextprotocol/sdk/server/index.js').Server;
|
|
38
|
+
var StdioServerTransport = require('@modelcontextprotocol/sdk/server/stdio.js').StdioServerTransport;
|
|
39
|
+
var CallToolRequestSchema = require('@modelcontextprotocol/sdk/types.js').CallToolRequestSchema;
|
|
40
|
+
var ListToolsRequestSchema = require('@modelcontextprotocol/sdk/types.js').ListToolsRequestSchema;
|
|
41
|
+
|
|
42
|
+
function getKeypair() {
|
|
43
|
+
var privKey = process.env.SVM_PRIVATE_KEY;
|
|
44
|
+
if (!privKey) throw new Error('SVM_PRIVATE_KEY not set in environment');
|
|
45
|
+
return Keypair.fromSecretKey(bs58.decode(privKey));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function findATA(wallet, mint) {
|
|
49
|
+
var walletPk = new PublicKey(wallet);
|
|
50
|
+
var mintPk = new PublicKey(mint);
|
|
51
|
+
var ataPk = new PublicKey(ATA_PROGRAM);
|
|
52
|
+
var tokPk = new PublicKey(TOKEN_PROGRAM);
|
|
53
|
+
return PublicKey.findProgramAddressSync([walletPk.toBuffer(), tokPk.toBuffer(), mintPk.toBuffer()], ataPk)[0];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// V1: direct on-chain USDC transfer + x402 memo for indexer
|
|
57
|
+
async function sendUSDC(amount, toolName) {
|
|
58
|
+
var kp = getKeypair();
|
|
59
|
+
var conn = new Connection(SOL_RPC, 'confirmed');
|
|
60
|
+
var userATA = findATA(kp.publicKey.toBase58(), USDC_MINT);
|
|
61
|
+
var recipientATA = findATA(RECIPIENT, USDC_MINT);
|
|
62
|
+
// TransferChecked ix
|
|
63
|
+
var keys = [
|
|
64
|
+
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
65
|
+
{ pubkey: new PublicKey(USDC_MINT), isSigner: false, isWritable: false },
|
|
66
|
+
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
67
|
+
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
68
|
+
];
|
|
69
|
+
var data = Buffer.alloc(9);
|
|
70
|
+
data[0] = 0x0c;
|
|
71
|
+
data.writeUInt32LE(amount & 0xFFFFFFFF, 1);
|
|
72
|
+
data.writeUInt32LE(Math.floor(amount / 0x100000000) & 0xFFFFFFFF, 5);
|
|
73
|
+
data[8] = 6;
|
|
74
|
+
var transferIx = { programId: new PublicKey(TOKEN_PROGRAM), keys: keys, data: data };
|
|
75
|
+
// Memo ix for x402scan indexer
|
|
76
|
+
var nonce = Date.now().toString(16) + Math.floor(Math.random() * 0xffff).toString(16);
|
|
77
|
+
var memoIx = {
|
|
78
|
+
programId: new PublicKey(MEMO_PROGRAM),
|
|
79
|
+
keys: [],
|
|
80
|
+
data: Buffer.from('x402:v1:' + (toolName || 'tool') + ':' + nonce, 'utf8')
|
|
81
|
+
};
|
|
82
|
+
var bh = await conn.getLatestBlockhash('confirmed');
|
|
83
|
+
var tx = new Transaction({ feePayer: kp.publicKey, blockhash: bh.blockhash, lastValidBlockHeight: bh.lastValidBlockHeight });
|
|
84
|
+
tx.add(memoIx);
|
|
85
|
+
tx.add(transferIx);
|
|
86
|
+
tx.sign(kp);
|
|
87
|
+
var sig = await conn.sendRawTransaction(tx.serialize(), { skipPreflight: false });
|
|
88
|
+
await conn.confirmTransaction({ signature: sig, blockhash: bh.blockhash, lastValidBlockHeight: bh.lastValidBlockHeight }, 'confirmed');
|
|
89
|
+
console.error('[cryptoiz-mcp] TX: ' + sig);
|
|
90
|
+
return sig;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function clientHeaders(extra) {
|
|
94
|
+
var h = { 'x-client-version': VERSION.replace(/^v/i, '') };
|
|
95
|
+
if (extra) for (var k in extra) if (Object.prototype.hasOwnProperty.call(extra, k)) h[k] = extra[k];
|
|
96
|
+
return h;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function callTool(toolName, args) {
|
|
100
|
+
var queryParts = ['tool=' + toolName];
|
|
101
|
+
if (toolName === 'get_whale_divergence' && args && args.timeframe) queryParts.push('tf=' + args.timeframe);
|
|
102
|
+
if (toolName === 'get_token_ca' && args && args.name) queryParts.push('name=' + encodeURIComponent(args.name));
|
|
103
|
+
var url = (TOOL_ENDPOINTS[toolName] || GATEWAY) + '?' + queryParts.join('&');
|
|
104
|
+
// Step 1: discovery
|
|
105
|
+
var resp1 = await fetch(url, { headers: clientHeaders() });
|
|
106
|
+
if (resp1.status === 200) { var d = await resp1.json(); notifyUpdate(d, resp1.headers); return d; }
|
|
107
|
+
if (resp1.status !== 402) throw new Error('Server error ' + resp1.status + ': ' + (await resp1.text()).substring(0, 200));
|
|
108
|
+
// Step 2: parse payment requirements
|
|
109
|
+
var payReq = null;
|
|
110
|
+
var prHeader = resp1.headers.get('payment-required');
|
|
111
|
+
if (prHeader) { try { var arr = JSON.parse(Buffer.from(prHeader, 'base64').toString('utf8')); if (arr && arr[0]) payReq = arr[0]; } catch(_e) {} }
|
|
112
|
+
if (!payReq) { var b402 = await resp1.json(); if (b402 && b402.accepts && b402.accepts[0]) payReq = b402.accepts[0]; }
|
|
113
|
+
if (!payReq) throw new Error('No payment requirements in 402');
|
|
114
|
+
var amount = parseInt(payReq.maxAmountRequired || payReq.amount || '10000');
|
|
115
|
+
console.error('[cryptoiz-mcp] Paying ' + (amount/1000000).toFixed(4) + ' USDC for ' + toolName);
|
|
116
|
+
// Step 3: V1 direct transfer
|
|
117
|
+
var sig = await sendUSDC(amount, toolName);
|
|
118
|
+
// Step 4: submit
|
|
119
|
+
var resp2 = await fetch(url, { headers: clientHeaders({ 'x-payment': Buffer.from(JSON.stringify({ signature: sig })).toString('base64') }) });
|
|
120
|
+
if (resp2.status !== 200) throw new Error('Payment failed ' + resp2.status + ': ' + (await resp2.text()).substring(0, 300));
|
|
121
|
+
var data = await resp2.json();
|
|
122
|
+
notifyUpdate(data, resp2.headers);
|
|
123
|
+
return data;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
var TOOLS = [
|
|
127
|
+
{ name: 'get_whale_alpha', description: 'Alpha scanner - early accumulation tokens. Cost: $0.05 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
128
|
+
{ name: 'get_whale_divergence', description: 'Whale divergence signals. Cost: $0.02 USDC', inputSchema: { type: 'object', properties: { timeframe: { type: 'string', enum: ['4h', '1d'] } }, additionalProperties: false } },
|
|
129
|
+
{ name: 'get_whale_accumulation', description: 'Accumulation phase tokens. Cost: $0.02 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
130
|
+
{ name: 'get_whale_neutral', description: 'Neutral phase tokens. Cost: $0.02 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
131
|
+
{ name: 'get_whale_distribution', description: 'Distribution phase tokens. Cost: $0.02 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
132
|
+
{ name: 'get_btc_regime', description: 'BTC macro regime. Cost: $0.01 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
133
|
+
{ name: 'get_btc_futures_signal', description: 'BTC futures signal. Cost: $0.03 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
134
|
+
{ name: 'get_token_ca', description: 'Token contract address by name. FREE', inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'], additionalProperties: false } },
|
|
135
|
+
{ name: 'get_status', description: 'CryptoIZ MCP status. FREE', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
var server = new Server({ name: 'cryptoiz-mcp', version: VERSION }, { capabilities: { tools: {} } });
|
|
139
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
140
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
141
|
+
try {
|
|
142
|
+
var result = await callTool(request.params.name, request.params.arguments || {});
|
|
143
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
144
|
+
} catch(e) {
|
|
145
|
+
return { content: [{ type: 'text', text: 'Error: ' + e.message }], isError: true };
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
async function main() {
|
|
150
|
+
var transport = new StdioServerTransport();
|
|
151
|
+
await server.connect(transport);
|
|
152
|
+
console.error('[cryptoiz-mcp] ' + VERSION + ' running (V1 direct)');
|
|
153
|
+
}
|
|
154
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,53 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "cryptoiz-mcp",
|
|
3
|
-
"version": "4.16.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
"cryptoiz-mcp": "./
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=18.0.0"
|
|
25
|
-
},
|
|
26
|
-
"keywords": [
|
|
27
|
-
"mcp",
|
|
28
|
-
"mcp-server",
|
|
29
|
-
"claude",
|
|
30
|
-
"solana",
|
|
31
|
-
"crypto",
|
|
32
|
-
"trading",
|
|
33
|
-
"x402",
|
|
34
|
-
"usdc",
|
|
35
|
-
"dexter",
|
|
36
|
-
"whale-tracking",
|
|
37
|
-
"whale-intelligence",
|
|
38
|
-
"smart-money",
|
|
39
|
-
"alpha-signals",
|
|
40
|
-
"divergence",
|
|
41
|
-
"accumulation",
|
|
42
|
-
"distribution",
|
|
43
|
-
"defi",
|
|
44
|
-
"dex"
|
|
45
|
-
],
|
|
46
|
-
"author": "CryptoIZ",
|
|
47
|
-
"license": "MIT",
|
|
48
|
-
"homepage": "https://cryptoiz.org/McpLanding",
|
|
49
|
-
"repository": {
|
|
50
|
-
"type": "git",
|
|
51
|
-
"url": "https://github.com/dadang11/cryptoiz-mcp"
|
|
52
|
-
}
|
|
53
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "cryptoiz-mcp",
|
|
3
|
+
"version": "4.16.8",
|
|
4
|
+
"description": "CryptoIZ MCP Server - Solana DEX whale intelligence via Claude Desktop with x402 USDC micropayments",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cryptoiz-mcp": "./index.js",
|
|
9
|
+
"cryptoiz-mcp-setup": "./setup.js"
|
|
10
|
+
},
|
|
11
|
+
"files": ["index.js", "setup.js", "package.json", "README.md"],
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
14
|
+
"@solana/web3.js": "^1.95.8",
|
|
15
|
+
"bs58": "^6.0.0"
|
|
16
|
+
},
|
|
17
|
+
"engines": { "node": ">=18.0.0" },
|
|
18
|
+
"author": "CryptoIZ",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": { "type": "git", "url": "git+https://github.com/dadang11/cryptoiz-mcp.git" }
|
|
21
|
+
}
|
package/setup.js
CHANGED
|
@@ -1,132 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
function buildEntry(key) {
|
|
53
|
-
if (os.platform() === 'win32') {
|
|
54
|
-
var pkgPath = findPackagePath();
|
|
55
|
-
if (!pkgPath) { print('ERROR: Run npm install -g cryptoiz-mcp first'); process.exit(1); }
|
|
56
|
-
return { command: process.execPath, args: [pkgPath], env: { SVM_PRIVATE_KEY: key } };
|
|
57
|
-
}
|
|
58
|
-
return { command: 'npx', args: ['-y', 'cryptoiz-mcp@' + VERSION.replace('v','')], env: { SVM_PRIVATE_KEY: key } };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function injectConfig(cfgPath, entry) {
|
|
62
|
-
var config = {};
|
|
63
|
-
if (fs.existsSync(cfgPath)) {
|
|
64
|
-
try { config = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); } catch(e) {
|
|
65
|
-
fs.copyFileSync(cfgPath, cfgPath + '.backup.' + Date.now());
|
|
66
|
-
print('Config had error. Backup created.');
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (!config.mcpServers) config.mcpServers = {};
|
|
70
|
-
if (config.mcpServers.cryptoiz) print('Updating existing CryptoIZ entry...');
|
|
71
|
-
config.mcpServers.cryptoiz = entry;
|
|
72
|
-
var dir = path.dirname(cfgPath);
|
|
73
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
74
|
-
fs.writeFileSync(cfgPath, JSON.stringify(config, null, 2), 'utf8');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
var key = (process.argv[2] || '').trim();
|
|
78
|
-
|
|
79
|
-
print('');
|
|
80
|
-
print('========================================');
|
|
81
|
-
print(' CryptoIZ MCP Installer ' + VERSION);
|
|
82
|
-
print('========================================');
|
|
83
|
-
print('OS: ' + os.platform() + ' ' + os.arch());
|
|
84
|
-
|
|
85
|
-
if (!key) {
|
|
86
|
-
print('');
|
|
87
|
-
print('Usage:');
|
|
88
|
-
print(' npx cryptoiz-mcp-setup YOUR_PRIVATE_KEY');
|
|
89
|
-
print('');
|
|
90
|
-
print('Example:');
|
|
91
|
-
print(' npx cryptoiz-mcp-setup 5MaiiCavjCmn9Hs1o...');
|
|
92
|
-
print('');
|
|
93
|
-
print('SECURITY:');
|
|
94
|
-
print('- Use a DEDICATED wallet (not main wallet)');
|
|
95
|
-
print('- Fund with $1-5 USDC only, no SOL needed');
|
|
96
|
-
print('- Export: Phantom > Settings > Security > Export Private Key');
|
|
97
|
-
print('');
|
|
98
|
-
print('Guide: cryptoiz.org/McpLanding');
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
var chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
103
|
-
if (key.length < 40 || key.length > 100) { print('ERROR: Invalid key length (' + key.length + ' chars). Expected 44-88.'); process.exit(1); }
|
|
104
|
-
for (var i = 0; i < key.length; i++) {
|
|
105
|
-
if (chars.indexOf(key[i]) === -1) { print('ERROR: Invalid base58 character at position ' + i + ': "' + key[i] + '"'); process.exit(1); }
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
var cfgPath = findConfigPath();
|
|
109
|
-
if (!cfgPath) { print('ERROR: Claude Desktop not found.'); process.exit(1); }
|
|
110
|
-
print('Config: ' + cfgPath);
|
|
111
|
-
|
|
112
|
-
if (os.platform() === 'win32') {
|
|
113
|
-
print('[Windows] absolute paths mode');
|
|
114
|
-
var pkg = findPackagePath();
|
|
115
|
-
if (!pkg) { print('Run: npm install -g cryptoiz-mcp'); process.exit(1); }
|
|
116
|
-
print('Node: ' + process.execPath);
|
|
117
|
-
print('Package: ' + pkg);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
injectConfig(cfgPath, buildEntry(key));
|
|
121
|
-
|
|
122
|
-
print('');
|
|
123
|
-
print('SETUP COMPLETE!');
|
|
124
|
-
print('Config: ' + cfgPath);
|
|
125
|
-
print('');
|
|
126
|
-
print('Next:');
|
|
127
|
-
print('1. Close Claude Desktop completely');
|
|
128
|
-
print('2. Reopen Claude Desktop');
|
|
129
|
-
print('3. Type: get_status');
|
|
130
|
-
print('');
|
|
131
|
-
print('Guide: cryptoiz.org/McpLanding');
|
|
132
|
-
print('');
|
|
1
|
+
'use strict';
|
|
2
|
+
var VERSION = 'v4.16.7';
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var os = require('os');
|
|
5
|
+
var path = require('path');
|
|
6
|
+
|
|
7
|
+
var privKey = process.argv[2];
|
|
8
|
+
if (!privKey) {
|
|
9
|
+
console.log('Usage: npx cryptoiz-mcp-setup YOUR_SOLANA_PRIVATE_KEY');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var config = {
|
|
14
|
+
mcpServers: {
|
|
15
|
+
cryptoiz: {
|
|
16
|
+
command: 'C:\\Program Files\\nodejs\\node.exe',
|
|
17
|
+
args: [require.resolve('./index.js')],
|
|
18
|
+
env: { SVM_PRIVATE_KEY: privKey }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
var configPaths = [
|
|
24
|
+
path.join(process.env.LOCALAPPDATA || '', 'Packages', 'Claude_pzs8sxrjxfjjc', 'LocalCache', 'Roaming', 'Claude', 'claude_desktop_config.json'),
|
|
25
|
+
path.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json'),
|
|
26
|
+
path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
var written = false;
|
|
30
|
+
for (var i = 0; i < configPaths.length; i++) {
|
|
31
|
+
var p = configPaths[i];
|
|
32
|
+
try {
|
|
33
|
+
var dir = path.dirname(p);
|
|
34
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
35
|
+
var existing = {};
|
|
36
|
+
if (fs.existsSync(p)) {
|
|
37
|
+
try { existing = JSON.parse(fs.readFileSync(p, 'utf8')); } catch(_e) {}
|
|
38
|
+
}
|
|
39
|
+
existing.mcpServers = existing.mcpServers || {};
|
|
40
|
+
existing.mcpServers.cryptoiz = config.mcpServers.cryptoiz;
|
|
41
|
+
fs.writeFileSync(p, JSON.stringify(existing, null, 2), 'utf8');
|
|
42
|
+
console.log('Config written to: ' + p);
|
|
43
|
+
written = true;
|
|
44
|
+
} catch(_e) {}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (written) {
|
|
48
|
+
console.log('Done! Restart Claude Desktop to activate CryptoIZ MCP.');
|
|
49
|
+
} else {
|
|
50
|
+
console.log('Could not write config. Please manually add config to Claude Desktop settings.');
|
|
51
|
+
}
|