@dritan/mcp 0.5.1 → 0.6.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 -0
  2. package/dist/index.js +103 -7
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -39,6 +39,8 @@ npm run build && npm start
39
39
  ## Tools
40
40
 
41
41
  - `system_check_prereqs`
42
+ - `auth_status`
43
+ - `auth_set_api_key`
42
44
  - `wallet_create_local`
43
45
  - `wallet_get_address`
44
46
  - `wallet_get_balance`
@@ -79,9 +81,11 @@ npm run build && npm start
79
81
  - Wallets default to `~/.config/dritan-mcp/wallets`.
80
82
  - Private keys never leave local files; only public address/signature are returned.
81
83
  - `swap_sign_and_broadcast` signs locally, then broadcasts via Dritan.
84
+ - `auth_set_api_key` activates a key for the running MCP process without restart.
82
85
  - Agent onboarding without `DRITAN_API_KEY` should present two options:
83
86
  - 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
87
  - Option 2: user gets a free key at `https://dritan.dev`.
88
+ - `x402_create_api_key` auto-activates returned keys for the current MCP session.
85
89
  - `token_get_ohlcv_chart` returns a shareable chart URL plus a ready-to-send markdown image snippet.
86
90
  - `token_get_ohlcv_chart` supports `chartType: "line-volume" | "candlestick"` (default is `line-volume`).
87
91
  - Ticker workflow for chart requests: `token_search` -> extract mint -> `token_get_ohlcv` or `token_get_ohlcv_chart`.
