aidex-mcp 1.5.2 → 1.6.1
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 +15 -0
- package/FUTURE.md +75 -0
- package/build/commands/setup.d.ts +1 -0
- package/build/commands/setup.js +148 -11
- package/build/constants.d.ts +1 -0
- package/build/constants.js +4 -0
- package/build/server/mcp-server.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to AiDex will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.6.1] - 2026-02-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **MCP Server version**: Now reads version dynamically from package.json (was hardcoded to 1.3.0)
|
|
9
|
+
- **`aidex setup` for local installs**: Detects if `aidex` is globally available; falls back to `node /full/path/index.js` when not installed globally
|
|
10
|
+
|
|
11
|
+
## [1.6.0] - 2026-02-01
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **Auto CLAUDE.md instructions**: `aidex setup` now installs AI instructions in `~/.claude/CLAUDE.md`
|
|
15
|
+
- Tells Claude to auto-run `aidex_init` when no `.aidex/` exists
|
|
16
|
+
- Provides tool usage guide (prefer AiDex over Grep/Glob)
|
|
17
|
+
- `aidex unsetup` cleanly removes the instructions block
|
|
18
|
+
- **Idempotent setup**: Re-running `aidex setup` updates existing config without errors
|
|
19
|
+
|
|
5
20
|
## [1.5.2] - 2026-02-01
|
|
6
21
|
|
|
7
22
|
### Fixed
|
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.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* AiDex Setup - Auto-register as MCP server in AI clients
|
|
3
3
|
*
|
|
4
4
|
* Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf
|
|
5
|
+
* Also installs CLAUDE.md instructions for Claude Code/Desktop.
|
|
5
6
|
*/
|
|
6
7
|
export declare function setupMcpClients(): void;
|
|
7
8
|
export declare function unsetupMcpClients(): void;
|
package/build/commands/setup.js
CHANGED
|
@@ -2,18 +2,78 @@
|
|
|
2
2
|
* AiDex Setup - Auto-register as MCP server in AI clients
|
|
3
3
|
*
|
|
4
4
|
* Supports: Claude Code (via CLI), Claude Desktop, Cursor, Windsurf
|
|
5
|
+
* Also installs CLAUDE.md instructions for Claude Code/Desktop.
|
|
5
6
|
*/
|
|
6
|
-
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
8
|
+
import { join, dirname, resolve } from 'path';
|
|
8
9
|
import { homedir, platform } from 'os';
|
|
9
10
|
import { execSync } from 'child_process';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
10
12
|
// ============================================================
|
|
11
|
-
// MCP Server
|
|
13
|
+
// MCP Server Command Detection
|
|
12
14
|
// ============================================================
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
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
|
+
}
|
|
28
|
+
// ============================================================
|
|
29
|
+
// CLAUDE.md Instructions Block
|
|
30
|
+
// ============================================================
|
|
31
|
+
const CLAUDE_MD_START = '<!-- AIDEX-START -->';
|
|
32
|
+
const CLAUDE_MD_END = '<!-- AIDEX-END -->';
|
|
33
|
+
const CLAUDE_MD_BLOCK = `${CLAUDE_MD_START}
|
|
34
|
+
## AiDex - Persistent Code Index (MCP Server)
|
|
35
|
+
|
|
36
|
+
AiDex provides fast, precise code search through a pre-built index. **Always prefer AiDex over Grep/Glob for code searches.**
|
|
37
|
+
|
|
38
|
+
### Auto-Init Rule
|
|
39
|
+
|
|
40
|
+
**At the start of every session, check if \`.aidex/\` exists in the project directory.**
|
|
41
|
+
- If \`.aidex/\` does NOT exist → **automatically run \`aidex_init\`** to create the index. Do not ask, just do it.
|
|
42
|
+
- If \`.aidex/\` exists → use AiDex tools for all code searches.
|
|
43
|
+
|
|
44
|
+
### When to Use AiDex (instead of Grep/Glob)
|
|
45
|
+
|
|
46
|
+
| Task | Do NOT use | Use instead |
|
|
47
|
+
|------|-----------|-------------|
|
|
48
|
+
| Find a function/class/variable | \`Grep pattern="name"\` | \`aidex_query term="name"\` |
|
|
49
|
+
| See all methods in a file | \`Read entire_file.cs\` | \`aidex_signature file="..."\` |
|
|
50
|
+
| Explore multiple files | Multiple Read calls | \`aidex_signatures pattern="src/**"\` |
|
|
51
|
+
| Project overview | Many Glob/Read calls | \`aidex_summary\` + \`aidex_tree\` |
|
|
52
|
+
| What changed recently? | \`git log\` + Read | \`aidex_query term="X" modified_since="2h"\` |
|
|
53
|
+
|
|
54
|
+
### Available Tools
|
|
55
|
+
|
|
56
|
+
| Tool | Purpose |
|
|
57
|
+
|------|---------|
|
|
58
|
+
| \`aidex_init\` | Index a project (creates \`.aidex/\`) |
|
|
59
|
+
| \`aidex_query\` | Search by term (exact/contains/starts_with) |
|
|
60
|
+
| \`aidex_signature\` | Get one file's classes + methods |
|
|
61
|
+
| \`aidex_signatures\` | Get signatures for multiple files (glob) |
|
|
62
|
+
| \`aidex_update\` | Re-index a single changed file |
|
|
63
|
+
| \`aidex_summary\` | Project overview with entry points |
|
|
64
|
+
| \`aidex_tree\` | File tree with statistics |
|
|
65
|
+
| \`aidex_files\` | List project files by type |
|
|
66
|
+
| \`aidex_session\` | Start session, detect external changes |
|
|
67
|
+
| \`aidex_note\` | Read/write session notes |
|
|
68
|
+
| \`aidex_viewer\` | Open interactive project tree in browser |
|
|
69
|
+
|
|
70
|
+
### Why AiDex over Grep?
|
|
71
|
+
|
|
72
|
+
- **~50 tokens** per search vs 2000+ with Grep
|
|
73
|
+
- **Identifiers only** - no noise from comments/strings
|
|
74
|
+
- **Persistent** - index survives between sessions
|
|
75
|
+
- **Structure-aware** - knows methods, classes, types
|
|
76
|
+
${CLAUDE_MD_END}`;
|
|
17
77
|
// ============================================================
|
|
18
78
|
// Client Detection
|
|
19
79
|
// ============================================================
|
|
@@ -22,11 +82,13 @@ function getClients() {
|
|
|
22
82
|
const plat = platform();
|
|
23
83
|
const clients = [];
|
|
24
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];
|
|
25
87
|
clients.push({
|
|
26
88
|
type: 'cli',
|
|
27
89
|
name: 'Claude Code',
|
|
28
90
|
detectCmd: 'claude --version',
|
|
29
|
-
addCmd:
|
|
91
|
+
addCmd: cliAddCmd,
|
|
30
92
|
removeCmd: ['claude', 'mcp', 'remove', '--scope', 'user', 'aidex']
|
|
31
93
|
});
|
|
32
94
|
// Claude Desktop - JSON config
|
|
@@ -122,6 +184,58 @@ function writeJsonConfig(filePath, data) {
|
|
|
122
184
|
}
|
|
123
185
|
}
|
|
124
186
|
// ============================================================
|
|
187
|
+
// CLAUDE.md Management
|
|
188
|
+
// ============================================================
|
|
189
|
+
function getClaudeMdPath() {
|
|
190
|
+
return join(homedir(), '.claude', 'CLAUDE.md');
|
|
191
|
+
}
|
|
192
|
+
function installClaudeMd() {
|
|
193
|
+
const mdPath = getClaudeMdPath();
|
|
194
|
+
const dir = dirname(mdPath);
|
|
195
|
+
// Ensure directory exists
|
|
196
|
+
if (!existsSync(dir)) {
|
|
197
|
+
mkdirSync(dir, { recursive: true });
|
|
198
|
+
}
|
|
199
|
+
let content = '';
|
|
200
|
+
if (existsSync(mdPath)) {
|
|
201
|
+
content = readFileSync(mdPath, 'utf8');
|
|
202
|
+
// Already has AiDex block? Replace it
|
|
203
|
+
if (content.includes(CLAUDE_MD_START)) {
|
|
204
|
+
const regex = new RegExp(`${CLAUDE_MD_START}[\\s\\S]*?${CLAUDE_MD_END}`, 'g');
|
|
205
|
+
content = content.replace(regex, CLAUDE_MD_BLOCK);
|
|
206
|
+
writeFileSync(mdPath, content, 'utf8');
|
|
207
|
+
return { success: true, action: 'updated' };
|
|
208
|
+
}
|
|
209
|
+
// Append to existing file
|
|
210
|
+
content = content.trimEnd() + '\n\n' + CLAUDE_MD_BLOCK + '\n';
|
|
211
|
+
writeFileSync(mdPath, content, 'utf8');
|
|
212
|
+
return { success: true, action: 'appended' };
|
|
213
|
+
}
|
|
214
|
+
// Create new file
|
|
215
|
+
writeFileSync(mdPath, CLAUDE_MD_BLOCK + '\n', 'utf8');
|
|
216
|
+
return { success: true, action: 'created' };
|
|
217
|
+
}
|
|
218
|
+
function uninstallClaudeMd() {
|
|
219
|
+
const mdPath = getClaudeMdPath();
|
|
220
|
+
if (!existsSync(mdPath)) {
|
|
221
|
+
return { success: true, removed: false };
|
|
222
|
+
}
|
|
223
|
+
let content = readFileSync(mdPath, 'utf8');
|
|
224
|
+
if (!content.includes(CLAUDE_MD_START)) {
|
|
225
|
+
return { success: true, removed: false };
|
|
226
|
+
}
|
|
227
|
+
const regex = new RegExp(`\\n?\\n?${CLAUDE_MD_START}[\\s\\S]*?${CLAUDE_MD_END}\\n?`, 'g');
|
|
228
|
+
content = content.replace(regex, '').trim();
|
|
229
|
+
if (content.length === 0) {
|
|
230
|
+
// File would be empty, but don't delete it - might have been user-created
|
|
231
|
+
writeFileSync(mdPath, '', 'utf8');
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
writeFileSync(mdPath, content + '\n', 'utf8');
|
|
235
|
+
}
|
|
236
|
+
return { success: true, removed: true };
|
|
237
|
+
}
|
|
238
|
+
// ============================================================
|
|
125
239
|
// Setup
|
|
126
240
|
// ============================================================
|
|
127
241
|
function setupCliClient(client) {
|
|
@@ -132,9 +246,11 @@ function setupCliClient(client) {
|
|
|
132
246
|
if (result.success) {
|
|
133
247
|
return { status: ` ✓ ${client.name}`, registered: true };
|
|
134
248
|
}
|
|
135
|
-
|
|
136
|
-
|
|
249
|
+
// "already exists" is not an error
|
|
250
|
+
if (result.error && result.error.includes('already exists')) {
|
|
251
|
+
return { status: ` ✓ ${client.name} (already registered)`, registered: true };
|
|
137
252
|
}
|
|
253
|
+
return { status: ` ✗ ${client.name} (${result.error})`, registered: false };
|
|
138
254
|
}
|
|
139
255
|
function setupJsonClient(client) {
|
|
140
256
|
if (!existsSync(client.detectDir)) {
|
|
@@ -154,7 +270,8 @@ function setupJsonClient(client) {
|
|
|
154
270
|
if (!data.mcpServers || typeof data.mcpServers !== 'object') {
|
|
155
271
|
data.mcpServers = {};
|
|
156
272
|
}
|
|
157
|
-
|
|
273
|
+
const serverCmd = getServerCommand();
|
|
274
|
+
data.mcpServers.aidex = { ...serverCmd };
|
|
158
275
|
const writeResult = writeJsonConfig(client.configPath, data);
|
|
159
276
|
if (!writeResult.success) {
|
|
160
277
|
return { status: ` ✗ ${client.name} (${writeResult.error})`, registered: false };
|
|
@@ -166,6 +283,8 @@ export function setupMcpClients() {
|
|
|
166
283
|
let registered = 0;
|
|
167
284
|
console.log('\nAiDex MCP Server Registration');
|
|
168
285
|
console.log('==============================\n');
|
|
286
|
+
// Register with AI clients
|
|
287
|
+
console.log(' MCP Servers:');
|
|
169
288
|
for (const client of clients) {
|
|
170
289
|
const result = client.type === 'cli'
|
|
171
290
|
? setupCliClient(client)
|
|
@@ -174,6 +293,13 @@ export function setupMcpClients() {
|
|
|
174
293
|
if (result.registered)
|
|
175
294
|
registered++;
|
|
176
295
|
}
|
|
296
|
+
// Install CLAUDE.md instructions
|
|
297
|
+
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})`);
|
|
302
|
+
}
|
|
177
303
|
console.log(`\nRegistered AiDex with ${registered} client(s).\n`);
|
|
178
304
|
if (registered > 0) {
|
|
179
305
|
console.log('Restart your AI client(s) to activate AiDex.\n');
|
|
@@ -222,6 +348,8 @@ export function unsetupMcpClients() {
|
|
|
222
348
|
let removed = 0;
|
|
223
349
|
console.log('\nAiDex MCP Server Unregistration');
|
|
224
350
|
console.log('================================\n');
|
|
351
|
+
// Unregister from AI clients
|
|
352
|
+
console.log(' MCP Servers:');
|
|
225
353
|
for (const client of clients) {
|
|
226
354
|
const result = client.type === 'cli'
|
|
227
355
|
? unsetupCliClient(client)
|
|
@@ -230,6 +358,15 @@ export function unsetupMcpClients() {
|
|
|
230
358
|
if (result.removed)
|
|
231
359
|
removed++;
|
|
232
360
|
}
|
|
361
|
+
// Remove CLAUDE.md instructions
|
|
362
|
+
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)`);
|
|
369
|
+
}
|
|
233
370
|
console.log(`\nUnregistered AiDex from ${removed} client(s).\n`);
|
|
234
371
|
}
|
|
235
372
|
//# sourceMappingURL=setup.js.map
|
package/build/constants.d.ts
CHANGED
|
@@ -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
|
package/build/constants.js
CHANGED
|
@@ -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:
|
|
12
|
+
version: PRODUCT_VERSION,
|
|
13
13
|
}, {
|
|
14
14
|
capabilities: {
|
|
15
15
|
tools: {},
|