@phidiassj/aiyoperps-mcp-installer 0.6.7 → 0.6.9
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/bin/aiyoperps-mcp-installer.js +99 -37
- package/package.json +1 -1
|
@@ -147,13 +147,11 @@ async function detectClaudeCode(url) {
|
|
|
147
147
|
|
|
148
148
|
async function detectClaudeDesktop(url) {
|
|
149
149
|
const candidates = getClaudeDesktopCandidates();
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
const baseConfigRoot = path.dirname(path.dirname(configPath));
|
|
156
|
-
const baseRootExists = fs.existsSync(baseConfigRoot);
|
|
150
|
+
const configPaths = selectClaudeDesktopConfigPaths(candidates);
|
|
151
|
+
const primaryPath = configPaths[0];
|
|
152
|
+
const exists = configPaths.some(fileExists);
|
|
153
|
+
const parentExists = configPaths.some(configPath => fs.existsSync(path.dirname(configPath)));
|
|
154
|
+
const baseRootExists = configPaths.some(configPath => fs.existsSync(path.dirname(path.dirname(configPath))));
|
|
157
155
|
const detected = exists || parentExists || baseRootExists;
|
|
158
156
|
let supported = baseRootExists;
|
|
159
157
|
let installed = false;
|
|
@@ -167,8 +165,12 @@ async function detectClaudeDesktop(url) {
|
|
|
167
165
|
|
|
168
166
|
if (exists) {
|
|
169
167
|
try {
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
installed = configPaths
|
|
169
|
+
.filter(fileExists)
|
|
170
|
+
.some(configPath => {
|
|
171
|
+
const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
172
|
+
return Boolean(parsed?.mcpServers?.[SERVER_NAME]);
|
|
173
|
+
});
|
|
172
174
|
reason = installed ? 'installed' : 'config parsed successfully';
|
|
173
175
|
} catch (error) {
|
|
174
176
|
supported = false;
|
|
@@ -184,9 +186,10 @@ async function detectClaudeDesktop(url) {
|
|
|
184
186
|
supported,
|
|
185
187
|
installed,
|
|
186
188
|
reason,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
configPaths,
|
|
190
|
+
path: configPaths.join(' | '),
|
|
191
|
+
install: () => installClaudeDesktop(configPaths, url),
|
|
192
|
+
uninstall: () => uninstallClaudeDesktop(configPaths)
|
|
190
193
|
};
|
|
191
194
|
}
|
|
192
195
|
|
|
@@ -412,7 +415,7 @@ function createInstallAction(host, url) {
|
|
|
412
415
|
case 'claude-code':
|
|
413
416
|
return () => installClaudeCode(url);
|
|
414
417
|
case 'claude-desktop':
|
|
415
|
-
return () => installClaudeDesktop(host.
|
|
418
|
+
return () => installClaudeDesktop(host.configPaths, url);
|
|
416
419
|
case 'openclaw':
|
|
417
420
|
return () => installOpenClaw(url);
|
|
418
421
|
default:
|
|
@@ -463,37 +466,46 @@ function uninstallCodex(configPath) {
|
|
|
463
466
|
fs.writeFileSync(configPath, next.trim() ? `${next.replace(/\s*$/, '')}\n` : '', 'utf8');
|
|
464
467
|
}
|
|
465
468
|
|
|
466
|
-
function installClaudeDesktop(
|
|
467
|
-
|
|
469
|
+
function installClaudeDesktop(configPaths, url) {
|
|
470
|
+
const targets = configPaths.filter(fileExists);
|
|
471
|
+
if (targets.length === 0) {
|
|
472
|
+
targets.push(configPaths[0]);
|
|
473
|
+
}
|
|
468
474
|
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
: {};
|
|
475
|
+
for (const configPath of targets) {
|
|
476
|
+
ensureParentDir(configPath);
|
|
472
477
|
|
|
473
|
-
|
|
474
|
-
|
|
478
|
+
const payload = fileExists(configPath)
|
|
479
|
+
? JSON.parse(fs.readFileSync(configPath, 'utf8'))
|
|
480
|
+
: {};
|
|
475
481
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
482
|
+
payload.mcpServers ??= {};
|
|
483
|
+
payload.mcpServers[SERVER_NAME] = buildJsonServerConfig(url);
|
|
479
484
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
return;
|
|
485
|
+
backupIfExists(configPath);
|
|
486
|
+
fs.writeFileSync(configPath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
|
|
483
487
|
}
|
|
488
|
+
}
|
|
484
489
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
490
|
+
function uninstallClaudeDesktop(configPaths) {
|
|
491
|
+
for (const configPath of configPaths) {
|
|
492
|
+
if (!fileExists(configPath)) {
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
489
495
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
496
|
+
const payload = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
497
|
+
if (!payload?.mcpServers?.[SERVER_NAME]) {
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
494
500
|
|
|
495
|
-
|
|
496
|
-
|
|
501
|
+
delete payload.mcpServers[SERVER_NAME];
|
|
502
|
+
if (Object.keys(payload.mcpServers).length === 0) {
|
|
503
|
+
delete payload.mcpServers;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
backupIfExists(configPath);
|
|
507
|
+
fs.writeFileSync(configPath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
|
|
508
|
+
}
|
|
497
509
|
}
|
|
498
510
|
|
|
499
511
|
function installClaudeCode(url) {
|
|
@@ -1003,10 +1015,32 @@ function getClaudeDesktopCandidates() {
|
|
|
1003
1015
|
|
|
1004
1016
|
if (process.platform === 'win32') {
|
|
1005
1017
|
const appData = env.APPDATA || path.join(env.USERPROFILE || os.homedir(), 'AppData', 'Roaming');
|
|
1006
|
-
|
|
1018
|
+
const localAppData = env.LOCALAPPDATA || path.join(env.USERPROFILE || os.homedir(), 'AppData', 'Local');
|
|
1019
|
+
const storeCandidates = [];
|
|
1020
|
+
const roamingCandidates = [
|
|
1007
1021
|
path.join(appData, 'Claude', 'claude_desktop_config.json'),
|
|
1008
1022
|
path.join(appData, 'Claude', 'config.json')
|
|
1009
1023
|
];
|
|
1024
|
+
|
|
1025
|
+
const packagesRoot = path.join(localAppData, 'Packages');
|
|
1026
|
+
if (fs.existsSync(packagesRoot)) {
|
|
1027
|
+
try {
|
|
1028
|
+
const packageDirs = fs.readdirSync(packagesRoot, { withFileTypes: true })
|
|
1029
|
+
.filter(entry => entry.isDirectory())
|
|
1030
|
+
.map(entry => entry.name)
|
|
1031
|
+
.filter(name => name.toLowerCase().startsWith('claude_'));
|
|
1032
|
+
|
|
1033
|
+
for (const packageDir of packageDirs) {
|
|
1034
|
+
storeCandidates.push(
|
|
1035
|
+
path.join(packagesRoot, packageDir, 'LocalCache', 'Roaming', 'Claude', 'claude_desktop_config.json'),
|
|
1036
|
+
path.join(packagesRoot, packageDir, 'LocalCache', 'Roaming', 'Claude', 'config.json'));
|
|
1037
|
+
}
|
|
1038
|
+
} catch {
|
|
1039
|
+
// Ignore directory enumeration failures and keep default candidates.
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
return [...new Set([...storeCandidates, ...roamingCandidates])];
|
|
1010
1044
|
}
|
|
1011
1045
|
|
|
1012
1046
|
if (process.platform === 'darwin') {
|
|
@@ -1022,6 +1056,34 @@ function getClaudeDesktopCandidates() {
|
|
|
1022
1056
|
];
|
|
1023
1057
|
}
|
|
1024
1058
|
|
|
1059
|
+
function selectClaudeDesktopConfigPaths(candidates) {
|
|
1060
|
+
const existingPrimary = candidates.filter(candidate =>
|
|
1061
|
+
fileExists(candidate) &&
|
|
1062
|
+
path.basename(candidate).toLowerCase() === 'claude_desktop_config.json');
|
|
1063
|
+
if (existingPrimary.length > 0) {
|
|
1064
|
+
return existingPrimary;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
const existingAny = candidates.filter(fileExists);
|
|
1068
|
+
if (existingAny.length > 0) {
|
|
1069
|
+
return existingAny;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
const creatablePrimary = candidates.find(candidate =>
|
|
1073
|
+
path.basename(candidate).toLowerCase() === 'claude_desktop_config.json' &&
|
|
1074
|
+
fs.existsSync(path.dirname(candidate)));
|
|
1075
|
+
if (creatablePrimary) {
|
|
1076
|
+
return [creatablePrimary];
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
const creatableAny = candidates.find(candidate => fs.existsSync(path.dirname(candidate)));
|
|
1080
|
+
if (creatableAny) {
|
|
1081
|
+
return [creatableAny];
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
return [candidates[0]];
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1025
1087
|
function resolveOpenClawConfigPath() {
|
|
1026
1088
|
const explicit = env.OPENCLAW_CONFIG_PATH;
|
|
1027
1089
|
if (explicit) {
|