aidex-mcp 1.5.1 → 1.5.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to AiDex will be documented in this file.
4
4
 
5
+ ## [1.5.2] - 2026-02-01
6
+
7
+ ### Fixed
8
+ - **`aidex setup` for Claude Code**: Uses `claude mcp add --scope user` instead of editing settings.json directly
9
+ - Claude Desktop, Cursor, Windsurf still use JSON config editing
10
+
5
11
  ## [1.5.1] - 2026-01-31
6
12
 
7
13
  ### Fixed
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AiDex Setup - Auto-register as MCP server in AI clients
3
3
  *
4
- * Supports: Claude Code, Claude Desktop, Cursor, Windsurf
4
+ * Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf
5
5
  */
6
6
  export declare function setupMcpClients(): void;
7
7
  export declare function unsetupMcpClients(): void;
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * AiDex Setup - Auto-register as MCP server in AI clients
3
3
  *
4
- * Supports: Claude Code, Claude Desktop, Cursor, Windsurf
4
+ * Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf
5
5
  */
6
6
  import { existsSync, readFileSync, writeFileSync } from 'fs';
7
7
  import { join } from 'path';
8
8
  import { homedir, platform } from 'os';
9
+ import { execSync } from 'child_process';
9
10
  // ============================================================
10
- // MCP Server Entry
11
+ // MCP Server Entry (for JSON-based clients)
11
12
  // ============================================================
