cryptoiz-mcp 4.7.0 → 4.9.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 (2) hide show
  1. package/package.json +14 -3
  2. package/src/index.js +87 -28
package/package.json CHANGED
@@ -1,13 +1,24 @@
1
1
  {
2
2
  "name": "cryptoiz-mcp",
3
- "version": "4.7.0",
3
+ "version": "4.9.0",
4
4
  "description": "CryptoIZ MCP Server — Solana DEX signals with x402 micropayments. Pay $0.01 USDC per call.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
7
  "bin": {
8
8
  "cryptoiz-mcp": "src/index.js"
9
9
  },
10
- "keywords": ["cryptoiz", "solana", "defi", "mcp", "claude", "crypto", "alpha", "signals", "x402", "usdc"],
10
+ "keywords": [
11
+ "cryptoiz",
12
+ "solana",
13
+ "defi",
14
+ "mcp",
15
+ "claude",
16
+ "crypto",
17
+ "alpha",
18
+ "signals",
19
+ "x402",
20
+ "usdc"
21
+ ],
11
22
  "author": "CryptoIZ <cryptoiz.suport@gmail.com> (https://cryptoiz.org)",
12
23
  "license": "MIT",
13
24
  "repository": {
@@ -24,4 +35,4 @@
24
35
  "engines": {
25
36
  "node": ">=18.0.0"
26
37
  }
27
- }
38
+ }
package/src/index.js CHANGED
@@ -2,11 +2,14 @@
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
- import { Connection, Keypair, PublicKey, Transaction } from '@solana/web3.js';
6
- import { getOrCreateAssociatedTokenAccount, createTransferInstruction } from '@solana/spl-token';
5
+ import { Connection, Keypair, PublicKey, VersionedTransaction, TransactionMessage } from '@solana/web3.js';
6
+ import { getAssociatedTokenAddress, createTransferInstruction } from '@solana/spl-token';
7
7
  import bs58 from 'bs58';
8
8
 
9
9
  const GATEWAY_URL = 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-x402-gateway';
10
+ const DEXTER_FACILITATOR = 'https://x402.dexter.cash';
11
+ const DEXTER_FEE_PAYER = new PublicKey('DEXVS3su4dZQWTvvPnLDJLRK1CeeKG6K3QqdzthgAkNV');
12
+ const SOLANA_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';
10
13
  const SVM_PRIVATE_KEY = process.env.SVM_PRIVATE_KEY || '';
11
14
  const CRYPTOIZ_WALLET = new PublicKey('DsKmdkYx49Xc1WhqMUAztwhdYPTqieyC98VmnnJdgpXX');
12
15
  const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
@@ -25,29 +28,71 @@ const PRICE_LABELS = {
25
28
  get_btc_regime: '$0.01',
26
29
  };
27
30
 
