mcp-server-madeonsol 1.14.0 → 1.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 CHANGED
@@ -13,6 +13,8 @@ MCP server for [MadeOnSol](https://madeonsol.com) Solana KOL intelligence API. U
13
13
 
14
14
  > Real-time Solana trading intelligence: track 1,069 KOL wallets with <3s latency, score 23,000+ Pump.fun deployers, surface deshred deploy signals **~500ms before on-chain confirmation**, detect multi-KOL coordination, and stream every DEX trade across 9+ programs. Free tier: 200 requests/day at [madeonsol.com/pricing](https://madeonsol.com/pricing) — no credit card required.
15
15
 
16
+ > **New in 1.15.0** — **Almost-bonded discovery + trending sorts.** New tool `madeonsol_almost_bonded` — pre-bond pump.fun tokens near graduation, ranked by velocity (Δprogress/min): "95% and accelerating" beats "92% stalled". Each token carries `progress_pct`, `velocity_pct_per_min`, `eta_minutes`, `stalled`, `real_sol_reserves`, `market_cap_usd`, `liquidity_usd`, `authorities_revoked`, `deployer_tier`, and `age_minutes`. Params: `min_progress`, `max_progress`, `min_velocity_pct_per_min`, `max_age_minutes`, `deployer_tier`, `authority_revoked`, `min_liq`, `sort` (velocity_desc / progress_desc / eta_asc), `limit`. PRO/ULTRA only. Plus `madeonsol_tokens_list` gains four momentum sorts — `mc_change_5m_desc`, `mc_change_1h_desc`, `volume_1h_desc`, and `trending` (composite recent-volume × positive-momentum rank).
17
+ >
16
18
  > **New in 1.14.0** — **Token trade flow.** New tool `madeonsol_token_flow` — a trade-flow aggregate (organic-vs-fake volume) over a `1h`/`24h` window: `unique_wallets` / `unique_buyers` / `unique_sellers`, `buy_count` / `sell_count` / `total_trades`, `buy_sol` / `sell_sol` / `net_sol` (sell − buy; positive = net SOL leaving the pool), and `trades_per_wallet` (wash-trading proxy). PRO/ULTRA only. Deployer alerts (`madeonsol_deployer_alerts`) now carry `deployers.deployer_sol_balance` — the deployer wallet's SOL balance at alert time (null for historical rows).
17
19
  >
18
20
  > **New in 1.13.0** — **Token OHLCV candles.** New tool `madeonsol_token_candles` — historical price candles (1m/5m/15m/1h/4h/1d) aggregated from the on-chain trade firehose. Each candle has `t/open/high/low/close/volume_usd/trades/market_cap_usd`. PRO returns OHLCV for the last 30 days; ULTRA adds buy/sell volume + count splits, net flow, MEV volume, open/close liquidity, high/low MC, and full history. PRO/ULTRA only.
@@ -63,6 +65,37 @@ Add to `claude_desktop_config.json` or Cursor MCP settings (free tier at https:/
63
65
 
64
66
  Restart Claude Desktop and ask: *"What are KOLs buying right now?"*
65
67
 
68
+ ## AI agent quickstart (x402 / pay-per-call)
69
+
70
+ Building an autonomous agent? Skip the signup. Point a **funded Solana wallet** at the server and every tool call **auto-pays a micropayment** over [x402](https://x402.org) — no API key, no account, no rate-limit dance.
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "madeonsol": {
76
+ "command": "mcp-server-madeonsol",
77
+ "env": {
78
+ "SVM_PRIVATE_KEY": "<base58 solana private key>"
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ How it works:
86
+
87
+ - The wallet behind `SVM_PRIVATE_KEY` settles each request as a **USDC micropayment on Solana** (~$0.005–$0.02 per call, settled on-chain). No subscription, no quota.
88
+ - The free **`madeonsol_discovery`** tool needs no auth and returns every endpoint with its exact per-call price — call it first to see what each tool costs.
89
+ - Install the x402 peer deps alongside the server (only required for this mode):
90
+
91
+ ```bash
92
+ npm install -g mcp-server-madeonsol @x402/fetch @x402/svm @x402/core @solana/kit @scure/base
93
+ ```
94
+
95
+ > **Data only.** MadeOnSol returns trading *intelligence* — it never trades, signs swaps, or takes custody of funds. The only thing your wallet ever pays for is the per-call data fee.
96
+
97
+ Prefer a fixed monthly bill, free tier, or no wallet? Use the developer path below.
98
+
66
99
  ## Authentication
67
100
 
68
101
  Two options (in priority order):
@@ -172,7 +205,8 @@ Scored from 1M+ early-buyer records (wallets seen in the first 20 buyers of Pump
172
205
 
173
206
  | Tool | Tier | Description |
174
207
  |---|---|---|
175
- | `madeonsol_tokens_list` | PRO+ | Filtered, sortable token directory — MC band, liquidity floor, primary DEX, authority/safety flags, computed 1h volume / MEV-share / MC-change deltas. Default `min_liq=2000` skips phantom-MC dust. |
208
+ | `madeonsol_tokens_list` | PRO+ | Filtered, sortable token directory — MC band, liquidity floor, primary DEX, authority/safety flags, computed 1h volume / MEV-share / MC-change deltas, plus momentum sorts (`mc_change_5m_desc`, `mc_change_1h_desc`, `volume_1h_desc`, `trending`). Default `min_liq=2000` skips phantom-MC dust. |
209
+ | `madeonsol_almost_bonded` | PRO+ | Pre-bond pump.fun tokens near graduation, ranked by velocity (Δprogress/min) — `progress_pct`, `velocity_pct_per_min`, `eta_minutes`, `stalled`, `deployer_tier`, `age_minutes` |
176
210
  | `madeonsol_token_cap_table` | PRO+ | First non-deployer early buyers, enriched with PnL/KOL/bot flags. PRO=10, ULTRA=20 |
177
211
  | `madeonsol_token_buyer_quality` | All | 0–100 buyer-quality score + full breakdown (5-min cached) |
178
212
  | `madeonsol_token_risk` | PRO+ | Transparent 0–100 rug-risk/safety score with `band`, explainable `factors[]`, and raw `inputs` |
package/dist/index.d.ts CHANGED
@@ -1,2 +1,17 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export type AuthMode = "madeonsol" | "x402" | "none";
3
+ /**
4
+ * Pure selection of the auth mode from environment. Extracted from initAuth()
5
+ * so the routing/auth-mode logic is unit-testable without setting up signers or
6
+ * network. Priority: MADEONSOL_API_KEY (Bearer) > SVM_PRIVATE_KEY (x402) > none.
7
+ */
8
+ export declare function resolveAuthMode(env?: {
9
+ MADEONSOL_API_KEY?: string;
10
+ SVM_PRIVATE_KEY?: string;
11
+ }): AuthMode;
12
+ /**
13
+ * Pure path rewrite. Tools are authored against /api/x402/ paths. In x402 / none
14
+ * mode the path is kept as-is; in madeonsol (API key) mode the prefix is
15
+ * rewritten to /api/v1/. Extracted from query() so it is unit-testable.
16
+ */
17
+ export declare function rewritePath(path: string, mode: AuthMode): string;
package/dist/index.js CHANGED
@@ -11,7 +11,29 @@ const PORT = parseInt(process.env.PORT || "3100", 10);
11
11
  const MODE = process.env.MCP_TRANSPORT || "stdio"; // "stdio" or "http"
12
12
  let authMode = "none";
13
13
  let paidFetch = fetch;
14
- const UA = "mcp-server-madeonsol/1.14.0";
14
+ /**
15
+ * Pure selection of the auth mode from environment. Extracted from initAuth()
16
+ * so the routing/auth-mode logic is unit-testable without setting up signers or
17
+ * network. Priority: MADEONSOL_API_KEY (Bearer) > SVM_PRIVATE_KEY (x402) > none.
18
+ */
19
+ export function resolveAuthMode(env = process.env) {
20
+ if (env.MADEONSOL_API_KEY)
21
+ return "madeonsol";
22
+ if (env.SVM_PRIVATE_KEY)
23
+ return "x402";
24
+ return "none";
25
+ }
26
+ /**
27
+ * Pure path rewrite. Tools are authored against /api/x402/ paths. In x402 / none
28
+ * mode the path is kept as-is; in madeonsol (API key) mode the prefix is
29
+ * rewritten to /api/v1/. Extracted from query() so it is unit-testable.
30
+ */
31
+ export function rewritePath(path, mode) {
32
+ return mode === "x402" || mode === "none"
33
+ ? path
34
+ : path.replace("/api/x402/", "/api/v1/");
35
+ }
36
+ const UA = "mcp-server-madeonsol/1.15.1";
15
37
  function apiKeyHeaders() {
16
38
  const h = { "User-Agent": UA };
17
39
  if (authMode === "madeonsol") {
@@ -20,12 +42,13 @@ function apiKeyHeaders() {
20
42
  return h;
21
43
  }
22
44
  async function initAuth() {
23
- if (MADEONSOL_API_KEY) {
45
+ const mode = resolveAuthMode({ MADEONSOL_API_KEY, SVM_PRIVATE_KEY: PRIVATE_KEY });
46
+ if (mode === "madeonsol") {
24
47
  authMode = "madeonsol";
25
48
  console.error("[madeonsol-mcp] Using MadeOnSol API key (Bearer auth)");
26
49
  return;
27
50
  }
28
- if (PRIVATE_KEY) {
51
+ if (mode === "x402" && PRIVATE_KEY) {
29
52
  try {
30
53
  const { wrapFetchWithPayment } = await import("@x402/fetch");
31
54
  const { x402Client } = await import("@x402/core/client");
@@ -50,9 +73,7 @@ async function initAuth() {
50
73
  }
51
74
  async function query(path, params) {
52
75
  // API key uses /api/v1/ endpoints; x402 uses /api/x402/
53
- const apiPath = authMode === "x402" || authMode === "none"
54
- ? path
55
- : path.replace("/api/x402/", "/api/v1/");
76
+ const apiPath = rewritePath(path, authMode);
56
77
  const url = new URL(apiPath, BASE_URL);
57
78
  if (params) {
58
79
  for (const [k, v] of Object.entries(params)) {
@@ -507,7 +528,7 @@ function registerTools(server) {
507
528
  min_liq_mc_ratio: z.number().optional().describe("Minimum liquidity-to-MC ratio (0-1). Filters out tokens where liquidity is thin relative to market cap."),
508
529
  max_liq_mc_ratio: z.number().optional().describe("Maximum liquidity-to-MC ratio (0-1)."),
509
530
  deployer_tier: z.enum(["elite", "good", "moderate", "rising", "cold", "unranked"]).optional().describe("Filter by deployer reputation tier."),
510
- sort: z.enum(["mc_desc", "mc_asc", "last_trade_desc", "liquidity_desc", "cumulative_volume_desc"]).optional().describe("Sort axis (default mc_desc)"),
531
+ sort: z.enum(["mc_desc", "mc_asc", "last_trade_desc", "liquidity_desc", "cumulative_volume_desc", "mc_change_5m_desc", "mc_change_1h_desc", "volume_1h_desc", "trending"]).optional().describe("Sort axis (default mc_desc). Momentum sorts: mc_change_5m_desc, mc_change_1h_desc, volume_1h_desc, trending (composite recent-volume × positive-momentum rank)."),
511
532
  limit: z.number().min(1).max(100).optional().describe("Page size (max 100)"),
512
533
  offset: z.number().min(0).optional().describe("Pagination offset"),
513
534
  }, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async (args) => {
@@ -520,6 +541,26 @@ function registerTools(server) {
520
541
  const text = res.ok ? JSON.stringify(await res.json(), null, 2) : `Error ${res.status}: ${await res.text().catch(() => "")}`;
521
542
  return { content: [{ type: "text", text }] };
522
543
  });
544
+ server.tool("madeonsol_almost_bonded", "Pre-bond pump.fun tokens approaching graduation, ranked by VELOCITY (Δprogress/min) — '95% and accelerating' beats '92% stalled'. Each token is enriched with its deployer's reputation tier. progress_pct comes from on-chain real_token_reserves depletion; velocity_pct_per_min is null until a 5-minute snapshot exists; eta_minutes is a linear projection from current velocity. Returns tokens[] with mint, symbol, name, progress_pct, velocity_pct_per_min, eta_minutes, stalled, real_sol_reserves, market_cap_usd, liquidity_usd, authorities_revoked, deployer_tier, age_minutes. PRO/ULTRA only.", {
545
+ min_progress: z.number().min(0).max(100).optional().describe("Lower bound on bonding progress % (default 80)"),
546
+ max_progress: z.number().min(0).max(100).optional().describe("Upper bound on bonding progress % (default 99.99 — already-bonded excluded)"),
547
+ min_velocity_pct_per_min: z.number().optional().describe("Minimum Δprogress/min; tokens without a 5m-ago snapshot are dropped when set"),
548
+ max_age_minutes: z.number().min(1).optional().describe("Max minutes since deploy (post-filter)"),
549
+ deployer_tier: z.enum(["elite", "good", "moderate", "rising", "cold", "unranked"]).optional().describe("Filter by deployer reputation tier"),
550
+ authority_revoked: z.boolean().optional().describe("Only tokens whose mint+freeze authorities are revoked"),
551
+ min_liq: z.number().min(0).optional().describe("Minimum liquidity in USD"),
552
+ sort: z.enum(["velocity_desc", "progress_desc", "eta_asc"]).optional().describe("Sort axis (default velocity_desc)"),
553
+ limit: z.number().min(1).max(100).optional().describe("Page size (1-100, default 50)"),
554
+ }, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async (args) => {
555
+ const url = new URL(`${BASE_URL}/api/v1/tokens/almost-bonded`);
556
+ for (const [k, v] of Object.entries(args)) {
557
+ if (v !== undefined)
558
+ url.searchParams.set(k, typeof v === "boolean" ? (v ? "true" : "false") : String(v));
559
+ }
560
+ const res = await fetch(url.toString(), { headers: { "Content-Type": "application/json", ...apiKeyHeaders() } });
561
+ const text = res.ok ? JSON.stringify(await res.json(), null, 2) : `Error ${res.status}: ${await res.text().catch(() => "")}`;
562
+ return { content: [{ type: "text", text }] };
563
+ });
523
564
  // ── Alpha wallet intelligence ──
524
565
  server.tool("madeonsol_alpha_leaderboard", "Top statistically profitable early-buyer wallets, scored from 47,000+ early-buyer records. BASIC=25 (truncated), PRO=100, ULTRA=500 + bot signals.", {
525
566
  period: z.enum(["7d", "30d", "all"]).default("30d").describe("Time window"),
@@ -908,7 +949,7 @@ async function main() {
908
949
  res.end(JSON.stringify({
909
950
  name: "madeonsol",
910
951
  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.",
911
- version: "1.13.0",
952
+ version: "1.15.1",
912
953
  tools: [
913
954
  { name: "madeonsol_kol_feed", description: "Get real-time Solana KOL trades from 1,000+ tracked wallets." },
914
955
  { name: "madeonsol_kol_coordination", description: "Get KOL convergence signals — tokens multiple KOLs are accumulating." },
@@ -930,7 +971,8 @@ async function main() {
930
971
  { name: "madeonsol_test_webhook", description: "Send a test payload to verify a webhook. Pro/Ultra." },
931
972
  { name: "madeonsol_stream_token", description: "Get a 24h WebSocket streaming token. Pro/Ultra." },
932
973
  { name: "madeonsol_me", description: "Inspect your account — tier, quota state, remaining requests, subscription expiry, per-feature usage." },
933
- { name: "madeonsol_tokens_list", description: "Filtered, sortable token directory — MC band, liquidity floor, primary DEX, authority/safety flags, computed 1h volume / MEV-share / MC-change. PRO+." },
974
+ { name: "madeonsol_tokens_list", description: "Filtered, sortable token directory — MC band, liquidity floor, primary DEX, authority/safety flags, computed 1h volume / MEV-share / MC-change, plus momentum sorts (mc_change_5m_desc, mc_change_1h_desc, volume_1h_desc, trending). PRO+." },
975
+ { name: "madeonsol_almost_bonded", description: "Pre-bond pump.fun tokens near graduation, ranked by velocity (Δprogress/min) — progress_pct, velocity_pct_per_min, eta_minutes, stalled, deployer_tier. PRO+." },
934
976
  { name: "madeonsol_wallet_tracker_watchlist", description: "List your tracked wallets and remaining capacity." },
935
977
  { name: "madeonsol_wallet_tracker_add", description: "Add a wallet to your watchlist." },
936
978
  { name: "madeonsol_wallet_tracker_remove", description: "Remove a wallet from your watchlist." },
@@ -992,7 +1034,7 @@ async function main() {
992
1034
  transport = new StreamableHTTPServerTransport({
993
1035
  sessionIdGenerator: undefined,
994
1036
  });
995
- const server = new McpServer({ name: "madeonsol", version: "1.13.0" });
1037
+ const server = new McpServer({ name: "madeonsol", version: "1.15.1" });
996
1038
  registerTools(server);
997
1039
  await server.connect(transport);
998
1040
  }
@@ -1036,4 +1078,8 @@ async function main() {
1036
1078
  await server.connect(transport);
1037
1079
  }
1038
1080
  }
1039
- main().catch(console.error);
1081
+ // Only auto-run when executed as a program (CLI / spawned process), not when
1082
+ // the module is imported by a test for its exported pure helpers.
1083
+ if (process.env.MADEONSOL_MCP_NO_AUTORUN !== "1") {
1084
+ main().catch(console.error);
1085
+ }
package/glama.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "mcp-server-madeonsol",
3
3
  "display_name": "MadeOnSol — Solana memecoin intelligence",
4
4
  "description": "Real-time Solana memecoin trading intelligence — track 1,000+ KOL wallets with <3s latency, score 6,700+ Pump.fun deployers, surface multi-KOL coordination signals, run server-side copy-trade rules, and stream every DEX trade across 9+ programs. Backtested first-touch scout signal (S-tier scouts attract ≥3 follow-on KOLs ~50% of the time vs 14% baseline). Free tier 200 requests per day; auth via msk_ API key or x402 micropayments.",
5
- "version": "1.7.4",
5
+ "version": "1.15.1",
6
6
  "homepage": "https://madeonsol.com/solana-api",
7
7
  "repository": "https://github.com/LamboPoewert/mcp-server-madeonsol",
8
8
  "license": "MIT",
@@ -46,7 +46,8 @@
46
46
  { "name": "madeonsol_alpha_leaderboard", "description": "Top profitable early-buyer wallets — 47,000+ scored, up to 500 on ULTRA." },
47
47
  { "name": "madeonsol_alpha_wallet", "description": "Full alpha profile + bot-signal flags for one wallet." },
48
48
  { "name": "madeonsol_alpha_linked", "description": "Behaviorally linked wallets (co-bought 3+ tokens within 2s)." },
49
- { "name": "madeonsol_tokens_list", "description": "Filtered token directory — MC band, liquidity, MEV-share, velocity, primary DEX, authority flags." },
49
+ { "name": "madeonsol_tokens_list", "description": "Filtered token directory — MC band, liquidity, MEV-share, velocity, primary DEX, authority flags, momentum/trending sorts." },
50
+ { "name": "madeonsol_almost_bonded", "description": "Pre-bond pump.fun tokens near graduation, ranked by velocity (Δprogress/min) — progress, eta, stalled, deployer tier." },
50
51
  { "name": "madeonsol_token_get", "description": "Single token detail — MC, holders, velocity, MEV-share, history age." },
51
52
  { "name": "madeonsol_token_batch", "description": "Bulk token detail fetch — up to 50 mints per call." },
52
53
  { "name": "madeonsol_token_cap_table", "description": "First non-deployer early buyers for a token, enriched with PnL/KOL/bot flags." },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-server-madeonsol",
3
- "version": "1.14.0",
3
+ "version": "1.15.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",
@@ -16,6 +16,7 @@
16
16
  ],
17
17
  "scripts": {
18
18
  "build": "tsc",
19
+ "test": "vitest run",
19
20
  "preflight": "bash ../../scripts/preflight-publish.sh",
20
21
  "prepublishOnly": "npm run preflight && npm run build"
21
22
  },
@@ -61,6 +62,7 @@
61
62
  },
62
63
  "devDependencies": {
63
64
  "@types/node": "^20",
64
- "typescript": "^5"
65
+ "typescript": "^5",
66
+ "vitest": "^4.1.5"
65
67
  }
66
68
  }