mcp-server-madeonsol 1.2.1 → 1.3.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.
Files changed (3) hide show
  1. package/README.md +18 -0
  2. package/dist/index.js +76 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -68,6 +68,7 @@ Add to MCP settings with the same command and env vars.
68
68
  |---|---|
69
69
  | `madeonsol_kol_feed` | Real-time KOL trade feed (1,000+ wallets) |
70
70
  | `madeonsol_kol_coordination` | Multi-KOL convergence signals (v1.1) — peak-density window, exit detection, 0-100 score |
71
+ | `madeonsol_kol_first_touches` | First-KOL-touch events — backtested scout signal. Filter by scout tier, winrate, token age, mint suffix |
71
72
  | `madeonsol_kol_leaderboard` | KOL PnL and win rate rankings (180 days of history; periods: today, 7d, 30d, 90d, 180d) |
72
73
  | `madeonsol_kol_pairs` | KOL affinity matrix — which KOLs co-trade the same tokens |
73
74
  | `madeonsol_kol_hot_tokens` | KOL momentum tokens — accelerating buy interest |
@@ -134,6 +135,23 @@ Real-time push alerts when a KOL cluster co-buys the same token. Fires within ~1
134
135
  | `madeonsol_coordination_alerts_update` | Update fields or toggle `is_active` |
135
136
  | `madeonsol_coordination_alerts_delete` | Delete permanently |
136
137
 
