@clix-so/clix-agent-skills 0.1.6 → 0.1.7

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/README.md CHANGED
@@ -16,9 +16,9 @@ you can install skills in different ways.
16
16
 
17
17
  ### Universal CLI (Recommended)
18
18
 
19
- For **Cursor**, **VS Code**, **Claude Desktop**, **OpenCode**, **Goose**,
20
- **GitHub Copilot**, **Amp**, and **Letta**, use our CLI tool to install skills
21
- and configure the Clix MCP Server automatically:
19
+ For **Cursor**, **VS Code**, **Claude Code**, **OpenCode**, **Goose**, **GitHub
20
+ Copilot**, **Amp**, and **Letta**, use our tool to install skills and configure
21
+ the Clix MCP Server automatically:
22
22
 
23
23
  #### Installation Modes
24
24
 
@@ -66,16 +66,16 @@ npx @clix-so/clix-agent-skills@latest install --all --client cursor --global
66
66
 
67
67
  **Supported Clients:**
68
68
 
69
- | Client | Flag | Default Path |
70
- | :------------- | :------------------ | :----------------- |
71
- | Amp | `--client amp` | `.amp/skills/` |
72
- | Claude | `--client claude` | `.claude/skills/` |
73
- | Codex | `--client codex` | `.codex/skills/` |
74
- | Cursor | `--client cursor` | `.cursor/skills/` |
75
- | GitHub Copilot | `--client github` | `.github/skills/` |
76
- | Goose | `--client goose` | `.goose/skills/` |
77
- | Letta | `--client letta` | `.skills/` |
78
- | OpenCode | `--client opencode` | `.opencode/skill/` |
69
+ | Client | Flag | Default Path |
70
+ | :------------- | :----------------------------------- | :----------------- |
71
+ | Amp | `--client amp` | `.amp/skills/` |
72
+ | Claude Code | `--client claude` (or `claude-code`) | `.claude/skills/` |
73
+ | Codex | `--client codex` | `.codex/skills/` |
74
+ | Cursor | `--client cursor` | `.cursor/skills/` |
75
+ | GitHub Copilot | `--client github` | `.github/skills/` |
76
+ | Goose | `--client goose` | `.goose/skills/` |
77
+ | Letta | `--client letta` | `.skills/` |
78
+ | OpenCode | `--client opencode` | `.opencode/skill/` |
79
79
 
80
80
  ### Claude Code
81
81
 
package/dist/bin/cli.js CHANGED
@@ -25,7 +25,7 @@ program
25
25
  program
26
26
  .command("install [skill]")
27
27
  .description("Install agent skill(s)")
28
- .option("-c, --client <client>", "Target AI client (cursor, claude, vscode, amp, kiro, amazonq, codex, opencode, manual)")
28
+ .option("-c, --client <client>", "Target AI client (cursor, claude|claude-code, vscode, amp, kiro, amazonq, codex, opencode, manual)")
29
29
  .option("-p, --path <path>", "Custom installation path (default: .clix/skills)")
30
30
  .option("-a, --all", "Install all available skills")
31
31
  .option("-g, --global", "Install globally to system root (default: installs to repo root)")
