aidex-mcp 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to AiDex will be documented in this file.
4
4
 
5
+ ## [1.7.0] - 2026-02-01
6
+
7
+ ### Added
8
+ - **Gemini CLI support**: `aidex setup` now detects and registers AiDex with Gemini CLI (`~/.gemini/settings.json`)
9
+ - **VS Code Copilot support**: `aidex setup` now detects and registers AiDex with VS Code (`mcp.json` with `"servers"` key and `"type": "stdio"`)
10
+
11
+ ### Changed
12
+ - JSON client config is now flexible: supports custom server key (`serversKey`) and extra fields (`extraFields`) per client
13
+ - Updated README with Gemini CLI and VS Code Copilot config examples
14
+
5
15
  ## [1.6.1] - 2026-02-01
6
16
 
7
17
  ### Fixed
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  **Stop wasting 80% of your AI's context window on code searches.**
9
9
 
10
- AiDex is an MCP server that gives AI coding assistants instant access to your entire codebase through a persistent, pre-built index. Works with any MCP-compatible AI assistant: Claude Code, Cursor, Windsurf, Continue.dev, and more.
10
+ AiDex is an MCP server that gives AI coding assistants instant access to your entire codebase through a persistent, pre-built index. Works with any MCP-compatible AI assistant: Claude Code, Claude Desktop, Cursor, Windsurf, Gemini CLI, VS Code Copilot, and more.
11
11
 
12
12
  <!-- TODO: Add demo GIF showing aidex_query vs grep -->
13
13
 
@@ -113,7 +113,7 @@ npm install -g aidex-mcp
113
113
  aidex setup
