aidex-mcp 1.6.0 → 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,22 @@
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
+
15
+ ## [1.6.1] - 2026-02-01
16
+
17
+ ### Fixed
18
+ - **MCP Server version**: Now reads version dynamically from package.json (was hardcoded to 1.3.0)
19
+ - **`aidex setup` for local installs**: Detects if `aidex` is globally available; falls back to `node /full/path/index.js` when not installed globally
20
+
5
21
  ## [1.6.0] - 2026-02-01
6
22
 
7
23
  ### Added
package/FUTURE.md ADDED
@@ -0,0 +1,75 @@
1
+ # AiDex - Future Ideas
2
+
3
+ Ideensammlung für zukünftige Features und Erweiterungen.
4
+
5
+ ---
6
+
7
+ ## A. Projekt-Ebene (Erweiterungen für einzelne Projekte)
8
+
9
+ ### Datei-Abhängigkeiten (File Dependencies)
10
+ - Import/Require-Analyse: Welche Datei importiert welche?
11
+ - Impact-Analyse: "Wenn ich diese Datei ändere, welche anderen sind betroffen?"
12
+ - Visualisierung als Graph im Viewer
13
+
14
+ ---
15
+
16
+ ## B. AiDex Global / Hub (v2.0) - Neue Meta-Ebene
17
+
18
+ Meta-Ebene über allen AiDex-Projekten. Eine zentrale Datenbank (`~/.aidex/global.db`) die alle Projekt-Datenbanken kennt und somit das gesamte Ökosystem auf dem Rechner versteht.
19
+
20
+ ### 1. Projekt-Registry
21
+ - Automatische Registrierung bei jedem `aidex_init`
22
+ - Kennt Pfad, Name, Sprachen, Größe, letzter Zugriff
23
+ - Weiß welche Projekte aktiv/archiviert/veraltet sind
24
+
25
+ ### 2. Cross-Project Suche
26
+ - "Hab ich das schon mal gebaut?" → Sucht einen Term in ALLEN Projekten gleichzeitig
27
+ - "Wo benutze ich WebSockets?" → Findet alle Projekte mit WebSocket-Code
28
+ - "Hab ich mich damit schon mal beschäftigt?" → Durchsucht gesamtes Ökosystem
29
+
30
+ ### 3. Dependency-Graph zwischen Projekten ⭐
31
+ - LibPyramid3D wird von DebugViewer verwendet
32
+ - LibWebAppGpu wird von 6 Projekten referenziert
33
+ - "Was bricht wenn ich LibX ändere?"
34
+ - Automatische Erkennung über package.json, .csproj, Cargo.toml etc.
35
+
36
+ ### 4. Duplikat-Erkennung
37
+ - Identische oder ähnliche Methoden-Signaturen über Projekte hinweg
38
+ - "Du hast diese Utility-Funktion in 3 Projekten kopiert"
39
+ - Vorschläge zum Zusammenführen in eine Shared-Library
40
+
41
+ ### 5. Technologie-Profil
42
+ - "Du hast 12 TypeScript-Projekte, 8 C#, 3 Rust"
43
+ - Welche Frameworks/Libraries werden wo eingesetzt?
44
+ - Versions-Überblick: "5 Projekte nutzen React 18, 2 noch React 17"
45
+
46
+ ### 6. Pattern-Bibliothek
47
+ - Häufig wiederverwendete Code-Patterns automatisch erkennen
48
+ - "Deine typische HTTP-Client-Konfiguration sieht so aus..."
49
+ - Best-Practices aus eigenen Projekten ableiten
50
+
51
+ ### 7. Skill / Wissens-Map
52
+ - Aus Code ableiten: "Erfahrung mit: WebGL, Tree-sitter, SQLite, MCP Protocol, ..."
53
+ - Tiefe vs. Breite: Wo viel Code, wo nur mal reingeschnuppert?
54
+ - Nützlich für: "Kann ich das mit meinem Wissen umsetzen?"
55
+
56
+ ### 8. Projekt-Empfehlungen
57
+ - "Projekt A und B haben ähnliche Lösungen - zusammenführen?"
58
+ - "Projekt X wurde seit 8 Monaten nicht angefasst - archivieren?"
59
+ - "Du hast 3 verschiedene Logger-Implementierungen - konsolidieren?"
60
+
61
+ ### Technische Skizze
62
+
63
+ ```
64
+ ~/.aidex/
65
+ ├── global.db ← Zentrale Meta-DB
66
+ └── (config, cache)
67
+
68
+ Tabellen:
69
+ - projects (path, name, languages, last_session, file_count, method_count)
70
+ - global_index (term, project_id, file, line) ← aggregiert aus Projekt-DBs
71
+ - dependencies (project_id, depends_on, type)
72
+ - tags (project_id, tag)
73
+ ```
74
+
75
+ Die globale DB zapft die Projekt-DBs periodisch an und baut einen aggregierten Index auf - nicht alles kopieren, aber genug für Cross-Project Queries.
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,20 +1,30 @@
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';
8
- import { join, dirname } from 'path';
8
+ import { join, dirname, resolve } from 'path';
9
9
  import { homedir, platform } from 'os';
