@dritan/mcp 0.3.1 → 0.5.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/.env.example CHANGED
@@ -1,5 +1,6 @@
1
1
  DRITAN_API_KEY=
2
2
  DRITAN_BASE_URL=https://us-east.dritan.dev
3
+ DRITAN_CONTROL_BASE_URL=https://api.dritan.dev
3
4
  DRITAN_WS_BASE_URL=wss://us-east.dritan.dev
4
5
  SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
5
6
  METEORA_THS_BASE_URL=https://ths.dritan.dev
package/README.md CHANGED
@@ -6,7 +6,8 @@ MCP server for personal agents to use `dritan-sdk` for market data and swap exec
6
6
 
7
7
  - Node.js 20+
8
8
  - `solana-keygen` available in `PATH`
9
- - Dritan API key (`DRITAN_API_KEY`)
9
+ - Optional: Dritan API key (`DRITAN_API_KEY`) for market/swap tools.
10
+ - For paid onboarding without an existing key, use x402 tools.
10
11
 
11
12
  ## Setup
12
13
 
@@ -41,6 +42,10 @@ npm run build && npm start
41
42
  - `wallet_create_local`
42
43
  - `wallet_get_address`
43
44
  - `wallet_get_balance`
45
+ - `wallet_transfer_sol`
46
+ - `x402_get_pricing`
47
+ - `x402_create_api_key_quote`
48
+ - `x402_create_api_key`
44
49
  - `dritan_health`
45
50
  - `market_get_snapshot`
46
51
  - `token_search`
@@ -74,7 +79,11 @@ npm run build && npm start
74
79
  - Wallets default to `~/.config/dritan-mcp/wallets`.
75
80
  - Private keys never leave local files; only public address/signature are returned.
76
81
  - `swap_sign_and_broadcast` signs locally, then broadcasts via Dritan.
82
+ - Agent onboarding without `DRITAN_API_KEY` should present two options:
83
+ - Option 1: paid x402 flow (`x402_get_pricing` -> `x402_create_api_key_quote` -> user funds agent wallet -> `wallet_transfer_sol` -> `x402_create_api_key`).
84
+ - Option 2: user gets a free key at `https://dritan.dev`.
77
85
  - `token_get_ohlcv_chart` returns a shareable chart URL plus a ready-to-send markdown image snippet.
86
+ - `token_get_ohlcv_chart` supports `chartType: "line-volume" | "candlestick"` (default is `line-volume`).
78
87
  - Ticker workflow for chart requests: `token_search` -> extract mint -> `token_get_ohlcv` or `token_get_ohlcv_chart`.
79
88
  - If users ask for `$WIF` style symbols, always resolve mint with `token_search` first.
80
89
  - If Solana CLI is missing, run `system_check_prereqs` and follow returned install steps.
package/dist/index.js CHANGED
@@ -7,9 +7,10 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
8
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
9
9
  import { DritanClient, MeteoraThsClient, } from "dritan-sdk";
10
- import { Connection, Keypair, VersionedTransaction, clusterApiUrl } from "@solana/web3.js";
10
+ import { Connection, Keypair, PublicKey, SystemProgram, Transaction, VersionedTransaction, clusterApiUrl, } from "@solana/web3.js";
11
11
  import { z } from "zod";
12
12
  const DEFAULT_WALLET_DIR = join(homedir(), ".config", "dritan-mcp", "wallets");
13
+ const LAMPORTS_PER_SOL = 1_000_000_000;
13
14
  const STREAM_DEXES = [
14
15
  "pumpamm",
15
16
  "pumpfun",
@@ -31,20 +32,42 @@ const server = new Server({
31
32
  tools: {},
32
33
  },
33
34
  instructions: [
34
- "This server requires a DRITAN_API_KEY environment variable to use market data and swap tools.",
35
- "Get your API key at https://dritan.dev and configure it:",
35
+ "This server supports two API-key onboarding options when DRITAN_API_KEY is missing:",
36
+ "1) x402 pay-per-use key flow: create wallet, receive SOL, create quote, forward payment, claim key.",
37
+ "2) Free key flow: user creates a free API key at https://dritan.dev.",
38
+ "After key is obtained, set DRITAN_API_KEY and continue with market/swap tools.",
39
+ "Suggested setup command:",
36
40
  " claude mcp add dritan-mcp -e DRITAN_API_KEY=<your-key> -- npx @dritan/mcp@latest",
37
- "Without the key, only system_check_prereqs and wallet tools (create_local, get_address, get_balance) will work.",
38
41
  ].join("\n"),
39
42
  });