138
+ ### KOL Scout Signal — first KOL touches *(new in 1.3)*
139
+
140
+ Every "first KOL buy on a token mint" event. Filterable by **scout tier** (S/A/B/C from `mv_kol_scout_score`), KOL winrate, token age, mint suffix.
141
+
142
+ **Backtest:** S-tier scouts attract ≥3 follow-on KOLs within 4h ~50% of the time vs ~14% baseline (38d / 491k buys / 72,549 events). Public leaderboard at [madeonsol.com/kol/scouts](https://madeonsol.com/kol/scouts).
143
+
144
+ | Tool | Description |
145
+ |---|---|
146
+ | `madeonsol_kol_first_touches` | Recent first-KOL-touch events. Filters: `min_scout_tier`, `min_kol_winrate_7d`, `token_age_max_min`, `mint_suffix`, `preset`, etc. |
147
+ | `madeonsol_first_touch_subscriptions_list` | List your first-touch webhook subscriptions — ULTRA |
148
+ | `madeonsol_first_touch_subscriptions_create` | Create a webhook rule (HMAC-signed). Returns `webhook_secret` once — store it. Up to 10/user — ULTRA |
149
+ | `madeonsol_first_touch_subscriptions_get` | Get one subscription — ULTRA |
150
+ | `madeonsol_first_touch_subscriptions_update` | Update fields or toggle `is_active` — ULTRA |
151
+ | `madeonsol_first_touch_subscriptions_delete` | Delete permanently — ULTRA |
152
+
153
+ > **Don't poll — push.** Median lead time before the second KOL is 12 seconds. WebSocket channel: `kol:first_touches` (PRO+).
154
+
137
155
  ### Streaming & Webhooks
138
156
 
139
157
  | Tool | Description |
package/dist/index.js CHANGED
@@ -537,6 +537,75 @@ function registerTools(server) {
537
537
  server.tool("madeonsol_coordination_alerts_delete", "Delete a coordination alert rule permanently.", { id: z.string().describe("Rule UUID") }, { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true }, async ({ id }) => ({
538
538
  content: [{ type: "text", text: await restQuery("DELETE", `/kol/coordination/alerts/${encodeURIComponent(id)}`) }],
539
539
  }));
540
+ // ── First-touch signal (read tool + ULTRA webhook subscriptions CRUD) ──
541
+ server.tool("madeonsol_kol_first_touches", "Recent first-KOL-touch events — every time a tracked KOL was the first to buy a token mint. Filterable by scout tier (S/A/B/C from mv_kol_scout_score), KOL winrate, token age, etc. Backtest: top scouts attract ≥3 follow-on KOLs within 4h ~50% of the time vs ~14% baseline. Median lead time before second KOL is 12s — for trading this signal, use the WebSocket channel rather than polling.", {
542
+ limit: z.number().min(1).max(100).optional().describe("Number of events to return (1-100, default 50)"),
543
+ since: z.string().optional().describe("ISO timestamp — events strictly newer than this. Polling cursor."),
544
+ before: z.string().optional().describe("ISO timestamp — events strictly older than this. Pagination cursor."),
545
+ kol: z.string().optional().describe("Filter to a single KOL wallet address (base58)"),
546
+ min_kol_winrate_7d: z.number().min(0).max(100).optional().describe("Minimum 7d winrate of the first-touch KOL (0-100)"),
547
+ min_scout_tier: z.enum(["S", "A", "B", "C"]).optional().describe("Restrict to first-touch KOLs of this scout tier or better. Requires n_first_touches_30d >= 30."),
548
+ min_n_touches: z.number().min(1).optional().describe("Lower the minimum sample size for scout scoring (default 30)"),
549
+ strategy: z.enum(["scalper", "day_trader", "swing_trader", "hodler", "mixed"]).optional().describe("Filter by first-touch KOL's auto-tagged strategy"),
550
+ token_age_max_min: z.number().min(1).optional().describe("Only events on tokens younger than N minutes (uses token_first_seen)"),
551
+ min_first_buy_sol: z.number().min(0).optional().describe("Minimum size of the first KOL buy in SOL"),
552
+ mint_suffix: z.string().optional().describe("Suffix-filter the token mint (e.g. 'pump', 'bonk')"),
553
+ preset: z.enum(["scout", "fresh_launch"]).optional().describe("Shortcut filter: 'scout' = min_scout_tier=B + min_n_touches=30 + token_age_max_min=60. 'fresh_launch' = token_age_max_min=15."),
554
+ include: z.string().optional().describe("Comma-separated includes — currently 'followers_4h' (computed for events >=4h old)"),
555
+ }, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async (args) => {
556
+ const params = {};
557
+ for (const [k, v] of Object.entries(args))
558
+ if (v !== undefined)
559
+ params[k] = v;
560
+ return { content: [{ type: "text", text: await restQuery("GET", `/kol/first-touches?${new URLSearchParams(params).toString()}`) }] };
561
+ });
562
+ server.tool("madeonsol_first_touch_subscriptions_list", "List your first-touch webhook subscriptions. ULTRA only.", {}, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async () => ({
563
+ content: [{ type: "text", text: await restQuery("GET", "/kol/first-touches/subscriptions") }],
564
+ }));
565
+ server.tool("madeonsol_first_touch_subscriptions_create", "Create a first-touch webhook subscription. ULTRA only — up to 10 active. Filters: kol (wallet), mint_suffix, min_first_buy_sol, min_scout_tier (S/A/B/C), min_n_touches. Returns webhook_secret ONCE — store it.", {
566
+ name: z.string().optional().describe("Optional label"),
567
+ filters: z.object({
568
+ kol: z.string().optional(),
569
+ mint_suffix: z.string().optional(),
570
+ min_first_buy_sol: z.number().min(0).optional(),
571
+ min_scout_tier: z.enum(["S", "A", "B", "C"]).optional(),
572
+ min_n_touches: z.number().min(1).optional(),
573
+ }).optional(),
574
+ delivery_mode: z.enum(["websocket", "webhook", "both"]).optional().describe("Default 'webhook'"),
575
+ webhook_url: z.string().url().optional().describe("Required when delivery_mode includes 'webhook'"),
576
+ }, { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, async (args) => {
577
+ const body = {};
578
+ for (const [k, v] of Object.entries(args))
579
+ if (v !== undefined)
580
+ body[k] = v;
581
+ return { content: [{ type: "text", text: await restQuery("POST", "/kol/first-touches/subscriptions", body) }] };
582
+ });
583
+ server.tool("madeonsol_first_touch_subscriptions_get", "Get one first-touch subscription by id. ULTRA only.", { id: z.string().describe("Subscription UUID") }, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async ({ id }) => ({
584
+ content: [{ type: "text", text: await restQuery("GET", `/kol/first-touches/subscriptions/${encodeURIComponent(id)}`) }],
585
+ }));
586
+ server.tool("madeonsol_first_touch_subscriptions_update", "Update fields on a first-touch subscription, including is_active toggle. ULTRA only.", {
587
+ id: z.string().describe("Subscription UUID"),
588
+ name: z.string().nullable().optional(),
589
+ filters: z.object({
590
+ kol: z.string().optional(),
591
+ mint_suffix: z.string().optional(),
592
+ min_first_buy_sol: z.number().min(0).optional(),
593
+ min_scout_tier: z.enum(["S", "A", "B", "C"]).optional(),
594
+ min_n_touches: z.number().min(1).optional(),
595
+ }).optional(),
596
+ delivery_mode: z.enum(["websocket", "webhook", "both"]).optional(),
597
+ webhook_url: z.string().url().nullable().optional(),
598
+ is_active: z.boolean().optional(),
599
+ }, { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, async ({ id, ...patch }) => {
600
+ const body = {};
601
+ for (const [k, v] of Object.entries(patch))
602
+ if (v !== undefined)
603
+ body[k] = v;
604
+ return { content: [{ type: "text", text: await restQuery("PATCH", `/kol/first-touches/subscriptions/${encodeURIComponent(id)}`, body) }] };
605
+ });
606
+ server.tool("madeonsol_first_touch_subscriptions_delete", "Delete a first-touch subscription permanently. ULTRA only.", { id: z.string().describe("Subscription UUID") }, { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true }, async ({ id }) => ({
607
+ content: [{ type: "text", text: await restQuery("DELETE", `/kol/first-touches/subscriptions/${encodeURIComponent(id)}`) }],
608
+ }));
540
609
  console.error("[madeonsol-mcp] Webhook & streaming tools enabled");
541
610
  }
542
611
  else {
@@ -581,7 +650,7 @@ async function main() {
581
650
  res.end(JSON.stringify({
582
651
  name: "madeonsol",
583
652
  description: "Solana KOL trading intelligence and deployer analytics. Real-time data from 1,000+ KOL wallets, 6,700+ Pump.fun deployers, 47,000+ scored alpha wallets, copy-trade rules, and wallet tracker. Supports MadeOnSol API key (msk_) or x402 micropayments.",
584
- version: "1.1.2",
653
+ version: "1.3.1",
585
654
  tools: [
586
655
  { name: "madeonsol_kol_feed", description: "Get real-time Solana KOL trades from 1,000+ tracked wallets." },
587
656
  { name: "madeonsol_kol_coordination", description: "Get KOL convergence signals — tokens multiple KOLs are accumulating." },
@@ -621,6 +690,12 @@ async function main() {
621
690
  { name: "madeonsol_copytrade_update", description: "Update a copy-trade rule. PRO/ULTRA." },
622
691
  { name: "madeonsol_copytrade_delete", description: "Delete a copy-trade rule. PRO/ULTRA." },
623
692
  { name: "madeonsol_copytrade_signals", description: "Recent fired copy-trade signals (up to 7 days). PRO/ULTRA." },
693
+ { name: "madeonsol_kol_first_touches", description: "Recent first-KOL-touch events on tokens — backtested scout signal. Filterable by scout tier S/A/B/C, KOL winrate, token age, mint suffix." },
694
+ { name: "madeonsol_first_touch_subscriptions_list", description: "List your first-touch webhook subscriptions. ULTRA only." },
695
+ { name: "madeonsol_first_touch_subscriptions_create", description: "Create a first-touch webhook subscription with HMAC signing. ULTRA only." },
696
+ { name: "madeonsol_first_touch_subscriptions_get", description: "Get one first-touch subscription. ULTRA only." },
697
+ { name: "madeonsol_first_touch_subscriptions_update", description: "Update a first-touch subscription. ULTRA only." },
698
+ { name: "madeonsol_first_touch_subscriptions_delete", description: "Delete a first-touch subscription. ULTRA only." },
624
699
  { name: "madeonsol_coordination_alerts_list", description: "List your KOL coordination alert rules. PRO/ULTRA." },
625
700
  { name: "madeonsol_coordination_alerts_create", description: "Create a coordination alert rule (push via WS + webhook, <1s latency). PRO/ULTRA." },
626
701
  { name: "madeonsol_coordination_alerts_get", description: "Get one coordination alert rule. PRO/ULTRA." },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-server-madeonsol",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "mcpName": "io.github.lambopoewert/madeonsol",
5
5
  "description": "MCP server for MadeOnSol Solana KOL intelligence API — use from Claude, Cursor, or any MCP client",
6
6
  "type": "module",