10
10
  import { execSync } from 'child_process';
11
+ import { fileURLToPath } from 'url';
11
12
  // ============================================================
12
- // MCP Server Entry (for JSON-based clients)
13
+ // MCP Server Command Detection
13
14
  // ============================================================
14
- const AIDEX_MCP_ENTRY = {
15
- command: 'aidex',
16
- args: []
17
- };
15
+ function getServerCommand() {
16
+ // Check if 'aidex' is available as a global command
17
+ try {
18
+ execSync(platform() === 'win32' ? 'where aidex' : 'which aidex', { stdio: 'pipe', timeout: 3000 });
19
+ return { command: 'aidex', args: [] };
20
+ }
21
+ catch {
22
+ // Not globally installed - use node with full path to index.js
23
+ }
24
+ const thisFile = fileURLToPath(import.meta.url);
25
+ const indexJs = resolve(dirname(thisFile), '..', 'index.js');
26
+ return { command: process.execPath, args: [indexJs] };
27
+ }
18
28
  // ============================================================
19
29
  // CLAUDE.md Instructions Block
20
30
  // ============================================================
@@ -72,11 +82,13 @@ function getClients() {
72
82
  const plat = platform();
73
83
  const clients = [];
74
84
  // Claude Code - uses its own CLI for MCP management
85
+ const serverCmd = getServerCommand();
86
+ const cliAddCmd = ['claude', 'mcp', 'add', '--scope', 'user', 'aidex', '--', serverCmd.command, ...serverCmd.args];
75
87
  clients.push({
76
88
  type: 'cli',
77
89
  name: 'Claude Code',
78
90
  detectCmd: 'claude --version',
79
- addCmd: ['claude', 'mcp', 'add', '--scope', 'user', 'aidex', '--', 'aidex'],
91
+ addCmd: cliAddCmd,
80
92
  removeCmd: ['claude', 'mcp', 'remove', '--scope', 'user', 'aidex']
81
93
  });
82
94
  // Claude Desktop - JSON config
@@ -119,6 +131,45 @@ function getClients() {
119
131
  configPath: join(home, '.codeium', 'windsurf', 'mcp_config.json'),
120
132
  detectDir: join(home, '.codeium', 'windsurf')
121
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
+ }
122
173
  return clients;
123
174
  }
124
175
  // ============================================================
@@ -171,55 +222,63 @@ function writeJsonConfig(filePath, data) {
171
222
  return { success: false, error: String(err) };
172
223
  }
173
224
  }
174
- // ============================================================
175
- // CLAUDE.md Management
176
- // ============================================================
177
- function getClaudeMdPath() {
178
- 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
+ ];
179
239
  }
