nia-wizard 0.1.2 → 0.1.9

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.
@@ -166,6 +166,18 @@ function getDefaultServerConfig(apiKey, mode) {
166
166
  // src/steps/add-mcp-server-to-clients/MCPClient.ts
167
167
  var SERVER_NAME = "nia";
168
168
  var MCPClient = class {
169
+ /**
170
+ * Documentation URL for this client's MCP setup
171
+ */
172
+ docsUrl;
173
+ /**
174
+ * Special notes for this client (e.g., alternative install methods)
175
+ */
176
+ note;
177
+ /**
178
+ * Whether this client uses CLI commands instead of config files
179
+ */
180
+ usesCLI;
169
181
  /**
170
182
  * Check if server is already installed
171
183
  */
@@ -486,6 +498,7 @@ import * as os from "os";
486
498
  import * as fs2 from "fs";
487
499
  var CursorMCPClient = class extends MCPClient {
488
500
  name = "Cursor";
501
+ docsUrl = "https://cursor.com/docs/context/mcp";
489
502
  async isClientSupported() {
490
503
  const platform = process.platform;
491
504
  if (platform !== "darwin" && platform !== "win32") {
@@ -509,6 +522,7 @@ var CursorMCPClient = class extends MCPClient {
509
522
  return getRemoteServerConfig(apiKey);
510
523
  }
511
524
  return {
525
+ type: "stdio",
512
526
  command: "pipx",
513
527
  args: ["run", "--no-cache", "nia-mcp-server"],
514
528
  env: {
@@ -525,6 +539,8 @@ import * as os2 from "os";
525
539
  import * as fs3 from "fs";
526
540
  var ClaudeDesktopMCPClient = class extends MCPClient {
527
541
  name = "Claude Desktop";
542
+ docsUrl = "https://modelcontextprotocol.io/quickstart/user";
543
+ note = "Only supports local (stdio) mode";
528
544
  async isClientSupported() {
529
545
  const platform = process.platform;
530
546
  if (platform !== "darwin" && platform !== "win32") {
@@ -585,6 +601,8 @@ import * as os3 from "os";
585
601
  import * as path4 from "path";
586
602
  var ClaudeCodeMCPClient = class extends MCPClient {
587
603
  name = "Claude Code";
604
+ docsUrl = "https://docs.anthropic.com/en/docs/claude-code/mcp-servers";
605
+ usesCLI = true;
588
606
  claudeBinaryPath = null;
589
607
  async isClientSupported() {
590
608
  try {
@@ -605,6 +623,9 @@ var ClaudeCodeMCPClient = class extends MCPClient {
605
623
  }
606
624
  const possiblePaths = [
607
625
  path4.join(os3.homedir(), ".claude", "local", "claude"),
626
+ path4.join(os3.homedir(), ".bun", "bin", "claude"),
627
+ path4.join(os3.homedir(), ".npm", "bin", "claude"),
628
+ path4.join(os3.homedir(), ".yarn", "bin", "claude"),
608
629
  "/usr/local/bin/claude",
609
630
  "/opt/homebrew/bin/claude"
610
631
  ];
@@ -682,6 +703,7 @@ import * as os4 from "os";
682
703
  import * as fs5 from "fs";
683
704
  var VSCodeMCPClient = class extends MCPClient {
684
705
  name = "VS Code";
706
+ docsUrl = "https://code.visualstudio.com/docs/copilot/chat/mcp-servers";
685
707
  async isClientSupported() {
686
708
  const platform = process.platform;
687
709
  if (platform !== "darwin" && platform !== "win32" && platform !== "linux") {
@@ -744,6 +766,7 @@ import * as os5 from "os";
744
766
  import * as fs6 from "fs";
745
767
  var WindsurfMCPClient = class extends MCPClient {
746
768
  name = "Windsurf";
769
+ docsUrl = "https://docs.windsurf.com/windsurf/cascade/mcp";
747
770
  async isClientSupported() {
748
771
  const platform = process.platform;
749
772
  if (platform !== "darwin" && platform !== "win32" && platform !== "linux") {
@@ -797,6 +820,8 @@ import * as os6 from "os";
797
820
  import * as fs7 from "fs";
798
821
  var ZedMCPClient = class extends MCPClient {
799
822
  name = "Zed";
823
+ docsUrl = "https://zed.dev/docs/ai/mcp";
824
+ note = "Only supports local (stdio) mode";
800
825
  async isClientSupported() {
801
826
  const platform = process.platform;
802
827
  if (platform !== "darwin" && platform !== "linux") {
@@ -845,6 +870,7 @@ import * as os7 from "os";
845
870
  import * as fs8 from "fs";
846
871
  var ClineMCPClient = class extends MCPClient {
847
872
  name = "Cline";
873
+ docsUrl = "https://docs.cline.bot/mcp/configuring-mcp-servers";
848
874
  async isClientSupported() {
849
875
  const configPath = await this.getConfigPath();
850
876
  const configDir = path8.dirname(configPath);
@@ -891,11 +917,43 @@ var ClineMCPClient = class extends MCPClient {
891
917
 
892
918
  // src/steps/add-mcp-server-to-clients/clients/codex.ts
893
919
  import { execSync as execSync2, spawnSync } from "child_process";
920
+ import * as fs9 from "fs";
921
+ import * as os8 from "os";
922
+ import * as path9 from "path";
894
923
  var CodexMCPClient = class extends MCPClient {
895
924
  name = "Codex CLI";
925
+ docsUrl = "https://developers.openai.com/codex/mcp/";
926
+ usesCLI = true;
927
+ note = "Only supports local mode, uses CLI configuration";
928
+ codexBinaryPath = null;
929
+ findCodexBinary() {
930
+ if (this.codexBinaryPath) return this.codexBinaryPath;
931
+ const possiblePaths = [
932
+ path9.join(os8.homedir(), ".bun", "bin", "codex"),
933
+ path9.join(os8.homedir(), ".npm", "bin", "codex"),
934
+ path9.join(os8.homedir(), ".yarn", "bin", "codex"),
935
+ "/usr/local/bin/codex",
936
+ "/opt/homebrew/bin/codex"
937
+ ];
938
+ for (const p of possiblePaths) {
939
+ if (fs9.existsSync(p)) {
940
+ this.codexBinaryPath = p;
941
+ return p;
942
+ }
943
+ }
944
+ try {
945
+ execSync2("command -v codex", { stdio: "pipe" });
946
+ this.codexBinaryPath = "codex";
947
+ return "codex";
948
+ } catch {
949
+ return null;
950
+ }
951
+ }
896
952
  async isClientSupported() {
953
+ const binary = this.findCodexBinary();
954
+ if (!binary) return false;
897
955
  try {
898
- execSync2("codex --version", { stdio: "ignore" });
956
+ execSync2(`${binary} --version`, { stdio: "ignore" });
899
957
  return true;
900
958
  } catch {
901
959
  return false;
@@ -908,8 +966,10 @@ var CodexMCPClient = class extends MCPClient {
908
966
  return "mcpServers";
909
967
  }
910
968
  async isServerInstalled() {
969
+ const binary = this.findCodexBinary();
970
+ if (!binary) return false;
911
971
  try {
912
- const result = spawnSync("codex", ["mcp", "list", "--json"], {
972
+ const result = spawnSync(binary, ["mcp", "list", "--json"], {
913
973
  encoding: "utf-8"
914
974
  });
915
975
  if (result.error || result.status !== 0) {
@@ -924,6 +984,8 @@ var CodexMCPClient = class extends MCPClient {
924
984
  }
925
985
  }
926
986
  async addServer(apiKey, _mode) {
987
+ const binary = this.findCodexBinary();
988
+ if (!binary) return { success: false, error: "Codex CLI not found" };
927
989
  const args = [
928
990
  "mcp",
929
991
  "add",
@@ -938,15 +1000,17 @@ var CodexMCPClient = class extends MCPClient {
938
1000
  "--no-cache",
939
1001
  "nia-mcp-server"
940
1002
  ];
941
- debug(`Running: codex ${args.join(" ")}`);
942
- const result = spawnSync("codex", args, { stdio: "ignore" });
1003
+ debug(`Running: ${binary} ${args.join(" ")}`);
1004
+ const result = spawnSync(binary, args, { stdio: "ignore" });
943
1005
  if (result.error || result.status !== 0) {
944
1006
  return { success: false, error: "Failed to add server to Codex CLI" };
945
1007
  }
946
1008
  return { success: true };
947
1009
  }
948
1010
  async removeServer() {
949
- const result = spawnSync("codex", ["mcp", "remove", SERVER_NAME], {
1011
+ const binary = this.findCodexBinary();
1012
+ if (!binary) return { success: false, error: "Codex CLI not found" };
1013
+ const result = spawnSync(binary, ["mcp", "remove", SERVER_NAME], {
950
1014
  stdio: "ignore"
951
1015
  });
952
1016
  if (result.error || result.status !== 0) {
@@ -960,22 +1024,23 @@ var CodexMCPClient = class extends MCPClient {
960
1024
  };
961
1025
 
962
1026
  // src/steps/add-mcp-server-to-clients/clients/continue.ts
963
- import * as path9 from "path";
964
- import * as os8 from "os";
965
- import * as fs9 from "fs";
1027
+ import * as path10 from "path";
1028
+ import * as os9 from "os";
1029
+ import * as fs10 from "fs";
966
1030
  var ContinueMCPClient = class extends MCPClient {
967
1031
  name = "Continue.dev";
1032
+ docsUrl = "https://docs.continue.dev/customize/mcp-tools";
968
1033
  async isClientSupported() {
969
1034
  const configPath = await this.getConfigPath();
970
- const configDir = path9.dirname(configPath);
971
- return fs9.existsSync(configDir);
1035
+ const configDir = path10.dirname(configPath);
1036
+ return fs10.existsSync(configDir);
972
1037
  }
973
1038
  async getConfigPath() {
974
1039
  const platform = process.platform;
975
1040
  if (platform === "win32") {
976
- return path9.join(process.env.USERPROFILE || "", ".continue", "config.json");
1041
+ return path10.join(process.env.USERPROFILE || "", ".continue", "config.json");
977
1042
  }
978
- return path9.join(os8.homedir(), ".continue", "config.json");
1043
+ return path10.join(os9.homedir(), ".continue", "config.json");
979
1044
  }
980
1045
  getServerPropertyName() {
981
1046
  return "experimental";
@@ -1011,21 +1076,23 @@ var ContinueMCPClient = class extends MCPClient {
1011
1076
  };
1012
1077
 
1013
1078
  // src/steps/add-mcp-server-to-clients/clients/jetbrains.ts
1014
- import * as path10 from "path";
1015
- import * as os9 from "os";
1016
- import * as fs10 from "fs";
1079
+ import * as path11 from "path";
1080
+ import * as os10 from "os";
1081
+ import * as fs11 from "fs";
1017
1082
  var JetBrainsMCPClient = class extends MCPClient {
1018
1083
  name = "JetBrains";
1084
+ docsUrl = "https://www.jetbrains.com/help/idea/mcp-server.html";
1085
+ note = "Only supports local (stdio) mode";
1019
1086
  async isClientSupported() {
1020
- const homeDir = os9.homedir();
1087
+ const homeDir = os10.homedir();
1021
1088
  const possibleDirs = [
1022
- path10.join(homeDir, ".config", "JetBrains"),
1023
- path10.join(homeDir, "Library", "Application Support", "JetBrains")
1089
+ path11.join(homeDir, ".config", "JetBrains"),
1090
+ path11.join(homeDir, "Library", "Application Support", "JetBrains")
1024
1091
  ];
1025
- return possibleDirs.some((dir) => fs10.existsSync(dir));
1092
+ return possibleDirs.some((dir) => fs11.existsSync(dir));
1026
1093
  }
1027
1094
  async getConfigPath() {
1028
- return path10.join(os9.homedir(), ".jetbrains", "mcp.json");
1095
+ return path11.join(os10.homedir(), ".jetbrains", "mcp.json");
1029
1096
  }
1030
1097
  getServerPropertyName() {
1031
1098
  return "mcpServers";
@@ -1046,18 +1113,19 @@ var JetBrainsMCPClient = class extends MCPClient {
1046
1113
  };
1047
1114
 
1048
1115
  // src/steps/add-mcp-server-to-clients/clients/antigravity.ts
1049
- import * as path11 from "path";
1050
- import * as os10 from "os";
1051
- import * as fs11 from "fs";
1116
+ import * as path12 from "path";
1117
+ import * as os11 from "os";
1118
+ import * as fs12 from "fs";
1052
1119
  var AntigravityMCPClient = class extends MCPClient {
1053
1120
  name = "Google Antigravity";
1121
+ docsUrl = "https://developers.google.com/gemini-code-assist/docs/use-mcp-servers";
1054
1122
  async isClientSupported() {
1055
1123
  const configPath = await this.getConfigPath();
1056
- const configDir = path11.dirname(configPath);
1057
- return fs11.existsSync(configDir) || fs11.existsSync(path11.dirname(configDir));
1124
+ const configDir = path12.dirname(configPath);
1125
+ return fs12.existsSync(configDir) || fs12.existsSync(path12.dirname(configDir));
1058
1126
  }
1059
1127
  async getConfigPath() {
1060
- return path11.join(os10.homedir(), ".gemini", "antigravity", "mcp_config.json");
1128
+ return path12.join(os11.homedir(), ".gemini", "antigravity", "mcp_config.json");
1061
1129
  }
1062
1130
  getServerPropertyName() {
1063
1131
  return "mcpServers";
@@ -1083,21 +1151,22 @@ var AntigravityMCPClient = class extends MCPClient {
1083
1151
  };
1084
1152
 
1085
1153
  // src/steps/add-mcp-server-to-clients/clients/trae.ts
1086
- import * as path12 from "path";
1087
- import * as os11 from "os";
1088
- import * as fs12 from "fs";
1154
+ import * as path13 from "path";
1155
+ import * as os12 from "os";
1156
+ import * as fs13 from "fs";
1089
1157
  var TraeMCPClient = class extends MCPClient {
1090
1158
  name = "Trae";
1159
+ docsUrl = "https://docs.trae.ai/ide/model-context-protocol";
1091
1160
  async isClientSupported() {
1092
1161
  const configPath = await this.getConfigPath();
1093
- const configDir = path12.dirname(configPath);
1094
- return fs12.existsSync(configDir) || fs12.existsSync(path12.dirname(configDir));
1162
+ const configDir = path13.dirname(configPath);
1163
+ return fs13.existsSync(configDir) || fs13.existsSync(path13.dirname(configDir));
1095
1164
  }
1096
1165
  async getConfigPath() {
1097
1166
  if (process.platform === "darwin") {
1098
- return path12.join(os11.homedir(), "Library", "Application Support", "Trae", "User", "mcp.json");
1167
+ return path13.join(os12.homedir(), "Library", "Application Support", "Trae", "User", "mcp.json");
1099
1168
  }
1100
- return path12.join(os11.homedir(), ".config", "trae", "mcp.json");
1169
+ return path13.join(os12.homedir(), ".config", "trae", "mcp.json");
1101
1170
  }
1102
1171
  getServerPropertyName() {
1103
1172
  return "mcpServers";
@@ -1123,18 +1192,19 @@ var TraeMCPClient = class extends MCPClient {
1123
1192
  };
1124
1193
 
1125
1194
  // src/steps/add-mcp-server-to-clients/clients/roo-code.ts
1126
- import * as path13 from "path";
1127
- import * as os12 from "os";
1128
- import * as fs13 from "fs";
1195
+ import * as path14 from "path";
1196
+ import * as os13 from "os";
1197
+ import * as fs14 from "fs";
1129
1198
  var RooCodeMCPClient = class extends MCPClient {
1130
1199
  name = "Roo Code";
1200
+ docsUrl = "https://docs.roocode.com/features/mcp/using-mcp-in-roo";
1131
1201
  async isClientSupported() {
1132
1202
  const configPath = await this.getConfigPath();
1133
- const configDir = path13.dirname(configPath);
1134
- return fs13.existsSync(configDir) || fs13.existsSync(path13.dirname(configDir));
1203
+ const configDir = path14.dirname(configPath);
1204
+ return fs14.existsSync(configDir) || fs14.existsSync(path14.dirname(configDir));
1135
1205
  }
1136
1206
  async getConfigPath() {
1137
- return path13.join(os12.homedir(), ".roo-code", "mcp.json");
1207
+ return path14.join(os13.homedir(), ".roo-code", "mcp.json");
1138
1208
  }
1139
1209
  getServerPropertyName() {
1140
1210
  return "mcpServers";
@@ -1161,18 +1231,19 @@ var RooCodeMCPClient = class extends MCPClient {
1161
1231
  };
1162
1232
 
1163
1233
  // src/steps/add-mcp-server-to-clients/clients/kilo-code.ts
1164
- import * as path14 from "path";
1165
- import * as os13 from "os";
1166
- import * as fs14 from "fs";
1234
+ import * as path15 from "path";
1235
+ import * as os14 from "os";
1236
+ import * as fs15 from "fs";
1167
1237
  var KiloCodeMCPClient = class extends MCPClient {
1168
1238
  name = "Kilo Code";
1239
+ docsUrl = "https://kilo.ai/docs/features/mcp/using-mcp-in-kilo-code";
1169
1240
  async isClientSupported() {
1170
1241
  const configPath = await this.getConfigPath();
1171
- const configDir = path14.dirname(configPath);
1172
- return fs14.existsSync(configDir) || fs14.existsSync(path14.dirname(configDir));
1242
+ const configDir = path15.dirname(configPath);
1243
+ return fs15.existsSync(configDir) || fs15.existsSync(path15.dirname(configDir));
1173
1244
  }
1174
1245
  async getConfigPath() {
1175
- return path14.join(os13.homedir(), ".kilocode", "mcp.json");
1246
+ return path15.join(os14.homedir(), ".kilocode", "mcp.json");
1176
1247
  }
1177
1248
  getServerPropertyName() {
1178
1249
  return "mcpServers";
@@ -1203,21 +1274,22 @@ var KiloCodeMCPClient = class extends MCPClient {
1203
1274
  };
1204
1275
 
1205
1276
  // src/steps/add-mcp-server-to-clients/clients/gemini-cli.ts
1206
- import * as path15 from "path";
1207
- import * as os14 from "os";
1208
- import * as fs15 from "fs";
1277
+ import * as path16 from "path";
1278
+ import * as os15 from "os";
1279
+ import * as fs16 from "fs";
1209
1280
  var GeminiCLIMCPClient = class extends MCPClient {
1210
1281
  name = "Gemini CLI";
1282
+ docsUrl = "https://googlegemini.com/docs/gemini-cli/tools/mcp-server";
1211
1283
  async isClientSupported() {
1212
1284
  const configPath = await this.getConfigPath();
1213
- const configDir = path15.dirname(configPath);
1214
- return fs15.existsSync(configDir) || fs15.existsSync(path15.dirname(configDir));
1285
+ const configDir = path16.dirname(configPath);
1286
+ return fs16.existsSync(configDir) || fs16.existsSync(path16.dirname(configDir));
1215
1287
  }
1216
1288
  async getConfigPath() {
1217
1289
  if (process.platform === "win32") {
1218
- return path15.join(process.env.USERPROFILE || "", ".gemini", "settings.json");
1290
+ return path16.join(process.env.USERPROFILE || "", ".gemini", "settings.json");
1219
1291
  }
1220
- return path15.join(os14.homedir(), ".gemini", "settings.json");
1292
+ return path16.join(os15.homedir(), ".gemini", "settings.json");
1221
1293
  }
1222
1294
  getServerPropertyName() {
1223
1295
  return "mcpServers";
@@ -1244,18 +1316,20 @@ var GeminiCLIMCPClient = class extends MCPClient {
1244
1316
  };
1245
1317
 
1246
1318
  // src/steps/add-mcp-server-to-clients/clients/opencode.ts
1247
- import * as path16 from "path";
1248
- import * as os15 from "os";
1249
- import * as fs16 from "fs";
1319
+ import * as path17 from "path";
1320
+ import * as os16 from "os";
1321
+ import * as fs17 from "fs";
1250
1322
  var OpencodeMCPClient = class extends MCPClient {
1251
1323
  name = "Opencode";
1324
+ docsUrl = "https://opencode.ai/docs/mcp-servers/";
1325
+ note = "Also available as dedicated plugin: bunx nia-opencode@latest install (Demo: https://x.com/arlanr/status/1879212916125777962)";
1252
1326
  async isClientSupported() {
1253
1327
  const configPath = await this.getConfigPath();
1254
- const configDir = path16.dirname(configPath);
1255
- return fs16.existsSync(configDir) || fs16.existsSync(path16.dirname(configDir));
1328
+ const configDir = path17.dirname(configPath);
1329
+ return fs17.existsSync(configDir) || fs17.existsSync(path17.dirname(configDir));
1256
1330
  }
1257
1331
  async getConfigPath() {
1258
- return path16.join(os15.homedir(), ".opencode", "config.json");
1332
+ return path17.join(os16.homedir(), ".opencode", "config.json");
1259
1333
  }
1260
1334
  getServerPropertyName() {
1261
1335
  return "mcp";
@@ -1284,18 +1358,19 @@ var OpencodeMCPClient = class extends MCPClient {
1284
1358
  };
1285
1359
 
1286
1360
  // src/steps/add-mcp-server-to-clients/clients/qodo-gen.ts
1287
- import * as path17 from "path";
1288
- import * as os16 from "os";
1289
- import * as fs17 from "fs";
1361
+ import * as path18 from "path";
1362
+ import * as os17 from "os";
1363
+ import * as fs18 from "fs";
1290
1364
  var QodoGenMCPClient = class extends MCPClient {
1291
1365
  name = "Qodo Gen";
1366
+ docsUrl = "https://docs.qodo.ai/qodo-documentation/qodo-gen/tools-mcps/agentic-tools-mcps";
1292
1367
  async isClientSupported() {
1293
1368
  const configPath = await this.getConfigPath();
1294
- const configDir = path17.dirname(configPath);
1295
- return fs17.existsSync(configDir) || fs17.existsSync(path17.dirname(configDir));
1369
+ const configDir = path18.dirname(configPath);
1370
+ return fs18.existsSync(configDir) || fs18.existsSync(path18.dirname(configDir));
1296
1371
  }
1297
1372
  async getConfigPath() {
1298
- return path17.join(os16.homedir(), ".qodo", "mcp.json");
1373
+ return path18.join(os17.homedir(), ".qodo", "mcp.json");
1299
1374
  }
1300
1375
  getServerPropertyName() {
1301
1376
  return "mcpServers";
@@ -1321,21 +1396,22 @@ var QodoGenMCPClient = class extends MCPClient {
1321
1396
  };
1322
1397
 
1323
1398
  // src/steps/add-mcp-server-to-clients/clients/qwen-coder.ts
1324
- import * as path18 from "path";
1325
- import * as os17 from "os";
1326
- import * as fs18 from "fs";
1399
+ import * as path19 from "path";
1400
+ import * as os18 from "os";
1401
+ import * as fs19 from "fs";
1327
1402
  var QwenCoderMCPClient = class extends MCPClient {
1328
1403
  name = "Qwen Coder";
1404
+ docsUrl = "https://qwenlm.github.io/blog/qwen2.5-coder-family/";
1329
1405
  async isClientSupported() {
1330
1406
  const configPath = await this.getConfigPath();
1331
- const configDir = path18.dirname(configPath);
1332
- return fs18.existsSync(configDir) || fs18.existsSync(path18.dirname(configDir));
1407
+ const configDir = path19.dirname(configPath);
1408
+ return fs19.existsSync(configDir) || fs19.existsSync(path19.dirname(configDir));
1333
1409
  }
1334
1410
  async getConfigPath() {
1335
1411
  if (process.platform === "win32") {
1336
- return path18.join(process.env.USERPROFILE || "", ".qwen", "settings.json");
1412
+ return path19.join(process.env.USERPROFILE || "", ".qwen", "settings.json");
1337
1413
  }
1338
- return path18.join(os17.homedir(), ".qwen", "settings.json");
1414
+ return path19.join(os18.homedir(), ".qwen", "settings.json");
1339
1415
  }
1340
1416
  getServerPropertyName() {
1341
1417
  return "mcpServers";
@@ -1362,21 +1438,22 @@ var QwenCoderMCPClient = class extends MCPClient {
1362
1438
  };
1363
1439
 
1364
1440
  // src/steps/add-mcp-server-to-clients/clients/visual-studio.ts
1365
- import * as path19 from "path";
1366
- import * as os18 from "os";
1367
- import * as fs19 from "fs";
1441
+ import * as path20 from "path";
1442
+ import * as os19 from "os";
1443
+ import * as fs20 from "fs";
1368
1444
  var VisualStudioMCPClient = class extends MCPClient {
1369
1445
  name = "Visual Studio 2022";
1446
+ docsUrl = "https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers";
1370
1447
  async isClientSupported() {
1371
1448
  if (process.platform !== "win32") {
1372
1449
  return false;
1373
1450
  }
1374
1451
  const configPath = await this.getConfigPath();
1375
- const configDir = path19.dirname(configPath);
1376
- return fs19.existsSync(configDir) || fs19.existsSync(path19.dirname(configDir));
1452
+ const configDir = path20.dirname(configPath);
1453
+ return fs20.existsSync(configDir) || fs20.existsSync(path20.dirname(configDir));
1377
1454
  }
1378
1455
  async getConfigPath() {
1379
- return path19.join(os18.homedir(), ".vs", "mcp.json");
1456
+ return path20.join(os19.homedir(), ".vs", "mcp.json");
1380
1457
  }
1381
1458
  getServerPropertyName() {
1382
1459
  return "servers";
@@ -1404,18 +1481,19 @@ var VisualStudioMCPClient = class extends MCPClient {
1404
1481
  };
1405
1482
 
1406
1483
  // src/steps/add-mcp-server-to-clients/clients/crush.ts
1407
- import * as path20 from "path";
1408
- import * as os19 from "os";
1409
- import * as fs20 from "fs";
1484
+ import * as path21 from "path";
1485
+ import * as os20 from "os";
1486
+ import * as fs21 from "fs";
1410
1487
  var CrushMCPClient = class extends MCPClient {
1411
1488
  name = "Crush";
1489
+ docsUrl = "https://github.com/charmbracelet/crush";
1412
1490
  async isClientSupported() {
1413
1491
  const configPath = await this.getConfigPath();
1414
- const configDir = path20.dirname(configPath);
1415
- return fs20.existsSync(configDir) || fs20.existsSync(path20.dirname(configDir));
1492
+ const configDir = path21.dirname(configPath);
1493
+ return fs21.existsSync(configDir) || fs21.existsSync(path21.dirname(configDir));
1416
1494
  }
1417
1495
  async getConfigPath() {
1418
- return path20.join(os19.homedir(), ".crush", "config.json");
1496
+ return path21.join(os20.homedir(), ".crush", "config.json");
1419
1497
  }
1420
1498
  getServerPropertyName() {
1421
1499
  return "mcp";
@@ -1443,22 +1521,23 @@ var CrushMCPClient = class extends MCPClient {
1443
1521
  };
1444
1522
 
1445
1523
  // src/steps/add-mcp-server-to-clients/clients/copilot.ts
1446
- import * as path21 from "path";
1447
- import * as os20 from "os";
1448
- import * as fs21 from "fs";
1524
+ import * as path22 from "path";
1525
+ import * as os21 from "os";
1526
+ import * as fs22 from "fs";
1449
1527
  var COPILOT_TOOLS = ["index", "search", "manage_resource", "nia_web_search", "nia_deep_research_agent"];
1450
1528
  var CopilotCLIMCPClient = class extends MCPClient {
1451
1529
  name = "Copilot CLI";
1530
+ docsUrl = "https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp";
1452
1531
  async isClientSupported() {
1453
1532
  const configPath = await this.getConfigPath();
1454
- const configDir = path21.dirname(configPath);
1455
- return fs21.existsSync(configDir) || fs21.existsSync(path21.dirname(configDir));
1533
+ const configDir = path22.dirname(configPath);
1534
+ return fs22.existsSync(configDir) || fs22.existsSync(path22.dirname(configDir));
1456
1535
  }
1457
1536
  async getConfigPath() {
1458
1537
  if (process.platform === "win32") {
1459
- return path21.join(process.env.USERPROFILE || "", ".copilot", "mcp-config.json");
1538
+ return path22.join(process.env.USERPROFILE || "", ".copilot", "mcp-config.json");
1460
1539
  }
1461
- return path21.join(os20.homedir(), ".copilot", "mcp-config.json");
1540
+ return path22.join(os21.homedir(), ".copilot", "mcp-config.json");
1462
1541
  }
1463
1542
  getServerPropertyName() {
1464
1543
  return "mcpServers";
@@ -1488,11 +1567,12 @@ var CopilotCLIMCPClient = class extends MCPClient {
1488
1567
  };
1489
1568
  var CopilotAgentMCPClient = class extends MCPClient {
1490
1569
  name = "Copilot Coding Agent";
1570
+ docsUrl = "https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp";
1491
1571
  async isClientSupported() {
1492
- return fs21.existsSync(".github");
1572
+ return fs22.existsSync(".github");
1493
1573
  }
1494
1574
  async getConfigPath() {
1495
- return path21.join(".github", "copilot-mcp.json");
1575
+ return path22.join(".github", "copilot-mcp.json");
1496
1576
  }
1497
1577
  getServerPropertyName() {
1498
1578
  return "mcpServers";
@@ -1522,15 +1602,17 @@ var CopilotAgentMCPClient = class extends MCPClient {
1522
1602
  };
1523
1603
 
1524
1604
  // src/steps/add-mcp-server-to-clients/clients/augment.ts
1525
- import * as path22 from "path";
1526
- import * as os21 from "os";
1605
+ import * as path23 from "path";
1606
+ import * as os22 from "os";
1527
1607
  var AugmentMCPClient = class extends MCPClient {
1528
1608
  name = "Augment Code";
1609
+ docsUrl = "https://docs.augmentcode.com/setup-augment/mcp";
1610
+ note = "Only supports local (stdio) mode";
1529
1611
  async isClientSupported() {
1530
1612
  return false;
1531
1613
  }
1532
1614
  async getConfigPath() {
1533
- return path22.join(os21.homedir(), ".vscode", "settings.json");
1615
+ return path23.join(os22.homedir(), ".vscode", "settings.json");
1534
1616
  }
1535
1617
  getServerPropertyName() {
1536
1618
  return "augment.advanced";
@@ -1556,18 +1638,20 @@ var AugmentMCPClient = class extends MCPClient {
1556
1638
  };
1557
1639
 
1558
1640
  // src/steps/add-mcp-server-to-clients/clients/kiro.ts
1559
- import * as path23 from "path";
1560
- import * as os22 from "os";
1561
- import * as fs22 from "fs";
1641
+ import * as path24 from "path";
1642
+ import * as os23 from "os";
1643
+ import * as fs23 from "fs";
1562
1644
  var KiroMCPClient = class extends MCPClient {
1563
1645
  name = "Kiro";
1646
+ docsUrl = "https://kiro.dev/docs/mcp/";
1647
+ note = "Only supports local (stdio) mode";
1564
1648
  async isClientSupported() {
1565
1649
  const configPath = await this.getConfigPath();
1566
- const configDir = path23.dirname(configPath);
1567
- return fs22.existsSync(configDir) || fs22.existsSync(path23.dirname(configDir));
1650
+ const configDir = path24.dirname(configPath);
1651
+ return fs23.existsSync(configDir) || fs23.existsSync(path24.dirname(configDir));
1568
1652
  }
1569
1653
  async getConfigPath() {
1570
- return path23.join(os22.homedir(), ".kiro", "mcp.json");
1654
+ return path24.join(os23.homedir(), ".kiro", "mcp.json");
1571
1655
  }
1572
1656
  getServerPropertyName() {
1573
1657
  return "mcpServers";
@@ -1590,18 +1674,20 @@ var KiroMCPClient = class extends MCPClient {
1590
1674
  };
1591
1675
 
1592
1676
  // src/steps/add-mcp-server-to-clients/clients/lm-studio.ts
1593
- import * as path24 from "path";
1594
- import * as os23 from "os";
1595
- import * as fs23 from "fs";
1677
+ import * as path25 from "path";
1678
+ import * as os24 from "os";
1679
+ import * as fs24 from "fs";
1596
1680
  var LMStudioMCPClient = class extends MCPClient {
1597
1681
  name = "LM Studio";
1682
+ docsUrl = "https://lmstudio.ai/docs/app/mcp";
1683
+ note = "Only supports local (stdio) mode";
1598
1684
  async isClientSupported() {
1599
1685
  const configPath = await this.getConfigPath();
1600
- const configDir = path24.dirname(configPath);
1601
- return fs23.existsSync(configDir) || fs23.existsSync(path24.dirname(configDir));
1686
+ const configDir = path25.dirname(configPath);
1687
+ return fs24.existsSync(configDir) || fs24.existsSync(path25.dirname(configDir));
1602
1688
  }
1603
1689
  async getConfigPath() {
1604
- return path24.join(os23.homedir(), ".lmstudio", "mcp.json");
1690
+ return path25.join(os24.homedir(), ".lmstudio", "mcp.json");
1605
1691
  }
1606
1692
  getServerPropertyName() {
1607
1693
  return "mcpServers";
@@ -1622,21 +1708,23 @@ var LMStudioMCPClient = class extends MCPClient {
1622
1708
  };
1623
1709
 
1624
1710
  // src/steps/add-mcp-server-to-clients/clients/bolt-ai.ts
1625
- import * as path25 from "path";
1626
- import * as os24 from "os";
1627
- import * as fs24 from "fs";
1711
+ import * as path26 from "path";
1712
+ import * as os25 from "os";
1713
+ import * as fs25 from "fs";
1628
1714
  var BoltAIMCPClient = class extends MCPClient {
1629
1715
  name = "BoltAI";
1716
+ docsUrl = "https://docs.boltai.com/docs/plugins/mcp-servers";
1717
+ note = "Only supports local (stdio) mode, macOS only";
1630
1718
  async isClientSupported() {
1631
1719
  if (process.platform !== "darwin") {
1632
1720
  return false;
1633
1721
  }
1634
1722
  const configPath = await this.getConfigPath();
1635
- const configDir = path25.dirname(configPath);
1636
- return fs24.existsSync(configDir) || fs24.existsSync(path25.dirname(configDir));
1723
+ const configDir = path26.dirname(configPath);
1724
+ return fs25.existsSync(configDir) || fs25.existsSync(path26.dirname(configDir));
1637
1725
  }
1638
1726
  async getConfigPath() {
1639
- return path25.join(os24.homedir(), "Library", "Application Support", "BoltAI", "mcp.json");
1727
+ return path26.join(os25.homedir(), "Library", "Application Support", "BoltAI", "mcp.json");
1640
1728
  }
1641
1729
  getServerPropertyName() {
1642
1730
  return "mcpServers";
@@ -1657,21 +1745,23 @@ var BoltAIMCPClient = class extends MCPClient {
1657
1745
  };
1658
1746
 
1659
1747
  // src/steps/add-mcp-server-to-clients/clients/perplexity.ts
1660
- import * as path26 from "path";
1661
- import * as os25 from "os";
1662
- import * as fs25 from "fs";
1748
+ import * as path27 from "path";
1749
+ import * as os26 from "os";
1750
+ import * as fs26 from "fs";
1663
1751
  var PerplexityMCPClient = class extends MCPClient {
1664
1752
  name = "Perplexity Desktop";
1753
+ docsUrl = "https://docs.perplexity.ai/guides/mcp-server";
1754
+ note = "Only supports local (stdio) mode, macOS only";
1665
1755
  async isClientSupported() {
1666
1756
  if (process.platform !== "darwin") {
1667
1757
  return false;
1668
1758
  }
1669
1759
  const configPath = await this.getConfigPath();
1670
- const configDir = path26.dirname(configPath);
1671
- return fs25.existsSync(configDir) || fs25.existsSync(path26.dirname(configDir));
1760
+ const configDir = path27.dirname(configPath);
1761
+ return fs26.existsSync(configDir) || fs26.existsSync(path27.dirname(configDir));
1672
1762
  }
1673
1763
  async getConfigPath() {
1674
- return path26.join(os25.homedir(), "Library", "Application Support", "Perplexity", "mcp.json");
1764
+ return path27.join(os26.homedir(), "Library", "Application Support", "Perplexity", "mcp.json");
1675
1765
  }
1676
1766
  getServerPropertyName() {
1677
1767
  return "mcpServers";
@@ -1692,18 +1782,20 @@ var PerplexityMCPClient = class extends MCPClient {
1692
1782
  };
1693
1783
 
1694
1784
  // src/steps/add-mcp-server-to-clients/clients/warp.ts
1695
- import * as path27 from "path";
1696
- import * as os26 from "os";
1697
- import * as fs26 from "fs";
1785
+ import * as path28 from "path";
1786
+ import * as os27 from "os";
1787
+ import * as fs27 from "fs";
1698
1788
  var WarpMCPClient = class extends MCPClient {
1699
1789
  name = "Warp";
1790
+ docsUrl = "https://docs.warp.dev/knowledge-and-collaboration/mcp";
1791
+ note = "Only supports local (stdio) mode";
1700
1792
  async isClientSupported() {
1701
1793
  const configPath = await this.getConfigPath();
1702
- const configDir = path27.dirname(configPath);
1703
- return fs26.existsSync(configDir) || fs26.existsSync(path27.dirname(configDir));
1794
+ const configDir = path28.dirname(configPath);
1795
+ return fs27.existsSync(configDir) || fs27.existsSync(path28.dirname(configDir));
1704
1796
  }
1705
1797
  async getConfigPath() {
1706
- return path27.join(os26.homedir(), ".warp", "mcp.json");
1798
+ return path28.join(os27.homedir(), ".warp", "mcp.json");
1707
1799
  }
1708
1800
  getServerPropertyName() {
1709
1801
  return "mcpServers";
@@ -1726,18 +1818,20 @@ var WarpMCPClient = class extends MCPClient {
1726
1818
  };
1727
1819
 
1728
1820
  // src/steps/add-mcp-server-to-clients/clients/amazon-q.ts
1729
- import * as path28 from "path";
1730
- import * as os27 from "os";
1731
- import * as fs27 from "fs";
1821
+ import * as path29 from "path";
1822
+ import * as os28 from "os";
1823
+ import * as fs28 from "fs";
1732
1824
  var AmazonQMCPClient = class extends MCPClient {
1733
1825
  name = "Amazon Q Developer CLI";
1826
+ docsUrl = "https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-mcp-configuration.html";
1827
+ note = "Only supports local (stdio) mode";
1734
1828
  async isClientSupported() {
1735
1829
  const configPath = await this.getConfigPath();
1736
- const configDir = path28.dirname(configPath);
1737
- return fs27.existsSync(configDir) || fs27.existsSync(path28.dirname(configDir));
1830
+ const configDir = path29.dirname(configPath);
1831
+ return fs28.existsSync(configDir) || fs28.existsSync(path29.dirname(configDir));
1738
1832
  }
1739
1833
  async getConfigPath() {
1740
- return path28.join(os27.homedir(), ".aws", "amazonq", "mcp.json");
1834
+ return path29.join(os28.homedir(), ".aws", "amazonq", "mcp.json");
1741
1835
  }
1742
1836
  getServerPropertyName() {
1743
1837
  return "mcpServers";
@@ -1759,64 +1853,156 @@ var AmazonQMCPClient = class extends MCPClient {
1759
1853
 
1760
1854
  // src/steps/add-mcp-server-to-clients/clients/factory.ts
1761
1855
  import { execSync as execSync3, spawnSync as spawnSync2 } from "child_process";
1856
+ import * as fs29 from "fs";
1857
+ import * as os29 from "os";
1858
+ import * as path30 from "path";
1762
1859
  var FactoryMCPClient = class extends MCPClient {
1763
1860
  name = "Factory";
1764
- async isClientSupported() {
1861
+ docsUrl = "https://docs.factory.ai/cli/configuration/mcp";
1862
+ note = "Supports droid CLI or config file (~/.factory/mcp.json)";
1863
+ droidBinaryPath = null;
1864
+ findDroidBinary() {
1865
+ if (this.droidBinaryPath) return this.droidBinaryPath;
1866
+ const possiblePaths = [
1867
+ path30.join(os29.homedir(), ".bun", "bin", "droid"),
1868
+ path30.join(os29.homedir(), ".npm", "bin", "droid"),
1869
+ path30.join(os29.homedir(), ".yarn", "bin", "droid"),
1870
+ "/usr/local/bin/droid",
1871
+ "/opt/homebrew/bin/droid"
1872
+ ];
1873
+ for (const p of possiblePaths) {
1874
+ if (fs29.existsSync(p)) {
1875
+ this.droidBinaryPath = p;
1876
+ return p;
1877
+ }
1878
+ }
1765
1879
  try {
1766
- execSync3("droid --version", { stdio: "ignore" });
1767
- return true;
1880
+ execSync3("command -v droid", { stdio: "pipe" });
1881
+ this.droidBinaryPath = "droid";
1882
+ return "droid";
1768
1883
  } catch {
1769
- return false;
1884
+ return null;
1885
+ }
1886
+ }
1887
+ getConfigFilePath() {
1888
+ return path30.join(os29.homedir(), ".factory", "mcp.json");
1889
+ }
1890
+ async isClientSupported() {
1891
+ const binary = this.findDroidBinary();
1892
+ if (binary) {
1893
+ try {
1894
+ execSync3(`${binary} --version`, { stdio: "ignore" });
1895
+ return true;
1896
+ } catch {
1897
+ }
1770
1898
  }
1899
+ const factoryDir = path30.join(os29.homedir(), ".factory");
1900
+ return fs29.existsSync(factoryDir);
1771
1901
  }
1772
1902
  async getConfigPath() {
1773
- throw new Error("Factory uses CLI configuration");
1903
+ return this.getConfigFilePath();
1774
1904
  }
1775
1905
  getServerPropertyName() {
1776
1906
  return "mcpServers";
1777
1907
  }
1908
+ getServerConfig(apiKey, mode) {
1909
+ if (mode === "remote") {
1910
+ return {
1911
+ type: "http",
1912
+ url: REMOTE_MCP_URL,
1913
+ headers: {
1914
+ Authorization: `Bearer ${apiKey}`
1915
+ }
1916
+ };
1917
+ }
1918
+ return {
1919
+ command: "pipx",
1920
+ args: ["run", "--no-cache", "nia-mcp-server"],
1921
+ env: {
1922
+ NIA_API_KEY: apiKey,
1923
+ NIA_API_URL
1924
+ }
1925
+ };
1926
+ }
1778
1927
  async isServerInstalled() {
1928
+ const binary = this.findDroidBinary();
1929
+ if (binary) {
1930
+ try {
1931
+ const result = spawnSync2(binary, ["mcp", "list"], {
1932
+ encoding: "utf-8",
1933
+ stdio: "pipe"
1934
+ });
1935
+ if (result.stdout?.includes(SERVER_NAME)) {
1936
+ return true;
1937
+ }
1938
+ } catch {
1939
+ }
1940
+ }
1941
+ const configPath = this.getConfigFilePath();
1942
+ if (!fs29.existsSync(configPath)) return false;
1779
1943
  try {
1780
- const result = spawnSync2("droid", ["mcp", "list"], {
1781
- encoding: "utf-8",
1782
- stdio: "pipe"
1783
- });
1784
- return result.stdout?.includes(SERVER_NAME) || false;
1944
+ const content = fs29.readFileSync(configPath, "utf-8");
1945
+ const config = JSON.parse(content);
1946
+ return !!config?.mcpServers?.[SERVER_NAME];
1785
1947
  } catch {
1786
1948
  return false;
1787
1949
  }
1788
1950
  }
1789
1951
  async addServer(apiKey, mode) {
1952
+ const binary = this.findDroidBinary();
1953
+ if (binary) {
1954
+ try {
1955
+ let args;
1956
+ if (mode === "remote") {
1957
+ args = [
1958
+ "mcp",
1959
+ "add",
1960
+ SERVER_NAME,
1961
+ REMOTE_MCP_URL,
1962
+ "--type",
1963
+ "http",
1964
+ "--header",
1965
+ `Authorization: Bearer ${apiKey}`
1966
+ ];
1967
+ } else {
1968
+ args = [
1969
+ "mcp",
1970
+ "add",
1971
+ SERVER_NAME,
1972
+ "pipx run --no-cache nia-mcp-server",
1973
+ "--env",
1974
+ `NIA_API_KEY=${apiKey}`,
1975
+ "--env",
1976
+ `NIA_API_URL=${NIA_API_URL}`
1977
+ ];
1978
+ }
1979
+ debug(`Running: ${binary} ${args.join(" ")}`);
1980
+ const result = spawnSync2(binary, args, { stdio: "pipe" });
1981
+ if (!result.error && result.status === 0) {
1982
+ return { success: true };
1983
+ }
1984
+ } catch {
1985
+ }
1986
+ }
1987
+ return this.addServerViaConfigFile(apiKey, mode);
1988
+ }
1989
+ async addServerViaConfigFile(apiKey, mode) {
1990
+ const configPath = this.getConfigFilePath();
1991
+ const configDir = path30.dirname(configPath);
1790
1992
  try {
1791
- let args;
1792
- if (mode === "remote") {
1793
- args = [
1794
- "mcp",
1795
- "add",
1796
- SERVER_NAME,
1797
- REMOTE_MCP_URL,
1798
- "--type",
1799
- "http",
1800
- "--header",
1801
- `Authorization: Bearer ${apiKey}`
1802
- ];
1803
- } else {
1804
- args = [
1805
- "mcp",
1806
- "add",
1807
- SERVER_NAME,
1808
- "pipx run --no-cache nia-mcp-server",
1809
- "--env",
1810
- `NIA_API_KEY=${apiKey}`,
1811
- "--env",
1812
- `NIA_API_URL=${NIA_API_URL}`
1813
- ];
1993
+ if (!fs29.existsSync(configDir)) {
1994
+ fs29.mkdirSync(configDir, { recursive: true });
1814
1995
  }
1815
- debug(`Running: droid ${args.join(" ")}`);
1816
- const result = spawnSync2("droid", args, { stdio: "pipe" });
1817
- if (result.error || result.status !== 0) {
1818
- return { success: false, error: "Failed to add server to Factory" };
1996
+ let config = {};
1997
+ if (fs29.existsSync(configPath)) {
1998
+ const content = fs29.readFileSync(configPath, "utf-8");
1999
+ config = JSON.parse(content);
1819
2000
  }
2001
+ if (!config.mcpServers) {
2002
+ config.mcpServers = {};
2003
+ }
2004
+ config.mcpServers[SERVER_NAME] = this.getServerConfig(apiKey, mode);
2005
+ fs29.writeFileSync(configPath, JSON.stringify(config, null, 2));
1820
2006
  return { success: true };
1821
2007
  } catch (error) {
1822
2008
  const message = error instanceof Error ? error.message : String(error);
@@ -1824,12 +2010,31 @@ var FactoryMCPClient = class extends MCPClient {
1824
2010
  }
1825
2011
  }
1826
2012
  async removeServer() {
2013
+ const binary = this.findDroidBinary();
2014
+ if (binary) {
2015
+ try {
2016
+ const result = spawnSync2(binary, ["mcp", "remove", SERVER_NAME], {
2017
+ stdio: "pipe"
2018
+ });
2019
+ if (!result.error && result.status === 0) {
2020
+ return { success: true };
2021
+ }
2022
+ } catch {
2023
+ }
2024
+ }
2025
+ return this.removeServerViaConfigFile();
2026
+ }
2027
+ async removeServerViaConfigFile() {
2028
+ const configPath = this.getConfigFilePath();
2029
+ if (!fs29.existsSync(configPath)) {
2030
+ return { success: true };
2031
+ }
1827
2032
  try {
1828
- const result = spawnSync2("droid", ["mcp", "remove", SERVER_NAME], {
1829
- stdio: "pipe"
1830
- });
1831
- if (result.error || result.status !== 0) {
1832
- return { success: false, error: "Failed to remove server from Factory" };
2033
+ const content = fs29.readFileSync(configPath, "utf-8");
2034
+ const config = JSON.parse(content);
2035
+ if (config.mcpServers?.[SERVER_NAME]) {
2036
+ delete config.mcpServers[SERVER_NAME];
2037
+ fs29.writeFileSync(configPath, JSON.stringify(config, null, 2));
1833
2038
  }
1834
2039
  return { success: true };
1835
2040
  } catch (error) {
@@ -1841,11 +2046,43 @@ var FactoryMCPClient = class extends MCPClient {
1841
2046
 
1842
2047
  // src/steps/add-mcp-server-to-clients/clients/amp.ts
1843
2048
  import { execSync as execSync4, spawnSync as spawnSync3 } from "child_process";
2049
+ import * as fs30 from "fs";
2050
+ import * as os30 from "os";
2051
+ import * as path31 from "path";
1844
2052
  var AmpMCPClient = class extends MCPClient {
1845
2053
  name = "Amp";
2054
+ docsUrl = "https://ampcode.com/docs/customize/mcp";
2055
+ usesCLI = true;
2056
+ note = "Only supports remote mode, uses CLI configuration";
2057
+ ampBinaryPath = null;
2058
+ findAmpBinary() {
2059
+ if (this.ampBinaryPath) return this.ampBinaryPath;
2060
+ const possiblePaths = [
2061
+ path31.join(os30.homedir(), ".bun", "bin", "amp"),
2062
+ path31.join(os30.homedir(), ".npm", "bin", "amp"),
2063
+ path31.join(os30.homedir(), ".yarn", "bin", "amp"),
2064
+ "/usr/local/bin/amp",
2065
+ "/opt/homebrew/bin/amp"
2066
+ ];
2067
+ for (const p of possiblePaths) {
2068
+ if (fs30.existsSync(p)) {
2069
+ this.ampBinaryPath = p;
2070
+ return p;
2071
+ }
2072
+ }
2073
+ try {
2074
+ execSync4("command -v amp", { stdio: "pipe" });
2075
+ this.ampBinaryPath = "amp";
2076
+ return "amp";
2077
+ } catch {
2078
+ return null;
2079
+ }
2080
+ }
1846
2081
  async isClientSupported() {
2082
+ const binary = this.findAmpBinary();
2083
+ if (!binary) return false;
1847
2084
  try {
1848
- execSync4("amp --version", { stdio: "ignore" });
2085
+ execSync4(`${binary} --version`, { stdio: "ignore" });
1849
2086
  return true;
1850
2087
  } catch {
1851
2088
  return false;
@@ -1858,8 +2095,10 @@ var AmpMCPClient = class extends MCPClient {
1858
2095
  return "mcpServers";
1859
2096
  }
1860
2097
  async isServerInstalled() {
2098
+ const binary = this.findAmpBinary();
2099
+ if (!binary) return false;
1861
2100
  try {
1862
- const result = spawnSync3("amp", ["mcp", "list"], {
2101
+ const result = spawnSync3(binary, ["mcp", "list"], {
1863
2102
  encoding: "utf-8",
1864
2103
  stdio: "pipe"
1865
2104
  });
@@ -1869,6 +2108,8 @@ var AmpMCPClient = class extends MCPClient {
1869
2108
  }
1870
2109
  }
1871
2110
  async addServer(apiKey, _mode) {
2111
+ const binary = this.findAmpBinary();
2112
+ if (!binary) return { success: false, error: "Amp not found" };
1872
2113
  try {
1873
2114
  const args = [
1874
2115
  "mcp",
@@ -1878,8 +2119,8 @@ var AmpMCPClient = class extends MCPClient {
1878
2119
  `Authorization=Bearer ${apiKey}`,
1879
2120
  REMOTE_MCP_URL
1880
2121
  ];
1881
- debug(`Running: amp ${args.join(" ")}`);
1882
- const result = spawnSync3("amp", args, { stdio: "pipe" });
2122
+ debug(`Running: ${binary} ${args.join(" ")}`);
2123
+ const result = spawnSync3(binary, args, { stdio: "pipe" });
1883
2124
  if (result.error || result.status !== 0) {
1884
2125
  return { success: false, error: "Failed to add server to Amp" };
1885
2126
  }
@@ -1890,8 +2131,10 @@ var AmpMCPClient = class extends MCPClient {
1890
2131
  }
1891
2132
  }
1892
2133
  async removeServer() {
2134
+ const binary = this.findAmpBinary();
2135
+ if (!binary) return { success: false, error: "Amp not found" };
1893
2136
  try {
1894
- const result = spawnSync3("amp", ["mcp", "remove", SERVER_NAME], {
2137
+ const result = spawnSync3(binary, ["mcp", "remove", SERVER_NAME], {
1895
2138
  stdio: "pipe"
1896
2139
  });
1897
2140
  if (result.error || result.status !== 0) {
@@ -1909,20 +2152,22 @@ var AmpMCPClient = class extends MCPClient {
1909
2152
  };
1910
2153
 
1911
2154
  // src/steps/add-mcp-server-to-clients/clients/vibe.ts
1912
- import * as path29 from "path";
1913
- import * as os28 from "os";
1914
- import * as fs28 from "fs";
2155
+ import * as path32 from "path";
2156
+ import * as os31 from "os";
2157
+ import * as fs31 from "fs";
1915
2158
  var VibeMCPClient = class extends MCPClient {
1916
2159
  name = "Mistral Vibe CLI";
2160
+ docsUrl = "https://github.com/mistralai/mistral-vibe?tab=readme-ov-file#mcp-server-configuration";
2161
+ note = "Only supports remote mode, uses TOML config";
1917
2162
  async isClientSupported() {
1918
2163
  const configPath = await this.getConfigPath();
1919
- return fs28.existsSync(configPath);
2164
+ return fs31.existsSync(configPath);
1920
2165
  }
1921
2166
  async getConfigPath() {
1922
2167
  if (process.platform === "win32") {
1923
- return path29.join(process.env.USERPROFILE || "", ".vibe", "config.toml");
2168
+ return path32.join(process.env.USERPROFILE || "", ".vibe", "config.toml");
1924
2169
  }
1925
- return path29.join(os28.homedir(), ".vibe", "config.toml");
2170
+ return path32.join(os31.homedir(), ".vibe", "config.toml");
1926
2171
  }
1927
2172
  getServerPropertyName() {
1928
2173
  return "mcp_servers";
@@ -1930,10 +2175,10 @@ var VibeMCPClient = class extends MCPClient {
1930
2175
  async isServerInstalled() {
1931
2176
  try {
1932
2177
  const configPath = await this.getConfigPath();
1933
- if (!fs28.existsSync(configPath)) {
2178
+ if (!fs31.existsSync(configPath)) {
1934
2179
  return false;
1935
2180
  }
1936
- const content = await fs28.promises.readFile(configPath, "utf8");
2181
+ const content = await fs31.promises.readFile(configPath, "utf8");
1937
2182
  return content.includes('name = "nia"');
1938
2183
  } catch {
1939
2184
  return false;
@@ -1942,10 +2187,10 @@ var VibeMCPClient = class extends MCPClient {
1942
2187
  async addServer(apiKey, _mode) {
1943
2188
  try {
1944
2189
  const configPath = await this.getConfigPath();
1945
- if (!fs28.existsSync(configPath)) {
2190
+ if (!fs31.existsSync(configPath)) {
1946
2191
  return { success: false, error: "Vibe config not found" };
1947
2192
  }
1948
- let content = await fs28.promises.readFile(configPath, "utf8");
2193
+ let content = await fs31.promises.readFile(configPath, "utf8");
1949
2194
  if (content.includes('name = "nia"')) {
1950
2195
  debug("Nia already configured in Vibe");
1951
2196
  return { success: true };
@@ -1961,7 +2206,7 @@ url = "${REMOTE_MCP_URL}"
1961
2206
  Authorization = "Bearer ${apiKey}"
1962
2207
  `;
1963
2208
  content = content.trimEnd() + "\n" + niaConfig;
1964
- await fs28.promises.writeFile(configPath, content, "utf8");
2209
+ await fs31.promises.writeFile(configPath, content, "utf8");
1965
2210
  debug(`Wrote Vibe config to ${configPath}`);
1966
2211
  return { success: true };
1967
2212
  } catch (error) {
@@ -1972,13 +2217,13 @@ Authorization = "Bearer ${apiKey}"
1972
2217
  async removeServer() {
1973
2218
  try {
1974
2219
  const configPath = await this.getConfigPath();
1975
- if (!fs28.existsSync(configPath)) {
2220
+ if (!fs31.existsSync(configPath)) {
1976
2221
  return { success: false, error: "Vibe config not found" };
1977
2222
  }
1978
- let content = await fs28.promises.readFile(configPath, "utf8");
2223
+ let content = await fs31.promises.readFile(configPath, "utf8");
1979
2224
  const niaBlockRegex = /\[\[mcp_servers\]\]\s*name\s*=\s*"nia"[\s\S]*?(?=\[\[|\[(?!\[)|$)/g;
1980
2225
  content = content.replace(niaBlockRegex, "");
1981
- await fs28.promises.writeFile(configPath, content.trimEnd() + "\n", "utf8");
2226
+ await fs31.promises.writeFile(configPath, content.trimEnd() + "\n", "utf8");
1982
2227
  return { success: true };
1983
2228
  } catch (error) {
1984
2229
  const message = error instanceof Error ? error.message : String(error);
@@ -1991,6 +2236,44 @@ Authorization = "Bearer ${apiKey}"
1991
2236
  };
1992
2237
 
1993
2238
  // src/steps/add-mcp-server-to-clients/index.ts
2239
+ function getAllClients() {
2240
+ return [
2241
+ // Core / popular clients first
2242
+ new CursorMCPClient(),
2243
+ new ClaudeCodeMCPClient(),
2244
+ new ClaudeDesktopMCPClient(),
2245
+ new VSCodeMCPClient(),
2246
+ new WindsurfMCPClient(),
2247
+ new ClineMCPClient(),
2248
+ new ContinueMCPClient(),
2249
+ new ZedMCPClient(),
2250
+ new JetBrainsMCPClient(),
2251
+ // Additional clients
2252
+ new AntigravityMCPClient(),
2253
+ new TraeMCPClient(),
2254
+ new RooCodeMCPClient(),
2255
+ new KiloCodeMCPClient(),
2256
+ new GeminiCLIMCPClient(),
2257
+ new OpencodeMCPClient(),
2258
+ new QodoGenMCPClient(),
2259
+ new QwenCoderMCPClient(),
2260
+ new VisualStudioMCPClient(),
2261
+ new CrushMCPClient(),
2262
+ new CopilotCLIMCPClient(),
2263
+ new CopilotAgentMCPClient(),
2264
+ new AugmentMCPClient(),
2265
+ new KiroMCPClient(),
2266
+ new LMStudioMCPClient(),
2267
+ new BoltAIMCPClient(),
2268
+ new PerplexityMCPClient(),
2269
+ new WarpMCPClient(),
2270
+ new AmazonQMCPClient(),
2271
+ new CodexMCPClient(),
2272
+ new FactoryMCPClient(),
2273
+ new AmpMCPClient(),
2274
+ new VibeMCPClient()
2275
+ ];
2276
+ }
1994
2277
  async function getSupportedClients() {
1995
2278
  const allClients = [
1996
2279
  // Core / popular clients first
@@ -2044,17 +2327,20 @@ async function getSupportedClients() {
2044
2327
  }
2045
2328
  async function addMCPServerToClientsStep(options) {
2046
2329
  const { apiKey, mode, ci = false } = options;
2047
- const supportedClients = await getSupportedClients();
2048
- if (supportedClients.length === 0) {
2049
- clack_default.log.warn("No supported coding agents detected on this system.");
2050
- clack_default.log.info(
2051
- "Supported agents: Cursor, Claude Code, Claude Desktop, VS Code, Windsurf, Cline, Continue, Zed, JetBrains, Antigravity, Trae, Roo Code, Kilo Code, Gemini CLI, Opencode, Qodo Gen, Qwen Coder, Visual Studio, Crush, Copilot CLI, Copilot Agent, Augment, Kiro, LM Studio, BoltAI, Perplexity, Warp, Amazon Q, Codex, Factory, Amp, Vibe"
2052
- );
2053
- return [];
2330
+ const allClients = getAllClients();
2331
+ const supportedNames = /* @__PURE__ */ new Set();
2332
+ for (const client of allClients) {
2333
+ if (await client.isClientSupported()) {
2334
+ supportedNames.add(client.name);
2335
+ }
2054
2336
  }
2055
2337
  let selectedClients;
2056
2338
  if (ci) {
2057
- selectedClients = supportedClients;
2339
+ selectedClients = allClients.filter((c) => supportedNames.has(c.name));
2340
+ if (selectedClients.length === 0) {
2341
+ clack_default.log.warn("No coding agents detected on this system.");
2342
+ return [];
2343
+ }
2058
2344
  clack_default.log.info(
2059
2345
  `Auto-selecting ${selectedClients.length} client(s): ${selectedClients.map((c) => c.name).join(", ")}`
2060
2346
  );
@@ -2062,15 +2348,16 @@ async function addMCPServerToClientsStep(options) {
2062
2348
  const selectedNames = await abortIfCancelled(
2063
2349
  clack_default.multiselect({
2064
2350
  message: "Select which coding agents to install Nia to:",
2065
- options: supportedClients.map((client) => ({
2351
+ options: allClients.map((client) => ({
2066
2352
  value: client.name,
2067
- label: client.name
2353
+ label: client.name,
2354
+ hint: supportedNames.has(client.name) ? void 0 : "not detected - rerun wizard \u2192 Manual Setup"
2068
2355
  })),
2069
- initialValues: supportedClients.map((client) => client.name),
2070
- required: true
2356
+ initialValues: allClients.filter((c) => supportedNames.has(c.name)).map((c) => c.name),
2357
+ required: false
2071
2358
  })
2072
2359
  );
2073
- selectedClients = supportedClients.filter(
2360
+ selectedClients = allClients.filter(
2074
2361
  (client) => selectedNames.includes(client.name)
2075
2362
  );
2076
2363
  }
@@ -2387,11 +2674,118 @@ function dependenciesReady() {
2387
2674
  }
2388
2675
 
2389
2676
  // src/run.ts
2677
+ async function runManualMode() {
2678
+ const allClients = getAllClients();
2679
+ const selectedName = await abortIfCancelled(
2680
+ clack_default.select({
2681
+ message: "Select a coding agent to view its configuration:",
2682
+ options: allClients.map((client2) => ({
2683
+ value: client2.name,
2684
+ label: client2.name,
2685
+ hint: client2.note || void 0
2686
+ }))
2687
+ })
2688
+ );
2689
+ const client = allClients.find((c) => c.name === selectedName);
2690
+ if (!client) {
2691
+ clack_default.log.error("Client not found");
2692
+ return;
2693
+ }
2694
+ console.log("");
2695
+ clack_default.log.info(chalk3.bold(`Configuration for ${client.name}`));
2696
+ console.log("");
2697
+ if (client.docsUrl) {
2698
+ console.log(chalk3.cyan(" Documentation:"));
2699
+ console.log(` ${chalk3.underline(client.docsUrl)}`);
2700
+ console.log("");
2701
+ }
2702
+ if (client.note) {
2703
+ console.log(chalk3.yellow(" Note:"));
2704
+ console.log(` ${client.note}`);
2705
+ console.log("");
2706
+ }
2707
+ let configPath = "";
2708
+ try {
2709
+ configPath = await client.getConfigPath();
2710
+ console.log(chalk3.cyan(" Config file path:"));
2711
+ console.log(` ${configPath}`);
2712
+ console.log("");
2713
+ } catch {
2714
+ if (client.usesCLI) {
2715
+ console.log(chalk3.cyan(" Configuration method:"));
2716
+ console.log(` Uses CLI commands (no config file)`);
2717
+ console.log("");
2718
+ }
2719
+ }
2720
+ const exampleApiKey = "nk_YOUR_API_KEY_HERE";
2721
+ console.log(chalk3.cyan(" Local mode config (stdio):"));
2722
+ const localConfig = client.getServerConfig(exampleApiKey, "local");
2723
+ console.log(chalk3.dim(" Add this to your config file under the servers section:"));
2724
+ console.log("");
2725
+ console.log(chalk3.green(` "${client.name === "Cursor" ? "mcpServers" : client.getServerPropertyName()}": {`));
2726
+ console.log(chalk3.green(` "nia": ${JSON.stringify(localConfig, null, 6).split("\n").map((line, i) => i === 0 ? line : " " + line).join("\n")}`));
2727
+ console.log(chalk3.green(` }`));
2728
+ console.log("");
2729
+ console.log(chalk3.cyan(" Remote mode config (HTTP):"));
2730
+ const remoteConfig = client.getServerConfig(exampleApiKey, "remote");
2731
+ console.log(chalk3.dim(" Add this to your config file under the servers section:"));
2732
+ console.log("");
2733
+ console.log(chalk3.green(` "${client.name === "Cursor" ? "mcpServers" : client.getServerPropertyName()}": {`));
2734
+ console.log(chalk3.green(` "nia": ${JSON.stringify(remoteConfig, null, 6).split("\n").map((line, i) => i === 0 ? line : " " + line).join("\n")}`));
2735
+ console.log(chalk3.green(` }`));
2736
+ console.log("");
2737
+ if (client.usesCLI) {
2738
+ console.log(chalk3.cyan(" CLI commands:"));
2739
+ if (client.name === "Claude Code") {
2740
+ console.log(chalk3.dim(" Local mode:"));
2741
+ console.log(` claude mcp add nia -e "NIA_API_KEY=${exampleApiKey}" -e "NIA_API_URL=https://apigcp.trynia.ai/" -s user -- pipx run --no-cache nia-mcp-server`);
2742
+ console.log("");
2743
+ console.log(chalk3.dim(" Remote mode:"));
2744
+ console.log(` claude mcp add --transport http nia ${REMOTE_MCP_URL} --header "Authorization: Bearer ${exampleApiKey}" -s user`);
2745
+ } else if (client.name === "Codex CLI") {
2746
+ console.log(chalk3.dim(" Local mode:"));
2747
+ console.log(` codex mcp add nia --env "NIA_API_KEY=${exampleApiKey}" --env "NIA_API_URL=https://apigcp.trynia.ai/" -- pipx run --no-cache nia-mcp-server`);
2748
+ } else if (client.name === "Factory") {
2749
+ console.log(chalk3.dim(" Local mode:"));
2750
+ console.log(` droid mcp add nia "pipx run --no-cache nia-mcp-server" --env "NIA_API_KEY=${exampleApiKey}" --env "NIA_API_URL=https://apigcp.trynia.ai/"`);
2751
+ console.log("");
2752
+ console.log(chalk3.dim(" Remote mode:"));
2753
+ console.log(` droid mcp add nia ${REMOTE_MCP_URL} --type http --header "Authorization: Bearer ${exampleApiKey}"`);
2754
+ } else if (client.name === "Amp") {
2755
+ console.log(chalk3.dim(" Remote mode:"));
2756
+ console.log(` amp mcp add nia --header "Authorization=Bearer ${exampleApiKey}" ${REMOTE_MCP_URL}`);
2757
+ }
2758
+ console.log("");
2759
+ }
2760
+ clack_default.outro(chalk3.dim("Press Enter to exit"));
2761
+ }
2390
2762
  async function runWizard(options) {
2391
2763
  if (options.debug) {
2392
2764
  enableDebug();
2393
2765
  }
2394
2766
  printWelcome();
2767
+ const wizardMode = await abortIfCancelled(
2768
+ clack_default.select({
2769
+ message: "What would you like to do?",
2770
+ options: [
2771
+ {
2772
+ value: "install",
2773
+ label: "Install Nia MCP Server",
2774
+ hint: "Automatically configure your coding agents"
2775
+ },
2776
+ {
2777
+ value: "manual",
2778
+ label: "Manual Setup (View Config)",
2779
+ hint: "View configuration for manual setup or troubleshooting"
2780
+ }
2781
+ ],
2782
+ initialValue: "install"
2783
+ })
2784
+ );
2785
+ if (wizardMode === "manual") {
2786
+ await runManualMode();
2787
+ return;
2788
+ }
2395
2789
  const apiKey = await getApiKey(options.apiKey);
2396
2790
  let mode;
2397
2791
  if (options.local !== void 0) {
@@ -2535,4 +2929,4 @@ export {
2535
2929
  runMCPAdd,
2536
2930
  runMCPRemove
2537
2931
  };
2538
- //# sourceMappingURL=chunk-Y3PXW4WX.js.map
2932
+ //# sourceMappingURL=chunk-ZCECE3N2.js.map