mcp-server-madeonsol 1.20.3 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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, surface bundle-cohort holdings (which same-slot wallets still hold a token's supply), verify any wallet's CURRENT on-chain holdings straight from its token accounts, and stream every DEX trade across 9+ programs. Free tier: 200 requests/day, every endpoint — no signup payment. Get a key at [madeonsol.com/pricing](https://madeonsol.com/pricing).
15
15
 
16
+ > **New in 1.21.0 — the Deployer Hunter surface completed.** Seven new operations that existed on the API but had no SDK binding: `madeonsol_deployer_leaderboard`, `madeonsol_deployer_stats`, `madeonsol_deployer_profile`, `madeonsol_deployer_tokens`, `madeonsol_deployer_alert_stats`, `madeonsol_deployer_best_tokens` and `madeonsol_deployer_recent_bonds`. Read `bonding_rate` (lifetime) against `recent_bond_rate` (rolling) — the gap between them is the signal, not either number alone. `runner_rate` only means something once `labeled_tokens >= 3`, and an **untracked wallet returns a profile with zeroed counters, not a 404**, so check `total_deployed` before reading a 0% bond rate as a track record. Dependency ranges are now bounded to the versions actually tested (`@x402/*` `^2.x`, `@solana/kit` `^5.5.1`) instead of open-ended `>=0.0.1`, and the lazily-imported x402 peers are marked optional — a keyed install no longer pulls the whole Solana stack.
17
+
16
18
  > **New in 1.20.0** — **Token depth / price impact + deployer self-activity on risk.** New tool `madeonsol_token_depth` (`GET /tokens/{mint}/depth`) — per-pool price-impact / slippage: "how much SOL moves this token's price N%", per pool (NOT router-optimal). Pass up to 8 SOL buy `sizes` (each >0 and ≤10000; default `[0.5, 1, 5, 10]`); every computable pool returns `spot_price_sol`, `fee_pct`, a `quotes[]` entry per size (`size_sol`, `tokens_out`, `avg_price_sol`, `price_impact_pct`), and `to_move_price` — the SOL required to move price **1% / 5% / 10%**. Constant-product AMMs are served from stream reserves (`source: "stream"` with `reserves_age_ms`); pump.fun/bonk bonding curves from a **live** read of the curve's virtual reserves (`source: "live_rpc"`). Pools that can't be priced honestly — concentrated CLMM/Orca/DLMM, Meteora-DBC curves, unclassified models — come back in `unsupported_pools[]` with a `reason` (e.g. `concentrated_liquidity_depth_not_supported`, `curve_graduated_use_amm_pool`) instead of a wrong number; `primary_pool` names the deepest computable pool, `found: false` means no pools tracked. PRO/ULTRA only. And `madeonsol_token_risk` now returns a top-level **`dev` block** (deployer self-activity; `null` when the mint has no deployer-pipeline row): the create-tx self-buy snapshot (`buy_sol`, `buy_tokens`, `buy_supply_pct`), the post-create rollup (`bought_tokens_after` — catches the same-second-separate-tx dev buy the create snapshot reads as 0 — `sold_tokens`, `sold_sol`, `first_sell_at`/`last_sell_at`), **live on-chain holdings** (`holdings_tokens`, `holdings_supply_pct` — pump.fun 1B denominator, null elsewhere — `wallet_empty`: is the dev wallet empty NOW), and `transferred_out` (tokens left without a sell; `null` = unknown, never a guess), plus `as_of`. `deployer:alert` webhook/WS payloads gain `dev_buy_sol` + `dev_buy_supply_pct`.
17
19
  >
18
20
  > **New in 1.19.0** — **Batch wallet classification + token trade tape + bigger keyless catalog.** New tool `madeonsol_wallet_batch_classify` — reputation flags for 1–100 wallets in one call (counts as one request): per wallet `is_sniper` / `is_bundler` / `is_dumper` / `is_kol` (+ `kol_name`), `bot_confidence` (string enum `none`/`low`/`medium`/`high`, `null` when not alpha-tracked), and a `dump_cluster` block (`dump_cohorts`, `runner_cohorts`, `total_cohorts`, `as_of`). Flags are pump.fun-pipeline scoped — `false` = not observed, NOT verified clean; `is_bundler` is lifetime, `is_dumper` is a rolling 42d window. New tool `madeonsol_token_trades` — mint-scoped cursor-paginated trade tape (the backfill complement to the live firehose): `tx_signature`, `wallet_address`, `action`, `sol_amount`, `token_amount`, `price_sol`/`price_usd`, `early_buyer_rank`, `slot`, `block_time`, `traded_at`; filters `action` / `wallet` / `since`–`until` (default FULL history — capture starts 2026-04-12), plus a `coverage` honesty block. Both PRO/ULTRA. `madeonsol_wallet_stats` flags gain `is_sniper`/`is_bundler`/`is_dumper` + `dump_cluster`, and `bot_confidence` is now correctly typed as a string enum (it was documented as a number and always came back `null` due to a server bug — now returns real values). `madeonsol_token_risk` inputs and `madeonsol_sniper_recent` deploys gain the slot-window `sniper_footprint`/`footprint` rollup (`buys`, `buyers`, `sol`, `supply_pct`, `sniper_wallet_buys`, `data_available`, `as_of` — `null` = not observable, not zero). The **keyless x402 catalog grows 18 → 25 endpoints**: token candles ($0.01), almost-bonded ($0.01), top-traders ($0.02), cap-table ($0.02), sniper recent ($0.01), token flow ($0.01), deployer trajectory ($0.01) — `madeonsol_sniper_recent` and `madeonsol_deployer_trajectory` now work keyless via x402 too.
package/dist/index.js CHANGED
@@ -215,6 +215,75 @@ function registerTools(server) {
215
215
  }, readOnlyAnnotations, async ({ wallet }) => ({
216
216
  content: [{ type: "text", text: await query(`/api/x402/deployer-hunter/${encodeURIComponent(wallet)}/trajectory`) }],
217
217
  }));
218
+ /* ── Deployer hunter: reputation, leaderboard, outcomes ──
219
+ * "Bonding" is the pump.fun graduation event. bonding_rate is LIFETIME,
220
+ * recent_bond_rate is the ROLLING recent window — a deployer can hold a strong
221
+ * lifetime rate and a collapsing recent one, which is why both are exposed.
222
+ * runner_rate means nothing until labeled_tokens >= 3. These 7 are key-only
223
+ * (msk_); they are not on the keyless x402 rail. */
224
+ server.tool("madeonsol_deployer_stats", "Ecosystem-wide Pump.fun deployer stats — tracked_count (how many deployers we grade), signals_today, bonds_detected, the chain-wide bond_rate, and a per-tier count (elite/good/rising). Use this to size expectations before reading the leaderboard: a bond_rate of ~0.02 chain-wide is what makes an elite deployer's 0.30 meaningful. Requires an msk_ key.", {}, readOnlyAnnotations, async () => ({
225
+ content: [{ type: "text", text: await query("/api/v1/deployer-hunter/stats") }],
226
+ }));
227
+ server.tool("madeonsol_deployer_leaderboard", "Pump.fun deployer reputation leaderboard, ranked by bonding rate, recent form, total bonded, or last deploy. Unranked deployers are excluded. IMPORTANT: compare bonding_rate (LIFETIME) against recent_bond_rate (ROLLING) — the gap between them is the signal, not either number alone; a deployer at 0.40 lifetime and 0.05 recent is cooling off. runner_rate (share of labeled tokens that ran rather than dumped) is only meaningful once labeled_tokens >= 3. Requires an msk_ key.", {
228
+ tier: z.enum(["elite", "good", "rising", "neutral", "spammer", "unranked"]).optional().describe("Restrict to one reputation grade"),
229
+ sort: z.enum(["bonding_rate", "recent", "total_bonded", "last_deploy"]).default("bonding_rate").describe("Ranking axis"),
230
+ limit: z.number().min(1).max(100).default(20).describe("Page size (1-100, default 20)"),
231
+ offset: z.number().min(0).default(0).describe("Pagination offset"),
232
+ }, readOnlyAnnotations, async (args) => {
233
+ const params = {};
234
+ for (const [k, v] of Object.entries(args))
235
+ if (v !== undefined)
236
+ params[k] = v;
237
+ return { content: [{ type: "text", text: await query("/api/v1/deployer-hunter/leaderboard", params) }] };
238
+ });
239
+ server.tool("madeonsol_deployer_profile", "One Pump.fun deployer's profile — tier, lifetime bonding_rate, recent_bond_rate, total deployed/bonded, first seen, last deploy, average time-to-bond, and runner_rate. NOTE: an untracked wallet returns a profile with zeroed counters, NOT a 404, so check total_deployed before concluding anything about a wallet. Gate runner_rate on labeled_tokens >= 3. Requires an msk_ key.", {
240
+ wallet: z.string().describe("Deployer wallet address (base58)"),
241
+ }, readOnlyAnnotations, async ({ wallet }) => ({
242
+ content: [{ type: "text", text: await query(`/api/v1/deployer-hunter/${encodeURIComponent(wallet)}`) }],
243
+ }));
244
+ server.tool("madeonsol_deployer_tokens", "Every token deployed by one Pump.fun wallet, paginated — each row with deployed_at, bonded_at, time-to-bond and peak market cap. Use only_bonded to see just the graduations. Pair with madeonsol_deployer_profile to check whether a deployer's record comes from a few big winners or a consistent rate. Requires an msk_ key.", {
245
+ wallet: z.string().describe("Deployer wallet address (base58)"),
246
+ limit: z.number().min(1).max(100).default(50).describe("Page size (1-100, default 50)"),
247
+ offset: z.number().min(0).default(0).describe("Pagination offset"),
248
+ only_bonded: z.boolean().default(false).describe("Return only tokens that graduated"),
249
+ }, readOnlyAnnotations, async ({ wallet, ...rest }) => {
250
+ const params = {};
251
+ for (const [k, v] of Object.entries(rest))
252
+ if (v !== undefined)
253
+ params[k] = v;
254
+ return { content: [{ type: "text", text: await query(`/api/v1/deployer-hunter/${encodeURIComponent(wallet)}/tokens`, params) }] };
255
+ });
256
+ server.tool("madeonsol_deployer_alert_stats", "Deployer alert volume over a lookback window, with bond-rate and market-cap-multiplier distributions (pct_2x / pct_5x / pct_10x / pct_50x, avg and best) broken out per tier. This is the tool for sizing and monitoring deployer-hunter usage, and for answering 'how often does an elite-tier alert actually 10x?' with a number instead of a guess. Requires an msk_ key.", {
257
+ period: z.string().optional().describe("Lookback window, e.g. '24h', '7d', '30d'"),
258
+ }, readOnlyAnnotations, async (args) => {
259
+ const params = {};
260
+ for (const [k, v] of Object.entries(args))
261
+ if (v !== undefined)
262
+ params[k] = v;
263
+ return { content: [{ type: "text", text: await query("/api/v1/deployer-hunter/alert-stats", params) }] };
264
+ });
265
+ server.tool("madeonsol_deployer_best_tokens", "Best-performing recent tokens launched by RANKED (non-unranked) Pump.fun deployers, by peak market cap multiple over the alert price. Each row carries the deployer wallet and tier alongside mc_at_bond, peak_market_cap and mc_multiplier. Requires an msk_ key.", {
266
+ period: z.string().default("7d").describe("Lookback window, e.g. '24h', '7d', '30d' (default '7d')"),
267
+ limit: z.number().min(1).max(100).default(5).describe("Rows to return (default 5)"),
268
+ }, readOnlyAnnotations, async (args) => {
269
+ const params = {};
270
+ for (const [k, v] of Object.entries(args))
271
+ if (v !== undefined)
272
+ params[k] = v;
273
+ return { content: [{ type: "text", text: await query("/api/v1/deployer-hunter/best-tokens", params) }] };
274
+ });
275
+ server.tool("madeonsol_deployer_recent_bonds", "Tokens from tracked Pump.fun deployers that just graduated to Raydium, newest first, each with time_to_bond_minutes, mc_at_bond, peak market cap and the full deployer reputation block. POLL INCREMENTALLY: pass the previous response's next_since back as `since` to get only what bonded after it — do not re-fetch the whole window. Requires an msk_ key.", {
276
+ limit: z.number().min(1).max(100).default(20).describe("Page size (1-100, default 20)"),
277
+ since: z.string().optional().describe("Incremental cursor — the previous response's next_since"),
278
+ tier: z.enum(["elite", "good", "rising", "neutral", "spammer", "unranked"]).optional().describe("Restrict to one deployer grade"),
279
+ peak_mc_min: z.number().min(0).optional().describe("Floor on peak market cap (USD)"),
280
+ }, readOnlyAnnotations, async (args) => {
281
+ const params = {};
282
+ for (const [k, v] of Object.entries(args))
283
+ if (v !== undefined)
284
+ params[k] = v;
285
+ return { content: [{ type: "text", text: await query("/api/v1/deployer-hunter/recent-bonds", params) }] };
286
+ });
218
287
  server.tool("madeonsol_kol_hot_tokens", "KOL momentum tokens — tokens with accelerating KOL buy interest, early signals before coordination triggers. PRO+ adds buyer-quality filters.", {
219
288
  period: z.enum(["1h", "6h"]).default("6h").describe("Time period: 1h or 6h"),
220
289
  min_kols: z.number().min(1).max(20).default(1).describe("Minimum KOL buyers to include a token"),
@@ -1023,6 +1092,13 @@ async function main() {
1023
1092
  { name: "madeonsol_kol_pairs", description: "KOL affinity matrix — which KOLs co-trade the same tokens." },
1024
1093
  { name: "madeonsol_kol_timing", description: "KOL entry/exit timing profile. Pro/Ultra." },
1025
1094
  { name: "madeonsol_deployer_trajectory", description: "Deployer skill curve — streaks, trend. Pro/Ultra." },
1095
+ { name: "madeonsol_deployer_stats", description: "Chain-wide deployer stats — tracked count, bonds detected, bond rate, tier counts." },
1096
+ { name: "madeonsol_deployer_leaderboard", description: "Deployer reputation leaderboard; compare lifetime vs recent bond rate." },
1097
+ { name: "madeonsol_deployer_profile", description: "One deployer's tier, bond rates, totals, runner_rate. Untracked returns zeros, not 404." },
1098
+ { name: "madeonsol_deployer_tokens", description: "Every token one deployer launched, with time-to-bond and peak MC." },
1099
+ { name: "madeonsol_deployer_alert_stats", description: "Alert volume + per-tier bond-rate and MC-multiplier distributions." },
1100
+ { name: "madeonsol_deployer_best_tokens", description: "Best recent tokens from ranked deployers, by peak MC multiple." },
1101
+ { name: "madeonsol_deployer_recent_bonds", description: "Fresh graduations from tracked deployers; poll with next_since." },
1026
1102
  { name: "madeonsol_kol_hot_tokens", description: "KOL momentum tokens — accelerating buy interest." },
1027
1103
  { name: "madeonsol_kol_pnl", description: "Deep per-wallet PnL: equity curve, risk metrics, positions." },
1028
1104
  { name: "madeonsol_kol_trending_tokens", description: "Tokens ranked by KOL buy volume (5m–12h windows)." },
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "1.20.3";
1
+ export declare const VERSION = "1.21.0";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // AUTO-GENERATED by ../gen-version.mjs (npm prebuild) from package.json. Do not edit.
2
- export const VERSION = "1.20.3";
2
+ export const VERSION = "1.21.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-server-madeonsol",
3
- "version": "1.20.3",
3
+ "version": "1.21.0",
4
4
  "mcpName": "io.github.MadeOnSol/madeonsol",
5
5
  "description": "MCP server for MadeOnSol Solana KOL intelligence API — use from Claude, Cursor, or any MCP client. Free tier 200 req/day, no payment to start.",
6
6
  "type": "module",
@@ -56,11 +56,28 @@
56
56
  "zod": "^4.3.6"
57
57
  },
58
58
  "peerDependencies": {
59
- "@x402/fetch": ">=0.1.0",
60
- "@x402/core": ">=0.1.0",
61
- "@x402/svm": ">=0.1.0",
62
- "@solana/kit": ">=2.0.0",
63
- "@scure/base": ">=1.0.0"
59
+ "@x402/fetch": "^2.8.0",
60
+ "@x402/core": "^2.8.0",
61
+ "@x402/svm": "^2.8.0",
62
+ "@solana/kit": "^5.5.1",
63
+ "@scure/base": "^2.0.0"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "@x402/fetch": {
67
+ "optional": true
68
+ },
69
+ "@x402/core": {
70
+ "optional": true
71
+ },
72
+ "@x402/svm": {
73
+ "optional": true
74
+ },
75
+ "@solana/kit": {
76
+ "optional": true
77
+ },
78
+ "@scure/base": {
79
+ "optional": true
80
+ }
64
81
  },
65
82
  "devDependencies": {
66
83
  "@types/node": "^20",