43
+ function getControlBaseUrl() {
44
+ return process.env.DRITAN_CONTROL_BASE_URL ?? "https://api.dritan.dev";
45
+ }
46
+ function missingApiKeyError() {
47
+ return new Error([
48
+ "Missing DRITAN_API_KEY in environment.",
49
+ "Option 1 (paid): use x402 tools (x402_get_pricing, x402_create_api_key_quote, x402_create_api_key) and wallet tools.",
50
+ "Option 2 (free): create a free key at https://dritan.dev and set DRITAN_API_KEY.",
51
+ ].join(" "));
52
+ }
40
53
  function getDritanClient() {
41
54
  const apiKey = process.env.DRITAN_API_KEY;
42
55
  if (!apiKey) {
43
- throw new Error("Missing DRITAN_API_KEY in environment");
56
+ throw missingApiKeyError();
44
57
  }
45
58
  return new DritanClient({
46
59
  apiKey,
47
60
  baseUrl: process.env.DRITAN_BASE_URL,
61
+ controlBaseUrl: getControlBaseUrl(),
62
+ wsBaseUrl: process.env.DRITAN_WS_BASE_URL,
63
+ });
64
+ }
65
+ function getX402Client() {
66
+ return new DritanClient({
67
+ // x402 endpoints are public; SDK constructor still needs a string.
68
+ apiKey: process.env.DRITAN_API_KEY ?? "x402_public_endpoints",
69
+ baseUrl: process.env.DRITAN_BASE_URL,
70
+ controlBaseUrl: getControlBaseUrl(),
48
71
  wsBaseUrl: process.env.DRITAN_WS_BASE_URL,
49
72
  });
50
73
  }
@@ -61,7 +84,7 @@ async function searchTokens(client, query, options) {
61
84
  // Backward-compatible fallback for environments where dritan-sdk hasn't been upgraded yet.
62
85
  const apiKey = process.env.DRITAN_API_KEY;
63
86
  if (!apiKey) {
64
- throw new Error("Missing DRITAN_API_KEY in environment");
87
+ throw missingApiKeyError();
65
88
  }
66
89
  const baseUrl = process.env.DRITAN_BASE_URL ?? "https://us-east.dritan.dev";
67
90
  const url = new URL("/token/search", baseUrl);
@@ -89,6 +112,65 @@ async function searchTokens(client, query, options) {
89
112
  return { ok: true, raw: text };
90
113
  }
91
114
  }
