cryptoiz-mcp 4.14.0 → 4.15.1
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 +51 -0
- package/index.js +334 -108
- package/package.json +31 -11
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# CryptoIZ MCP Server
|
|
2
|
+
|
|
3
|
+
Solana DEX trading signals for Claude Desktop via x402 USDC micropayments.
|
|
4
|
+
|
|
5
|
+
## v4.15.0 — x402 V2 (Dexter Facilitator)
|
|
6
|
+
|
|
7
|
+
**NEW:** Dexter facilitator sponsors gas fees. Users only need USDC, no SOL required for transaction fees.
|
|
8
|
+
|
|
9
|
+
### Payment Protocol
|
|
10
|
+
|
|
11
|
+
- **V2 (default):** Client builds partially-signed tx → edge function forwards to Dexter `/settle` → Dexter adds feePayer signature, submits on-chain, sponsors gas
|
|
12
|
+
- **V1 (fallback):** Client sends USDC on-chain → edge function verifies via Solana RPC
|
|
13
|
+
|
|
14
|
+
### Setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g cryptoiz-mcp@4.15.0
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Claude Desktop Config (Windows)
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"cryptoiz": {
|
|
26
|
+
"command": "C:\\Program Files\\nodejs\\node.exe",
|
|
27
|
+
"args": ["C:\\Users\\CRYPT0_iz\\AppData\\Roaming\\npm\\node_modules\\cryptoiz-mcp\\index.js"],
|
|
28
|
+
"env": {
|
|
29
|
+
"SVM_PRIVATE_KEY": "your-base58-solana-private-key"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Tools & Pricing
|
|
37
|
+
|
|
38
|
+
| Tool | Price | Data |
|
|
39
|
+
|------|-------|------|
|
|
40
|
+
| `get_alpha_scanner` | $0.05 USDC | 20 smart money signals |
|
|
41
|
+
| `get_divergence` | $0.02 USDC | 20 divergence signals |
|
|
42
|
+
| `get_accumulation` | $0.02 USDC | 20 accumulation tokens |
|
|
43
|
+
| `get_btc_regime` | $0.01 USDC | BTC macro + technicals |
|
|
44
|
+
| `get_token_ca` | FREE | Contract address lookup |
|
|
45
|
+
| `get_status` | FREE | Server status |
|
|
46
|
+
|
|
47
|
+
### Links
|
|
48
|
+
|
|
49
|
+
- Platform: https://cryptoiz.org
|
|
50
|
+
- Setup Guide: https://cryptoiz.org/McpLanding
|
|
51
|
+
- Twitter: @cryptoiz_IDN
|
package/index.js
CHANGED
|
@@ -1,131 +1,357 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// CryptoIZ MCP Server v4.15.0
|
|
3
|
+
// x402 V2: Dexter facilitator (gas sponsored) + V1 backward compat
|
|
4
|
+
// ZERO template literals — Windows PowerShell safe
|
|
2
5
|
|
|
3
6
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
7
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
8
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
-
import { Connection, Keypair, PublicKey, Transaction } from '@solana/web3.js';
|
|
9
|
+
import { Connection, Keypair, PublicKey, Transaction, SystemProgram, VersionedTransaction, TransactionMessage } from '@solana/web3.js';
|
|
7
10
|
import bs58 from 'bs58';
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
var VERSION = 'v4.15.1';
|
|
13
|
+
var GATEWAY = 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-x402-gateway';
|
|
14
|
+
var RECIPIENT = 'DsKmdkYx49Xc1WhqMUAztwhdYPTqieyC98VmnnJdgpXX';
|
|
15
|
+
var USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
16
|
+
var DEXTER_FEE_PAYER = 'DEXVS3su4dZQWTvvPnLDJLRK1CeeKG6K3QqdzthgAkNV';
|
|
17
|
+
var SOL_RPC = 'https://api.mainnet-beta.solana.com';
|
|
18
|
+
var TOKEN_PROGRAM = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';
|
|
19
|
+
var ATA_PROGRAM = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';
|
|
20
|
+
var DEV_KEY = process.env.CRYPTOIZ_DEV_KEY || '';
|
|
17
21
|
|
|
18
22
|
function getKeypair() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
var privKey = process.env.SVM_PRIVATE_KEY;
|
|
24
|
+
if (!privKey) throw new Error('SVM_PRIVATE_KEY env var not set');
|
|
25
|
+
try {
|
|
26
|
+
var decoded = bs58.decode(privKey);
|
|
27
|
+
return Keypair.fromSecretKey(decoded);
|
|
28
|
+
} catch(e) {
|
|
29
|
+
throw new Error('Invalid SVM_PRIVATE_KEY: ' + e.message);
|
|
30
|
+
}
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
function findATA(wallet, mint) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
29
|
-
|
|
34
|
+
var walletPk = new PublicKey(wallet);
|
|
35
|
+
var mintPk = new PublicKey(mint);
|
|
36
|
+
var ataProgramPk = new PublicKey(ATA_PROGRAM);
|
|
37
|
+
var tokenProgramPk = new PublicKey(TOKEN_PROGRAM);
|
|
38
|
+
var seeds = [walletPk.toBuffer(), tokenProgramPk.toBuffer(), mintPk.toBuffer()];
|
|
39
|
+
var ata = PublicKey.findProgramAddressSync(seeds, ataProgramPk);
|
|
40
|
+
return ata[0];
|
|
30
41
|
}
|
|
31
42
|
|
|
43
|
+
// ===== V2: Build partially-signed tx for Dexter facilitator =====
|
|
44
|
+
// Dexter pays gas (feePayer), user only signs the transfer
|
|
45
|
+
async function buildV2PaymentPayload(amount) {
|
|
46
|
+
var kp = getKeypair();
|
|
47
|
+
var conn = new Connection(SOL_RPC, 'confirmed');
|
|
48
|
+
|
|
49
|
+
var userATA = findATA(kp.publicKey.toBase58(), USDC_MINT);
|
|
50
|
+
var recipientATA = findATA(RECIPIENT, USDC_MINT);
|
|
51
|
+
var feePayerPk = new PublicKey(DEXTER_FEE_PAYER);
|
|
52
|
+
|
|
53
|
+
// Build SPL Token transfer instruction
|
|
54
|
+
var tokenProgramPk = new PublicKey(TOKEN_PROGRAM);
|
|
55
|
+
var keys = [
|
|
56
|
+
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
57
|
+
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
58
|
+
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
// SPL Token Transfer instruction data: instruction index 3 + u64 amount (LE)
|
|
62
|
+
var data = Buffer.alloc(9);
|
|
63
|
+
data.writeUInt8(3, 0); // Transfer instruction index
|
|
64
|
+
// Write amount as u64 LE
|
|
65
|
+
var lo = amount & 0xFFFFFFFF;
|
|
66
|
+
var hi = Math.floor(amount / 0x100000000) & 0xFFFFFFFF;
|
|
67
|
+
data.writeUInt32LE(lo, 1);
|
|
68
|
+
data.writeUInt32LE(hi, 5);
|
|
69
|
+
|
|
70
|
+
var transferIx = {
|
|
71
|
+
programId: tokenProgramPk,
|
|
72
|
+
keys: keys,
|
|
73
|
+
data: data,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Get recent blockhash
|
|
77
|
+
var bhResult = await conn.getLatestBlockhash('confirmed');
|
|
78
|
+
|
|
79
|
+
// Build V0 message with Dexter as feePayer
|
|
80
|
+
var message = new TransactionMessage({
|
|
81
|
+
payerKey: feePayerPk,
|
|
82
|
+
recentBlockhash: bhResult.blockhash,
|
|
83
|
+
instructions: [transferIx],
|
|
84
|
+
}).compileToV0Message();
|
|
85
|
+
|
|
86
|
+
var vtx = new VersionedTransaction(message);
|
|
87
|
+
|
|
88
|
+
// Partially sign with user keypair only (Dexter signs as feePayer later)
|
|
89
|
+
vtx.sign([kp]);
|
|
90
|
+
|
|
91
|
+
// Serialize and base64 encode
|
|
92
|
+
var serialized = vtx.serialize();
|
|
93
|
+
var txB64 = Buffer.from(serialized).toString('base64');
|
|
94
|
+
|
|
95
|
+
return txB64;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ===== V1 FALLBACK: Send USDC on-chain, return signature =====
|
|
32
99
|
async function sendUSDC(amount) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
100
|
+
var kp = getKeypair();
|
|
101
|
+
var conn = new Connection(SOL_RPC, 'confirmed');
|
|
102
|
+
|
|
103
|
+
var userATA = findATA(kp.publicKey.toBase58(), USDC_MINT);
|
|
104
|
+
var recipientATA = findATA(RECIPIENT, USDC_MINT);
|
|
105
|
+
|
|
106
|
+
var tokenProgramPk = new PublicKey(TOKEN_PROGRAM);
|
|
107
|
+
var keys = [
|
|
108
|
+
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
109
|
+
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
110
|
+
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
var data = Buffer.alloc(9);
|
|
114
|
+
data.writeUInt8(3, 0);
|
|
115
|
+
var lo = amount & 0xFFFFFFFF;
|
|
116
|
+
var hi = Math.floor(amount / 0x100000000) & 0xFFFFFFFF;
|
|
117
|
+
data.writeUInt32LE(lo, 1);
|
|
118
|
+
data.writeUInt32LE(hi, 5);
|
|
119
|
+
|
|
120
|
+
var transferIx = {
|
|
121
|
+
programId: tokenProgramPk,
|
|
122
|
+
keys: keys,
|
|
123
|
+
data: data,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
var bhResult = await conn.getLatestBlockhash('confirmed');
|
|
127
|
+
var tx = new Transaction({
|
|
128
|
+
feePayer: kp.publicKey,
|
|
129
|
+
blockhash: bhResult.blockhash,
|
|
130
|
+
lastValidBlockHeight: bhResult.lastValidBlockHeight,
|
|
131
|
+
});
|
|
132
|
+
tx.add(transferIx);
|
|
133
|
+
tx.sign(kp);
|
|
134
|
+
|
|
135
|
+
var rawTx = tx.serialize();
|
|
136
|
+
var sig = await conn.sendRawTransaction(rawTx, { skipPreflight: false });
|
|
137
|
+
await conn.confirmTransaction({ signature: sig, blockhash: bhResult.blockhash, lastValidBlockHeight: bhResult.lastValidBlockHeight }, 'confirmed');
|
|
62
138
|
return sig;
|
|
63
139
|
}
|
|
64
140
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
141
|
+
// ===== TOOL CALL HANDLER =====
|
|
142
|
+
async function callTool(toolName, args) {
|
|
143
|
+
var toolParam = toolName;
|
|
144
|
+
var queryParts = ['tool=' + toolParam];
|
|
145
|
+
|
|
146
|
+
if (toolName === 'get_divergence' && args && args.timeframe) {
|
|
147
|
+
queryParts.push('tf=' + args.timeframe);
|
|
148
|
+
}
|
|
149
|
+
if (toolName === 'get_token_ca' && args && args.name) {
|
|
150
|
+
queryParts.push('name=' + encodeURIComponent(args.name));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
var url = GATEWAY + '?' + queryParts.join('&');
|
|
154
|
+
|
|
155
|
+
// Dev mode bypass
|
|
156
|
+
if (DEV_KEY) {
|
|
157
|
+
var devResp = await fetch(url, { headers: { 'x-dev-key': DEV_KEY } });
|
|
158
|
+
var devData = await devResp.json();
|
|
159
|
+
return devData;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Step 1: Fetch gateway — expect 402 or 200 (free tools)
|
|
163
|
+
var resp1 = await fetch(url);
|
|
164
|
+
|
|
165
|
+
if (resp1.status === 200) {
|
|
166
|
+
return await resp1.json();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (resp1.status !== 402) {
|
|
170
|
+
var errText = await resp1.text();
|
|
171
|
+
throw new Error('Gateway error ' + resp1.status + ': ' + errText);
|
|
74
172
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
const url = new URL(EDGE_FUNCTION_URL);
|
|
90
|
-
url.searchParams.set('tool', name);
|
|
91
|
-
if (name === 'get_divergence' && args.tf) url.searchParams.set('tf', args.tf);
|
|
92
|
-
if (name === 'get_token_ca' && args.name) url.searchParams.set('name', args.name);
|
|
93
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
94
|
-
if (DEV_SECRET) headers['x-dev-key'] = DEV_SECRET;
|
|
95
|
-
|
|
96
|
-
let response = await fetch(url.toString(), { headers });
|
|
97
|
-
|
|
98
|
-
if (response.status === 402 && SVM_PRIVATE_KEY && !DEV_SECRET) {
|
|
99
|
-
const payInfo = await response.json();
|
|
100
|
-
const accepts = payInfo.accepts;
|
|
101
|
-
if (!accepts || !accepts.length) throw new Error('No payment options');
|
|
102
|
-
const amt = parseInt(accepts[0].amount);
|
|
103
|
-
console.error('[Payment] ' + name + ' requires ' + amt + ' micro-USDC');
|
|
104
|
-
const sig = await sendUSDC(amt);
|
|
105
|
-
const proof = Buffer.from(JSON.stringify({ signature: sig })).toString('base64');
|
|
106
|
-
response = await fetch(url.toString(), { headers: { 'Content-Type':'application/json', 'x-payment': proof } });
|
|
107
|
-
if (!response.ok) {
|
|
108
|
-
const err = await response.text();
|
|
109
|
-
throw new Error('Payment OK but data failed (' + response.status + '): ' + err + ' Sig: ' + sig);
|
|
110
|
-
}
|
|
111
|
-
console.error('[Payment] Success! ' + name + ' paid & received.');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (response.status === 402) {
|
|
115
|
-
return { content:[{type:'text',text:'Payment required. Set SVM_PRIVATE_KEY in config.\nSetup: https://cryptoiz.org/McpLanding'}] };
|
|
116
|
-
}
|
|
117
|
-
if (!response.ok) throw new Error('HTTP ' + response.status + ': ' + (await response.text()));
|
|
118
|
-
return { content:[{type:'text',text:JSON.stringify(await response.json(), null, 2)}] };
|
|
119
|
-
} catch (error) {
|
|
120
|
-
return { content:[{type:'text',text:'Error calling ' + name + ': ' + error.message}], isError:true };
|
|
173
|
+
|
|
174
|
+
// Step 2: Parse 402 response — try V2 header first, fallback to body
|
|
175
|
+
var paymentRequirements = null;
|
|
176
|
+
var useV2 = false;
|
|
177
|
+
|
|
178
|
+
var prHeader = resp1.headers.get('payment-required');
|
|
179
|
+
if (prHeader) {
|
|
180
|
+
try {
|
|
181
|
+
var prDecoded = Buffer.from(prHeader, 'base64').toString('utf8');
|
|
182
|
+
var prArray = JSON.parse(prDecoded);
|
|
183
|
+
if (Array.isArray(prArray) && prArray.length > 0) {
|
|
184
|
+
paymentRequirements = prArray[0];
|
|
185
|
+
useV2 = true;
|
|
121
186
|
}
|
|
122
|
-
})
|
|
187
|
+
} catch(e) {
|
|
188
|
+
console.error('[cryptoiz-mcp] Failed to parse PAYMENT-REQUIRED header:', e.message);
|
|
189
|
+
}
|
|
123
190
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
191
|
+
|
|
192
|
+
// Fallback: read from body (V1 compat)
|
|
193
|
+
if (!paymentRequirements) {
|
|
194
|
+
var body402 = await resp1.json();
|
|
195
|
+
if (body402.accepts && body402.accepts.length > 0) {
|
|
196
|
+
paymentRequirements = body402.accepts[0];
|
|
197
|
+
} else {
|
|
198
|
+
throw new Error('402 response missing payment requirements');
|
|
199
|
+
}
|
|
128
200
|
}
|
|
201
|
+
|
|
202
|
+
var amount = parseInt(paymentRequirements.maxAmountRequired || paymentRequirements.amount || '10000');
|
|
203
|
+
var displayAmount = (amount / 1000000).toFixed(4);
|
|
204
|
+
var hasFeePayer = paymentRequirements.extra && paymentRequirements.extra.feePayer;
|
|
205
|
+
console.error('[cryptoiz-mcp] Payment required: ' + displayAmount + ' USDC for ' + toolName + (hasFeePayer ? ' (V2 Dexter)' : ' (V1 self-pay)'));
|
|
206
|
+
|
|
207
|
+
// Step 3: Build and send payment
|
|
208
|
+
var paymentHeader = '';
|
|
209
|
+
var headerName = '';
|
|
210
|
+
|
|
211
|
+
if (useV2 && paymentRequirements.extra && paymentRequirements.extra.feePayer) {
|
|
212
|
+
// V2: Build partially-signed tx, Dexter pays gas
|
|
213
|
+
console.error('[cryptoiz-mcp] V2 mode: building partial tx for Dexter gas sponsorship...');
|
|
214
|
+
try {
|
|
215
|
+
var txB64 = await buildV2PaymentPayload(amount);
|
|
216
|
+
|
|
217
|
+
// Build V2 payment payload per x402 spec
|
|
218
|
+
var v2Payload = {
|
|
219
|
+
x402Version: 2,
|
|
220
|
+
scheme: 'exact',
|
|
221
|
+
network: paymentRequirements.network || 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
|
|
222
|
+
payload: {
|
|
223
|
+
transaction: txB64,
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
paymentHeader = Buffer.from(JSON.stringify(v2Payload)).toString('base64');
|
|
228
|
+
headerName = 'payment-signature';
|
|
229
|
+
console.error('[cryptoiz-mcp] V2 partial tx built, sending via PAYMENT-SIGNATURE header');
|
|
230
|
+
} catch(e) {
|
|
231
|
+
console.error('[cryptoiz-mcp] V2 build failed: ' + e.message + ', falling back to V1');
|
|
232
|
+
useV2 = false;
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
// No feePayer in requirements — force V1
|
|
236
|
+
useV2 = false;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (!useV2) {
|
|
240
|
+
// V1 fallback: send USDC on-chain, then pass signature
|
|
241
|
+
console.error('[cryptoiz-mcp] V1 mode: sending USDC on-chain...');
|
|
242
|
+
var sig = await sendUSDC(amount);
|
|
243
|
+
console.error('[cryptoiz-mcp] V1 TX confirmed: ' + sig);
|
|
244
|
+
|
|
245
|
+
var v1Payload = { signature: sig };
|
|
246
|
+
paymentHeader = Buffer.from(JSON.stringify(v1Payload)).toString('base64');
|
|
247
|
+
headerName = 'x-payment';
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Step 4: Retry with payment header
|
|
251
|
+
var headers2 = {};
|
|
252
|
+
headers2[headerName] = paymentHeader;
|
|
253
|
+
|
|
254
|
+
var resp2 = await fetch(url, { headers: headers2 });
|
|
255
|
+
|
|
256
|
+
if (resp2.status !== 200) {
|
|
257
|
+
var errBody = await resp2.text();
|
|
258
|
+
throw new Error('Payment failed (' + resp2.status + '): ' + errBody);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Read receipt header (V2 or V1)
|
|
262
|
+
var receipt = resp2.headers.get('payment-response') || resp2.headers.get('x-payment-response');
|
|
263
|
+
if (receipt) {
|
|
264
|
+
try {
|
|
265
|
+
var receiptData = JSON.parse(Buffer.from(receipt, 'base64').toString('utf8'));
|
|
266
|
+
console.error('[cryptoiz-mcp] Payment receipt: TX=' + (receiptData.transaction || 'n/a') + ' via ' + (receiptData.version || 'unknown'));
|
|
267
|
+
} catch(e) {
|
|
268
|
+
// ignore receipt parse errors
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
var data = await resp2.json();
|
|
273
|
+
return data;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ===== MCP SERVER SETUP =====
|
|
277
|
+
var TOOLS = [
|
|
278
|
+
{
|
|
279
|
+
name: 'get_alpha_scanner',
|
|
280
|
+
description: 'Get top 20 smart money alpha signals from CryptoIZ Solana DEX scanner. Shows accumulation patterns, whale/dolphin activity, and entry timing. Cost: $0.05 USDC.',
|
|
281
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
name: 'get_divergence',
|
|
285
|
+
description: 'Get divergence signals - hidden accumulation, breakout accumulation, classic divergence between price and smart money. Cost: $0.02 USDC.',
|
|
286
|
+
inputSchema: {
|
|
287
|
+
type: 'object',
|
|
288
|
+
properties: {
|
|
289
|
+
timeframe: { type: 'string', description: 'Timeframe: 4h (default) or 1d', enum: ['4h', '1d'] },
|
|
290
|
+
},
|
|
291
|
+
required: [],
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: 'get_accumulation',
|
|
296
|
+
description: 'Get tokens in accumulation phase with holder tier analysis (whale/dolphin/shrimp deltas). Cost: $0.02 USDC.',
|
|
297
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: 'get_btc_regime',
|
|
301
|
+
description: 'Get Bitcoin macro regime, fear/greed index, futures signals, and technicals (RSI, EMA, MACD). Cost: $0.01 USDC.',
|
|
302
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: 'get_token_ca',
|
|
306
|
+
description: 'Look up a Solana token contract address by name. FREE - no payment required.',
|
|
307
|
+
inputSchema: {
|
|
308
|
+
type: 'object',
|
|
309
|
+
properties: {
|
|
310
|
+
name: { type: 'string', description: 'Token name to search for' },
|
|
311
|
+
},
|
|
312
|
+
required: ['name'],
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: 'get_status',
|
|
317
|
+
description: 'Check CryptoIZ MCP server status, available tools, and pricing. FREE.',
|
|
318
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
319
|
+
},
|
|
320
|
+
];
|
|
321
|
+
|
|
322
|
+
var server = new Server(
|
|
323
|
+
{ name: 'cryptoiz-mcp', version: VERSION },
|
|
324
|
+
{ capabilities: { tools: {} } }
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
server.setRequestHandler(ListToolsRequestSchema, async function() {
|
|
328
|
+
return { tools: TOOLS };
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
server.setRequestHandler(CallToolRequestSchema, async function(request) {
|
|
332
|
+
var toolName = request.params.name;
|
|
333
|
+
var args = request.params.arguments || {};
|
|
334
|
+
|
|
335
|
+
try {
|
|
336
|
+
var result = await callTool(toolName, args);
|
|
337
|
+
return {
|
|
338
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
339
|
+
};
|
|
340
|
+
} catch(e) {
|
|
341
|
+
return {
|
|
342
|
+
content: [{ type: 'text', text: 'Error: ' + e.message }],
|
|
343
|
+
isError: true,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
async function main() {
|
|
349
|
+
var transport = new StdioServerTransport();
|
|
350
|
+
await server.connect(transport);
|
|
351
|
+
console.error('[cryptoiz-mcp] ' + VERSION + ' running on stdio (x402 V2 Dexter + V1 compat)');
|
|
129
352
|
}
|
|
130
|
-
|
|
131
|
-
|
|
353
|
+
|
|
354
|
+
main().catch(function(e) {
|
|
355
|
+
console.error('[cryptoiz-mcp] Fatal:', e.message);
|
|
356
|
+
process.exit(1);
|
|
357
|
+
});
|
package/package.json
CHANGED
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cryptoiz-mcp",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "CryptoIZ MCP Server -
|
|
3
|
+
"version": "4.15.1",
|
|
4
|
+
"description": "CryptoIZ MCP Server - Solana DEX trading signals via Claude Desktop with x402 USDC micropayments (V2 Dexter facilitator)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
"bin": {
|
|
8
|
+
"cryptoiz-mcp": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.js",
|
|
12
|
+
"package.json",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
13
15
|
"dependencies": {
|
|
14
16
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
15
|
-
"@dexterai/x402": "latest",
|
|
16
17
|
"@solana/web3.js": "^1.95.8",
|
|
17
18
|
"bs58": "^6.0.0"
|
|
18
19
|
},
|
|
19
|
-
"engines": {
|
|
20
|
-
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18.0.0"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mcp",
|
|
25
|
+
"claude",
|
|
26
|
+
"solana",
|
|
27
|
+
"crypto",
|
|
28
|
+
"trading",
|
|
29
|
+
"x402",
|
|
30
|
+
"usdc",
|
|
31
|
+
"dexter"
|
|
32
|
+
],
|
|
33
|
+
"author": "CryptoIZ",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"homepage": "https://cryptoiz.org/McpLanding",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/dadang11/cryptoiz-mcp"
|
|
39
|
+
}
|
|
40
|
+
}
|