@dritan/mcp 0.6.0 → 0.7.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.
Files changed (3) hide show
  1. package/README.md +4 -1
  2. package/dist/index.js +80 -13
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -72,6 +72,7 @@ npm run build && npm start
72
72
  - `ths_get_score`
73
73
  - `ths_get_score_tokens_get`
74
74
  - `ths_get_score_tokens_post`
75
+ - `ths_get_top_wallets`
75
76
  - `swap_build`
76
77
  - `swap_sign_and_broadcast`
77
78
  - `swap_build_sign_and_broadcast`
@@ -82,12 +83,14 @@ npm run build && npm start
82
83
  - Private keys never leave local files; only public address/signature are returned.
83
84
  - `swap_sign_and_broadcast` signs locally, then broadcasts via Dritan.
84
85
  - `auth_set_api_key` activates a key for the running MCP process without restart.
86
+ - `auth_set_api_key` and successful `x402_create_api_key` responses include a capability summary so agents can immediately guide users to next actions.
85
87
  - Agent onboarding without `DRITAN_API_KEY` should present two options:
86
88
  - Option 1: paid x402 flow (`x402_get_pricing` -> `x402_create_api_key_quote` -> user funds agent wallet -> `wallet_transfer_sol` -> `x402_create_api_key`).
87
89
  - Option 2: user gets a free key at `https://dritan.dev`.
88
90
  - `x402_create_api_key` auto-activates returned keys for the current MCP session.
89
91
  - `token_get_ohlcv_chart` returns a shareable chart URL plus a ready-to-send markdown image snippet.
90
- - `token_get_ohlcv_chart` supports `chartType: "line-volume" | "candlestick"` (default is `line-volume`).
92
+ - `token_get_ohlcv_chart` supports `chartType: "line-volume" | "candlestick"` (default is `candlestick`).
93
+ - `ths_get_top_wallets` returns a paginated leaderboard of THS-ranked wallets (`page`, `limit`) for smart-wallet discovery workflows.
91
94
  - Ticker workflow for chart requests: `token_search` -> extract mint -> `token_get_ohlcv` or `token_get_ohlcv_chart`.
92
95
  - If users ask for `$WIF` style symbols, always resolve mint with `token_search` first.
93
96
  - If Solana CLI is missing, run `system_check_prereqs` and follow returned install steps.
package/dist/index.js CHANGED
@@ -86,6 +86,19 @@ function missingApiKeyError() {
86
86
  "You can activate a key immediately with auth_set_api_key without restarting MCP.",
87
87
  ].join(" "));
88
88
  }
89
+ const postAuthCapabilities = [
90
+ "Token intelligence: token search, price, metadata, risk, first buyers, deployer stats.",
91
+ "Charts: OHLCV data and shareable line-volume/candlestick chart URLs.",
92
+ "Wallet analytics: summary, holdings, trade history, performance, and portfolio charts.",
93
+ "Trader discovery: Meteora THS wallet score lookups plus top-wallet leaderboard.",
94
+ "Execution: build/sign/broadcast swaps and monitor wallet/DEX streams.",
95
+ ];
96
+ function buildPostAuthGuidance() {
97
+ return {
98
+ capabilities: postAuthCapabilities,
99
+ suggestedNextPrompt: "Tell me your goal and I can proceed: token research, smart-wallet discovery, chart generation, or swap execution.",
100
+ };
101
+ }
89
102
  function getDritanClient() {
90
103
  const apiKey = getActiveApiKey();
91
104
  if (!apiKey) {
@@ -112,6 +125,24 @@ function getThsClient() {
112
125
  baseUrl: process.env.METEORA_THS_BASE_URL,
113
126
  });
114
127
  }
