@danainnovations/cortex-mcp 1.0.76 → 1.0.78

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/dist/index.d.ts CHANGED
@@ -78,7 +78,7 @@ declare function detectClients(): DetectedClient[];
78
78
  * Uses command/args/env format (Claude Desktop does not support HTTP url/headers).
79
79
  * Preserves existing non-Cortex entries.
80
80
  */
81
- declare function configureClaudeDesktop(_serverUrl: string, apiKey: string, _mcps: string[]): void;
81
+ declare function configureClaudeDesktop(_serverUrl: string, apiKey: string, _mcps: string[]): string;
82
82
  /**
83
83
  * Configure Claude Code by running `claude mcp add` commands.
84
84
  */
package/dist/index.js CHANGED
@@ -1083,12 +1083,14 @@ async function startStdioServer(options) {
1083
1083
  }
1084
1084
 
1085
1085
  // src/config/storage.ts
1086
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1086
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
1087
1087
  import { join as join3 } from "path";
1088
1088
 
1089
1089
  // src/utils/platform.ts
1090
1090
  import { homedir, platform } from "os";
1091
1091
  import { join as join2 } from "path";
1092
+ import { readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
1093
+ import { execSync } from "child_process";
1092
1094
  function getHomeDir() {
1093
1095
  return homedir();
1094
1096
  }
@@ -1098,9 +1100,44 @@ function getPlatform() {
1098
1100
  if (p === "win32") return "windows";
1099
1101
  return "linux";
1100
1102
  }
1103
+ function isWSL() {
1104
+ if (getPlatform() !== "linux") return false;
1105
+ try {
1106
+ const version = readFileSync3("/proc/version", "utf-8");
1107
+ return /microsoft|wsl/i.test(version);
1108
+ } catch {
1109
+ return false;
1110
+ }
1111
+ }
1112
+ function getWindowsHomeFromWSL() {
1113
+ try {
1114
+ const raw = execSync("cmd.exe /c echo %USERNAME%", {
1115
+ stdio: ["pipe", "pipe", "pipe"],
1116
+ timeout: 5e3
1117
+ }).toString().trim().replace(/\r/g, "");
1118
+ if (raw && raw !== "%USERNAME%") {
1119
+ return `/mnt/c/Users/${raw}`;
1120
+ }
1121
+ } catch {
1122
+ }
1123
+ try {
1124
+ const dirs = readdirSync2("/mnt/c/Users").filter(
1125
+ (d) => d !== "Public" && d !== "Default" && d !== "Default User" && d !== "All Users" && !d.startsWith(".")
1126
+ );
1127
+ if (dirs.length === 1) return `/mnt/c/Users/${dirs[0]}`;
1128
+ } catch {
1129
+ }
1130
+ return null;
1131
+ }
1101
1132
  function getClaudeDesktopConfigPath() {
1102
1133
  const home = getHomeDir();
1103
1134
  const p = getPlatform();
1135
+ if (p === "linux" && isWSL()) {
1136
+ const winHome = getWindowsHomeFromWSL();
1137
+ if (winHome) {
1138
+ return join2(winHome, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
1139
+ }
1140
+ }
1104
1141
  switch (p) {
1105
1142
  case "macos":
1106
1143
  return join2(
@@ -1148,7 +1185,7 @@ function readConfig() {
1148
1185
  const path = getConfigPath();
1149
1186
  if (!existsSync2(path)) return null;
1150
1187
  try {
1151
- const raw = readFileSync3(path, "utf-8");
1188
+ const raw = readFileSync4(path, "utf-8");
1152
1189
  return JSON.parse(raw);
1153
1190
  } catch {
1154
1191
  return null;
@@ -1175,10 +1212,10 @@ function createConfig(apiKey, mcps) {
1175
1212
  }
1176
1213
 
1177
1214
  // src/config/clients.ts
1178
- import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
1215
+ import { existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
1179
1216
  import { dirname as dirname2 } from "path";
1180
1217
  import { mkdirSync as mkdirSync3 } from "fs";
1181
- import { execSync } from "child_process";
1218
+ import { execSync as execSync2 } from "child_process";
1182
1219
  import { homedir as homedir2 } from "os";
1183
1220
  import { join as join4 } from "path";
1184
1221
  function detectClients() {
@@ -1193,7 +1230,7 @@ function detectClients() {
1193
1230
  });
1194
1231
  let claudeCodeDetected = false;
1195
1232
  try {
1196
- execSync("which claude", { stdio: "pipe" });
1233
+ execSync2("which claude", { stdio: "pipe" });
1197
1234
  claudeCodeDetected = true;
1198
1235
  } catch {
1199
1236
  }
@@ -1230,7 +1267,7 @@ function detectClients() {
1230
1267
  let codexDetected = existsSync3(join4(home, ".codex"));
1231
1268
  if (!codexDetected) {
1232
1269
  try {
1233
- execSync("which codex", { stdio: "pipe" });
1270
+ execSync2("which codex", { stdio: "pipe" });
1234
1271
  codexDetected = true;
1235
1272
  } catch {
1236
1273
  }
@@ -1273,41 +1310,63 @@ function configureClaudeDesktop(_serverUrl, apiKey, _mcps) {
1273
1310
  if (!existsSync3(dir)) {
1274
1311
  mkdirSync3(dir, { recursive: true });
1275
1312
  }
1276
- let config = {};
1277
- if (existsSync3(configPath)) {
1278
- try {
1279
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
1280
- } catch {
1281
- }
1282
- }
1283
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
1284
- config.mcpServers = {};
1285
- }
1286
- const servers = config.mcpServers;
1287
- for (const key of Object.keys(servers)) {
1288
- if (key.startsWith("cortex-") || key === "cortex") {
1289
- delete servers[key];
1290
- }
1291
- }
1292
- const isWindows = getPlatform() === "windows";
1293
- servers["cortex"] = isWindows ? {
1313
+ const isWindowsTarget = getPlatform() === "windows" || isWSL();
1314
+ const cortexEntry = isWindowsTarget ? {
1294
1315
  command: "cmd",
1295
1316
  args: ["/c", "npx", "-y", "@danainnovations/cortex-mcp@latest", "serve"]
1296
1317
  } : {
1297
1318
  command: "npx",
1298
1319
  args: ["-y", "@danainnovations/cortex-mcp@latest", "serve"]
1299
1320
  };
1300
- writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n");
1321
+ const maxAttempts = isWindowsTarget ? 3 : 1;
1322
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
1323
+ let config = {};
1324
+ if (existsSync3(configPath)) {
1325
+ try {
1326
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
1327
+ } catch {
1328
+ }
1329
+ }
1330
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
1331
+ config.mcpServers = {};
1332
+ }
1333
+ const servers = config.mcpServers;
1334
+ for (const key of Object.keys(servers)) {
1335
+ if (key.startsWith("cortex-") || key === "cortex") {
1336
+ delete servers[key];
1337
+ }
1338
+ }
1339
+ servers["cortex"] = cortexEntry;
1340
+ writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n");
1341
+ if (isWindowsTarget) {
1342
+ const start = Date.now();
1343
+ while (Date.now() - start < 500) {
1344
+ }
1345
+ try {
1346
+ const verify = JSON.parse(readFileSync5(configPath, "utf-8"));
1347
+ const verifyServers = verify.mcpServers;
1348
+ if (verifyServers && "cortex" in verifyServers) {
1349
+ return configPath;
1350
+ }
1351
+ } catch {
1352
+ }
1353
+ continue;
1354
+ }
1355
+ return configPath;
1356
+ }
1357
+ throw new Error(
1358
+ "Claude Desktop is overwriting the config file. Please close Claude Desktop completely (quit from the system tray), then re-run setup."
1359
+ );
1301
1360
  }
1302
1361
  function configureClaudeCode(serverUrl, apiKey, mcps) {
1303
1362
  for (const mcp of AVAILABLE_MCPS) {
1304
1363
  if (!mcps.includes(mcp.name)) continue;
1305
1364
  const url = `${serverUrl}/mcp/${mcp.name}`;
1306
1365
  try {
1307
- execSync(`claude mcp remove ${mcp.serverName}`, { stdio: "pipe" });
1366
+ execSync2(`claude mcp remove ${mcp.serverName}`, { stdio: "pipe" });
1308
1367
  } catch {
1309
1368
  }
1310
- execSync(
1369
+ execSync2(
1311
1370
  `claude mcp add --transport http ${mcp.serverName} ${url} -H "x-api-key: ${apiKey}"`,
1312
1371
  { stdio: "pipe" }
1313
1372
  );
@@ -1322,7 +1381,7 @@ function configureCursor(serverUrl, apiKey, mcps) {
1322
1381
  let config = {};
1323
1382
  if (existsSync3(configPath)) {
1324
1383
  try {
1325
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
1384
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
1326
1385
  } catch {
1327
1386
  }
1328
1387
  }
@@ -1348,7 +1407,7 @@ function configureVSCode(serverUrl, apiKey, mcps) {
1348
1407
  let config = {};
1349
1408
  if (existsSync3(configPath)) {
1350
1409
  try {
1351
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
1410
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
1352
1411
  } catch {
1353
1412
  }
1354
1413
  }
@@ -1374,7 +1433,7 @@ function configureAntigravity(serverUrl, apiKey, mcps) {
1374
1433
  let config = {};
1375
1434
  if (existsSync3(configPath)) {
1376
1435
  try {
1377
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
1436
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
1378
1437
  } catch {
1379
1438
  }
1380
1439
  }
@@ -1400,7 +1459,7 @@ function configureCodex(serverUrl, apiKey, mcps) {
1400
1459
  let existingContent = "";
1401
1460
  if (existsSync3(configPath)) {
1402
1461
  try {
1403
- existingContent = readFileSync4(configPath, "utf-8");
1462
+ existingContent = readFileSync5(configPath, "utf-8");
1404
1463
  } catch {
1405
1464
  }
1406
1465
  }
@@ -1440,10 +1499,10 @@ function configurePerplexity(serverUrl, _apiKey, mcps) {
1440
1499
  return lines.join("\n");
1441
1500
  }
1442
1501
  function generateStdioSnippet(_apiKey) {
1443
- const isWindows = getPlatform() === "windows";
1502
+ const isWindowsTarget = getPlatform() === "windows" || isWSL();
1444
1503
  const config = {
1445
1504
  mcpServers: {
1446
- cortex: isWindows ? {
1505
+ cortex: isWindowsTarget ? {
1447
1506
  command: "cmd",
1448
1507
  args: ["/c", "npx", "-y", "@danainnovations/cortex-mcp@latest", "serve"]
1449
1508
  } : {
@@ -1456,9 +1515,10 @@ function generateStdioSnippet(_apiKey) {
1456
1515
  }
1457
1516
  function configureClient(clientType, serverUrl, apiKey, mcps) {
1458
1517
  switch (clientType) {
1459
- case "claude-desktop":
1460
- configureClaudeDesktop(serverUrl, apiKey, mcps);
1461
- return "Claude Desktop configured";
1518
+ case "claude-desktop": {
1519
+ const path = configureClaudeDesktop(serverUrl, apiKey, mcps);
1520
+ return `Claude Desktop configured (${path})`;
1521
+ }
1462
1522
  case "claude-code":
1463
1523
  configureClaudeCode(serverUrl, apiKey, mcps);
1464
1524
  return "Claude Code configured";
@@ -1518,7 +1578,7 @@ async function validateApiKeyRemote(serverUrl, apiKey) {
1518
1578
  }
1519
1579
 
1520
1580
  // src/auth/credentials.ts
1521
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
1581
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
1522
1582
  import { join as join5 } from "path";
1523
1583
  function getCredentialsPath() {
1524
1584
  return join5(getHomeDir(), CONFIG_DIR_NAME, CREDENTIALS_FILE_NAME);
@@ -1527,7 +1587,7 @@ function readCredentials() {
1527
1587
  const path = getCredentialsPath();
1528
1588
  if (!existsSync4(path)) return null;
1529
1589
  try {
1530
- const raw = readFileSync5(path, "utf-8");
1590
+ const raw = readFileSync6(path, "utf-8");
1531
1591
  return JSON.parse(raw);
1532
1592
  } catch {
1533
1593
  return null;