180
- function installClaudeMd() {
181
- const mdPath = getClaudeMdPath();
182
- const dir = dirname(mdPath);
183
- // 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);
184
245
  if (!existsSync(dir)) {
185
246
  mkdirSync(dir, { recursive: true });
186
247
  }
187
248
  let content = '';
188
- if (existsSync(mdPath)) {
189
- content = readFileSync(mdPath, 'utf8');
249
+ if (existsSync(file.path)) {
250
+ content = readFileSync(file.path, 'utf8');
190
251
  // Already has AiDex block? Replace it
191
252
  if (content.includes(CLAUDE_MD_START)) {
192
253
  const regex = new RegExp(`${CLAUDE_MD_START}[\\s\\S]*?${CLAUDE_MD_END}`, 'g');
193
254
  content = content.replace(regex, CLAUDE_MD_BLOCK);
194
- writeFileSync(mdPath, content, 'utf8');
255
+ writeFileSync(file.path, content, 'utf8');
195
256
  return { success: true, action: 'updated' };
196
257
  }
197
258
  // Append to existing file
198
259
  content = content.trimEnd() + '\n\n' + CLAUDE_MD_BLOCK + '\n';
199
- writeFileSync(mdPath, content, 'utf8');
260
+ writeFileSync(file.path, content, 'utf8');
200
261
  return { success: true, action: 'appended' };
201
262
  }
202
263
  // Create new file
203
- writeFileSync(mdPath, CLAUDE_MD_BLOCK + '\n', 'utf8');
264
+ writeFileSync(file.path, CLAUDE_MD_BLOCK + '\n', 'utf8');
204
265
  return { success: true, action: 'created' };
205
266
  }
206
- function uninstallClaudeMd() {
207
- const mdPath = getClaudeMdPath();
208
- if (!existsSync(mdPath)) {
267
+ function uninstallInstructionFile(file) {
268
+ if (!existsSync(file.path)) {
209
269
  return { success: true, removed: false };
210
270
  }
211
- let content = readFileSync(mdPath, 'utf8');
271
+ let content = readFileSync(file.path, 'utf8');
212
272
  if (!content.includes(CLAUDE_MD_START)) {
213
273
  return { success: true, removed: false };
214
274
  }
215
275
  const regex = new RegExp(`\\n?\\n?${CLAUDE_MD_START}[\\s\\S]*?${CLAUDE_MD_END}\\n?`, 'g');
216
276
  content = content.replace(regex, '').trim();
217
277
  if (content.length === 0) {
218
- // File would be empty, but don't delete it - might have been user-created
219
- writeFileSync(mdPath, '', 'utf8');
278
+ writeFileSync(file.path, '', 'utf8');
220
279
  }
221
280
  else {
222
- writeFileSync(mdPath, content + '\n', 'utf8');
281
+ writeFileSync(file.path, content + '\n', 'utf8');
223
282
  }
224
283
  return { success: true, removed: true };
225
284
  }
@@ -255,10 +314,13 @@ function setupJsonClient(client) {
255
314
  else {
256
315
  data = {};
257
316
  }
258
- if (!data.mcpServers || typeof data.mcpServers !== 'object') {
259
- data.mcpServers = {};
317
+ const key = client.serversKey || 'mcpServers';
318
+ if (!data[key] || typeof data[key] !== 'object') {
319
+ data[key] = {};
260
320
  }
261
- data.mcpServers.aidex = { ...AIDEX_MCP_ENTRY };
321
+ const serverCmd = getServerCommand();
322
+ const entry = { ...client.extraFields, ...serverCmd };
323
+ data[key].aidex = entry;
262
324
  const writeResult = writeJsonConfig(client.configPath, data);
263
325
  if (!writeResult.success) {
264
326
  return { status: ` ✗ ${client.name} (${writeResult.error})`, registered: false };
@@ -280,12 +342,16 @@ export function setupMcpClients() {
280
342
  if (result.registered)
281
343
  registered++;
282
344
  }
283
- // Install CLAUDE.md instructions
345
+ // Install AI instruction files
284
346
  console.log('\n AI Instructions:');
285
- const mdResult = installClaudeMd();
286
- const mdPath = getClaudeMdPath();
287
- if (mdResult.success) {
288
- 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
+ }
289
355
  }
290
356
  console.log(`\nRegistered AiDex with ${registered} client(s).\n`);
291
357
  if (registered > 0) {
@@ -319,7 +385,8 @@ function unsetupJsonClient(client) {
319
385
  return { status: ` ✗ ${client.name} (${config.error})`, removed: false };
320
386
  }
321
387
  const data = config.data;
322
- const servers = data.mcpServers;
388
+ const key = client.serversKey || 'mcpServers';
389
+ const servers = data[key];
323
390
  if (!servers || !servers.aidex) {
324
391
  return { status: ` - ${client.name} (not registered)`, removed: false };
325
392
  }
@@ -345,14 +412,16 @@ export function unsetupMcpClients() {
345
412
  if (result.removed)
346
413
  removed++;
347
414
  }
348
- // Remove CLAUDE.md instructions
415
+ // Remove AI instruction files
349
416
  console.log('\n AI Instructions:');
350
- const mdResult = uninstallClaudeMd();
351
- if (mdResult.removed) {
352
- console.log(` ✓ Removed AiDex block from CLAUDE.md`);
353
- }
354
- else {
355
- 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
+ }
356
425
  }
357
426
  console.log(`\nUnregistered AiDex from ${removed} client(s).\n`);
358
427
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
  export declare const PRODUCT_NAME = "AiDex";
7
7
  export declare const PRODUCT_NAME_LOWER = "aidex";
8
+ export declare const PRODUCT_VERSION: string;
8
9
  export declare const INDEX_DIR = ".aidex";
9
10
  export declare const TOOL_PREFIX = "aidex_";
10
11
  //# sourceMappingURL=constants.d.ts.map
@@ -3,8 +3,12 @@
3
3
  *
4
4
  * Change product name here to rename the entire tool.
5
5
  */
6
+ import { createRequire } from 'module';
7
+ const require = createRequire(import.meta.url);
8
+ const pkg = require('../package.json');
6
9
  export const PRODUCT_NAME = 'AiDex';
7
10
  export const PRODUCT_NAME_LOWER = 'aidex';
11
+ export const PRODUCT_VERSION = pkg.version;
8
12
  export const INDEX_DIR = '.aidex';
9
13
  export const TOOL_PREFIX = 'aidex_';
10
14
  //# sourceMappingURL=constants.js.map
@@ -5,11 +5,11 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
6
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
7
7
  import { registerTools, handleToolCall } from './tools.js';
8
- import { PRODUCT_NAME, PRODUCT_NAME_LOWER } from '../constants.js';
8
+ import { PRODUCT_NAME, PRODUCT_NAME_LOWER, PRODUCT_VERSION } from '../constants.js';
9
9
  export function createServer() {
10
10
  const server = new Server({
11
11
  name: PRODUCT_NAME_LOWER,
12
- version: '1.3.0',
12
+ version: PRODUCT_VERSION,
13
13
  }, {
14
14
  capabilities: {
15
15
  tools: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidex-mcp",
3
- "version": "1.6.0",
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": {