cabal-hunter-mcp 0.1.0 → 1.0.2

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/.dockerignore ADDED
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ .git
3
+ demo
4
+ example_bot.py
package/.mcp.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "cabal-hunter": {
4
+ "url": "https://api.cabal-hunter.com/mcp",
5
+ "description": "On-chain Solana token cabal detection — traces coordinated wallet funding before you buy"
6
+ }
7
+ }
8
+ }
package/Dockerfile ADDED
@@ -0,0 +1,17 @@
1
+ # Cabal-Hunter local stdio MCP server.
2
+ # Used by Glama (and any MCP host) to build + run the server for automated
3
+ # tool discovery and quality checks. Requires no secrets — the free tier works
4
+ # out of the box; paid scans use x402 at call time.
5
+ FROM node:20-slim
6
+
7
+ WORKDIR /app
8
+
9
+ # Install deps first for layer caching.
10
+ COPY package.json ./
11
+ RUN npm install --omit=dev --no-audit --no-fund
12
+
13
+ # Copy the server.
14
+ COPY server ./server
15
+
16
+ # MCP servers speak JSON-RPC over stdio.
17
+ ENTRYPOINT ["node", "server/index.mjs"]
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Cabal-Hunter
3
+ Copyright (c) 2026 Cabal-Hunter (paulf280-ui)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,95 +1,444 @@
1
- # cabal-hunter-mcp
1
+ # Solana Safe Sniper — MCP Template
2
2
 