31
+ const fetchWithTimeout = (u, opts = {}, ms = 20000) => {
32
+ const ctrl = new AbortController();
33
+ const t = setTimeout(() => ctrl.abort(), ms);
34
+ return fetch(u, { ...opts, signal: ctrl.signal }).finally(() => clearTimeout(t));
35
+ };
36
+
28
37
  async function payAndFetch(url, tool = 'get_alpha_scanner') {
29
38
  const AMOUNT = PRICES[tool] || 10000;
30
- if (!SVM_PRIVATE_KEY) return { error: 'SVM_PRIVATE_KEY not set.' };
31
- // Timeout: 20s for initial check, 30s for paid request
32
- const fetchWithTimeout = (u, opts = {}, ms = 20000) => {
33
- const ctrl = new AbortController();
34
- const t = setTimeout(() => ctrl.abort(), ms);
35
- return fetch(u, { ...opts, signal: ctrl.signal }).finally(() => clearTimeout(t));
36
- };
39
+ if (!SVM_PRIVATE_KEY) return { error: 'SVM_PRIVATE_KEY not set. Add SVM_PRIVATE_KEY to Claude Desktop config.' };
40
+
41
+ // Step 1: First fetch to trigger 402
37
42
  let first;
38
43
  try { first = await fetchWithTimeout(url, {}, 20000); }
39
44
  catch (e) { return { error: `Gateway timeout or unreachable: ${e.message}` }; }
40
45
  if (first.status !== 402) return first.json();
46
+
41
47
  try {
48
+ // Step 2: Build Solana VersionedTransaction with Dexter as fee payer
42
49
  const keypair = Keypair.fromSecretKey(bs58.decode(SVM_PRIVATE_KEY));
43
50
  const connection = new Connection(SOL_RPC, 'confirmed');
44
- const fromAta = await getOrCreateAssociatedTokenAccount(connection, keypair, USDC_MINT, keypair.publicKey);
45
- const toAta = await getOrCreateAssociatedTokenAccount(connection, keypair, USDC_MINT, CRYPTOIZ_WALLET);
46
- const tx = new Transaction().add(createTransferInstruction(fromAta.address, toAta.address, keypair.publicKey, AMOUNT));
47
- const sig = await connection.sendTransaction(tx, [keypair]);
48
- await connection.confirmTransaction(sig, 'confirmed');
49
- const payment = Buffer.from(JSON.stringify({ signature: sig, network: 'solana', x402Version: 1 })).toString('base64');
50
- const paid = await fetchWithTimeout(url, { headers: { 'x-payment': payment } }, 30000);
51
+
52
+ // Compute ATAs (no creation user must have USDC already)
53
+ const fromAta = await getAssociatedTokenAddress(USDC_MINT, keypair.publicKey);
54
+ const toAta = await getAssociatedTokenAddress(USDC_MINT, CRYPTOIZ_WALLET);
55
+
56
+ // Get latest blockhash
57
+ const { blockhash } = await connection.getLatestBlockhash('confirmed');
58
+
59
+ // Build versioned message with Dexter as fee payer (Dexter sponsors SOL gas)
60
+ const message = new TransactionMessage({
61
+ payerKey: DEXTER_FEE_PAYER,
62
+ recentBlockhash: blockhash,
63
+ instructions: [
64
+ createTransferInstruction(fromAta, toAta, keypair.publicKey, AMOUNT)
65
+ ]
66
+ }).compileToV0Message();
67
+
68
+ const tx = new VersionedTransaction(message);
69
+ tx.sign([keypair]); // Partial sign — buyer signs, Dexter will add fee payer sig + submit
70
+
71
+ const serializedTx = Buffer.from(tx.serialize()).toString('base64');
72
+
73
+ // Step 3: Build x402 v2 paymentPayload
74
+ const paymentPayload = {
75
+ x402Version: 2,
76
+ resource: {
77
+ url,
78
+ description: `CryptoIZ ${tool} — ${PRICE_LABELS[tool] || '$0.01 USDC'}/call`,
79
+ mimeType: 'application/json',
80
+ },
81
+ accepted: {
82
+ scheme: 'exact',
83
+ network: SOLANA_NETWORK,
84
+ asset: USDC_MINT.toString(),
85
+ amount: String(AMOUNT),
86
+ payTo: CRYPTOIZ_WALLET.toString(),
87
+ maxTimeoutSeconds: 600,
88
+ },
89
+ payload: { transaction: serializedTx },
90
+ };
91
+
92
+ const paymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');
93
+
94
+ // Step 4: Retry with payment header — Dexter settles on-chain
95
+ const paid = await fetchWithTimeout(url, { headers: { 'x-payment': paymentHeader } }, 45000);
51
96
  return paid.json();
52
97
  } catch (err) {
53
98
  return { error: `Payment failed: ${err.message}` };
@@ -64,7 +109,12 @@ const dexLink = ca => ca ? `[Chart 📊](https://dexscreener.com/solana/${ca})`
64
109
  // ALPHA SCANNER — Markdown Table Format
65
110
  // ══════════════════════════════════════════════════════════════════
66
111
  function formatAlpha(data) {
67
- if (data.error) return `❌ **Error:** ${data.error}\n\nSetup: https://cryptoiz.org`;
112
+ if (data.error) return `❌ **Error:** ${data.error}\n\nSetup: https://cryptoiz.org/McpLanding`;
113
+
114
+ // Show signal quality warnings at top
115
+ let warnings = '';
116
+ if (data.signal_quality) warnings += `\n${data.signal_quality}\n`;
117
+ if (data.data_freshness) warnings += `\n${data.data_freshness}\n`;
68
118
  const signals = data.signals || [];
69
119
  const date = data.fetched_at?.split('T')[0];
70
120
 
@@ -348,20 +398,29 @@ async function getTokenCA(tokenName, data) {
348
398
  // ══════════════════════════════════════════════════════════════════
349
399
  function formatStatus() {
350
400
  const walletReady = !!SVM_PRIVATE_KEY;
401
+ const securityWarning = [
402
+ ``,
403
+ `> 🔐 **SECURITY WARNING**`,
404
+ `> Use a **dedicated wallet** with max $5 USDC + 0.01 SOL.`,
405
+ `> **NEVER** use your main wallet. **NEVER** share your config file.`,
406
+ `> If compromised → create a new wallet immediately.`,
407
+ ``,
408
+ ].join('\n');
409
+
351
410
  return [
352
- `## ⚡ CryptoIZ MCP Server v4.5.0`,
411
+ `## ⚡ CryptoIZ MCP Server v4.7.0`,
353
412
  `**AI-Powered Solana DEX Smart Money Signals — Pay Per Call via Solana USDC**`,
354
413
  ``,
355
414
  `> Detect whale accumulation, divergence signals, and BTC macro regime directly in Claude Desktop.`,
356
415
  `> No subscription needed — pay only when you call.`,
357
- ``,
416
+ securityWarning,
358
417
  `---`,
359
418
  ``,
360
419
  `### 🔌 Connection Status`,
361
420
  ``,
362
421
  `| | |`,
363
422
  `|-|-|`,
364
- `| Server | ✅ Connected |`,
423
+ `| Server | ✅ Connected — v4.7.0 |`,
365
424
  `| Wallet | ${walletReady ? '✅ Ready — USDC payments enabled' : '❌ Not configured — add SVM_PRIVATE_KEY to Claude Desktop config'} |`,
366
425
  `| Network | Solana Mainnet · USDC payments |`,
367
426
  `| Platform | https://cryptoiz.org |`,
@@ -372,11 +431,11 @@ function formatStatus() {
372
431
  ``,
373
432
  `| Tool | What You Get | Cost |`,
374
433
  `|------|-------------|------|`,
375
- `| \`get_alpha_scanner\` | Top 20 ALPHA_EARLY + ALPHA_BUILDING signals. Score, phase, whale/dolphin delta, MC now vs signal MC, risk flags, CA + DexScreener chart | **$0.05 USDC** |`,
434
+ `| \`get_alpha_scanner\` | Top signals (ALPHA_EARLY + BUILDING + WATCHLIST). Score, phase, whale/dolphin delta, MC now vs signal MC, risk flags, CA + chart + Jupiter buy link | **$0.05 USDC** |`,
376
435
  `| \`get_divergence\` | 3 divergence types (Hidden/Breakout/Classic). Score, confidence, whale holders now vs prev, dolphin delta, MC, CA + chart | **$0.02 USDC** |`,
377
- `| \`get_accumulation\` | 4-dimension accumulation score (Structure/AccDist/Holder/Market). Top 20 tokens in accumulation with CA + chart | **$0.02 USDC** |`,
378
- `| \`get_btc_regime\` | BTC macro: regime (Bull/Bear/Neutral), Fear & Greed, OI regime, funding rate, RSI/EMA/MACD (1H), altcoin recommendation | **$0.01 USDC** |`,
379
- `| \`get_token_ca\` | Exact contract address lookup + DexScreener link. Protects against fake/scam tokens with same name | **FREE** |`,
436
+ `| \`get_accumulation\` | 4-dimension accumulation score (Structure/AccDist/Holder/Market). Top 20 tokens with CA + chart | **$0.02 USDC** |`,
437
+ `| \`get_btc_regime\` | BTC macro: regime (Bull/Bear/Neutral), Fear & Greed, OI regime, funding rate, RSI/EMA/MACD (1H) | **$0.01 USDC** |`,
438
+ `| \`get_token_ca\` | Contract address lookup + DexScreener + Jupiter. Protects against scam tokens with same name | **FREE** |`,
380
439
  `| \`get_status\` | This status page | **FREE** |`,
381
440
  ``,
382
441
  `---`,
@@ -384,12 +443,12 @@ function formatStatus() {
384
443
  `### 💡 Quick Start`,
385
444
  ``,
386
445
  `\`\`\``,
387
- `get_status ← you are here`,
446
+ `get_status ← you are here (free)`,
447
+ `get token ca [name] ← verify any token CA (free)`,
388
448
  `get btc regime ← check macro first ($0.01)`,
389
449
  `get alpha scanner ← find best entry signals ($0.05)`,
390
450
  `get divergence scanner ← find reversal signals ($0.02)`,
391
451
  `get accumulation dashboard ← find tokens in accumulation ($0.02)`,
392
- `get token ca [name] ← verify any token CA (free)`,
393
452
  `\`\`\``,
394
453
  ``,
395
454
  `---`,
@@ -403,7 +462,7 @@ function formatStatus() {
403
462
  `| 3 Months | **$120** | Serious investors |`,
404
463
  `| 1 Year | **$400** | Best value |`,
405
464
  ``,
406
- `Full platform includes: visual charts, real-time alerts, Phase Leaderboard, Episode Feed, VIP Telegram signals.`,
465
+ `Full platform: visual charts, real-time alerts, Phase Leaderboard, Episode Feed, VIP Telegram.`,
407
466
  ``,
408
467
  `🔗 **Subscribe:** https://cryptoiz.org/Pricing`,
409
468
  `🔗 **Setup Guide:** https://cryptoiz.org/McpLanding`,
@@ -427,7 +486,7 @@ const TOOLS = [
427
486
  // ══════════════════════════════════════════════════════════════════
428
487
  // SERVER
429
488
  // ══════════════════════════════════════════════════════════════════
430
- const server = new Server({ name: 'cryptoiz-mcp', version: '4.6.0' }, { capabilities: { tools: {} } });
489
+ const server = new Server({ name: 'cryptoiz-mcp', version: '4.7.0' }, { capabilities: { tools: {} } });
431
490
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
432
491
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
433
492
  const { name, arguments: args } = request.params;