aidex-mcp 1.5.0 → 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 +11 -0
- package/build/commands/setup.d.ts +1 -1
- package/build/commands/setup.js +137 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
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
|
+
|
|
11
|
+
## [1.5.1] - 2026-01-31
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- **`aidex setup`**: Now creates config file if client directory exists but config is missing (e.g. fresh Claude Code install)
|
|
15
|
+
|
|
5
16
|
## [1.5.0] - 2026-01-31
|
|
6
17
|
|
|
7
18
|
### Added
|
|
@@ -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;
|
package/build/commands/setup.js
CHANGED
|
@@ -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,45 +21,80 @@ 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
|
-
|
|
28
|
+
detectCmd: 'claude --version',
|
|
29
|
+
addCmd: ['claude', 'mcp', 'add', '--scope', 'user', 'aidex', '--', 'aidex'],
|
|
30
|
+
removeCmd: ['claude', 'mcp', 'remove', '--scope', 'user', 'aidex']
|
|
27
31
|
});
|
|
28
|
-
// Claude Desktop
|
|
32
|
+
// Claude Desktop - JSON config
|
|
29
33
|
if (plat === 'win32') {
|
|
30
34
|
const appData = process.env.APPDATA || join(home, 'AppData', 'Roaming');
|
|
31
35
|
clients.push({
|
|
36
|
+
type: 'json',
|
|
32
37
|
name: 'Claude Desktop',
|
|
33
|
-
configPath: join(appData, 'Claude', 'claude_desktop_config.json')
|
|
38
|
+
configPath: join(appData, 'Claude', 'claude_desktop_config.json'),
|
|
39
|
+
detectDir: join(appData, 'Claude')
|
|
34
40
|
});
|
|
35
41
|
}
|
|
36
42
|
else if (plat === 'darwin') {
|
|
37
43
|
clients.push({
|
|
44
|
+
type: 'json',
|
|
38
45
|
name: 'Claude Desktop',
|
|
39
|
-
configPath: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json')
|
|
46
|
+
configPath: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
|
47
|
+
detectDir: join(home, 'Library', 'Application Support', 'Claude')
|
|
40
48
|
});
|
|
41
49
|
}
|
|
42
50
|
else {
|
|
43
51
|
clients.push({
|
|
52
|
+
type: 'json',
|
|
44
53
|
name: 'Claude Desktop',
|
|
45
|
-
configPath: join(home, '.config', 'Claude', 'claude_desktop_config.json')
|
|
54
|
+
configPath: join(home, '.config', 'Claude', 'claude_desktop_config.json'),
|
|
55
|
+
detectDir: join(home, '.config', 'Claude')
|
|
46
56
|
});
|
|
47
57
|
}
|
|
48
|
-
// Cursor
|
|
58
|
+
// Cursor - JSON config
|
|
49
59
|
clients.push({
|
|
60
|
+
type: 'json',
|
|
50
61
|
name: 'Cursor',
|
|
51
|
-
configPath: join(home, '.cursor', 'mcp.json')
|
|
62
|
+
configPath: join(home, '.cursor', 'mcp.json'),
|
|
63
|
+
detectDir: join(home, '.cursor')
|
|
52
64
|
});
|
|
53
|
-
// Windsurf
|
|
65
|
+
// Windsurf - JSON config
|
|
54
66
|
clients.push({
|
|
67
|
+
type: 'json',
|
|
55
68
|
name: 'Windsurf',
|
|
56
|
-
configPath: join(home, '.codeium', 'windsurf', 'mcp_config.json')
|
|
69
|
+
configPath: join(home, '.codeium', 'windsurf', 'mcp_config.json'),
|
|
70
|
+
detectDir: join(home, '.codeium', 'windsurf')
|
|
57
71
|
});
|
|
58
72
|
return clients;
|
|
59
73
|
}
|
|
60
74
|
// ============================================================
|
|
61
|
-
//
|
|
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
|
|
62
98
|
// ============================================================
|
|
63
99
|
function readJsonConfig(filePath) {
|
|
64
100
|
try {
|
|
@@ -86,75 +122,113 @@ function writeJsonConfig(filePath, data) {
|
|
|
86
122
|
}
|
|
87
123
|
}
|
|
88
124
|
// ============================================================
|
|
89
|
-
// Setup
|
|
125
|
+
// Setup
|
|
90
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
|
+
}
|
|
91
164
|
export function setupMcpClients() {
|
|
92
165
|
const clients = getClients();
|
|
93
|
-
const results = [];
|
|
94
166
|
let registered = 0;
|
|
95
167
|
console.log('\nAiDex MCP Server Registration');
|
|
96
168
|
console.log('==============================\n');
|
|
97
169
|
for (const client of clients) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!config.success || !config.data) {
|
|
105
|
-
results.push({ client: client.name, status: 'error', configPath: client.configPath, message: config.error });
|
|
106
|
-
console.log(` ✗ ${client.name} (${config.error})`);
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const data = config.data;
|
|
110
|
-
if (!data.mcpServers || typeof data.mcpServers !== 'object') {
|
|
111
|
-
data.mcpServers = {};
|
|
112
|
-
}
|
|
113
|
-
data.mcpServers.aidex = { ...AIDEX_MCP_ENTRY };
|
|
114
|
-
const writeResult = writeJsonConfig(client.configPath, data);
|
|
115
|
-
if (!writeResult.success) {
|
|
116
|
-
results.push({ client: client.name, status: 'error', configPath: client.configPath, message: writeResult.error });
|
|
117
|
-
console.log(` ✗ ${client.name} (${writeResult.error})`);
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
registered++;
|
|
121
|
-
results.push({ client: client.name, status: 'registered', configPath: client.configPath });
|
|
122
|
-
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++;
|
|
123
176
|
}
|
|
124
177
|
console.log(`\nRegistered AiDex with ${registered} client(s).\n`);
|
|
125
178
|
if (registered > 0) {
|
|
126
179
|
console.log('Restart your AI client(s) to activate AiDex.\n');
|
|
127
180
|
}
|
|
128
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
|
+
}
|
|
129
220
|
export function unsetupMcpClients() {
|
|
130
221
|
const clients = getClients();
|
|
131
222
|
let removed = 0;
|
|
132
223
|
console.log('\nAiDex MCP Server Unregistration');
|
|
133
224
|
console.log('================================\n');
|
|
134
225
|
for (const client of clients) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
console.log(` ✗ ${client.name} (${config.error})`);
|
|
142
|
-
continue;
|
|
143
|
-
}
|
|
144
|
-
const data = config.data;
|
|
145
|
-
const servers = data.mcpServers;
|
|
146
|
-
if (!servers || !servers.aidex) {
|
|
147
|
-
console.log(` - ${client.name} (not registered)`);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
delete servers.aidex;
|
|
151
|
-
const writeResult = writeJsonConfig(client.configPath, data);
|
|
152
|
-
if (!writeResult.success) {
|
|
153
|
-
console.log(` ✗ ${client.name} (${writeResult.error})`);
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
removed++;
|
|
157
|
-
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++;
|
|
158
232
|
}
|
|
159
233
|
console.log(`\nUnregistered AiDex from ${removed} client(s).\n`);
|
|
160
234
|
}
|