115
+ async function x402GetPricing(client) {
116
+ const sdkMethod = client.getX402Pricing;
117
+ if (typeof sdkMethod === "function") {
118
+ return await sdkMethod.call(client);
119
+ }
120
+ const url = new URL("/v1/x402/pricing", getControlBaseUrl());
121
+ const response = await fetch(url.toString(), { method: "GET" });
122
+ const text = await response.text();
123
+ if (!response.ok)
124
+ throw new Error(`x402 pricing failed (${response.status}): ${text}`);
125
+ try {
126
+ return JSON.parse(text);
127
+ }
128
+ catch {
129
+ return { raw: text };
130
+ }
131
+ }
132
+ async function x402CreateQuote(client, input) {
133
+ const sdkMethod = client.createX402ApiKeyQuote;
134
+ if (typeof sdkMethod === "function") {
135
+ return await sdkMethod.call(client, input);
136
+ }
137
+ const url = new URL("/v1/x402/api-keys/quote", getControlBaseUrl());
138
+ const response = await fetch(url.toString(), {
139
+ method: "POST",
140
+ headers: { "content-type": "application/json" },
141
+ body: JSON.stringify(input),
142
+ });
143
+ const text = await response.text();
144
+ if (!response.ok)
145
+ throw new Error(`x402 quote failed (${response.status}): ${text}`);
146
+ try {
147
+ return JSON.parse(text);
148
+ }
149
+ catch {
150
+ return { raw: text };
151
+ }
152
+ }
153
+ async function x402CreateApiKey(client, input) {
154
+ const sdkMethod = client.createX402ApiKey;
155
+ if (typeof sdkMethod === "function") {
156
+ return await sdkMethod.call(client, input);
157
+ }
158
+ const url = new URL("/v1/x402/api-keys", getControlBaseUrl());
159
+ const response = await fetch(url.toString(), {
160
+ method: "POST",
161
+ headers: { "content-type": "application/json" },
162
+ body: JSON.stringify(input),
163
+ });
164
+ const text = await response.text();
165
+ if (!response.ok)
166
+ throw new Error(`x402 create key failed (${response.status}): ${text}`);
167
+ try {
168
+ return JSON.parse(text);
169
+ }
170
+ catch {
171
+ return { raw: text };
172
+ }
173
+ }
92
174
  async function checkDritanHealth() {
93
175
  const baseUrl = process.env.DRITAN_BASE_URL ?? "https://us-east.dritan.dev";
94
176
  const url = new URL("/health", baseUrl).toString();
@@ -117,7 +199,7 @@ function formatChartLabel(ts) {
117
199
  return String(ts);
118
200
  return date.toISOString().replace("T", " ").slice(0, 16);
119
201
  }
120
- function buildOhlcvChartUrl(mint, timeframe, bars, width, height) {
202
+ function buildLineVolumeOhlcvChartUrl(mint, timeframe, bars, width, height) {
121
203
  const labels = bars.map((bar) => formatChartLabel(bar.time));
122
204
  const closeSeries = bars.map((bar) => Number(bar.close.toFixed(12)));
123
205
  const volumeSeries = bars.map((bar) => Number(bar.volume.toFixed(12)));
@@ -166,6 +248,66 @@ function buildOhlcvChartUrl(mint, timeframe, bars, width, height) {
166
248
  // so pinning `v=4` prevents runtime render errors like "Cannot read properties of undefined (reading 'options')".
167
249
  return `https://quickchart.io/chart?w=${width}&h=${height}&f=png&v=4&c=${encoded}`;
168
250
  }
251
+ function buildCandlestickOhlcvChartUrl(mint, timeframe, bars, width, height) {
252
+ const labels = bars.map((bar) => formatChartLabel(bar.time));
253
+ const candles = bars.map((bar, index) => ({
254
+ x: labels[index],
255
+ o: Number(bar.open.toFixed(12)),
256
+ h: Number(bar.high.toFixed(12)),
257
+ l: Number(bar.low.toFixed(12)),
258
+ c: Number(bar.close.toFixed(12)),
259
+ }));
260
+ const volumeSeries = bars.map((bar) => Number(bar.volume.toFixed(12)));
261
+ const volumeColors = bars.map((bar) => bar.close >= bar.open ? "rgba(16,185,129,0.25)" : "rgba(239,68,68,0.25)");
262
+ const config = {
263
+ type: "candlestick",
264
+ data: {
265
+ labels,
266
+ datasets: [
267
+ {
268
+ label: "OHLC",
269
+ data: candles,
270
+ color: {
271
+ up: "#10b981",
272
+ down: "#ef4444",
273
+ unchanged: "#94a3b8",
274
+ },
275
+ },
276
+ {
277
+ type: "bar",
278
+ label: "Volume",
279
+ data: volumeSeries,
280
+ backgroundColor: volumeColors,
281
+ borderWidth: 0,
282
+ yAxisID: "volume",
283
+ },
284
+ ],
285
+ },
286
+ options: {
287
+ plugins: {
288
+ legend: { display: true },
289
+ title: {
290
+ display: true,
291
+ text: `${mint} ${timeframe.toUpperCase()} Candlestick`,
292
+ },
293
+ },
294
+ scales: {
295
+ x: { type: "category" },
296
+ y: { type: "linear", position: "left" },
297
+ volume: { type: "linear", position: "right", grid: { drawOnChartArea: false } },
298
+ },
299
+ },
300
+ };
301
+ const encoded = encodeURIComponent(JSON.stringify(config));
302
+ // Pin Chart.js v4 for stable scale behavior and financial chart rendering.
303
+ return `https://quickchart.io/chart?w=${width}&h=${height}&f=png&v=4&c=${encoded}`;
304
+ }
305
+ function buildOhlcvChartUrl(chartType, mint, timeframe, bars, width, height) {
306
+ if (chartType === "candlestick") {
307
+ return buildCandlestickOhlcvChartUrl(mint, timeframe, bars, width, height);
308
+ }
309
+ return buildLineVolumeOhlcvChartUrl(mint, timeframe, bars, width, height);
310
+ }
169
311
  function getPlatformInstallHint(binary) {
170
312
  switch (process.platform) {
171
313
  case "darwin":
@@ -276,6 +418,31 @@ const walletPathSchema = z.object({
276
418
  const walletBalanceSchema = walletPathSchema.extend({
277
419
  rpcUrl: z.string().url().optional(),
278
420
  });
421
+ const walletTransferSchema = z
422
+ .object({
423
+ walletPath: z.string().min(1),
424
+ toAddress: z.string().min(32),
425
+ lamports: z.number().int().positive().optional(),
426
+ sol: z.number().positive().optional(),
427
+ rpcUrl: z.string().url().optional(),
428
+ })
429
+ .refine((v) => v.lamports != null || v.sol != null, {
430
+ message: "Either lamports or sol is required",
431
+ path: ["lamports"],
432
+ });
433
+ const x402QuoteSchema = z.object({
434
+ durationMinutes: z.number().int().min(1).max(60 * 24 * 30),
435
+ name: z.string().min(1).max(120).optional(),
436
+ scopes: z.array(z.string().min(1).max(120)).max(64).optional(),
437
+ payerWallet: z.string().min(32).max(80).optional(),
438
+ });
439
+ const x402CreateApiKeySchema = z.object({
440
+ quoteId: z.string().min(1),
441
+ paymentTxSignature: z.string().min(40),
442
+ payerWallet: z.string().min(32).max(80).optional(),
443
+ name: z.string().min(1).max(120).optional(),
444
+ scopes: z.array(z.string().min(1).max(120)).max(64).optional(),
445
+ });
279
446
  const marketSnapshotSchema = z.object({
280
447
  mint: z.string().min(1),
281
448
  mode: z.enum(["price", "metadata", "risk", "first-buyers", "aggregated"]).default("aggregated"),
@@ -300,6 +467,7 @@ const tokenOhlcvSchema = z.object({
300
467
  timeTo: z.number().int().positive().optional(),
301
468
  });
302
469
  const tokenOhlcvChartSchema = tokenOhlcvSchema.extend({
470
+ chartType: z.enum(["line-volume", "candlestick"]).default("line-volume"),
303
471
  includeActive: z.boolean().default(true),
304
472
  maxPoints: z.number().int().min(10).max(500).default(120),
305
473
  width: z.number().int().min(300).max(2000).default(1200),
@@ -397,6 +565,58 @@ const tools = [
397
565
  },
398
566
  },
399
567
  },
568
+ {
569
+ name: "wallet_transfer_sol",
570
+ description: "Send SOL from a local wallet to a destination wallet (used in x402 paid key flow).",
571
+ inputSchema: {
572
+ type: "object",
573
+ required: ["walletPath", "toAddress"],
574
+ properties: {
575
+ walletPath: { type: "string" },
576
+ toAddress: { type: "string" },
577
+ lamports: { type: "number", description: "Integer lamports to transfer" },
578
+ sol: { type: "number", description: "SOL amount to transfer (used when lamports is not provided)" },
579
+ rpcUrl: { type: "string" },
580
+ },
581
+ },
582
+ },
583
+ {
584
+ name: "x402_get_pricing",
585
+ description: "Get x402 pricing and receiver wallet for paid time-limited API keys.",
586
+ inputSchema: {
587
+ type: "object",
588
+ properties: {},
589
+ },
590
+ },
591
+ {
592
+ name: "x402_create_api_key_quote",
593
+ description: "Create an x402 payment quote for a time-limited API key (returns quoteId, receiverWallet, and exact SOL amount).",
594
+ inputSchema: {
595
+ type: "object",
596
+ required: ["durationMinutes"],
597
+ properties: {
598
+ durationMinutes: { type: "number", description: "Minutes for key validity (1 to 43200)." },
599
+ name: { type: "string", description: "Optional key name." },
600
+ payerWallet: { type: "string", description: "Optional payer wallet to lock quote payer." },
601
+ scopes: { type: "array", items: { type: "string" }, description: "Optional scopes." },
602
+ },
603
+ },
604
+ },
605
+ {
606
+ name: "x402_create_api_key",
607
+ description: "Claim a paid x402 API key using quoteId and payment transaction signature.",
608
+ inputSchema: {
609
+ type: "object",
610
+ required: ["quoteId", "paymentTxSignature"],
611
+ properties: {
612
+ quoteId: { type: "string" },
613
+ paymentTxSignature: { type: "string" },
614
+ payerWallet: { type: "string" },
615
+ name: { type: "string" },
616
+ scopes: { type: "array", items: { type: "string" } },
617
+ },
618
+ },
619
+ },
400
620
  {
401
621
  name: "dritan_health",
402
622
  description: "Check data plane health endpoint via Dritan SDK.",
@@ -515,7 +735,7 @@ const tools = [
515
735
  },
516
736
  {
517
737
  name: "token_get_ohlcv_chart",
518
- description: "Build a shareable chart URL from token OHLCV candles so agents can send an actual chart in chat (resolve ticker with token_search first).",
738
+ description: "Build a shareable chart URL from token OHLCV candles so agents can send an actual chart in chat (resolve ticker with token_search first). Supports line-volume or candlestick charts.",
519
739
  inputSchema: {
520
740
  type: "object",
521
741
  required: ["mint", "timeframe"],
@@ -523,6 +743,11 @@ const tools = [
523
743
  mint: { type: "string" },
524
744
  timeframe: { type: "string", description: "e.g. 1m, 5m, 1h, 1d" },
525
745
  timeTo: { type: "number" },
746
+ chartType: {
747
+ type: "string",
748
+ enum: ["line-volume", "candlestick"],
749
+ description: "Chart style. Default line-volume.",
750
+ },
526
751
  includeActive: { type: "boolean" },
527
752
  maxPoints: { type: "number" },
528
753
  width: { type: "number" },
@@ -754,6 +979,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
754
979
  const apiKeySet = !!process.env.DRITAN_API_KEY;
755
980
  return ok({
756
981
  ready: solanaCli.ok && apiKeySet,
982
+ readyForX402Onboarding: solanaCli.ok,
757
983
  checks: [
758
984
  solanaCli,
759
985
  {
@@ -761,11 +987,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
761
987
  name: "DRITAN_API_KEY",
762
988
  hint: apiKeySet
763
989
  ? "API key is configured."
764
- : "Missing DRITAN_API_KEY. Get your key at https://dritan.dev and set it as an environment variable.",
990
+ : "Missing DRITAN_API_KEY. You can either use x402 onboarding tools or get a free key at https://dritan.dev.",
765
991
  },
766
992
  ],
767
993
  nextAction: !apiKeySet
768
- ? "Set DRITAN_API_KEY environment variable. Get your key at https://dritan.dev"
994
+ ? "Choose one: (1) x402 paid onboarding flow with wallet tools, or (2) get a free key at https://dritan.dev and set DRITAN_API_KEY."
769
995
  : !solanaCli.ok
770
996
  ? "Install Solana CLI using installHint, then retry wallet_create_local."
771
997
  : "Environment ready.",
@@ -799,6 +1025,81 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
799
1025
  sol: lamports / 1_000_000_000,
800
1026
  });
801
1027
  }
1028
+ case "wallet_transfer_sol": {
1029
+ const input = walletTransferSchema.parse(args);
1030
+ const walletPath = resolve(input.walletPath);
1031
+ const keypair = loadKeypairFromPath(walletPath);
1032
+ const rpcUrl = getRpcUrl(input.rpcUrl);
1033
+ const conn = new Connection(rpcUrl, "confirmed");
1034
+ const lamportsRaw = input.lamports != null ? input.lamports : Math.round((input.sol ?? 0) * LAMPORTS_PER_SOL);
1035
+ if (!Number.isSafeInteger(lamportsRaw) || lamportsRaw <= 0) {
1036
+ throw new Error("Transfer amount must be a positive safe integer number of lamports.");
1037
+ }
1038
+ const toPubkey = new PublicKey(input.toAddress);
1039
+ const latest = await conn.getLatestBlockhash("confirmed");
1040
+ const tx = new Transaction({
1041
+ feePayer: keypair.publicKey,
1042
+ recentBlockhash: latest.blockhash,
1043
+ }).add(SystemProgram.transfer({
1044
+ fromPubkey: keypair.publicKey,
1045
+ toPubkey,
1046
+ lamports: lamportsRaw,
1047
+ }));
1048
+ tx.sign(keypair);
1049
+ const signature = await conn.sendRawTransaction(tx.serialize(), {
1050
+ skipPreflight: false,
1051
+ maxRetries: 3,
1052
+ });
1053
+ const confirmation = await conn.confirmTransaction({
1054
+ signature,
1055
+ blockhash: latest.blockhash,
1056
+ lastValidBlockHeight: latest.lastValidBlockHeight,
1057
+ }, "confirmed");
1058
+ if (confirmation.value.err) {
1059
+ throw new Error(`Transfer failed: ${JSON.stringify(confirmation.value.err)}`);
1060
+ }
1061
+ return ok({
1062
+ walletPath,
1063
+ fromAddress: keypair.publicKey.toBase58(),
1064
+ toAddress: toPubkey.toBase58(),
1065
+ rpcUrl,
1066
+ lamports: lamportsRaw,
1067
+ sol: lamportsRaw / LAMPORTS_PER_SOL,
1068
+ signature,
1069
+ explorerUrl: `https://solscan.io/tx/${signature}`,
1070
+ });
1071
+ }
1072
+ case "x402_get_pricing": {
1073
+ const client = getX402Client();
1074
+ const pricing = await x402GetPricing(client);
1075
+ return ok({
1076
+ ...(pricing ?? {}),
1077
+ onboardingOptions: [
1078
+ "Option 1 (paid x402): create wallet -> receive user SOL -> x402 quote -> forward payment -> claim key.",
1079
+ "Option 2 (free): user gets API key at https://dritan.dev and provides it as DRITAN_API_KEY.",
1080
+ ],
1081
+ });
1082
+ }
1083
+ case "x402_create_api_key_quote": {
1084
+ const input = x402QuoteSchema.parse(args);
1085
+ const client = getX402Client();
1086
+ const quote = await x402CreateQuote(client, input);
1087
+ return ok({
1088
+ ...(quote ?? {}),
1089
+ nextSteps: [
1090
+ "If user picked paid flow, ensure agent has a local wallet (wallet_create_local + wallet_get_address).",
1091
+ "User funds the agent wallet.",
1092
+ "Transfer quoted SOL amount to receiver wallet using wallet_transfer_sol.",
1093
+ "Claim key with x402_create_api_key using returned tx signature.",
1094
+ ],
1095
+ });
1096
+ }
1097
+ case "x402_create_api_key": {
1098
+ const input = x402CreateApiKeySchema.parse(args);
1099
+ const client = getX402Client();
1100
+ const created = await x402CreateApiKey(client, input);
1101
+ return ok(created);
1102
+ }
802
1103
  case "market_get_snapshot": {
803
1104
  const input = marketSnapshotSchema.parse(args);
804
1105
  const client = getDritanClient();
@@ -868,10 +1169,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
868
1169
  if (trimmedBars.length === 0) {
869
1170
  throw new Error(`No OHLCV data available for ${input.mint} (${input.timeframe})`);
870
1171
  }
871
- const chartUrl = buildOhlcvChartUrl(input.mint, input.timeframe, trimmedBars, input.width, input.height);
1172
+ const chartUrl = buildOhlcvChartUrl(input.chartType, input.mint, input.timeframe, trimmedBars, input.width, input.height);
872
1173
  return ok({
873
1174
  mint: input.mint,
874
1175
  timeframe: input.timeframe,
1176
+ chartType: input.chartType,
875
1177
  points: trimmedBars.length,
876
1178
  chartUrl,
877
1179
  markdown: `![${input.mint} ${input.timeframe} chart](${chartUrl})`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dritan/mcp",
3
- "version": "0.3.1",
3
+ "version": "0.5.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",
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.17.4",
36
36
  "@solana/web3.js": "^1.98.4",
37
- "dritan-sdk": "^0.6.0",
37
+ "dritan-sdk": "^0.9.0",
38
38
  "zod": "^3.24.1"
39
39
  },
40
40
  "devDependencies": {