@mearl/mcp-server 2.8.2 → 2.9.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/dist/cliArgs.d.ts +6 -0
- package/dist/cliArgs.js +84 -0
- package/dist/configure.d.ts +1 -0
- package/dist/configure.js +56 -28
- package/dist/index.js +21 -5
- package/dist/uninstall.d.ts +6 -0
- package/dist/uninstall.js +47 -3
- package/package.json +7 -3
package/dist/cliArgs.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export async function parseMcpArgs(argv) {
|
|
2
|
+
if (argv.length === 0)
|
|
3
|
+
return { forwardedArgs: [], mode: 'server' };
|
|
4
|
+
const { Command, CommanderError } = await import('commander');
|
|
5
|
+
const configureAlias = argv.includes('--configure');
|
|
6
|
+
const uninstallAlias = argv.includes('--uninstall');
|
|
7
|
+
if (configureAlias && uninstallAlias) {
|
|
8
|
+
throw new Error('--configure and --uninstall cannot be used together');
|
|
9
|
+
}
|
|
10
|
+
const compatibilityMode = configureAlias ? 'configure' : uninstallAlias ? 'uninstall' : undefined;
|
|
11
|
+
const normalizedArgv = compatibilityMode
|
|
12
|
+
? [compatibilityMode, ...argv.filter(arg => arg !== '--configure' && arg !== '--uninstall')]
|
|
13
|
+
: argv;
|
|
14
|
+
const program = new Command()
|
|
15
|
+
.name('mearl-mcp-server')
|
|
16
|
+
.helpOption(false)
|
|
17
|
+
.allowExcessArguments(false)
|
|
18
|
+
.exitOverride()
|
|
19
|
+
.configureOutput({ writeErr: () => { }, writeOut: () => { } })
|
|
20
|
+
.argument('[command]')
|
|
21
|
+
.option('--extension-id <id>')
|
|
22
|
+
.option('--id <id>')
|
|
23
|
+
.option('--skip-mcp')
|
|
24
|
+
.option('--get')
|
|
25
|
+
.option('--global-install')
|
|
26
|
+
.option('--managed-by-setup')
|
|
27
|
+
.option('-y, --yes')
|
|
28
|
+
.option('--non-interactive')
|
|
29
|
+
.option('-h, --help')
|
|
30
|
+
.option('-v, --version');
|
|
31
|
+
try {
|
|
32
|
+
program.parse(['node', 'mearl-mcp-server', ...normalizedArgv]);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error instanceof CommanderError) {
|
|
36
|
+
throw new Error(error.message.replace(/^error:\s*/i, ''), { cause: error });
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
const options = program.opts();
|
|
41
|
+
if (options.help)
|
|
42
|
+
return { forwardedArgs: [], mode: 'help' };
|
|
43
|
+
if (options.version)
|
|
44
|
+
return { forwardedArgs: [], mode: 'version' };
|
|
45
|
+
const command = program.processedArgs[0];
|
|
46
|
+
if (command !== 'configure' && command !== 'uninstall') {
|
|
47
|
+
throw new Error(command ? `Unknown command: ${command}` : 'configure or uninstall is required');
|
|
48
|
+
}
|
|
49
|
+
const configureOnly = [
|
|
50
|
+
['extensionId', '--extension-id'],
|
|
51
|
+
['id', '--id'],
|
|
52
|
+
['skipMcp', '--skip-mcp'],
|
|
53
|
+
['get', '--get'],
|
|
54
|
+
['globalInstall', '--global-install'],
|
|
55
|
+
];
|
|
56
|
+
const uninstallOnly = [['managedBySetup', '--managed-by-setup']];
|
|
57
|
+
const disallowed = command === 'configure' ? uninstallOnly : configureOnly;
|
|
58
|
+
for (const [name, flag] of disallowed) {
|
|
59
|
+
if (program.getOptionValueSource(name) === 'cli') {
|
|
60
|
+
throw new Error(`${flag} is not available for ${command}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (options.extensionId && options.id && options.extensionId !== options.id) {
|
|
64
|
+
throw new Error('--extension-id and --id cannot specify different values');
|
|
65
|
+
}
|
|
66
|
+
const forwardedArgs = [];
|
|
67
|
+
if (command === 'configure') {
|
|
68
|
+
const extensionId = options.extensionId ?? options.id;
|
|
69
|
+
if (extensionId)
|
|
70
|
+
forwardedArgs.push('--extension-id', extensionId);
|
|
71
|
+
if (options.skipMcp)
|
|
72
|
+
forwardedArgs.push('--skip-mcp');
|
|
73
|
+
if (options.get)
|
|
74
|
+
forwardedArgs.push('--get');
|
|
75
|
+
if (options.globalInstall)
|
|
76
|
+
forwardedArgs.push('--global-install');
|
|
77
|
+
}
|
|
78
|
+
else if (options.managedBySetup) {
|
|
79
|
+
forwardedArgs.push('--managed-by-setup');
|
|
80
|
+
}
|
|
81
|
+
if (options.yes || options.nonInteractive)
|
|
82
|
+
forwardedArgs.push('--yes');
|
|
83
|
+
return { forwardedArgs, mode: command };
|
|
84
|
+
}
|
package/dist/configure.d.ts
CHANGED
package/dist/configure.js
CHANGED
|
@@ -15,39 +15,63 @@ import path, { dirname, join } from 'node:path';
|
|
|
15
15
|
import { fileURLToPath } from 'node:url';
|
|
16
16
|
import { HOST_NAME, DEFAULT_EXTENSION_ID } from './constants.js';
|
|
17
17
|
import prompts from 'prompts';
|
|
18
|
+
import { Command, CommanderError } from 'commander';
|
|
18
19
|
import { MCP_CLIENTS, getMCPServerConfig, isNpxMode, isClientInstalled, } from './mcp-clients.js';
|
|
19
20
|
// 日志输出
|
|
20
21
|
const log = (...args) => {
|
|
21
22
|
console.log('[Configure]', ...args);
|
|
22
23
|
};
|
|
23
|
-
|
|
24
|
+
class ConfigureUsageError extends Error {
|
|
25
|
+
name = 'ConfigureUsageError';
|
|
26
|
+
}
|
|
24
27
|
export function parseConfigureArgs(args = process.argv.slice(2)) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
else if (arg === '--yes' || arg === '-y' || arg === '--non-interactive') {
|
|
47
|
-
yes = true;
|
|
28
|
+
const program = new Command()
|
|
29
|
+
.name('mearl-mcp-configure')
|
|
30
|
+
.helpOption(false)
|
|
31
|
+
.allowExcessArguments(false)
|
|
32
|
+
.exitOverride()
|
|
33
|
+
.configureOutput({ writeErr: () => { }, writeOut: () => { } })
|
|
34
|
+
.option('--extension-id <id>')
|
|
35
|
+
.option('--id <id>')
|
|
36
|
+
.option('--skip-mcp')
|
|
37
|
+
.option('--get')
|
|
38
|
+
.option('--global-install')
|
|
39
|
+
.option('-y, --yes')
|
|
40
|
+
.option('--non-interactive')
|
|
41
|
+
.option('-h, --help');
|
|
42
|
+
try {
|
|
43
|
+
program.parse(['node', 'mearl-mcp-configure', ...args]);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error instanceof CommanderError) {
|
|
47
|
+
throw new ConfigureUsageError(error.message.replace(/^error:\s*/i, ''), { cause: error });
|
|
48
48
|
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
const options = program.opts();
|
|
52
|
+
if (options.extensionId && options.id && options.extensionId !== options.id) {
|
|
53
|
+
throw new ConfigureUsageError('--extension-id and --id cannot specify different values');
|
|
49
54
|
}
|
|
50
|
-
return {
|
|
55
|
+
return {
|
|
56
|
+
extensionId: options.extensionId ?? options.id,
|
|
57
|
+
get: options.get === true,
|
|
58
|
+
globalInstall: options.globalInstall === true,
|
|
59
|
+
help: options.help === true,
|
|
60
|
+
skipMcp: options.skipMcp === true,
|
|
61
|
+
yes: options.yes === true || options.nonInteractive === true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function printConfigureHelp() {
|
|
65
|
+
console.log(`Usage: mearl-mcp-configure [options]
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
--extension-id <id> Configure a custom extension ID
|
|
69
|
+
--skip-mcp Skip MCP client configuration
|
|
70
|
+
--get Print current configuration
|
|
71
|
+
--global-install Use the globally installed command
|
|
72
|
+
--yes, -y Configure detected clients without prompts
|
|
73
|
+
--non-interactive Alias for --yes
|
|
74
|
+
--help, -h Show this help`);
|
|
51
75
|
}
|
|
52
76
|
// 替换或追加 TOML 中的 mcp_servers.xxx 节
|
|
53
77
|
function replaceTOMLSection(content, serverName, newSectionLines) {
|
|
@@ -211,7 +235,11 @@ export function shouldUseNpx(globalInstall, detectNpxMode = isNpxMode) {
|
|
|
211
235
|
return !globalInstall && detectNpxMode();
|
|
212
236
|
}
|
|
213
237
|
export async function runConfigure(argv = process.argv.slice(2)) {
|
|
214
|
-
const { extensionId, get, globalInstall, skipMcp, yes } = parseConfigureArgs(argv);
|
|
238
|
+
const { extensionId, get, globalInstall, help, skipMcp, yes } = parseConfigureArgs(argv);
|
|
239
|
+
if (help) {
|
|
240
|
+
printConfigureHelp();
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
215
243
|
// 如果是查看配置,显示后退出
|
|
216
244
|
if (get) {
|
|
217
245
|
showCurrentConfig();
|
|
@@ -328,7 +356,7 @@ if (process.argv[1] && path.resolve(process.argv[1]) === currentFile) {
|
|
|
328
356
|
await runConfigure();
|
|
329
357
|
}
|
|
330
358
|
catch (error) {
|
|
331
|
-
console.error(
|
|
332
|
-
process.exitCode = 1;
|
|
359
|
+
console.error(`Configuration failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
360
|
+
process.exitCode = error instanceof ConfigureUsageError ? 2 : 1;
|
|
333
361
|
}
|
|
334
362
|
}
|