3
- **On-chain Solana cabal & rug detection as an MCP server.** One tool — `check_cabal_risk` — scans any Solana token mint *before your agent buys* and returns an **Exit-Liquidity Risk** verdict (`SAFE | REVIEW | AVOID`), a 0–100 cabal score, funding-cluster detection, same-block Jito-bundle detection, coordinated-dump detection, serial-rug **deployer history** ("launched 14, 13 dead"), and a Solana-native **honeypot** check (freeze authority + Token-2022 traps). Every flag links to its on-chain evidence transaction.
4
-
5
- [![npm](https://img.shields.io/npm/v/cabal-hunter-mcp?color=cb3837&logo=npm)](https://www.npmjs.com/package/cabal-hunter-mcp)
6
3
  [![MCP server](https://img.shields.io/badge/MCP-server-7c3aed)](https://api.cabal-hunter.com/mcp)
7
4
  [![Solana](https://img.shields.io/badge/Solana-on--chain-14F195)](https://api.cabal-hunter.com)
8
- [![Free tier](https://img.shields.io/badge/250%2Fmo%20free-no%20API%20key-10b981)](https://api.cabal-hunter.com/api/info)
5
+ [![Live demo](https://img.shields.io/badge/%E2%96%B6%20live-holder%20map-2dd4bf)](https://api.cabal-hunter.com/demo)
6
+ [![Free tier](https://img.shields.io/badge/250%2Fmo%20free-then%20%240.001-ff4d6d)](https://api.cabal-hunter.com/api/info)
7
+ [![Install MCP in VS Code](https://img.shields.io/badge/VS_Code-One--click_MCP_install-0098FF?logo=githubcopilot&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=cabal-hunter&config=%7B%22type%22%3A%20%22http%22%2C%20%22url%22%3A%20%22https%3A%2F%2Fapi.cabal-hunter.com%2Fmcp%22%7D)
8
+ [![Install MCP in Cursor](https://img.shields.io/badge/Cursor-One--click_MCP_install-111111)](https://cursor.com/install-mcp?name=cabal-hunter&config=eyJ1cmwiOiAiaHR0cHM6Ly9hcGkuY2FiYWwtaHVudGVyLmNvbS9tY3AifQ==)
9
+ [![ElizaOS plugin](https://img.shields.io/badge/ElizaOS-plugin--cabal--hunter-7c3aed)](https://github.com/paulf280-ui/plugin-cabal-hunter)
9
10
  [![License: MIT](https://img.shields.io/badge/license-MIT-94a3b8)](LICENSE)
10
11
 
11
- Contract-clean is **not** cabal-clean. RugCheck-style scanners tell you the mint/freeze/LP are fine they don't tell you that 15 wallets funded from one source are holding 30% of supply, waiting to dump on you. That's what this catches.
12
+ > 🌐 **Available in 9 languages:** [English](https://api.cabal-hunter.com/) · [Español](https://api.cabal-hunter.com/es) · [Português](https://api.cabal-hunter.com/pt) · [Français](https://api.cabal-hunter.com/fr) · [Deutsch](https://api.cabal-hunter.com/de) · [Nederlands](https://api.cabal-hunter.com/nl) · [中文](https://api.cabal-hunter.com/zh) · [日本語](https://api.cabal-hunter.com/ja) · [한국어](https://api.cabal-hunter.com/ko)
12
13
 
13
- ## Quick start
14
+ ![Cabal-Hunter live Solana cabal and rug analysis: interactive 3D holder map, serial-launcher deployer history, and an Exit-Liquidity Risk verdict](demo/screenshot.png)
14
15
 
15
- ```bash
16
- npx cabal-hunter-mcp
16
+ > Stop your AI trading agents getting rugged by coordinated wallet cabals.
17
+ > Drop-in template for Claude Code, Cursor, and ElizaOS.
18
+
19
+ **▶ Try it now: [live 3D holder map of any Solana token →](https://api.cabal-hunter.com/demo)** — no signup.
20
+
21
+ **Cabal-Hunter is a free on-chain Solana token safety scanner and rug checker.** It detects coordinated wallet cabals, same-block Jito bundle buys, serial-launcher deployers and coordinated dumps on any Solana mint (pump.fun, PumpSwap, Raydium) — and answers the one question that matters before you ape: *are you the exit liquidity?* Use it via **MCP** (Claude, Cursor, ElizaOS), a **REST API**, or a free **interactive 3D holder map**.
22
+
23
+ ---
24
+
25
+ ## The Problem
26
+
27
+ Your autonomous trading agent is reading rug.check scores, liquidity locks, and contract audits.
28
+
29
+ **None of that catches a cabal.**
30
+
31
+ A handful of wallets take the bottom of a launch, the chart looks clean — contract fine, LP burned, everything green — and then they sell into whoever bought after them. You are the exit liquidity.
32
+
33
+ This template integrates **[Cabal-Hunter](https://api.cabal-hunter.com)** as a pre-trade safety check, so your agent can see who is holding and who has already positioned to sell before it signs a swap.
34
+
35
+ > **A note on what we do and don't claim.** This README used to open with "15 fresh wallets funded from the same master wallet, accumulating 25-40% of supply." We went looking for that pattern and could not find it. Tracing 323 pump.fun launches at the bonding curve turned up **zero coordinated funding clusters**, and showed why: the median launch has about **five successful buyers**, because on one representative token **1,260 of the curve's 1,266 transactions failed**. Launch capture is a sniper *race* between competing bots, not a quiet cabal. The detection layers below are the ones we can actually evidence — holder concentration, same-block bundles, coordinated selling and deployer history. The pre-launch funding tracer was withdrawn; the [full write-up is here](https://github.com/paulf280-ui/cabal-hunter-mcp#a-note-on-the-withdrawn-trace_funding-tool).
36
+
37
+ ---
38
+
39
+ ## The one question it answers: are YOU the exit liquidity?
40
+
41
+ The classic pump.fun exit-liquidity setup: wallets positioned before the crowd take the bottom of a launch, then dump on the retail (and bots) that pile in after. Cabal-Hunter's headline output is a single **Exit-Liquidity Risk** verdict (`LOW | ELEVATED | HIGH`) that synthesises every signal below into the only thing that matters before you sign a swap: *are the insiders positioned to dump on you?*
42
+
43
+ ## What Cabal-Hunter Does
44
+
45
+ ```
46
+ Token mint address
47
+
48
+ 0. EXIT-LIQUIDITY RISK — the headline verdict. Synthesises the layers
49
+ below (bundle, concentration, shared funder, coordinated dump, serial-
50
+ rug dev) into LOW | ELEVATED | HIGH: are insiders set up to dump on
51
+ a buyer? The one number a trading agent needs.
52
+
53
+ 1. HOLDER FUNDING LINEAGE — the CURRENT top holders walked back: were
54
+ they seeded by the same wallet? Only System-owned accounts count as
55
+ a funder, so pools, vaults and routers can never be mistaken for a
56
+ person (that mistake is exactly what got our pre-launch tracer
57
+ withdrawn). Every cluster carries evidence_txs[] — the actual
58
+ funding transactions on Solscan. This layer is genuinely rare to
59
+ fire; treat a hit as significant and its absence as no evidence
60
+ either way.
61
+
62
+ 2. SAME-BLOCK BUNDLE DETECTION — holders whose token accounts were
63
+ created in the EXACT same slot bought in one Jito bundle. Catches
64
+ stealth launches that route funding through intermediaries to
65
+ evade layer 1. Returned as `time_sync: true`.
66
+
67
+ 3. COORDINATED DUMP DETECTION — ≥2 holders that SOLD a meaningful chunk
68
+ (≥25% of their bag each) in the EXACT same block — a cabal exiting in
69
+ real time. `coordinated_exit: true`, with sold_pct = % of supply
70
+ dumped and the sell transactions linked. Same-slot + meaningful-size +
71
+ distinct wallets = near-zero false positives.
72
+
73
+ 4. DEV TRACK RECORD — the creator wallet is resolved on-chain (bonding
74
+ curve pre-graduation, pump-amm pool after — works on any age token),
75
+ and their full launch history is pulled WITH THE PEAK MARKET CAP each
76
+ past token hit. A dead-count alone hides a pump-and-dump: a dev whose
77
+ tokens all died at $4k is a nobody, but one who ran a token to $728k
78
+ then dumped it to dust has done it to holders before. Reputation:
79
+ SERIAL_RUGGER | DEAD_ON_ARRIVAL | MIXED | PROVEN, with per-launch
80
+ peak → now (paid tier returns the full launches[] array).
81
+
82
+ 5. CEX-NOISE FILTER — holders funded from a shared exchange or
83
+ high-volume infra wallet are NOT a cabal. They're excluded from the
84
+ score and surfaced transparently in filtered_clusters[], so you never
85
+ get a false positive from people who just withdrew from Binance.
86
+
87
+ 6. HONEYPOT CHECK (Solana-native) — one RPC read of the mint account:
88
+ is the FREEZE authority live (issuer can freeze your tokens — the
89
+ sell-block lever)? is the MINT authority live (supply can be
90
+ inflated)? any Token-2022 traps (transfer fees up to 100%, transfer
91
+ hooks that block sells, permanent-delegate clawback)? On Solana a
92
+ "honeypot" is built from these — tokens have no per-token contract
93
+ code to audit. Returns `honeypot_risk: LOW | HIGH` +
94
+ `freeze_authority_revoked` / `mint_authority_revoked` /
95
+ `token2022_risks[]`.
96
+
97
+ Returns: Cabal Score (0-100) + cluster map + deployer verdict
98
+ + honeypot verdict + on-chain receipts + hard verdict
17
99
  ```
18
100
 
19
- No install, no signup, no API key **250 free scans/month per IP**. That's the whole setup; the command below is what you drop into any MCP client.
101
+ The deployer layer is the one cabals can't dodge: **wallets rotate, deployers leave a paper trail.** A response of `"deployer": {"reputation": "SERIAL_RUGGER", "tokens_launched": 22, "best_peak_usd": 728432, "pump_and_dumps": 2}` shows the dev's full track record before the first candle — including whether this "dead" dev has quietly run tokens to six figures and dumped them on holders before. (Honest context: most prolific pump.fun creators have high dead-token rates, so this signal is capped it flags a token for review but never drives a HIGH verdict on its own.)
20
102
 
21
- ### Claude Desktop / Claude Code / Cursor / VS Code / ElizaOS
103
+ **Receipts, not magic.** Every cluster and red flag links to the underlying Solscan transaction (`evidence_txs[]`, `holders[].funding_tx`) — verify the trail yourself instead of trusting a score.
104
+
105
+ **Response in <100ms** on pre-indexed tokens — every pump.fun graduation is scanned and cached automatically as it happens.
106
+
107
+ **Free tier: 250 scans/month per IP.** Then $0.001 USDC per scan — priced at cost (it covers the Helius RPC calls behind each live on-chain trace), paid natively on Solana. No account. No API key. No subscription.
108
+
109
+ ---
110
+
111
+ ## Quick Start
112
+
113
+ ### 1. Claude Code / Claude Desktop
114
+
115
+ Add to your MCP config (`~/.claude/mcp.json` or project `.mcp.json`):
22
116
 
23
117
  ```json
24
118
  {
25
119
  "mcpServers": {
26
120
  "cabal-hunter": {
27
- "command": "npx",
28
- "args": ["-y", "cabal-hunter-mcp"]
121
+ "url": "https://api.cabal-hunter.com/mcp"
29
122
  }
30
123
  }
31
124
  }
32
125
  ```
33
126
 
34
- Prefer a remote HTTP server (no local process)? Point straight at the hosted endpoint instead:
127
+ That's it. Claude will now call `check_cabal_risk` automatically when you ask it to analyse a Solana token.
128
+
129
+ **Example prompt:**
130
+ > "Before we buy into this token, check if there are any coordinated wallets: `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`"
131
+
132
+ Claude calls the tool, pays $0.001 USDC from your connected wallet, and returns the full analysis.
133
+
134
+ ---
135
+
136
+ ### 2. Cursor
137
+
138
+ Add to `.cursor/mcp.json` in your project root:
35
139
 
36
140
  ```json
37
- { "mcpServers": { "cabal-hunter": { "url": "https://api.cabal-hunter.com/mcp" } } }
141
+ {
142
+ "mcpServers": {
143
+ "cabal-hunter": {
144
+ "url": "https://api.cabal-hunter.com/mcp"
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ### 3. ElizaOS (with automatic x402 payment)
153
+
154
+ If you're using ElizaOS with `@hugen/plugin-x402-solana`, payment is handled automatically. Add to your agent config:
155
+
156
+ ```json
157
+ {
158
+ "plugins": ["@hugen/plugin-x402-solana"],
159
+ "mcpServers": {
160
+ "cabal-hunter": {
161
+ "url": "https://api.cabal-hunter.com/mcp"
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ Your agent will call `check_cabal_risk(mintAddress)` before any swap and abort if `cabalScore >= 35` or `isControlled === true`.
168
+
169
+ ---
170
+
171
+ ### 4. Direct REST API
172
+
173
+ For headless scripts, custom bots, or any language. **The first 250 calls/month are free — no key, no signup.** Just call it:
174
+
175
+ ```bash
176
+ curl "https://api.cabal-hunter.com/api/scan-cabal?mintAddress=YOUR_MINT_ADDRESS"
177
+ ```
178
+
179
+ You get the full analysis back immediately, with `free_queries_remaining` so you always know where you stand. Machine-readable contract: [`/openapi.json`](https://api.cabal-hunter.com/openapi.json).
180
+
181
+ Once the free tier is used up, calls are $0.001 USDC via x402 — your agent just pays, no billing setup:
182
+
183
+ **Step 1 — Request analysis (get payment instructions):**
184
+ ```bash
185
+ curl -X POST https://api.cabal-hunter.com/api/scan-cabal \
186
+ -H "Content-Type: application/json" \
187
+ -d '{"mintAddress": "YOUR_MINT_ADDRESS"}'
38
188
  ```
39
189
 
40
- ## The tool
190
+ Response (HTTP 402):
191
+ ```json
192
+ {
193
+ "error": "payment_required",
194
+ "payment": {
195
+ "recipient": "ATYjZ1kWoHWhj74umGJ8wFqUeW1yeSGBbLi1UQpahPxt",
196
+ "amount_usdc": 0.001,
197
+ "memo_required": "ch-xxxx-xxxx-xxxx",
198
+ "instructions": "Send 0.001 USDC with this memo, then resubmit with X-Payment-Signature header"
199
+ }
200
+ }
201
+ ```
41
202
 
42
- **`check_cabal_risk({ mint })`** pass a Solana token mint (contract) address. Returns the full forensic JSON:
203
+ **Step 2Pay & resubmit:**
204
+ ```bash
205
+ curl -X POST https://api.cabal-hunter.com/api/scan-cabal \
206
+ -H "Content-Type: application/json" \
207
+ -H "X-Payment-Signature: YOUR_TX_SIGNATURE" \
208
+ -d '{"mintAddress": "YOUR_MINT_ADDRESS"}'
209
+ ```
43
210
 
44
- ```jsonc
211
+ **Response (HTTP 200):**
212
+ ```json
45
213
  {
46
- "recommendation": "AVOID", // SAFE | REVIEW | AVOID ← the headline
47
- "risk": "HIGH", // exit-liquidity risk
48
- "cabal_score": 100, // 0-100
49
- "honeypot_risk": "LOW", // freeze authority + Token-2022 traps
50
- "mint_authority_revoked": true,
51
- "freeze_authority_revoked": true,
52
- "deployer": { "verdict": "SERIAL_RUGGER", "tokens_launched": 14, "dead": 13 },
214
+ "mint": "YOUR_MINT",
215
+ "token_name": "EXAMPLE",
216
+ "risk": "HIGH",
217
+ "cabal_score": 72.4,
218
+ "is_controlled": true,
219
+ "time_sync": true,
220
+ "verdict": "AVOID — 4 wallets bought in the EXACT same block (bundled launch), controlling 34.1% of supply. DEPLOYER ALERT: this creator has launched 14 tokens, 13 of 13 checked are dead (100%).",
53
221
  "coordinated_clusters": [
54
- { "wallets": 5, "combined_pct": 23.1, "evidence_tx": "https://solscan.io/tx/…" }
222
+ {
223
+ "type": "funding",
224
+ "master_full": "FvbEKF...9RUg",
225
+ "master_short": "FvbEKF…9RUg",
226
+ "wallet_count": 4,
227
+ "combined_pct": 34.1,
228
+ "risk": "HIGH",
229
+ "evidence_txs": ["4Y8auc5G...", "2XQx9LFv...", "AAbJ7rej..."]
230
+ }
55
231
  ],
56
- "time_sync": true, // same-block (Jito-bundled) buys
57
- "coordinated_exit": false, // ≥2 holders dumped together
58
- "top_reasons": ["..."],
59
- "wallets_checked": 15,
60
- "scan_complete": true
232
+ "filtered_clusters": [
233
+ {
234
+ "funder_label": "high-volume wallet",
235
+ "master_short": "43ViqZ…Z6iy",
236
+ "wallet_count": 2,
237
+ "combined_pct": 4.4
238
+ }
239
+ ],
240
+ "deployer": {
241
+ "creator": "5TbRN6...full address...",
242
+ "creator_short": "5TbRN6…2TGC",
243
+ "tokens_launched": 14,
244
+ "dead": 13,
245
+ "sampled": 13,
246
+ "dead_pct": 100.0,
247
+ "verdict": "SERIAL_LAUNCHER"
248
+ },
249
+ "holders": [
250
+ { "rank": 1, "address": "...", "pct": 12.4, "cluster_id": 0, "funding_tx": "4Y8auc5G..." }
251
+ ],
252
+ "wallets_checked": 12,
253
+ "analysis_time_ms": 487,
254
+ "source": "real_time"
255
+ }
256
+ ```
257
+
258
+ ### 5. Run the MCP server locally (Docker / Node)
259
+
260
+ **Fastest — no clone needed:** `npx cabal-hunter-mcp` — the same stdio server, published to npm ([cabal-hunter-mcp](https://github.com/paulf280-ui/cabal-hunter-mcp) · [npm](https://www.npmjs.com/package/cabal-hunter-mcp)). Or run it from this repo:
261
+
262
+ Prefer to run the connector yourself instead of hitting the hosted `/mcp`
263
+ endpoint? This repo ships a thin **stdio MCP server** that exposes
264
+ `check_cabal_risk(mintAddress)` and proxies to the Cabal-Hunter API (free tier
265
+ works with no key; paid scans use x402 at call time):
266
+
267
+ ```bash
268
+ # Node 18+
269
+ npm install
270
+ node server/index.mjs
271
+
272
+ # or Docker
273
+ docker build -t cabal-hunter-mcp .
274
+ docker run -i cabal-hunter-mcp
275
+ ```
276
+
277
+ Then point any MCP client at the local command:
278
+
279
+ ```json
280
+ {
281
+ "mcpServers": {
282
+ "cabal-hunter": {
283
+ "command": "node",
284
+ "args": ["server/index.mjs"]
285
+ }
286
+ }
61
287
  }
62
288
  ```
63
289
 
64
- `scan_complete` / `wallets_checked` are included on purpose so your agent can apply **its own** risk tolerance instead of inheriting ours — the score is a starting point you can verify (every cluster carries an `evidence_tx`), not a verdict you take on faith.
290
+ ---
291
+
292
+ ## Integrate into Your Trading Logic
293
+
294
+ ```python
295
+ import requests
296
+
297
+ def is_safe_to_buy(mint_address: str, payment_sig: str) -> bool:
298
+ """Returns True if token passes cabal check."""
299
+ resp = requests.post(
300
+ "https://api.cabal-hunter.com/api/scan-cabal",
301
+ json={"mintAddress": mint_address},
302
+ headers={"X-Payment-Signature": payment_sig}
303
+ )
304
+ if resp.status_code != 200:
305
+ return False # fail-safe: don't buy on error
306
+ data = resp.json()
307
+ # Block on: coordinated control, high score, bundled launch,
308
+ # or a deployer with a history of dead tokens
309
+ deployer_verdict = (data.get("deployer") or {}).get("verdict", "UNKNOWN")
310
+ return (
311
+ not data.get("is_controlled")
312
+ and data.get("cabal_score", 100) < 35
313
+ and not data.get("time_sync")
314
+ and deployer_verdict not in ("SERIAL_RUGGER", "SERIAL_LAUNCHER", "POOR_TRACK_RECORD")
315
+ )
316
+
317
+ # In your bot's buy logic:
318
+ if is_safe_to_buy(token_mint, my_payment_sig):
319
+ execute_swap(token_mint, sol_amount)
320
+ else:
321
+ print(f"Cabal detected — skipping {token_mint}")
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Interactive 3D Holder Map (Free)
327
+
328
+ See exactly what the analysis found. Every real holder is a faceted crystal sized by its share of supply; wallets in the same cluster are joined by light beams, and the liquidity pool and locked supply sit apart in a wireframe vault because they cannot be sold. Drag to rotate, hover for the wallet, click through to Solscan:
329
+
330
+ ```
331
+ https://api.cabal-hunter.com/map?mint=ANY_SOLANA_MINT
332
+ ```
333
+
334
+ Free to view, in 9 languages. Share this URL when you catch a rug. Every crystal is clickable and links to Solscan for deep-dive research.
335
+
336
+ ---
337
+
338
+ ## Cabal-Hunter everywhere
339
+
340
+ Same detection engine, wherever your stack lives:
65
341
 
66
- ### Gate a buy in your agent
342
+ - **`npx cabal-hunter-mcp`** standalone MCP server for Claude · Cursor · VS Code · any MCP client: [cabal-hunter-mcp](https://github.com/paulf280-ui/cabal-hunter-mcp) · [npm](https://www.npmjs.com/package/cabal-hunter-mcp)
343
+ - **ElizaOS plugin:** `npm i elizaos-plugin-cabal-hunter` — [plugin-cabal-hunter](https://github.com/paulf280-ui/plugin-cabal-hunter) · [npm](https://www.npmjs.com/package/elizaos-plugin-cabal-hunter)
344
+ - **REST API + OpenAPI:** [api.cabal-hunter.com](https://api.cabal-hunter.com) · [/openapi.json](https://api.cabal-hunter.com/openapi.json)
67
345
 
68
- > "Before buying any token, call `check_cabal_risk` with the mint. If `recommendation` is `AVOID` or `cabal_score >= 65` or `honeypot_risk` is `HIGH`, skip the trade and say why."
346
+ ---
69
347
 
70
348
  ## Pricing
71
349
 
72
- - **250 scans/month per IP free, no key.**
73
- - After that: **$9/month for Unlimited** (fair use), or pay-as-you-go at **$0.001 USDC per scan** (priced at cost). No signup, no card.
74
- - Prepaid key: send USDC, `POST /api/buy-key`, then set `CABAL_HUNTER_API_KEY` (sent as the `X-API-Key` header). Full details: [api.cabal-hunter.com/pricing](https://api.cabal-hunter.com/pricing).
350
+ **First 250 scans every month are free** — per IP, no signup, no API key.
351
+
352
+ After that, pick whatever matches how hard your bot works (priced at cost — it covers the Helius RPC behind each live on-chain trace):
353
+
354
+ | Plan | Price | What you get |
355
+ |------|-------|--------------|
356
+ | **Unlimited** ⭐ | $9 USDC / month | Scan all you want — _fair use: 50,000/mo, more than any bot needs_ |
357
+ | **Pay as you go** | $0.001 USDC / scan | Only what you use — prepaid or per-call, no commitment |
358
+
359
+ Prepaid keys: send USDC once → `POST /api/buy-key` with the tx signature → use header `X-API-Key` on every scan. Or pay per-call via x402 (`X-Payment-Signature` header). No credit card, no account, no lock-in.
360
+
361
+ **Does it pay for itself?** Work it out with your own numbers rather than ours: the Unlimited tier is $9 a month, so it pays for itself the first time it keeps you out of a position bigger than $9 that goes to zero. Whether that happens once a month or once a week depends on what you trade and how often — we are not going to invent an average for you.
362
+
363
+ Payment is native on Solana — no credit card, no account, no subscription lock-in.
364
+
365
+ ---
366
+
367
+ ## Live dashboard badge
368
+
369
+ Drop a live safety badge into your own bot's dashboard — two lines of HTML, and every token shows its verdict as it trades:
370
+
371
+ ```html
372
+ <div class="cabal-hunter-badge" data-mint="YOUR_TOKEN_MINT"></div>
373
+ <script src="https://api.cabal-hunter.com/widget.js" defer></script>
374
+ ```
375
+
376
+ It renders the 0–100 score, the plain-English verdict, and the active flags (bundled launch, coordinated dump, whale concentration, serial-launcher deployer, honeypot). Add `data-refresh="120"` to re-scan live as you trade, and `data-api-key="..."` once you're past your free scans. Works anywhere — React, plain HTML, any site.
377
+
378
+ ---
379
+
380
+ ## API Reference
75
381
 
76
- ## Configuration
382
+ | Endpoint | Description | Auth |
383
+ |----------|-------------|------|
384
+ | `POST /api/scan-cabal` | Full cabal analysis | $0.001 USDC |
385
+ | `GET /api/scan-cabal?mintAddress=` | GET version | $0.001 USDC |
386
+ | `GET /map?mint=` | Interactive 3D holder map | Free |
387
+ | `GET /api/cex-funding?mint=` | Per-exchange funding breakdown (which CEXes funded holders, % each) | Free |
388
+ | `GET /api/trade-analysis?mint=` | Cohort PnL (Team/Snipers/Insiders) + wash-trading score + exit-liquidity price impact, one call | Free |
389
+ | `POST /api/watch` | Register an emergency dump webhook for a mint (push on dump/rug start) | Free |
390
+ | `GET /api/info` | Pricing, endpoints | Free |
77
391
 
78
- | Env var | Default | Purpose |
79
- |---|---|---|
80
- | `CABAL_HUNTER_API_KEY` | *(none)* | Prepaid key for unlimited / metered use (`X-API-Key`). |
81
- | `CABAL_HUNTER_API` | `https://api.cabal-hunter.com` | Override the API base URL. |
392
+ ### Emergency dump webhook (auto-exit)
82
393
 
83
- ## Other ways to use Cabal-Hunter
394
+ Instead of polling, let your bot subscribe to a token it holds — we push the moment a coordinated dump or liquidity drain starts:
84
395
 
85
- - **REST:** `curl "https://api.cabal-hunter.com/api/scan-cabal?mintAddress=<MINT>"` — [OpenAPI spec](https://api.cabal-hunter.com/openapi.json)
86
- - **ElizaOS plugin:** [`elizaos-plugin-cabal-hunter`](https://github.com/paulf280-ui/plugin-cabal-hunter) (`npm install elizaos-plugin-cabal-hunter`)
87
- - **Human?** Free interactive bubble map — wallets, Solscan receipts, live chart + trade links on one screen: [api.cabal-hunter.com/map](https://api.cabal-hunter.com/map)
396
+ ```bash
397
+ curl -X POST https://api.cabal-hunter.com/api/watch \
398
+ -H "Content-Type: application/json" \
399
+ -d '{"mint":"YOUR_MINT","webhook_url":"https://your-bot.com/dump-alert"}'
400
+ ```
401
+
402
+ Your endpoint receives:
403
+ ```json
404
+ { "event":"dump_detected", "mint":"...", "reason":"price −34% since last check",
405
+ "coordinated": true, "price_usd": 0.0001, "liquidity_usd": 4200,
406
+ "action":"consider_immediate_exit", "ts": 1781370000 }
407
+ ```
408
+ | `GET /health` | Uptime check | Free |
409
+ | `POST /mcp` | MCP tool endpoint | $0.001 USDC per call |
410
+
411
+ ---
412
+
413
+ ## Infrastructure
414
+
415
+ - **RPC**: Dedicated Helius node (Frankfurt) — fastest Solana data available
416
+ - **Hosting**: AWS EC2 Frankfurt — low latency for EU/global
417
+ - **Analysis**: Real on-chain data — no scrapers, no caches of cached caches
418
+ - **Uptime**: 99.9% target — monitored, auto-restart via systemd
419
+
420
+ ---
421
+
422
+ ## FAQ
423
+
424
+ **What is a Solana cabal?**
425
+ A group of wallets — often funded from the same source and buying in the same block — that quietly accumulate a large share of a token's supply before retail, then dump simultaneously into everyone who buys after launch.
426
+
427
+ **How do I check if a Solana token is a rug?**
428
+ Scan the mint with Cabal-Hunter (MCP, REST API, or the free 3D holder map). It traces holder funding back to shared sources, detects same-block bundle buys, flags serial-launcher deployers and live coordinated dumps, and returns an **Exit-Liquidity Risk** verdict: `LOW`, `ELEVATED`, or `HIGH`.
429
+
430
+ **Is it free?**
431
+ Yes — 250 scans/month per IP, with no signup or API key. Beyond that it's $0.001 USDC per scan — which just covers the Helius RPC cost of the live trace — paid natively on Solana.
432
+
433
+ **Can AI trading agents use it?**
434
+ Yes — that's the whole point. The MCP server (`api.cabal-hunter.com/mcp`) lets Claude, Cursor and ElizaOS agents call `check_cabal_risk(mintAddress)` automatically before any swap, and a REST API covers any other language.
435
+
436
+ ---
88
437
 
89
- ## What it detects (why "contract-clean" misses it)
438
+ ## License
90
439
 
91
- A cabal is 15 fresh wallets all funded from the same master wallet, all buying in the first seconds of launch — quietly accumulating 25–40% of supply before your bot sees the first candle. Contract clean. LP burned. Everything green. Then they dump, simultaneously, into your liquidity. Cabal-Hunter traces the funding graph on-chain and answers the only question that matters before you sign a swap: **are you the exit liquidity?**
440
+ MITfork it, build on it, integrate it. If you build something with this, share it.
92
441
 
93
442
  ---
94
443
 
95
- MIT licensed. Powered by [Cabal-Hunter](https://api.cabal-hunter.com). This package is a thin MCP wrapper over the hosted API — the detection runs server-side against live Solana on-chain data (Helius RPC).
444
+ *Built by [PF Capital](https://api.cabal-hunter.com) · Powered by Helius · Contact: api.cabal-hunter.com/api/info*
@@ -0,0 +1,74 @@
1
+ """
2
+ Cabal-Hunter API demo — Python
3
+ Checks a Solana token for coordinated wallet clusters before buying.
4
+
5
+ First 250 scans/month are FREE — no signup, no API key, no payment.
6
+ After that: $0.001 USDC per scan via X-Payment-Signature, or a prepaid
7
+ key ($9/month unlimited, fair use 50k) via X-API-Key.
8
+
9
+ Run: python demo/python_demo.py
10
+ """
11
+
12
+ import requests
13
+ import json
14
+
15
+ API = "https://api.cabal-hunter.com/api/scan-cabal"
16
+
17
+ # Demo token — known cabal detected
18
+ DEMO_MINT = "Axpzs7FEMYzpcfqVcDjDMQb2rsgMYVJADNpUZe7bpump"
19
+
20
+
21
+ def check_token(mint: str) -> dict:
22
+ """
23
+ Query Cabal-Hunter for a token.
24
+ Free for the first 250 scans/month. After that, pass X-Payment-Signature
25
+ or X-API-Key.
26
+ """
27
+ resp = requests.post(API, json={"mintAddress": mint}, timeout=30)
28
+
29
+ if resp.status_code == 200:
30
+ return resp.json()
31
+
32
+ if resp.status_code == 402:
33
+ data = resp.json()
34
+ print("\n💳 Free quota exhausted. Payment required:")
35
+ print(f" Send {data['payment']['amount_usdc']} USDC to {data['payment']['recipient']}")
36
+ print(f" Memo: {data['payment']['memo_required']}")
37
+ print(f" Then re-submit with: X-Payment-Signature: <your_tx_sig>")
38
+ return {}
39
+
40
+ raise RuntimeError(f"Unexpected {resp.status_code}: {resp.text}")
41
+
42
+
43
+ def is_safe(report: dict) -> bool:
44
+ """Returns True if the token passes the cabal check."""
45
+ if not report:
46
+ return False # fail-safe: treat no-response as unsafe
47
+ return not report.get("is_controlled") and report.get("cabal_score", 100) < 35
48
+
49
+
50
+ if __name__ == "__main__":
51
+ print(f"Checking {DEMO_MINT[:8]}…\n")
52
+
53
+ report = check_token(DEMO_MINT)
54
+ if not report:
55
+ exit(1)
56
+
57
+ free_left = report.get("free_queries_remaining")
58
+ if free_left is not None:
59
+ print(f"✅ Free tier — {free_left} free scans remaining this month\n")
60
+
61
+ print(f"Token: {report.get('token_name', '?')}")
62
+ print(f"Risk: {report.get('risk')}")
63
+ print(f"Cabal Score: {report.get('cabal_score')}/100")
64
+ print(f"Verdict: {report.get('verdict')}")
65
+ print(f"Analysis: {report.get('analysis_time_ms')}ms ({report.get('source')})")
66
+
67
+ clusters = report.get("coordinated_clusters", [])
68
+ if clusters:
69
+ print(f"\n⚠️ {len(clusters)} cluster(s) detected:")
70
+ for c in clusters:
71
+ print(f" {c['wallet_count']} wallets from {c['master_short']} — {c['combined_pct']}% supply [{c['risk']}]")
72
+
73
+ print(f"\n{'🚫 SKIP — cabal detected' if not is_safe(report) else '✅ SAFE — no cabal detected'}")
74
+ print(f"\nVisual map: https://api.cabal-hunter.com/map?mint={DEMO_MINT}")
Binary file
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Cabal-Hunter API demo — TypeScript/Node.js
3
+ * Checks a Solana token for coordinated wallet clusters before buying.
4
+ *
5
+ * First 250 scans/month are FREE — no signup, no payment required.
6
+ * After that: $9/month unlimited, or $0.001 USDC per scan via x402
7
+ * (X-Payment-Signature header).
8
+ *
9
+ * Run: npx tsx demo/typescript_demo.ts
10
+ */
11
+
12
+ const API = "https://api.cabal-hunter.com/api/scan-cabal"
13
+
14
+ // Demo token — known cabal detected
15
+ const DEMO_MINT = "Axpzs7FEMYzpcfqVcDjDMQb2rsgMYVJADNpUZe7bpump"
16
+
17
+ interface CabalReport {
18
+ token_name: string
19
+ risk: "HIGH" | "MEDIUM" | "CLEAN"
20
+ cabal_score: number
21
+ is_controlled: boolean
22
+ verdict: string
23
+ coordinated_clusters: Array<{
24
+ master_short: string
25
+ wallet_count: number
26
+ combined_pct: number
27
+ risk: string
28
+ }>
29
+ wallets_checked: number
30
+ analysis_time_ms: number
31
+ source: string
32
+ free_queries_remaining?: number
33
+ }
34
+
35
+ async function checkToken(mint: string, paymentSig?: string): Promise<CabalReport | null> {
36
+ const headers: Record<string, string> = { "Content-Type": "application/json" }
37
+ if (paymentSig) headers["X-Payment-Signature"] = paymentSig
38
+
39
+ const resp = await fetch(API, {
40
+ method: "POST",
41
+ headers,
42
+ body: JSON.stringify({ mintAddress: mint }),
43
+ })
44
+
45
+ if (resp.status === 200) return resp.json() as Promise<CabalReport>
46
+
47
+ if (resp.status === 402) {
48
+ const data = await resp.json() as { payment: { amount_usdc: number; recipient: string; memo_required: string } }
49
+ console.log("\n💳 Free quota exhausted. Payment required:")
50
+ console.log(` Send ${data.payment.amount_usdc} USDC to ${data.payment.recipient}`)
51
+ console.log(` Memo: ${data.payment.memo_required}`)
52
+ console.log(` Then re-submit with: X-Payment-Signature: <your_tx_sig>`)
53
+ return null
54
+ }
55
+
56
+ throw new Error(`Unexpected ${resp.status}: ${await resp.text()}`)
57
+ }
58
+
59
+ function isSafe(report: CabalReport): boolean {
60
+ return !report.is_controlled && report.cabal_score < 35
61
+ }
62
+
63
+ async function main() {
64
+ console.log(`Checking ${DEMO_MINT.slice(0, 8)}…\n`)
65
+
66
+ const report = await checkToken(DEMO_MINT)
67
+ if (!report) process.exit(1)
68
+
69
+ if (report.free_queries_remaining !== undefined) {
70
+ console.log(`✅ Free tier — ${report.free_queries_remaining} free scans remaining this month\n`)
71
+ }
72
+
73
+ console.log(`Token: ${report.token_name}`)
74
+ console.log(`Risk: ${report.risk}`)
75
+ console.log(`Cabal Score: ${report.cabal_score}/100`)
76
+ console.log(`Verdict: ${report.verdict}`)
77
+ console.log(`Analysis: ${report.analysis_time_ms}ms (${report.source})`)
78
+
79
+ if (report.coordinated_clusters.length > 0) {
80
+ console.log(`\n⚠️ ${report.coordinated_clusters.length} cluster(s) detected:`)
81
+ for (const c of report.coordinated_clusters) {
82
+ console.log(` ${c.wallet_count} wallets from ${c.master_short} — ${c.combined_pct}% supply [${c.risk}]`)
83
+ }
84
+ }
85
+
86
+ console.log(`\n${isSafe(report) ? "✅ SAFE — no cabal detected" : "🚫 SKIP — cabal detected"}`)
87
+ console.log(`\nVisual map: https://api.cabal-hunter.com/map?mint=${DEMO_MINT}`)
88
+ }
89
+
90
+ main().catch(console.error)
package/example_bot.py ADDED
@@ -0,0 +1,84 @@
1
+ """
2
+ Example: Integrate Cabal-Hunter into a Solana trading bot.
3
+ Checks for coordinated wallet clusters before executing any swap.
4
+ Cost: 250 scans/month free, then $0.001 USDC per check (or $9/month
5
+ unlimited). Pays for itself the first time it blocks a rug.
6
+ """
7
+
8
+ import requests
9
+
10
+ CABAL_HUNTER_URL = "https://api.cabal-hunter.com/api/scan-cabal"
11
+ MAX_CABAL_SCORE = 35 # block if score >= 35 (controlled token)
12
+
13
+
14
+ def get_payment_instructions(mint: str) -> dict:
15
+ """Step 1: Get payment instructions from the API."""
16
+ resp = requests.post(CABAL_HUNTER_URL, json={"mintAddress": mint})
17
+ if resp.status_code == 402:
18
+ return resp.json()["payment"]
19
+ raise ValueError(f"Unexpected response: {resp.status_code}")
20
+
21
+
22
+ def check_cabal(mint: str, payment_tx_sig: str) -> dict:
23
+ """Step 2: Submit analysis with payment proof."""
24
+ resp = requests.post(
25
+ CABAL_HUNTER_URL,
26
+ json={"mintAddress": mint},
27
+ headers={"X-Payment-Signature": payment_tx_sig},
28
+ )
29
+ if resp.status_code == 200:
30
+ return resp.json()
31
+ raise ValueError(f"Analysis failed: {resp.status_code} {resp.text}")
32
+
33
+
34
+ def is_safe_to_buy(mint: str, payment_tx_sig: str) -> tuple[bool, str]:
35
+ """
36
+ Returns (safe, reason).
37
+ safe=True means proceed with the trade.
38
+ safe=False means the token has detected cabal risk — skip.
39
+ """
40
+ try:
41
+ result = check_cabal(mint, payment_tx_sig)
42
+ score = result.get("cabal_score", 0)
43
+ risk = result.get("risk", "CLEAN")
44
+
45
+ if result.get("is_controlled") or score >= MAX_CABAL_SCORE:
46
+ clusters = result.get("coordinated_clusters", [])
47
+ c = clusters[0] if clusters else {}
48
+ reason = (
49
+ f"CABAL DETECTED — Score {score}/100 — "
50
+ f"{c.get('wallet_count','?')} coordinated wallets holding "
51
+ f"{c.get('combined_pct','?')}% of supply"
52
+ )
53
+ return False, reason
54
+
55
+ return True, f"CLEAN — Score {score}/100 — {result.get('wallets_checked','?')} wallets traced"
56
+
57
+ except Exception as e:
58
+ # Fail safe: skip trade on any error
59
+ return False, f"Cabal check failed ({e}) — skipping trade as precaution"
60
+
61
+
62
+ # ── Example usage ─────────────────────────────────────────────────────────────
63
+
64
+ if __name__ == "__main__":
65
+ token_mint = "PASTE_TOKEN_MINT_HERE"
66
+
67
+ # Step 1: Get payment instructions
68
+ print(f"Checking {token_mint[:8]}…")
69
+ payment = get_payment_instructions(token_mint)
70
+ print(f" → Send {payment['amount_usdc']} USDC to {payment['recipient']}")
71
+ print(f" → Memo: {payment['memo_required']}")
72
+
73
+ # Step 2: You send the USDC (via your wallet SDK), get the tx sig
74
+ payment_sig = input("Paste your transaction signature: ").strip()
75
+
76
+ # Step 3: Check result
77
+ safe, reason = is_safe_to_buy(token_mint, payment_sig)
78
+ print(f"\n{'✅ SAFE' if safe else '🚫 BLOCKED'}: {reason}")
79
+
80
+ if safe:
81
+ print("Proceeding with swap…")
82
+ # execute_swap(token_mint, sol_amount)
83
+ else:
84
+ print("Trade cancelled — protecting your capital.")
package/glama.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": ["paulf280-ui"]
4
+ }
package/package.json CHANGED
@@ -1,58 +1,33 @@
1
1
  {
2
2
  "name": "cabal-hunter-mcp",
3
- "version": "0.1.0",
4
- "description": "MCP server for on-chain Solana cabal & rug detection exit-liquidity risk verdict, funding-cluster + same-block-bundle + coordinated-dump detection, serial-rug deployer history, and honeypot check for any token mint. Run with npx, no API key. 250 free scans/month.",
3
+ "version": "1.0.2",
4
+ "description": "MCP server for Cabal-Hunter \u2014 Solana token rug & cabal detection for AI agents. Wallet clusters, same-block bundles, deployer track record with peak market caps, honeypot and authority traps. 250 free scans/month, no signup.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "cabal-hunter-mcp": "index.js"
7
+ "cabal-hunter-mcp": "server/index.mjs"
8
+ },
9
+ "main": "server/index.mjs",
10
+ "scripts": {
11
+ "start": "node server/index.mjs"
8
12
  },
9
- "main": "index.js",
10
- "files": [
11
- "index.js",
12
- "README.md",
13
- "LICENSE"
14
- ],
15
13
  "engines": {
16
14
  "node": ">=18"
17
15
  },
18
- "scripts": {
19
- "start": "node index.js"
20
- },
21
16
  "dependencies": {
22
- "@modelcontextprotocol/sdk": "^1.0.0"
17
+ "@modelcontextprotocol/sdk": "^1.7.0"
23
18
  },
24
19
  "keywords": [
25
20
  "mcp",
26
- "model-context-protocol",
27
- "mcp-server",
28
21
  "solana",
29
- "rug-check",
30
22
  "rug-detection",
31
- "rugcheck",
32
- "cabal-detection",
33
- "memecoin",
34
- "pump-fun",
35
- "pumpfun",
36
- "token-safety",
37
- "honeypot-detection",
38
- "exit-liquidity",
39
- "trading-bot",
40
- "ai-agent",
41
- "ai-agents",
42
- "web3",
43
- "defi",
44
- "claude",
45
- "cursor",
46
- "elizaos"
23
+ "cabal",
24
+ "trading",
25
+ "model-context-protocol"
47
26
  ],
48
27
  "license": "MIT",
49
- "author": "Cabal-Hunter (https://api.cabal-hunter.com)",
50
- "homepage": "https://api.cabal-hunter.com",
51
28
  "repository": {
52
29
  "type": "git",
53
- "url": "git+https://github.com/paulf280-ui/cabal-hunter-mcp.git"
30
+ "url": "git+https://github.com/paulf280-ui/solana-safe-sniper-mcp-template.git"
54
31
  },
55
- "bugs": {
56
- "url": "https://github.com/paulf280-ui/cabal-hunter-mcp/issues"
57
- }
32
+ "homepage": "https://api.cabal-hunter.com"
58
33
  }
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cabal-Hunter — local stdio MCP server.
4
+ *
5
+ * A thin Model Context Protocol server that exposes one tool, `check_cabal_risk`,
6
+ * and proxies to the hosted Cabal-Hunter API (https://api.cabal-hunter.com).
7
+ * Drop it into any MCP client (Claude Desktop, Cursor, ElizaOS) to give an agent
8
+ * a pre-trade safety check that catches coordinated wallet cabals, same-block
9
+ * Jito bundles, the dev's launch track record (peak market cap per past token +
10
+ * pump-and-dump history) and live coordinated dumps on any Solana mint before it
11
+ * signs a swap.
12
+ *
13
+ * Free tier: 250 scans/month per IP, no signup. Beyond that it is $9/month
14
+ * unlimited (fair use), or $0.001 USDC per scan via x402 on Solana — when a
15
+ * scan needs payment the API returns HTTP 402 with the payment instructions,
16
+ * which this tool surfaces to the caller.
17
+ *
18
+ * Uses the low-level Server API + JSON-Schema tool definitions for maximum
19
+ * compatibility across @modelcontextprotocol/sdk versions.
20
+ */
21
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
+ import {
24
+ ListToolsRequestSchema,
25
+ CallToolRequestSchema,
26
+ } from "@modelcontextprotocol/sdk/types.js";
27
+
28
+ const API_BASE = process.env.CABAL_HUNTER_API || "https://api.cabal-hunter.com";
29
+ const SCAN_URL = `${API_BASE}/api/scan-cabal`;
30
+
31
+ const server = new Server(
32
+ { name: "cabal-hunter", version: "1.0.0" },
33
+ { capabilities: { tools: {} } }
34
+ );
35
+
36
+ const CHECK_CABAL_RISK = {
37
+ name: "check_cabal_risk",
38
+ description:
39
+ "Scan a Solana token mint for coordinated wallet cabals, same-block Jito " +
40
+ "bundle buys, the dev's launch track record (peak market cap per past token " +
41
+ "+ pump-and-dump history) and live coordinated dumps. Returns an " +
42
+ "Exit-Liquidity Risk verdict (cabal_score 0-100, risk level, is_controlled, " +
43
+ "coordinated wallet clusters) so a trading agent can decide whether it is " +
44
+ "about to become exit liquidity BEFORE it signs a swap. Works on pump.fun, " +
45
+ "PumpSwap and Raydium tokens.",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ mintAddress: {
50
+ type: "string",
51
+ description: "The Solana token mint address (base58) to scan.",
52
+ },
53
+ },
54
+ required: ["mintAddress"],
55
+ },
56
+ };
57
+
58
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
59
+ tools: [CHECK_CABAL_RISK],
60
+ }));
61
+
62
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
63
+ if (request.params.name !== "check_cabal_risk") {
64
+ throw new Error(`Unknown tool: ${request.params.name}`);
65
+ }
66
+ const mintAddress = request.params.arguments?.mintAddress;
67
+ if (!mintAddress || typeof mintAddress !== "string") {
68
+ return {
69
+ isError: true,
70
+ content: [{ type: "text", text: "mintAddress is required (base58 mint string)." }],
71
+ };
72
+ }
73
+
74
+ try {
75
+ const resp = await fetch(SCAN_URL, {
76
+ method: "POST",
77
+ headers: { "Content-Type": "application/json" },
78
+ body: JSON.stringify({ mintAddress }),
79
+ });
80
+
81
+ // x402: payment required — surface the instructions rather than failing.
82
+ if (resp.status === 402) {
83
+ const body = await resp.json().catch(() => ({}));
84
+ return {
85
+ content: [
86
+ {
87
+ type: "text",
88
+ text:
89
+ "Payment required (x402). Free tier exhausted — this scan costs " +
90
+ "$0.02 USDC on Solana.\n\n" +
91
+ JSON.stringify(body.payment || body, null, 2),
92
+ },
93
+ ],
94
+ };
95
+ }
96
+
97
+ if (!resp.ok) {
98
+ const text = await resp.text().catch(() => "");
99
+ return {
100
+ isError: true,
101
+ content: [{ type: "text", text: `Scan failed: HTTP ${resp.status} ${text}` }],
102
+ };
103
+ }
104
+
105
+ const data = await resp.json();
106
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
107
+ } catch (err) {
108
+ return {
109
+ isError: true,
110
+ content: [{ type: "text", text: `Scan error: ${err?.message || String(err)}` }],
111
+ };
112
+ }
113
+ });
114
+
115
+ async function main() {
116
+ const transport = new StdioServerTransport();
117
+ await server.connect(transport);
118
+ // stdio transport keeps the process alive; log to stderr so stdout stays clean.
119
+ console.error("cabal-hunter MCP server running on stdio");
120
+ }
121
+
122
+ main().catch((err) => {
123
+ console.error("fatal:", err);
124
+ process.exit(1);
125
+ });
package/index.js DELETED
@@ -1,95 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * cabal-hunter-mcp — local MCP server for on-chain Solana cabal/rug detection.
4
- *
5
- * Exposes one tool, `check_cabal_risk`, that scans any Solana token mint and
6
- * returns an exit-liquidity risk verdict (SAFE / REVIEW / AVOID), a 0-100 cabal
7
- * score, funding-cluster + same-block-bundle + coordinated-dump detection,
8
- * serial-rug deployer history, and a honeypot (freeze / Token-2022) check.
9
- *
10
- * It is a thin stdio wrapper over the hosted Cabal-Hunter API
11
- * (https://api.cabal-hunter.com) so any MCP client — Claude Desktop, Claude
12
- * Code, Cursor, VS Code, ElizaOS — can run it with `npx cabal-hunter-mcp`.
13
- *
14
- * Free tier: 250 scans/month per IP, no signup, no key. To use a prepaid key
15
- * (e.g. $9/mo unlimited), set CABAL_HUNTER_API_KEY.
16
- */
17
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
18
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
19
- import {
20
- ListToolsRequestSchema,
21
- CallToolRequestSchema,
22
- } from "@modelcontextprotocol/sdk/types.js";
23
-
24
- const API = (process.env.CABAL_HUNTER_API || "https://api.cabal-hunter.com").replace(/\/+$/, "");
25
- const API_KEY = process.env.CABAL_HUNTER_API_KEY || "";
26
-
27
- const TOOL = {
28
- name: "check_cabal_risk",
29
- description:
30
- "Real-time on-chain coordinated-wallet (cabal) and rug detection for any " +
31
- "Solana token mint. One call returns an Exit-Liquidity Risk verdict " +
32
- "(SAFE | REVIEW | AVOID), a 0-100 cabal score, funding-cluster detection " +
33
- "(top holders funded by the same source), same-block Jito-bundle detection, " +
34
- "coordinated-dump detection, serial-rug deployer history (e.g. 'launched 14, " +
35
- "13 dead'), a honeypot check (freeze authority + Token-2022 traps), and " +
36
- "on-chain evidence transactions for every flag. Use it before an agent buys a " +
37
- "pump.fun / PumpSwap / Raydium token to answer: are you the exit liquidity? " +
38
- "Free: 250 scans/month, no API key required.",
39
- inputSchema: {
40
- type: "object",
41
- properties: {
42
- mint: {
43
- type: "string",
44
- description:
45
- "The Solana token mint (contract) address to scan, e.g. " +
46
- "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
47
- },
48
- },
49
- required: ["mint"],
50
- },
51
- };
52
-
53
- const server = new Server(
54
- { name: "cabal-hunter", version: "0.1.0" },
55
- { capabilities: { tools: {} } }
56
- );
57
-
58
- server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [TOOL] }));
59
-
60
- server.setRequestHandler(CallToolRequestSchema, async (req) => {
61
- const { name, arguments: args } = req.params;
62
- if (name !== TOOL.name) {
63
- return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
64
- }
65
- const mint = String(args?.mint || "").trim();
66
- if (!mint) {
67
- return {
68
- content: [{ type: "text", text: "Error: 'mint' (a Solana token mint address) is required." }],
69
- isError: true,
70
- };
71
- }
72
- const url = `${API}/api/scan-cabal?mintAddress=${encodeURIComponent(mint)}`;
73
- const headers = { Accept: "application/json" };
74
- if (API_KEY) headers["X-API-Key"] = API_KEY;
75
- try {
76
- const res = await fetch(url, { headers });
77
- const text = await res.text();
78
- if (!res.ok) {
79
- return {
80
- content: [{ type: "text", text: `Cabal-Hunter API error ${res.status}: ${text.slice(0, 800)}` }],
81
- isError: true,
82
- };
83
- }
84
- return { content: [{ type: "text", text }] };
85
- } catch (e) {
86
- return {
87
- content: [{ type: "text", text: `Request to Cabal-Hunter failed: ${e?.message || String(e)}` }],
88
- isError: true,
89
- };
90
- }
91
- });
92
-
93
- const transport = new StdioServerTransport();
94
- await server.connect(transport);
95
- console.error(`cabal-hunter MCP server running on stdio → ${API}`);