114
114
  ```
115
115
 
116
- `aidex setup` automatically detects and registers AiDex with your installed AI clients (Claude Code, Claude Desktop, Cursor, Windsurf). To unregister: `aidex unsetup`.
116
+ `aidex setup` automatically detects and registers AiDex with your installed AI clients (Claude Code, Claude Desktop, Cursor, Windsurf, Gemini CLI, VS Code Copilot). To unregister: `aidex unsetup`.
117
117
 
118
118
  ### 2. Or register manually with your AI assistant
119
119
 
@@ -145,6 +145,29 @@ aidex setup
145
145
 
146
146
  > **Important:** The server name in your config determines the MCP tool prefix. Use `"aidex"` as shown above — this gives you tool names like `aidex_query`, `aidex_signature`, etc. Using a different name (e.g., `"codegraph"`) would change the prefix accordingly.
147
147
 
148
+ **For Gemini CLI** (`~/.gemini/settings.json`):
149
+ ```json
150
+ {
151
+ "mcpServers": {
152
+ "aidex": {
153
+ "command": "aidex"
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ **For VS Code Copilot** (run `MCP: Open User Configuration` in Command Palette):
160
+ ```json
161
+ {
162
+ "servers": {
163
+ "aidex": {
164
+ "type": "stdio",
165
+ "command": "aidex"
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
148
171
  **For other MCP clients**: See your client's documentation for MCP server configuration.
149
172
 
150
173
  ### 3. Make your AI actually use it
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AiDex Setup - Auto-register as MCP server in AI clients
3
3
  *
4
- * Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf
4
+ * Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf, Gemini CLI, VS Code Copilot
5
5
  * Also installs CLAUDE.md instructions for Claude Code/Desktop.
6
6
  */
7
7
  export declare function setupMcpClients(): void;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AiDex Setup - Auto-register as MCP server in AI clients
3
3
  *
4
- * Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf
4
+ * Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf, Gemini CLI, VS Code Copilot
5
5
  * Also installs CLAUDE.md instructions for Claude Code/Desktop.
6
6
  */
7
7
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
@@ -131,6 +131,45 @@ function getClients() {
131
131
  configPath: join(home, '.codeium', 'windsurf', 'mcp_config.json'),
132
132
  detectDir: join(home, '.codeium', 'windsurf')
133
133
  });
134
+ // Gemini CLI - JSON config (always uses ~/.gemini/ on all platforms)
135
+ clients.push({
136
+ type: 'json',
137
+ name: 'Gemini CLI',
138
+ configPath: join(home, '.gemini', 'settings.json'),
139
+ detectDir: join(home, '.gemini')
140
+ });
141
+ // VS Code Copilot - JSON config (uses "servers" key + "type": "stdio")
142
+ if (plat === 'win32') {
143
+ const appData = process.env.APPDATA || join(home, 'AppData', 'Roaming');
144
+ clients.push({
145
+ type: 'json',
146
+ name: 'VS Code',
147
+ configPath: join(appData, 'Code', 'User', 'mcp.json'),
148
+ detectDir: join(appData, 'Code', 'User'),
149
+ serversKey: 'servers',
150
+ extraFields: { type: 'stdio' }
151
+ });
152
+ }
153
+ else if (plat === 'darwin') {
154
+ clients.push({
155
+ type: 'json',
156
+ name: 'VS Code',
157
+ configPath: join(home, 'Library', 'Application Support', 'Code', 'User', 'mcp.json'),
158
+ detectDir: join(home, 'Library', 'Application Support', 'Code', 'User'),
159
+ serversKey: 'servers',
160
+ extraFields: { type: 'stdio' }
161
+ });
162
+ }
163
+ else {
164
+ clients.push({
165
+ type: 'json',
166
+ name: 'VS Code',
167
+ configPath: join(home, '.config', 'Code', 'User', 'mcp.json'),
168
+ detectDir: join(home, '.config', 'Code', 'User'),
169
+ serversKey: 'servers',
170
+ extraFields: { type: 'stdio' }
171
+ });
172
+ }
134
173
  return clients;
135
174
  }
136
175
  // ============================================================
@@ -183,55 +222,63 @@ function writeJsonConfig(filePath, data) {
183
222
  return { success: false, error: String(err) };
184
223
  }
185
224
  }
186
- // ============================================================
187
- // CLAUDE.md Management
188
- // ============================================================
189
- function getClaudeMdPath() {
190
- return join(homedir(), '.claude', 'CLAUDE.md');
225
+ function getInstructionFiles() {
226
+ const home = homedir();
227
+ return [
228
+ {
229
+ name: 'CLAUDE.md',
230
+ path: join(home, '.claude', 'CLAUDE.md'),
231
+ detectDir: join(home, '.claude')
232
+ },
233
+ {
234
+ name: 'GEMINI.md',
235
+ path: join(home, '.gemini', 'GEMINI.md'),
236
+ detectDir: join(home, '.gemini')
237
+ }
238
+ ];
191
239
  }
192
- function installClaudeMd() {
193
- const mdPath = getClaudeMdPath();
194
- const dir = dirname(mdPath);
195
- // Ensure directory exists
240
+ function installInstructionFile(file) {
241
+ if (!existsSync(file.detectDir)) {
242
+ return { success: true, action: 'skipped (not installed)' };
243
+ }
244
+ const dir = dirname(file.path);
196
245
  if (!existsSync(dir)) {
197
246
  mkdirSync(dir, { recursive: true });
198
247
  }
199
248
  let content = '';
200
- if (existsSync(mdPath)) {
201
- content = readFileSync(mdPath, 'utf8');
249
+ if (existsSync(file.path)) {
250
+ content = readFileSync(file.path, 'utf8');
202
251
  // Already has AiDex block? Replace it
203
252
  if (content.includes(CLAUDE_MD_START)) {
204
253
  const regex = new RegExp(`${CLAUDE_MD_START}[\\s\\S]*?${CLAUDE_MD_END}`, 'g');
205
254
  content = content.replace(regex, CLAUDE_MD_BLOCK);
206
- writeFileSync(mdPath, content, 'utf8');
255
+ writeFileSync(file.path, content, 'utf8');
207
256
  return { success: true, action: 'updated' };
208
257
  }
209
258
  // Append to existing file
210
259
  content = content.trimEnd() + '\n\n' + CLAUDE_MD_BLOCK + '\n';
211
- writeFileSync(mdPath, content, 'utf8');
260
+ writeFileSync(file.path, content, 'utf8');
212
261
  return { success: true, action: 'appended' };
213
262
  }
214
263
  // Create new file
215
- writeFileSync(mdPath, CLAUDE_MD_BLOCK + '\n', 'utf8');
264
+ writeFileSync(file.path, CLAUDE_MD_BLOCK + '\n', 'utf8');
216
265
  return { success: true, action: 'created' };
217
266
  }
218
- function uninstallClaudeMd() {
219
- const mdPath = getClaudeMdPath();
220
- if (!existsSync(mdPath)) {
267
+ function uninstallInstructionFile(file) {
268
+ if (!existsSync(file.path)) {
221
269
  return { success: true, removed: false };
222
270
  }
223
- let content = readFileSync(mdPath, 'utf8');
271
+ let content = readFileSync(file.path, 'utf8');
224
272
  if (!content.includes(CLAUDE_MD_START)) {
225
273
  return { success: true, removed: false };
226
274
  }
227
275
  const regex = new RegExp(`\\n?\\n?${CLAUDE_MD_START}[\\s\\S]*?${CLAUDE_MD_END}\\n?`, 'g');
228
276
  content = content.replace(regex, '').trim();
229
277
  if (content.length === 0) {
230
- // File would be empty, but don't delete it - might have been user-created
231
- writeFileSync(mdPath, '', 'utf8');
278
+ writeFileSync(file.path, '', 'utf8');
232
279
  }
233
280
  else {
234
- writeFileSync(mdPath, content + '\n', 'utf8');
281
+ writeFileSync(file.path, content + '\n', 'utf8');
235
282
  }
236
283
  return { success: true, removed: true };
237
284
  }
@@ -267,11 +314,13 @@ function setupJsonClient(client) {
267
314
  else {
268
315
  data = {};
269
316
  }
270
- if (!data.mcpServers || typeof data.mcpServers !== 'object') {
271
- data.mcpServers = {};
317
+ const key = client.serversKey || 'mcpServers';
318
+ if (!data[key] || typeof data[key] !== 'object') {
319
+ data[key] = {};
272
320
  }
273
321
  const serverCmd = getServerCommand();
274
- data.mcpServers.aidex = { ...serverCmd };
322
+ const entry = { ...client.extraFields, ...serverCmd };
323
+ data[key].aidex = entry;
275
324
  const writeResult = writeJsonConfig(client.configPath, data);
276
325
  if (!writeResult.success) {
277
326
  return { status: ` ✗ ${client.name} (${writeResult.error})`, registered: false };
@@ -293,12 +342,16 @@ export function setupMcpClients() {
293
342
  if (result.registered)
294
343
  registered++;
295
344
  }
296
- // Install CLAUDE.md instructions
345
+ // Install AI instruction files
297
346
  console.log('\n AI Instructions:');
298
- const mdResult = installClaudeMd();
299
- const mdPath = getClaudeMdPath();
300
- if (mdResult.success) {
301
- console.log(` CLAUDE.md (${mdResult.action}: ${mdPath})`);
347
+ for (const file of getInstructionFiles()) {
348
+ const mdResult = installInstructionFile(file);
349
+ if (mdResult.action === 'skipped (not installed)') {
350
+ console.log(` - ${file.name} (client not installed)`);
351
+ }
352
+ else if (mdResult.success) {
353
+ console.log(` ✓ ${file.name} (${mdResult.action}: ${file.path})`);
354
+ }
302
355
  }
303
356
  console.log(`\nRegistered AiDex with ${registered} client(s).\n`);
304
357
  if (registered > 0) {
@@ -332,7 +385,8 @@ function unsetupJsonClient(client) {
332
385
  return { status: ` ✗ ${client.name} (${config.error})`, removed: false };
333
386
  }
334
387
  const data = config.data;
335
- const servers = data.mcpServers;
388
+ const key = client.serversKey || 'mcpServers';
389
+ const servers = data[key];
336
390
  if (!servers || !servers.aidex) {
337
391
  return { status: ` - ${client.name} (not registered)`, removed: false };
338
392
  }
@@ -358,14 +412,16 @@ export function unsetupMcpClients() {
358
412
  if (result.removed)
359
413
  removed++;
360
414
  }
361
- // Remove CLAUDE.md instructions
415
+ // Remove AI instruction files
362
416
  console.log('\n AI Instructions:');
363
- const mdResult = uninstallClaudeMd();
364
- if (mdResult.removed) {
365
- console.log(` ✓ Removed AiDex block from CLAUDE.md`);
366
- }
367
- else {
368
- console.log(` - CLAUDE.md (no AiDex block found)`);
417
+ for (const file of getInstructionFiles()) {
418
+ const mdResult = uninstallInstructionFile(file);
419
+ if (mdResult.removed) {
420
+ console.log(` ✓ Removed AiDex block from ${file.name}`);
421
+ }
422
+ else {
423
+ console.log(` - ${file.name} (no AiDex block found)`);
424
+ }
369
425
  }
370
426
  console.log(`\nUnregistered AiDex from ${removed} client(s).\n`);
371
427
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidex-mcp",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "MCP Server providing persistent code indexing for Claude Code",
5
5
  "main": "build/index.js",
6
6
  "bin": {