@@ -64,6 +64,8 @@ async function installSkill(skillName, options) {
64
64
  else if (options.client) {
65
65
  switch (options.client.toLowerCase()) {
66
66
  case "claude":
67
+ case "claude-code":
68
+ // Claude Code uses the .claude/ folder convention, but MCP is configured via `claude mcp ...`
67
69
  relativeDest = ".claude/skills";
68
70
  break;
69
71
  case "cursor":
@@ -43,6 +43,7 @@ const os_1 = __importDefault(require("os"));
43
43
  const chalk_1 = __importDefault(require("chalk"));
44
44
  const inquirer_1 = __importDefault(require("inquirer"));
45
45
  const TOML = __importStar(require("@iarna/toml"));
46
+ const child_process_1 = require("child_process");
46
47
  // ============================================================================
47
48
  // Constants
48
49
  // ============================================================================
@@ -50,6 +51,17 @@ const CLIX_MCP_SERVER_ENTRY = {
50
51
  command: "npx",
51
52
  args: ["-y", "@clix-so/clix-mcp-server@latest"],
52
53
  };
54
+ const CLAUDE_CODE_MCP_ADD_ARGS = [
55
+ "mcp",
56
+ "add",
57
+ "--transport",
58
+ "stdio",
59
+ "clix-mcp-server",
60
+ "--",
61
+ "npx",
62
+ "-y",
63
+ "@clix-so/clix-mcp-server@latest",
64
+ ];
53
65
  // ============================================================================
54
66
  // Helper Functions
55
67
  // ============================================================================
@@ -62,6 +74,47 @@ function getErrorMessage(error) {
62
74
  }
63
75
  return String(error);
64
76
  }
77
+ function hasClixServerInClaudeMcpListOutput(output) {
78
+ return output.toLowerCase().includes("clix-mcp-server");
79
+ }
80
+ /**
81
+ * Configure MCP for Claude Code using the `claude` CLI (no config file editing).
82
+ */
83
+ async function configureClaudeCode() {
84
+ console.log(chalk_1.default.blue("Checking MCP config via Claude Code CLI (`claude mcp`)..."));
85
+ // Verify Claude CLI exists and supports MCP.
86
+ const helpRes = (0, child_process_1.spawnSync)("claude", ["mcp", "--help"], { encoding: "utf8" });
87
+ if (helpRes.error) {
88
+ console.log(chalk_1.default.yellow(`Could not run Claude CLI (${getErrorMessage(helpRes.error)}). Skipping MCP configuration.`));
89
+ return;
90
+ }
91
+ if (helpRes.status !== 0) {
92
+ console.log(chalk_1.default.yellow("Claude CLI does not appear to support `claude mcp`. Skipping MCP configuration."));
93
+ return;
94
+ }
95
+ // Best-effort idempotency: if list works and already contains the server, skip.
96
+ const listRes = (0, child_process_1.spawnSync)("claude", ["mcp", "list"], { encoding: "utf8" });
97
+ const listOut = `${listRes.stdout ?? ""}\n${listRes.stderr ?? ""}`;
98
+ if (!listRes.error && listRes.status === 0 && hasClixServerInClaudeMcpListOutput(listOut)) {
99
+ console.log(chalk_1.default.green("✔ Clix MCP Server is already configured."));
100
+ return;
101
+ }
102
+ const addRes = (0, child_process_1.spawnSync)("claude", CLAUDE_CODE_MCP_ADD_ARGS, { encoding: "utf8" });
103
+ if (addRes.error || addRes.status !== 0) {
104
+ const out = `${addRes.stdout ?? ""}\n${addRes.stderr ?? ""}`.trim();
105
+ console.log(chalk_1.default.yellow(`Failed to configure MCP via Claude Code CLI. ${out ? `Output:\n${out}` : "No output captured."}`));
106
+ return;
107
+ }
108
+ console.log(chalk_1.default.green("✔ Added Clix MCP Server to configuration. Please restart claude."));
109
+ }
110
+ function isClaudeCodeClient(client) {
111
+ const c = client.toLowerCase();
112
+ return (c === "claude" ||
113
+ c === "claude_code" ||
114
+ c === "claude-code" ||
115
+ c === "claudecode" ||
116
+ c === "claude code");
117
+ }
65
118
  /**
66
119
  * Gets the MCP servers object from JSON config based on client type
67
120
  */
@@ -106,19 +159,6 @@ function getClientConfig(client) {
106
159
  format: "json",
107
160
  };
108
161
  }
109
- case "claude": {
110
- let configPath = null;
111
- if (process.platform === "darwin") {
112
- configPath = path_1.default.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
113
- }
114
- else if (process.platform === "win32") {
115
- configPath = path_1.default.join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json");
116
- }
117
- else if (process.platform === "linux") {
118
- configPath = path_1.default.join(home, ".config", "Claude", "claude_desktop_config.json");
119
- }
120
- return configPath ? { path: configPath, configKey: "mcpServers", format: "json" } : null;
121
- }
122
162
  case "vscode":
123
163
  return {
124
164
  path: path_1.default.join(home, ".vscode", "mcp.json"),
@@ -306,7 +346,7 @@ async function configureMCP(client) {
306
346
  message: "Which AI client are you using?",
307
347
  choices: [
308
348
  { name: "Cursor", value: "cursor" },
309
- { name: "Claude Desktop", value: "claude" },
349
+ { name: "Claude Code", value: "claude" },
310
350
  { name: "VS Code", value: "vscode" },
311
351
  { name: "Amp", value: "amp" },
312
352
  { name: "Kiro", value: "kiro" },
@@ -322,10 +362,19 @@ async function configureMCP(client) {
322
362
  ]);
323
363
  targetClient = answers.client;
324
364
  }
365
+ if (!targetClient) {
366
+ console.log(chalk_1.default.yellow("No client selected. Skipping MCP configuration."));
367
+ return;
368
+ }
325
369
  if (targetClient === "manual") {
326
370
  console.log(chalk_1.default.blue("Skipping automatic MCP configuration."));
327
371
  return;
328
372
  }
373
+ // Claude Code is configured via the `claude` CLI (no file editing).
374
+ if (targetClient && isClaudeCodeClient(targetClient)) {
375
+ await configureClaudeCode();
376
+ return;
377
+ }
329
378
  // Handle OpenCode separately (different JSON structure)
330
379
  if (targetClient === "opencode") {
331
380
  await configureOpenCode();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clix-so/clix-agent-skills",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "An open collection of agent skills for Clix.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -97,7 +97,7 @@ bash <skill-dir>/scripts/validate-event-plan.sh event-plan.json
97
97
  The skill directory is typically:
98
98
 
99
99
  - `.cursor/skills/event-tracking/` (Cursor)
100
- - `.claude/skills/event-tracking/` (Claude Desktop)
100
+ - `.claude/skills/event-tracking/` (Claude Code)
101
101
  - `.vscode/skills/event-tracking/` (VS Code/Amp)
102
102
  - Or check where this skill was installed
103
103
 
@@ -38,11 +38,12 @@ latest verified SDK source code.
38
38
  1. **Ask the user**: "The Clix MCP Server is not detected. It provides the
39
39
  latest official SDK code. Would you like me to install it now?"
40
40
  2. **If User says YES**:
41
- - Run: `bash scripts/install-mcp.sh`
41
+ - Run: `bash scripts/install-mcp.sh --client <your-client>`
42
42
  - The script will:
43
43
  - Verify the package is available
44
- - Auto-detect the MCP client (OpenCode, Amp, Codex, Cursor, Claude
45
- Desktop, VS Code, etc.)
44
+ - Configure the MCP server for the specified client
45
+ - (If you omit `--client` and multiple clients are installed, the script
46
+ will stop and ask you to choose.)
46
47
  - Automatically configure the MCP server in the appropriate config file
47
48
  - Provide clear instructions for restart
48
49
  - Instruct user to restart their agent/IDE to load the new server.
@@ -263,26 +263,6 @@ claude mcp add --transport stdio clix-mcp-server -- npx -y @clix-so/clix-mcp-ser
263
263
  }
264
264
  ```
265
265
 
266
- #### Claude Desktop App
267
-
268
- **Setup**
269
-
270
- 1. Open config
271
- (`~/Library/Application Support/Claude/claude_desktop_config.json` or
272
- `%APPDATA%\\Claude\\claude_desktop_config.json`).
273
- 2. Add and restart:
274
-
275
- ```json
276
- {
277
- "mcpServers": {
278
- "clix-mcp-server": {
279
- "command": "npx",
280
- "args": ["-y", "@clix-so/clix-mcp-server@latest"]
281
- }
282
- }
283
- }
284
- ```
285
-
286
266
  #### Amp
287
267
 
288
268
  **Setup**
@@ -18,6 +18,64 @@ log() {
18
18
  printf "%b\n" "$1"
19
19
  }
20
20
 
21
+ log_err() {
22
+ printf "%b\n" "$1" >&2
23
+ }
24
+
25
+ usage() {
26
+ cat <<'EOF'
27
+ Clix MCP Server Installer
28
+
29
+ Usage:
30
+ bash scripts/install-mcp.sh [--client <client>]
31
+
32
+ Options:
33
+ --client <client> Explicitly select the MCP client to configure.
34
+ Supported: claude, claude-code, opencode, amp, codex, cursor, vscode
35
+ --help Show this help.
36
+
37
+ Environment:
38
+ CLIX_MCP_CLIENT Same as --client (takes precedence).
39
+
40
+ Notes:
41
+ If multiple MCP clients are detected on this machine, you MUST pass --client
42
+ (or set CLIX_MCP_CLIENT). A shell script cannot reliably know "which client is
43
+ currently running" on a machine with multiple clients installed.
44
+ EOF
45
+ }
46
+
47
+ # Parse args/env
48
+ CLIENT_OVERRIDE="${CLIX_MCP_CLIENT:-}"
49
+ while [ $# -gt 0 ]; do
50
+ case "$1" in
51
+ --help|-h)
52
+ usage
53
+ exit 0
54
+ ;;
55
+ --client)
56
+ shift
57
+ CLIENT_OVERRIDE="${1:-}"
58
+ ;;
59
+ --client=*)
60
+ CLIENT_OVERRIDE="${1#*=}"
61
+ ;;
62
+ *)
63
+ log_err "${YELLOW}⚠️ Unknown argument: $1${RESET}"
64
+ usage
65
+ exit 2
66
+ ;;
67
+ esac
68
+ shift || true
69
+ done
70
+
71
+ validate_client() {
72
+ case "${1:-}" in
73
+ claude|claude-code|opencode|amp|codex|cursor|vscode) return 0 ;;
74
+ "") return 1 ;;
75
+ *) return 1 ;;
76
+ esac
77
+ }
78
+
21
79
  # Detect platform
22
80
  detect_platform() {
23
81
  case "$(uname -s)" in
@@ -35,6 +93,10 @@ get_config_path() {
35
93
  local platform=$(detect_platform)
36
94
 
37
95
  case "$client" in
96
+ claude-code)
97
+ # Claude Code CLI manages MCP via `claude mcp ...` commands (no direct config file here)
98
+ echo ""
99
+ ;;
38
100
  codex)
39
101
  echo "${home}/.codex/config.toml"
40
102
  ;;
@@ -47,13 +109,8 @@ get_config_path() {
47
109
  fi
48
110
  ;;
49
111
  claude)
50
- if [ "$platform" = "darwin" ]; then
51
- echo "${home}/Library/Application Support/Claude/claude_desktop_config.json"
52
- elif [ "$platform" = "win32" ]; then
53
- echo "${APPDATA:-}/Claude/claude_desktop_config.json"
54
- else
55
- echo "${home}/.config/claude/claude_desktop_config.json"
56
- fi
112
+ # Alias for Claude Code
113
+ echo ""
57
114
  ;;
58
115
  vscode)
59
116
  echo "${home}/.vscode/mcp.json"
@@ -88,6 +145,25 @@ get_config_path() {
88
145
  esac
89
146
  }
90
147
 
148
+ # Configure MCP for Claude Code CLI
149
+ configure_claude_code() {
150
+ if ! command -v claude &> /dev/null; then
151
+ log "${RED}❌ Claude CLI not found on PATH.${RESET}"
152
+ exit 1
153
+ fi
154
+
155
+ # Best-effort: avoid failing if already configured.
156
+ # If list isn't supported, we'll just attempt add.
157
+ if claude mcp list 2>/dev/null | grep -q "clix-mcp-server"; then
158
+ log "${GREEN}✔ Clix MCP Server already configured in Claude Code${RESET}"
159
+ return 0
160
+ fi
161
+
162
+ # Configure via CLI (non-interactive)
163
+ claude mcp add --transport stdio clix-mcp-server -- npx -y @clix-so/clix-mcp-server@latest
164
+ log "${GREEN}✔ Configured Clix MCP Server in Claude Code${RESET}"
165
+ }
166
+
91
167
  # Configure MCP for Codex (TOML format)
92
168
  configure_codex() {
93
169
  local config_path="$1"
@@ -158,7 +234,7 @@ configure_amp() {
158
234
  return 0
159
235
  fi
160
236
 
161
- # Use node to safely update JSON
237
+ # Use node to safely update JSON/JSONC (VS Code settings often allow comments)
162
238
  if command -v node &> /dev/null; then
163
239
  node <<EOF
164
240
  const fs = require('fs');
@@ -166,7 +242,61 @@ const path = '$config_path';
166
242
  let config = {};
167
243
  try {
168
244
  const content = fs.readFileSync(path, 'utf8');
169
- config = JSON.parse(content);
245
+ const stripJsonc = (input) => {
246
+ // Strips // and /* */ comments, but preserves anything inside strings.
247
+ let out = '';
248
+ let inStr = false;
249
+ let esc = false;
250
+ let inLine = false;
251
+ let inBlock = false;
252
+ for (let i = 0; i < input.length; i++) {
253
+ const c = input[i];
254
+ const n = input[i + 1];
255
+ if (inLine) {
256
+ if (c === '\n') {
257
+ inLine = false;
258
+ out += c;
259
+ }
260
+ continue;
261
+ }
262
+ if (inBlock) {
263
+ if (c === '*' && n === '/') {
264
+ inBlock = false;
265
+ i++;
266
+ }
267
+ continue;
268
+ }
269
+ if (inStr) {
270
+ out += c;
271
+ if (esc) {
272
+ esc = false;
273
+ } else if (c === '\\\\') {
274
+ esc = true;
275
+ } else if (c === '"') {
276
+ inStr = false;
277
+ }
278
+ continue;
279
+ }
280
+ if (c === '"') {
281
+ inStr = true;
282
+ out += c;
283
+ continue;
284
+ }
285
+ if (c === '/' && n === '/') {
286
+ inLine = true;
287
+ i++;
288
+ continue;
289
+ }
290
+ if (c === '/' && n === '*') {
291
+ inBlock = true;
292
+ i++;
293
+ continue;
294
+ }
295
+ out += c;
296
+ }
297
+ return out;
298
+ };
299
+ config = JSON.parse(stripJsonc(content));
170
300
  } catch (e) {
171
301
  config = {};
172
302
  }
@@ -218,17 +348,72 @@ EOF
218
348
  const fs = require('fs');
219
349
  const path = '$config_path';
220
350
  let content = fs.readFileSync(path, 'utf8');
221
- // Remove comments for JSONC parsing (simple approach)
222
- let jsonContent = content.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
223
- let config = JSON.parse(jsonContent);
351
+ const stripJsonc = (input) => {
352
+ // Strips // and /* */ comments, but preserves anything inside strings.
353
+ let out = '';
354
+ let inStr = false;
355
+ let esc = false;
356
+ let inLine = false;
357
+ let inBlock = false;
358
+ for (let i = 0; i < input.length; i++) {
359
+ const c = input[i];
360
+ const n = input[i + 1];
361
+ if (inLine) {
362
+ if (c === '\n') {
363
+ inLine = false;
364
+ out += c;
365
+ }
366
+ continue;
367
+ }
368
+ if (inBlock) {
369
+ if (c === '*' && n === '/') {
370
+ inBlock = false;
371
+ i++;
372
+ }
373
+ continue;
374
+ }
375
+ if (inStr) {
376
+ out += c;
377
+ if (esc) {
378
+ esc = false;
379
+ } else if (c === '\\\\') {
380
+ esc = true;
381
+ } else if (c === '"') {
382
+ inStr = false;
383
+ }
384
+ continue;
385
+ }
386
+ if (c === '"') {
387
+ inStr = true;
388
+ out += c;
389
+ continue;
390
+ }
391
+ if (c === '/' && n === '/') {
392
+ inLine = true;
393
+ i++;
394
+ continue;
395
+ }
396
+ if (c === '/' && n === '*') {
397
+ inBlock = true;
398
+ i++;
399
+ continue;
400
+ }
401
+ out += c;
402
+ }
403
+ return out;
404
+ };
405
+ let config = {};
406
+ try {
407
+ config = JSON.parse(stripJsonc(content));
408
+ } catch (e) {
409
+ config = {};
410
+ }
224
411
  if (!config.mcp) config.mcp = {};
225
412
  config.mcp['clix-mcp-server'] = {
226
413
  type: 'local',
227
414
  command: ['npx', '-y', '@clix-so/clix-mcp-server@latest'],
228
415
  enabled: true
229
416
  };
230
- // Write back as JSONC if original was .jsonc, otherwise JSON
231
- const isJsonc = path.endsWith('.jsonc');
232
417
  fs.writeFileSync(path, JSON.stringify(config, null, 2) + '\n');
233
418
  EOF
234
419
  log "${GREEN}✔ Configured Clix MCP Server in OpenCode${RESET}"
@@ -291,48 +476,93 @@ EOF
291
476
  fi
292
477
  }
293
478
 
294
- # Auto-detect client
295
- detect_client() {
296
- # Check for OpenCode (check for opencode.json/jsonc or opencode command)
479
+ # Detect all matching clients (heuristics). Output one per line.
480
+ detect_clients() {
481
+ # Claude Code CLI (supports `claude mcp ...`)
482
+ if command -v claude &> /dev/null && claude mcp --help &> /dev/null; then
483
+ echo "claude"
484
+ fi
485
+
486
+ # OpenCode (project config files or opencode command)
297
487
  if [ -f "opencode.json" ] || [ -f "opencode.jsonc" ] || command -v opencode &> /dev/null; then
298
488
  echo "opencode"
299
- return
300
489
  fi
301
490
 
302
- # Check for Amp (check for amp.mcpServers in settings.json or amp command)
491
+ # Amp (amp command or amp.mcpServers present)
303
492
  if command -v amp &> /dev/null || \
304
493
  grep -q "amp.mcpServers" ".vscode/settings.json" 2>/dev/null || \
305
494
  grep -q "amp.mcpServers" "${HOME}/.vscode/settings.json" 2>/dev/null; then
306
495
  echo "amp"
307
- return
308
496
  fi
309
497
 
310
- # Check for Codex
498
+ # Codex
311
499
  if [ -f "${HOME}/.codex/config.toml" ] || command -v codex &> /dev/null; then
312
500
  echo "codex"
313
- return
314
501
  fi
315
502
 
316
- # Check for Cursor
503
+ # Cursor
317
504
  if [ -f "${HOME}/.cursor/mcp.json" ] || [ -f ".cursor/mcp.json" ]; then
318
505
  echo "cursor"
506
+ fi
507
+
508
+ # VS Code
509
+ if [ -f "${HOME}/.vscode/mcp.json" ]; then
510
+ echo "vscode"
511
+ fi
512
+ }
513
+
514
+ choose_client() {
515
+ if [ -n "${CLIENT_OVERRIDE:-}" ]; then
516
+ if ! validate_client "$CLIENT_OVERRIDE"; then
517
+ log_err "${RED}❌ Invalid --client / CLIX_MCP_CLIENT: ${CLIENT_OVERRIDE}${RESET}"
518
+ usage
519
+ exit 2
520
+ fi
521
+ if [ "$CLIENT_OVERRIDE" = "claude-code" ]; then
522
+ echo "claude"
523
+ return
524
+ fi
525
+ echo "$CLIENT_OVERRIDE"
319
526
  return
320
527
  fi
321
528
 
322
- # Check for Claude Desktop
323
- if [ -f "${HOME}/Library/Application Support/Claude/claude_desktop_config.json" ] 2>/dev/null || \
324
- [ -f "${APPDATA:-}/Claude/claude_desktop_config.json" ] 2>/dev/null; then
325
- echo "claude"
529
+ local detected
530
+ detected="$(detect_clients | awk 'NF' | sort -u)"
531
+ local count
532
+ count="$(printf "%s\n" "$detected" | awk 'NF' | wc -l | tr -d ' ')"
533
+
534
+ if [ "${count:-0}" -eq 0 ]; then
535
+ echo "unknown"
326
536
  return
327
537
  fi
328
538
 
329
- # Check for VS Code
330
- if [ -f "${HOME}/.vscode/mcp.json" ]; then
331
- echo "vscode"
539
+ if [ "${count:-0}" -eq 1 ]; then
540
+ printf "%s\n" "$detected"
332
541
  return
333
542
  fi
334
543
 
335
- echo "unknown"
544
+ # Multiple detected: we can't know which one is "currently running".
545
+ log_err "${YELLOW}⚠️ Multiple MCP clients detected on this machine:${RESET}"
546
+ printf "%s\n" "$detected" | sed 's/^/ - /' >&2
547
+
548
+ if [ -t 0 ]; then
549
+ log_err "${BLUE}Select which client to configure:${RESET}"
550
+ local options=()
551
+ while IFS= read -r line; do options+=("$line"); done <<<"$detected"
552
+ options+=("cancel")
553
+ select opt in "${options[@]}"; do
554
+ if [ "$opt" = "cancel" ] || [ -z "${opt:-}" ]; then
555
+ log_err "${YELLOW}Cancelled.${RESET}"
556
+ exit 2
557
+ fi
558
+ echo "$opt"
559
+ return
560
+ done
561
+ fi
562
+
563
+ log_err "${RED}❌ Ambiguous MCP client selection in non-interactive mode.${RESET}"
564
+ log_err "${YELLOW}Please re-run with: bash scripts/install-mcp.sh --client <client>${RESET}"
565
+ exit 2
336
566
  }
337
567
 
338
568
  log "${BLUE}📦 Installing Clix MCP Server...${RESET}"
@@ -355,13 +585,18 @@ fi
355
585
 
356
586
  # Auto-detect and configure
357
587
  log "${BLUE}🔍 Detecting MCP client...${RESET}"
358
- detected_client=$(detect_client)
588
+ detected_client=$(choose_client)
359
589
 
360
590
  if [ "$detected_client" != "unknown" ]; then
361
591
  log "${GREEN}Detected: $detected_client${RESET}"
362
592
  config_path=$(get_config_path "$detected_client")
363
593
 
364
- if [ -n "$config_path" ]; then
594
+ if [ "$detected_client" = "claude" ]; then
595
+ log "${BLUE}Configuring MCP server for Claude Code...${RESET}"
596
+ configure_claude_code
597
+ log "${GREEN}✅ Successfully configured Clix MCP Server!${RESET}"
598
+ log "${YELLOW}⚠️ IMPORTANT: Please RESTART Claude Code for the changes to take effect.${RESET}"
599
+ elif [ -n "$config_path" ]; then
365
600
  log "${BLUE}Configuring MCP server for $detected_client...${RESET}"
366
601
 
367
602
  if [ "$detected_client" = "codex" ]; then
@@ -387,7 +622,7 @@ else
387
622
  log "${BLUE} - Amp: Add to .vscode/settings.json or ~/.vscode/settings.json${RESET}"
388
623
  log "${BLUE} - Codex: Add to ~/.codex/config.toml${RESET}"
389
624
  log "${BLUE} - Cursor: Add to .cursor/mcp.json or ~/.cursor/mcp.json${RESET}"
390
- log "${BLUE} - Claude Desktop: Add to config file${RESET}"
625
+ log "${BLUE} - Claude Code: Run: claude mcp add --transport stdio clix-mcp-server -- npx -y @clix-so/clix-mcp-server@latest${RESET}"
391
626
  log "${BLUE}See references/mcp-integration.md for detailed instructions.${RESET}"
392
627
  fi
393
628