package/dist/index.js CHANGED
@@ -11,6 +11,41 @@ import { Connection, Keypair, PublicKey, SystemProgram, Transaction, VersionedTr
11
11
  import { z } from "zod";
12
12
  const DEFAULT_WALLET_DIR = join(homedir(), ".config", "dritan-mcp", "wallets");
13
13
  const LAMPORTS_PER_SOL = 1_000_000_000;
14
+ function normalizeApiKey(value) {
15
+ const trimmed = value?.trim();
16
+ return trimmed ? trimmed : null;
17
+ }
18
+ function apiKeyPreview(apiKey) {
19
+ if (!apiKey)
20
+ return null;
21
+ if (apiKey.length <= 12)
22
+ return `${apiKey.slice(0, 4)}...`;
23
+ return `${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`;
24
+ }
25
+ let runtimeApiKey = normalizeApiKey(process.env.DRITAN_API_KEY);
26
+ let runtimeApiKeySource = runtimeApiKey ? "env" : "none";
27
+ function setRuntimeApiKey(apiKey, source) {
28
+ const normalized = normalizeApiKey(apiKey);
29
+ if (!normalized) {
30
+ throw new Error("apiKey is required");
31
+ }
32
+ runtimeApiKey = normalized;
33
+ runtimeApiKeySource = source;
34
+ process.env.DRITAN_API_KEY = normalized;
35
+ return normalized;
36
+ }
37
+ function getActiveApiKey() {
38
+ if (runtimeApiKey)
39
+ return runtimeApiKey;
40
+ const fromEnv = normalizeApiKey(process.env.DRITAN_API_KEY);
41
+ if (fromEnv) {
42
+ runtimeApiKey = fromEnv;
43
+ runtimeApiKeySource = "env";
44
+ return fromEnv;
45
+ }
46
+ runtimeApiKeySource = "none";
47
+ return null;
48
+ }
14
49
  const STREAM_DEXES = [
15
50
  "pumpamm",
16
51
  "pumpfun",
@@ -35,7 +70,7 @@ const server = new Server({
35
70
  "This server supports two API-key onboarding options when DRITAN_API_KEY is missing:",
36
71
  "1) x402 pay-per-use key flow: create wallet, receive SOL, create quote, forward payment, claim key.",
37
72
  "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.",
73
+ "After key is obtained, set it with auth_set_api_key (no restart needed), or restart with DRITAN_API_KEY configured.",
39
74
  "Suggested setup command:",
40
75
  " claude mcp add dritan-mcp -e DRITAN_API_KEY=<your-key> -- npx @dritan/mcp@latest",
41
76
  ].join("\n"),
@@ -48,10 +83,11 @@ function missingApiKeyError() {
48
83
  "Missing DRITAN_API_KEY in environment.",
49
84
  "Option 1 (paid): use x402 tools (x402_get_pricing, x402_create_api_key_quote, x402_create_api_key) and wallet tools.",
50
85
  "Option 2 (free): create a free key at https://dritan.dev and set DRITAN_API_KEY.",
86
+ "You can activate a key immediately with auth_set_api_key without restarting MCP.",
51
87
  ].join(" "));
52
88
  }
53
89
  function getDritanClient() {
54
- const apiKey = process.env.DRITAN_API_KEY;
90
+ const apiKey = getActiveApiKey();
55
91
  if (!apiKey) {
56
92
  throw missingApiKeyError();
57
93
  }
@@ -65,7 +101,7 @@ function getDritanClient() {
65
101
  function getX402Client() {
66
102
  return new DritanClient({
67
103
  // x402 endpoints are public; SDK constructor still needs a string.
68
- apiKey: process.env.DRITAN_API_KEY ?? "x402_public_endpoints",
104
+ apiKey: getActiveApiKey() ?? "x402_public_endpoints",
69
105
  baseUrl: process.env.DRITAN_BASE_URL,
70
106
  controlBaseUrl: getControlBaseUrl(),
71
107
  wsBaseUrl: process.env.DRITAN_WS_BASE_URL,
@@ -82,7 +118,7 @@ async function searchTokens(client, query, options) {
82
118
  return await sdkSearch.call(client, query, options);
83
119
  }
84
120
  // Backward-compatible fallback for environments where dritan-sdk hasn't been upgraded yet.
85
- const apiKey = process.env.DRITAN_API_KEY;
121
+ const apiKey = getActiveApiKey();
86
122
  if (!apiKey) {
87
123
  throw missingApiKeyError();
88
124
  }
@@ -412,6 +448,9 @@ const walletCreateSchema = z.object({
412
448
  name: z.string().min(1).default("agent-wallet"),
413
449
  walletDir: z.string().min(1).optional(),
414
450
  });
451
+ const authSetApiKeySchema = z.object({
452
+ apiKey: z.string().min(8),
453
+ });
415
454
  const walletPathSchema = z.object({
416
455
  walletPath: z.string().min(1),
417
456
  });
@@ -531,6 +570,25 @@ const tools = [
531
570
  properties: {},
532
571
  },
533
572
  },
573
+ {
574
+ name: "auth_status",
575
+ description: "Show current API key status for this MCP session (active source, preview, and onboarding options).",
576
+ inputSchema: {
577
+ type: "object",
578
+ properties: {},
579
+ },
580
+ },
581
+ {
582
+ name: "auth_set_api_key",
583
+ description: "Set the active Dritan API key for this running MCP process without restart (runtime session scope).",
584
+ inputSchema: {
585
+ type: "object",
586
+ required: ["apiKey"],
587
+ properties: {
588
+ apiKey: { type: "string" },
589
+ },
590
+ },
591
+ },
534
592
  {
535
593
  name: "wallet_create_local",
536
594
  description: "Create a local Solana wallet using solana-keygen and return path + public address.",
@@ -976,7 +1034,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
976
1034
  switch (request.params.name) {
977
1035
  case "system_check_prereqs": {
978
1036
  const solanaCli = checkSolanaCli();
979
- const apiKeySet = !!process.env.DRITAN_API_KEY;
1037
+ const activeApiKey = getActiveApiKey();
1038
+ const apiKeySet = !!activeApiKey;
980
1039
  return ok({
981
1040
  ready: solanaCli.ok && apiKeySet,
982
1041
  readyForX402Onboarding: solanaCli.ok,
@@ -985,6 +1044,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
985
1044
  {
986
1045
  ok: apiKeySet,
987
1046
  name: "DRITAN_API_KEY",
1047
+ source: runtimeApiKeySource,
1048
+ preview: apiKeyPreview(activeApiKey),
988
1049
  hint: apiKeySet
989
1050
  ? "API key is configured."
990
1051
  : "Missing DRITAN_API_KEY. You can either use x402 onboarding tools or get a free key at https://dritan.dev.",
@@ -997,6 +1058,29 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
997
1058
  : "Environment ready.",
998
1059
  });
999
1060
  }
1061
+ case "auth_status": {
1062
+ const activeApiKey = getActiveApiKey();
1063
+ return ok({
1064
+ apiKeyConfigured: !!activeApiKey,
1065
+ source: runtimeApiKeySource,
1066
+ preview: apiKeyPreview(activeApiKey),
1067
+ controlBaseUrl: getControlBaseUrl(),
1068
+ onboardingOptions: [
1069
+ "Option 1 (paid x402): create wallet -> receive user SOL -> x402 quote -> transfer -> claim key.",
1070
+ "Option 2 (free): create key at https://dritan.dev and set it with auth_set_api_key.",
1071
+ ],
1072
+ });
1073
+ }
1074
+ case "auth_set_api_key": {
1075
+ const input = authSetApiKeySchema.parse(args);
1076
+ const activated = setRuntimeApiKey(input.apiKey, "runtime");
1077
+ return ok({
1078
+ ok: true,
1079
+ message: "API key activated for this MCP session without restart.",
1080
+ source: runtimeApiKeySource,
1081
+ preview: apiKeyPreview(activated),
1082
+ });
1083
+ }
1000
1084
  case "dritan_health": {
1001
1085
  return ok(await checkDritanHealth());
1002
1086
  }
@@ -1090,7 +1174,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1090
1174
  "If user picked paid flow, ensure agent has a local wallet (wallet_create_local + wallet_get_address).",
1091
1175
  "User funds the agent wallet.",
1092
1176
  "Transfer quoted SOL amount to receiver wallet using wallet_transfer_sol.",
1093
- "Claim key with x402_create_api_key using returned tx signature.",
1177
+ "Claim key with x402_create_api_key using returned tx signature (MCP auto-activates returned apiKey).",
1094
1178
  ],
1095
1179
  });
1096
1180
  }
@@ -1098,7 +1182,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1098
1182
  const input = x402CreateApiKeySchema.parse(args);
1099
1183
  const client = getX402Client();
1100
1184
  const created = await x402CreateApiKey(client, input);
1101
- return ok(created);
1185
+ const payload = typeof created === "object" && created !== null
1186
+ ? { ...created }
1187
+ : { value: created };
1188
+ if (typeof payload.apiKey === "string") {
1189
+ const activated = setRuntimeApiKey(payload.apiKey, "x402");
1190
+ payload.mcpAuth = {
1191
+ activated: true,
1192
+ source: runtimeApiKeySource,
1193
+ preview: apiKeyPreview(activated),
1194
+ message: "x402-created API key is active for this MCP session (no restart needed).",
1195
+ };
1196
+ }
1197
+ return ok(payload);
1102
1198
  }
1103
1199
  case "market_get_snapshot": {
1104
1200
  const input = marketSnapshotSchema.parse(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dritan/mcp",
3
- "version": "0.5.1",
3
+ "version": "0.6.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",