128
+ async function getThsTopWallets(ths, options = {}) {
129
+ const sdkMethod = ths.getTopWalletsByScore;
130
+ if (typeof sdkMethod === "function") {
131
+ return await sdkMethod.call(ths, options);
132
+ }
133
+ const baseUrl = ths.baseUrl ?? "https://ths.dritan.dev";
134
+ const url = new URL("/ths/top-wallets", baseUrl);
135
+ if (options.page !== undefined)
136
+ url.searchParams.set("page", String(options.page));
137
+ if (options.limit !== undefined)
138
+ url.searchParams.set("limit", String(options.limit));
139
+ const res = await fetch(url.toString(), { method: "GET" });
140
+ if (!res.ok) {
141
+ const text = await res.text().catch(() => "");
142
+ throw new Error(`Meteora THS request failed (${res.status}): ${text || res.statusText}`);
143
+ }
144
+ return (await res.json());
145
+ }
115
146
  async function searchTokens(client, query, options) {
116
147
  const sdkSearch = client.searchTokens;
117
148
  if (typeof sdkSearch === "function") {
@@ -296,27 +327,35 @@ function buildCandlestickOhlcvChartUrl(mint, timeframe, bars, width, height) {
296
327
  const volumeSeries = bars.map((bar) => Number(bar.volume.toFixed(12)));
297
328
  const volumeColors = bars.map((bar) => bar.close >= bar.open ? "rgba(16,185,129,0.25)" : "rgba(239,68,68,0.25)");
298
329
  const config = {
299
- type: "candlestick",
330
+ type: "bar",
300
331
  data: {
301
332
  labels,
302
333
  datasets: [
303
334
  {
335
+ type: "bar",
336
+ label: "Volume",
337
+ data: volumeSeries,
338
+ backgroundColor: volumeColors,
339
+ borderWidth: 0,
340
+ yAxisID: "volume",
341
+ barPercentage: 0.9,
342
+ categoryPercentage: 1,
343
+ maxBarThickness: 14,
344
+ order: 1,
345
+ },
346
+ {
347
+ type: "candlestick",
304
348
  label: "OHLC",
305
349
  data: candles,
350
+ yAxisID: "price",
351
+ parsing: false,
352
+ order: 2,
306
353
  color: {
307
354
  up: "#10b981",
308
355
  down: "#ef4444",
309
356
  unchanged: "#94a3b8",
310
357
  },
311
358
  },
312
- {
313
- type: "bar",
314
- label: "Volume",
315
- data: volumeSeries,
316
- backgroundColor: volumeColors,
317
- borderWidth: 0,
318
- yAxisID: "volume",
319
- },
320
359
  ],
321
360
  },
322
361
  options: {
@@ -329,8 +368,13 @@ function buildCandlestickOhlcvChartUrl(mint, timeframe, bars, width, height) {
329
368
  },
330
369
  scales: {
331
370
  x: { type: "category" },
332
- y: { type: "linear", position: "left" },
333
- volume: { type: "linear", position: "right", grid: { drawOnChartArea: false } },
371
+ price: { type: "linear", position: "left" },
372
+ volume: {
373
+ type: "linear",
374
+ position: "right",
375
+ beginAtZero: true,
376
+ grid: { drawOnChartArea: false },
377
+ },
334
378
  },
335
379
  },
336
380
  };
@@ -506,7 +550,7 @@ const tokenOhlcvSchema = z.object({
506
550
  timeTo: z.number().int().positive().optional(),
507
551
  });
508
552
  const tokenOhlcvChartSchema = tokenOhlcvSchema.extend({
509
- chartType: z.enum(["line-volume", "candlestick"]).default("line-volume"),
553
+ chartType: z.enum(["line-volume", "candlestick"]).default("candlestick"),
510
554
  includeActive: z.boolean().default(true),
511
555
  maxPoints: z.number().int().min(10).max(500).default(120),
512
556
  width: z.number().int().min(300).max(2000).default(1200),
@@ -545,6 +589,10 @@ const thsScoreSchema = z.object({
545
589
  const thsScoreTokensSchema = thsScoreSchema.extend({
546
590
  tokenMints: z.array(z.string().min(1)).min(1).max(200),
547
591
  });
592
+ const thsTopWalletsSchema = z.object({
593
+ page: z.number().int().min(1).optional(),
594
+ limit: z.number().int().min(1).max(100).optional(),
595
+ });
548
596
  const swapBuildSchema = z.object({
549
597
  walletPath: z.string().min(1).optional(),
550
598
  userPublicKey: z.string().min(1).optional(),
@@ -804,7 +852,7 @@ const tools = [
804
852
  chartType: {
805
853
  type: "string",
806
854
  enum: ["line-volume", "candlestick"],
807
- description: "Chart style. Default line-volume.",
855
+ description: "Chart style. Default candlestick.",
808
856
  },
809
857
  includeActive: { type: "boolean" },
810
858
  maxPoints: { type: "number" },
@@ -975,6 +1023,17 @@ const tools = [
975
1023
  },
976
1024
  },
977
1025
  },
1026
+ {
1027
+ name: "ths_get_top_wallets",
1028
+ description: "Fetch paginated top wallets ranked by THS score.",
1029
+ inputSchema: {
1030
+ type: "object",
1031
+ properties: {
1032
+ page: { type: "number" },
1033
+ limit: { type: "number" },
1034
+ },
1035
+ },
1036
+ },
978
1037
  {
979
1038
  name: "swap_build",
980
1039
  description: "Build an unsigned swap transaction with Dritan.",
@@ -1069,6 +1128,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1069
1128
  "Option 1 (paid x402): create wallet -> receive user SOL -> x402 quote -> transfer -> claim key.",
1070
1129
  "Option 2 (free): create key at https://dritan.dev and set it with auth_set_api_key.",
1071
1130
  ],
1131
+ ...(activeApiKey ? buildPostAuthGuidance() : {}),
1072
1132
  });
1073
1133
  }
1074
1134
  case "auth_set_api_key": {
@@ -1079,6 +1139,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1079
1139
  message: "API key activated for this MCP session without restart.",
1080
1140
  source: runtimeApiKeySource,
1081
1141
  preview: apiKeyPreview(activated),
1142
+ ...buildPostAuthGuidance(),
1082
1143
  });
1083
1144
  }
1084
1145
  case "dritan_health": {
@@ -1193,6 +1254,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1193
1254
  preview: apiKeyPreview(activated),
1194
1255
  message: "x402-created API key is active for this MCP session (no restart needed).",
1195
1256
  };
1257
+ Object.assign(payload, buildPostAuthGuidance());
1196
1258
  }
1197
1259
  return ok(payload);
1198
1260
  }
@@ -1420,6 +1482,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1420
1482
  breakdown: input.breakdown,
1421
1483
  }));
1422
1484
  }
1485
+ case "ths_get_top_wallets": {
1486
+ const input = thsTopWalletsSchema.parse(args);
1487
+ const ths = getThsClient();
1488
+ return ok(await getThsTopWallets(ths, input));
1489
+ }
1423
1490
  case "swap_build": {
1424
1491
  const input = swapBuildSchema.parse(args);
1425
1492
  const client = getDritanClient();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dritan/mcp",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "MCP server for Dritan SDK market data and local Solana wallet swap execution",