12
13
  const AIDEX_MCP_ENTRY = {
13
14
  command: 'aidex',
@@ -20,16 +21,19 @@ function getClients() {
20
21
  const home = homedir();
21
22
  const plat = platform();
22
23
  const clients = [];
23
- // Claude Code
24
+ // Claude Code - uses its own CLI for MCP management
24
25
  clients.push({
26
+ type: 'cli',
25
27
  name: 'Claude Code',
26
- configPath: join(home, '.claude', 'settings.json'),
27
- detectDir: join(home, '.claude')
28
+ detectCmd: 'claude --version',
29
+ addCmd: ['claude', 'mcp', 'add', '--scope', 'user', 'aidex', '--', 'aidex'],
30
+ removeCmd: ['claude', 'mcp', 'remove', '--scope', 'user', 'aidex']
28
31
  });
29
- // Claude Desktop
32
+ // Claude Desktop - JSON config
30
33
  if (plat === 'win32') {
31
34
  const appData = process.env.APPDATA || join(home, 'AppData', 'Roaming');
32
35
  clients.push({
36
+ type: 'json',
33
37
  name: 'Claude Desktop',
34
38
  configPath: join(appData, 'Claude', 'claude_desktop_config.json'),
35
39
  detectDir: join(appData, 'Claude')
@@ -37,6 +41,7 @@ function getClients() {
37
41
  }
38
42
  else if (plat === 'darwin') {
39
43
  clients.push({
44
+ type: 'json',
40
45
  name: 'Claude Desktop',
41
46
  configPath: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
42
47
  detectDir: join(home, 'Library', 'Application Support', 'Claude')
@@ -44,19 +49,22 @@ function getClients() {
44
49
  }
45
50
  else {
46
51
  clients.push({
52
+ type: 'json',
47
53
  name: 'Claude Desktop',
48
54
  configPath: join(home, '.config', 'Claude', 'claude_desktop_config.json'),
49
55
  detectDir: join(home, '.config', 'Claude')
50
56
  });
51
57
  }
52
- // Cursor
58
+ // Cursor - JSON config
53
59
  clients.push({
60
+ type: 'json',
54
61
  name: 'Cursor',
55
62
  configPath: join(home, '.cursor', 'mcp.json'),
56
63
  detectDir: join(home, '.cursor')
57
64
  });
58
- // Windsurf
65
+ // Windsurf - JSON config
59
66
  clients.push({
67
+ type: 'json',
60
68
  name: 'Windsurf',
61
69
  configPath: join(home, '.codeium', 'windsurf', 'mcp_config.json'),
62
70
  detectDir: join(home, '.codeium', 'windsurf')
@@ -64,7 +72,29 @@ function getClients() {
64
72
  return clients;
65
73
  }
66
74
  // ============================================================
67
- // Config Read/Write
75
+ // CLI helpers
76
+ // ============================================================
77
+ function isCmdAvailable(cmd) {
78
+ try {
79
+ execSync(cmd, { stdio: 'pipe', timeout: 5000 });
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ function runCmd(args) {
87
+ try {
88
+ const output = execSync(args.join(' '), { stdio: 'pipe', timeout: 10000 }).toString().trim();
89
+ return { success: true, output };
90
+ }
91
+ catch (err) {
92
+ const msg = err instanceof Error ? err.message : String(err);
93
+ return { success: false, error: msg };
94
+ }
95
+ }
96
+ // ============================================================
97
+ // JSON Config Read/Write
68
98
  // ============================================================
69
99
  function readJsonConfig(filePath) {
70
100
  try {
@@ -92,83 +122,113 @@ function writeJsonConfig(filePath, data) {
92
122
  }
93
123
  }
94
124
  // ============================================================
95
- // Setup / Unsetup
125
+ // Setup
96
126
  // ============================================================
127
+ function setupCliClient(client) {
128
+ if (!isCmdAvailable(client.detectCmd)) {
129
+ return { status: ` - ${client.name} (not installed)`, registered: false };
130
+ }
131
+ const result = runCmd(client.addCmd);
132
+ if (result.success) {
133
+ return { status: ` ✓ ${client.name}`, registered: true };
134
+ }
135
+ else {
136
+ return { status: ` ✗ ${client.name} (${result.error})`, registered: false };
137
+ }
138
+ }
139
+ function setupJsonClient(client) {
140
+ if (!existsSync(client.detectDir)) {
141
+ return { status: ` - ${client.name} (not installed)`, registered: false };
142
+ }
143
+ let data;
144
+ if (existsSync(client.configPath)) {
145
+ const config = readJsonConfig(client.configPath);
146
+ if (!config.success || !config.data) {
147
+ return { status: ` ✗ ${client.name} (${config.error})`, registered: false };
148
+ }
149
+ data = config.data;
150
+ }
151
+ else {
152
+ data = {};
153
+ }
154
+ if (!data.mcpServers || typeof data.mcpServers !== 'object') {
155
+ data.mcpServers = {};
156
+ }
157
+ data.mcpServers.aidex = { ...AIDEX_MCP_ENTRY };
158
+ const writeResult = writeJsonConfig(client.configPath, data);
159
+ if (!writeResult.success) {
160
+ return { status: ` ✗ ${client.name} (${writeResult.error})`, registered: false };
161
+ }
162
+ return { status: ` ✓ ${client.name} (${client.configPath})`, registered: true };
163
+ }
97
164
  export function setupMcpClients() {
98
165
  const clients = getClients();
99
- const results = [];
100
166
  let registered = 0;
101
167
  console.log('\nAiDex MCP Server Registration');
102
168
  console.log('==============================\n');
103
169
  for (const client of clients) {
104
- // Check if client is installed (detect directory exists)
105
- if (!existsSync(client.detectDir)) {
106
- results.push({ client: client.name, status: 'skipped', configPath: client.configPath });
107
- console.log(` - ${client.name} (not installed)`);
108
- continue;
109
- }
110
- // Read existing config or start with empty object
111
- let data;
112
- if (existsSync(client.configPath)) {
113
- const config = readJsonConfig(client.configPath);
114
- if (!config.success || !config.data) {
115
- results.push({ client: client.name, status: 'error', configPath: client.configPath, message: config.error });
116
- console.log(` ✗ ${client.name} (${config.error})`);
117
- continue;
118
- }
119
- data = config.data;
120
- }
121
- else {
122
- data = {};
123
- }
124
- if (!data.mcpServers || typeof data.mcpServers !== 'object') {
125
- data.mcpServers = {};
126
- }
127
- data.mcpServers.aidex = { ...AIDEX_MCP_ENTRY };
128
- const writeResult = writeJsonConfig(client.configPath, data);
129
- if (!writeResult.success) {
130
- results.push({ client: client.name, status: 'error', configPath: client.configPath, message: writeResult.error });
131
- console.log(` ✗ ${client.name} (${writeResult.error})`);
132
- continue;
133
- }
134
- registered++;
135
- results.push({ client: client.name, status: 'registered', configPath: client.configPath });
136
- console.log(` ✓ ${client.name} (${client.configPath})`);
170
+ const result = client.type === 'cli'
171
+ ? setupCliClient(client)
172
+ : setupJsonClient(client);
173
+ console.log(result.status);
174
+ if (result.registered)
175
+ registered++;
137
176
  }
138
177
  console.log(`\nRegistered AiDex with ${registered} client(s).\n`);
139
178
  if (registered > 0) {
140
179
  console.log('Restart your AI client(s) to activate AiDex.\n');
141
180
  }
142
181
  }
182
+ // ============================================================
183
+ // Unsetup
184
+ // ============================================================
185
+ function unsetupCliClient(client) {
186
+ if (!isCmdAvailable(client.detectCmd)) {
187
+ return { status: ` - ${client.name} (not installed)`, removed: false };
188
+ }
189
+ const result = runCmd(client.removeCmd);
190
+ if (result.success) {
191
+ return { status: ` ✓ Removed from ${client.name}`, removed: true };
192
+ }
193
+ else {
194
+ return { status: ` - ${client.name} (not registered)`, removed: false };
195
+ }
196
+ }
197
+ function unsetupJsonClient(client) {
198
+ if (!existsSync(client.detectDir)) {
199
+ return { status: ` - ${client.name} (not installed)`, removed: false };
200
+ }
201
+ if (!existsSync(client.configPath)) {
202
+ return { status: ` - ${client.name} (not registered)`, removed: false };
203
+ }
204
+ const config = readJsonConfig(client.configPath);
205
+ if (!config.success || !config.data) {
206
+ return { status: ` ✗ ${client.name} (${config.error})`, removed: false };
207
+ }
208
+ const data = config.data;
209
+ const servers = data.mcpServers;
210
+ if (!servers || !servers.aidex) {
211
+ return { status: ` - ${client.name} (not registered)`, removed: false };
212
+ }
213
+ delete servers.aidex;
214
+ const writeResult = writeJsonConfig(client.configPath, data);
215
+ if (!writeResult.success) {
216
+ return { status: ` ✗ ${client.name} (${writeResult.error})`, removed: false };
217
+ }
218
+ return { status: ` ✓ Removed from ${client.name}`, removed: true };
219
+ }
143
220
  export function unsetupMcpClients() {
144
221
  const clients = getClients();
145
222
  let removed = 0;
146
223
  console.log('\nAiDex MCP Server Unregistration');
147
224
  console.log('================================\n');
148
225
  for (const client of clients) {
149
- if (!existsSync(client.configPath)) {
150
- console.log(` - ${client.name} (not installed)`);
151
- continue;
152
- }
153
- const config = readJsonConfig(client.configPath);
154
- if (!config.success || !config.data) {
155
- console.log(` ✗ ${client.name} (${config.error})`);
156
- continue;
157
- }
158
- const data = config.data;
159
- const servers = data.mcpServers;
160
- if (!servers || !servers.aidex) {
161
- console.log(` - ${client.name} (not registered)`);
162
- continue;
163
- }
164
- delete servers.aidex;
165
- const writeResult = writeJsonConfig(client.configPath, data);
166
- if (!writeResult.success) {
167
- console.log(` ✗ ${client.name} (${writeResult.error})`);
168
- continue;
169
- }
170
- removed++;
171
- console.log(` ✓ Removed from ${client.name}`);
226
+ const result = client.type === 'cli'
227
+ ? unsetupCliClient(client)
228
+ : unsetupJsonClient(client);
229
+ console.log(result.status);
230
+ if (result.removed)
231
+ removed++;
172
232
  }
173
233
  console.log(`\nUnregistered AiDex from ${removed} client(s).\n`);
174
234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidex-mcp",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "MCP Server providing persistent code indexing for Claude Code",
5
5
  "main": "build/index.js",
6
6
  "bin": {