@meldocio/mcp-stdio-proxy 1.0.23 → 1.0.24
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/bin/cli.js +33 -1088
- package/bin/meldoc-mcp-proxy.js +136 -1110
- package/lib/cli/commands.js +277 -0
- package/lib/cli/formatters.js +137 -0
- package/lib/core/constants.js +98 -0
- package/lib/http/client.js +61 -0
- package/lib/http/error-handler.js +195 -0
- package/lib/install/config-manager.js +203 -0
- package/lib/install/config-paths.js +198 -0
- package/lib/install/installers.js +328 -0
- package/lib/install/templates.js +266 -0
- package/lib/mcp/handlers.js +185 -0
- package/lib/mcp/tools-call.js +179 -0
- package/lib/protocol/error-codes.js +143 -0
- package/lib/protocol/json-rpc.js +183 -0
- package/lib/protocol/tools-schema.js +239 -0
- package/package.json +1 -1
- package/lib/constants.js +0 -31
- /package/lib/{auth.js → core/auth.js} +0 -0
- /package/lib/{config.js → core/config.js} +0 -0
- /package/lib/{credentials.js → core/credentials.js} +0 -0
- /package/lib/{device-flow.js → core/device-flow.js} +0 -0
- /package/lib/{logger.js → core/logger.js} +0 -0
- /package/lib/{workspace.js → core/workspace.js} +0 -0
package/bin/cli.js
CHANGED
|
@@ -1,1083 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { interactiveLogin } = require('../lib/device-flow');
|
|
4
|
-
const { readCredentials, deleteCredentials } = require('../lib/credentials');
|
|
5
|
-
const { getAuthStatus } = require('../lib/auth');
|
|
6
|
-
const { setWorkspaceAlias, getWorkspaceAlias } = require('../lib/config');
|
|
7
|
-
const { getAccessToken } = require('../lib/auth');
|
|
8
|
-
const { getApiUrl, getAppUrl } = require('../lib/constants');
|
|
9
|
-
const axios = require('axios');
|
|
10
|
-
const https = require('https');
|
|
11
|
-
const chalk = require('chalk');
|
|
12
|
-
const logger = require('../lib/logger');
|
|
13
|
-
const fs = require('fs');
|
|
14
|
-
const path = require('path');
|
|
15
|
-
const os = require('os');
|
|
16
|
-
|
|
17
|
-
const API_URL = getApiUrl();
|
|
18
|
-
const APP_URL = getAppUrl();
|
|
19
|
-
|
|
20
|
-
// Support localhost testing
|
|
21
|
-
if (process.env.MELDOC_API_URL) {
|
|
22
|
-
logger.debug(`Using API URL: ${process.env.MELDOC_API_URL}`);
|
|
23
|
-
}
|
|
24
|
-
if (process.env.MELDOC_APP_URL) {
|
|
25
|
-
logger.debug(`Using App URL: ${process.env.MELDOC_APP_URL}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Handle auth login command
|
|
30
|
-
*/
|
|
31
|
-
async function handleAuthLogin() {
|
|
32
|
-
try {
|
|
33
|
-
await interactiveLogin({
|
|
34
|
-
autoOpen: true,
|
|
35
|
-
showQR: false,
|
|
36
|
-
timeout: 120000,
|
|
37
|
-
apiBaseUrl: API_URL,
|
|
38
|
-
appUrl: APP_URL
|
|
39
|
-
});
|
|
40
|
-
process.exit(0);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Handle auth status command
|
|
48
|
-
*/
|
|
49
|
-
async function handleAuthStatus() {
|
|
50
|
-
const status = await getAuthStatus();
|
|
51
|
-
if (!status || !status.authenticated) {
|
|
52
|
-
logger.error('Not authenticated');
|
|
53
|
-
console.log('\n' + logger.label('To authenticate, run:'));
|
|
54
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login') + '\n');
|
|
55
|
-
process.exit(1);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
logger.section('🔑 Authentication Status');
|
|
59
|
-
|
|
60
|
-
if (status.type === 'user_session' && status.user) {
|
|
61
|
-
logger.item('Email', logger.value(status.user.email));
|
|
62
|
-
if (status.expiresAt) {
|
|
63
|
-
logger.item('Token expires', logger.value(new Date(status.expiresAt).toLocaleString()));
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
logger.item('Type', logger.value(status.type));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
console.log();
|
|
70
|
-
process.exit(0);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Handle auth logout command
|
|
75
|
-
*/
|
|
76
|
-
async function handleAuthLogout() {
|
|
77
|
-
deleteCredentials();
|
|
78
|
-
logger.success('Logged out successfully');
|
|
79
|
-
process.exit(0);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Handle config set-workspace command
|
|
84
|
-
*/
|
|
85
|
-
function handleConfigSetWorkspace(alias) {
|
|
86
|
-
if (!alias) {
|
|
87
|
-
logger.error('Workspace alias is required');
|
|
88
|
-
console.log('\n' + logger.label('Usage:'));
|
|
89
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy config set-workspace <alias>') + '\n');
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
setWorkspaceAlias(alias);
|
|
95
|
-
logger.success(`Workspace set to: ${logger.highlight(alias)}`);
|
|
96
|
-
process.exit(0);
|
|
97
|
-
} catch (error) {
|
|
98
|
-
logger.error(`Failed to set workspace: ${error.message}`);
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Handle config get-workspace command
|
|
105
|
-
*/
|
|
106
|
-
function handleConfigGetWorkspace() {
|
|
107
|
-
const alias = getWorkspaceAlias();
|
|
108
|
-
if (alias) {
|
|
109
|
-
console.log(logger.highlight(alias));
|
|
110
|
-
}
|
|
111
|
-
process.exit(0);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Handle config list-workspaces command
|
|
116
|
-
*/
|
|
117
|
-
async function handleConfigListWorkspaces() {
|
|
118
|
-
try {
|
|
119
|
-
const tokenInfo = await getAccessToken();
|
|
120
|
-
if (!tokenInfo) {
|
|
121
|
-
logger.error('Not authenticated');
|
|
122
|
-
console.log('\n' + logger.label('To authenticate, run:'));
|
|
123
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login') + '\n');
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Call MCP tool meldoc.list_workspaces via POST /mcp/v1/rpc
|
|
128
|
-
const response = await axios.post(`${API_URL}/mcp/v1/rpc`, {
|
|
129
|
-
jsonrpc: '2.0',
|
|
130
|
-
id: 1,
|
|
131
|
-
method: 'tools/call',
|
|
132
|
-
params: {
|
|
133
|
-
name: 'meldoc.list_workspaces',
|
|
134
|
-
arguments: {}
|
|
135
|
-
}
|
|
136
|
-
}, {
|
|
137
|
-
headers: {
|
|
138
|
-
'Authorization': `Bearer ${tokenInfo.token}`,
|
|
139
|
-
'Content-Type': 'application/json'
|
|
140
|
-
},
|
|
141
|
-
timeout: 10000,
|
|
142
|
-
httpsAgent: new https.Agent({ keepAlive: true })
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
if (response.data.error) {
|
|
146
|
-
logger.error(`Error: ${response.data.error.message}`);
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const workspaces = response.data.result?.workspaces || [];
|
|
151
|
-
if (workspaces.length === 0) {
|
|
152
|
-
logger.info('No workspaces available');
|
|
153
|
-
process.exit(0);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
logger.section('📁 Available Workspaces');
|
|
157
|
-
for (const ws of workspaces) {
|
|
158
|
-
const role = ws.role || 'member';
|
|
159
|
-
const roleColor = role === 'owner' ? chalk.red : role === 'admin' ? chalk.yellow : chalk.gray;
|
|
160
|
-
logger.item(
|
|
161
|
-
`${logger.highlight(ws.alias)} ${chalk.gray('(' + ws.name + ')')}`,
|
|
162
|
-
roleColor(`[${role}]`)
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
console.log();
|
|
166
|
-
|
|
167
|
-
process.exit(0);
|
|
168
|
-
} catch (error) {
|
|
169
|
-
if (error.response?.data?.error) {
|
|
170
|
-
const errorData = error.response.data.error;
|
|
171
|
-
if (errorData.code === 'AUTH_REQUIRED' || errorData.data?.code === 'AUTH_REQUIRED') {
|
|
172
|
-
logger.error('Not authenticated');
|
|
173
|
-
console.log('\n' + logger.label('To authenticate, run:'));
|
|
174
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login') + '\n');
|
|
175
|
-
process.exit(1);
|
|
176
|
-
}
|
|
177
|
-
logger.error(`Error: ${errorData.message || error.message}`);
|
|
178
|
-
} else {
|
|
179
|
-
logger.error(`Error: ${error.message}`);
|
|
180
|
-
}
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Get Claude Desktop config file path based on OS
|
|
187
|
-
*/
|
|
188
|
-
function getClaudeDesktopConfigPath() {
|
|
189
|
-
const platform = os.platform();
|
|
190
|
-
const homeDir = os.homedir();
|
|
191
|
-
|
|
192
|
-
if (platform === 'darwin') {
|
|
193
|
-
// macOS
|
|
194
|
-
return path.join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
195
|
-
} else if (platform === 'win32') {
|
|
196
|
-
// Windows
|
|
197
|
-
const appData = process.env.APPDATA || path.join(homeDir, 'AppData', 'Roaming');
|
|
198
|
-
return path.join(appData, 'Claude', 'claude_desktop_config.json');
|
|
199
|
-
} else {
|
|
200
|
-
// Linux and others
|
|
201
|
-
return path.join(homeDir, '.config', 'Claude', 'claude_desktop_config.json');
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Get Cursor config file path (project-specific)
|
|
207
|
-
*/
|
|
208
|
-
function getCursorProjectConfigPath() {
|
|
209
|
-
const cwd = process.cwd();
|
|
210
|
-
return path.join(cwd, '.cursor', 'mcp.json');
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Get Cursor global config file path
|
|
215
|
-
*/
|
|
216
|
-
function getCursorGlobalConfigPath() {
|
|
217
|
-
const homeDir = os.homedir();
|
|
218
|
-
return path.join(homeDir, '.cursor', 'mcp.json');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Get local mcp.json path (in current directory)
|
|
223
|
-
*/
|
|
224
|
-
function getLocalMcpJsonPath() {
|
|
225
|
-
return path.join(process.cwd(), 'mcp.json');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Get Claude Code project config path (.mcp.json)
|
|
230
|
-
*/
|
|
231
|
-
function getClaudeCodeProjectConfigPath() {
|
|
232
|
-
return path.join(process.cwd(), '.mcp.json');
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Get Claude Code user config path (~/.claude.json)
|
|
237
|
-
*/
|
|
238
|
-
function getClaudeCodeUserConfigPath() {
|
|
239
|
-
return path.join(os.homedir(), '.claude.json');
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Get Claude Code local config path (~/.claude.json in project path)
|
|
244
|
-
* Note: Local scope uses ~/.claude.json but stores project-specific paths
|
|
245
|
-
*/
|
|
246
|
-
function getClaudeCodeLocalConfigPath() {
|
|
247
|
-
// For local scope, Claude Code uses ~/.claude.json with project-specific paths
|
|
248
|
-
// This is the same file as user scope, but with different path context
|
|
249
|
-
return path.join(os.homedir(), '.claude.json');
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Get expected Meldoc MCP configuration for Claude Desktop
|
|
254
|
-
*/
|
|
255
|
-
function getExpectedMeldocConfig() {
|
|
256
|
-
return {
|
|
257
|
-
command: 'npx',
|
|
258
|
-
args: ['-y', '@meldocio/mcp-stdio-proxy@latest']
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Get expected Meldoc MCP configuration for Cursor (stdio)
|
|
264
|
-
*/
|
|
265
|
-
function getExpectedMeldocConfigForCursor() {
|
|
266
|
-
return {
|
|
267
|
-
command: 'npx',
|
|
268
|
-
args: ['-y', '@meldocio/mcp-stdio-proxy@latest']
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Get expected Meldoc MCP configuration for Claude Code (stdio)
|
|
274
|
-
*/
|
|
275
|
-
function getExpectedMeldocConfigForClaudeCode() {
|
|
276
|
-
return {
|
|
277
|
-
type: 'stdio',
|
|
278
|
-
command: 'npx',
|
|
279
|
-
args: ['-y', '@meldocio/mcp-stdio-proxy@latest']
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Check if two configurations are equal (deep comparison)
|
|
285
|
-
*/
|
|
286
|
-
function configsEqual(config1, config2) {
|
|
287
|
-
if (!config1 || !config2) return false;
|
|
288
|
-
if (config1.command !== config2.command) return false;
|
|
289
|
-
if (!Array.isArray(config1.args) || !Array.isArray(config2.args)) return false;
|
|
290
|
-
if (config1.args.length !== config2.args.length) return false;
|
|
291
|
-
return config1.args.every((arg, i) => arg === config2.args[i]);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Merge MCP server configurations (preserve existing, add new)
|
|
296
|
-
*/
|
|
297
|
-
function mergeMcpServers(existing, newServer) {
|
|
298
|
-
const merged = { ...existing };
|
|
299
|
-
if (!merged.meldoc) {
|
|
300
|
-
merged.meldoc = newServer;
|
|
301
|
-
} else {
|
|
302
|
-
// Check if it's the same config
|
|
303
|
-
if (configsEqual(merged.meldoc, newServer)) {
|
|
304
|
-
return { merged, changed: false };
|
|
305
|
-
}
|
|
306
|
-
// Update if different
|
|
307
|
-
merged.meldoc = newServer;
|
|
308
|
-
}
|
|
309
|
-
return { merged, changed: true };
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Install for Claude Desktop
|
|
314
|
-
*/
|
|
315
|
-
function installClaudeDesktop() {
|
|
316
|
-
try {
|
|
317
|
-
logger.section('🚀 Installing Meldoc MCP for Claude Desktop');
|
|
318
|
-
console.log();
|
|
319
|
-
|
|
320
|
-
const configPath = getClaudeDesktopConfigPath();
|
|
321
|
-
const configDir = path.dirname(configPath);
|
|
322
|
-
const expectedConfig = getExpectedMeldocConfig();
|
|
323
|
-
|
|
324
|
-
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
325
|
-
console.log();
|
|
326
|
-
|
|
327
|
-
// Read existing config or create new one
|
|
328
|
-
let config = {};
|
|
329
|
-
let configExists = false;
|
|
330
|
-
|
|
331
|
-
if (fs.existsSync(configPath)) {
|
|
332
|
-
try {
|
|
333
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
334
|
-
config = JSON.parse(content);
|
|
335
|
-
configExists = true;
|
|
336
|
-
logger.info('Found existing Claude Desktop configuration');
|
|
337
|
-
} catch (error) {
|
|
338
|
-
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
339
|
-
logger.info('Will create a new configuration file');
|
|
340
|
-
}
|
|
341
|
-
} else {
|
|
342
|
-
logger.info('Configuration file does not exist, will create it');
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Ensure mcpServers object exists
|
|
346
|
-
if (!config.mcpServers) {
|
|
347
|
-
config.mcpServers = {};
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Check if meldoc is already configured
|
|
351
|
-
if (config.mcpServers.meldoc) {
|
|
352
|
-
const existingConfig = config.mcpServers.meldoc;
|
|
353
|
-
const isEqual = configsEqual(existingConfig, expectedConfig);
|
|
354
|
-
|
|
355
|
-
if (isEqual) {
|
|
356
|
-
logger.success('Meldoc MCP is already configured correctly!');
|
|
357
|
-
console.log();
|
|
358
|
-
logger.info('Current configuration:');
|
|
359
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
360
|
-
console.log();
|
|
361
|
-
logger.info('No changes needed. Next steps:');
|
|
362
|
-
console.log(' 1. Restart Claude Desktop (if you haven\'t already)');
|
|
363
|
-
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
364
|
-
console.log();
|
|
365
|
-
process.exit(0);
|
|
366
|
-
} else {
|
|
367
|
-
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
368
|
-
console.log();
|
|
369
|
-
logger.info('Current configuration:');
|
|
370
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
371
|
-
console.log();
|
|
372
|
-
logger.info('Expected configuration:');
|
|
373
|
-
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
374
|
-
console.log();
|
|
375
|
-
logger.info('To update the configuration, run:');
|
|
376
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy uninstall'));
|
|
377
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install'));
|
|
378
|
-
console.log();
|
|
379
|
-
process.exit(0);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Add meldoc configuration
|
|
384
|
-
config.mcpServers.meldoc = expectedConfig;
|
|
385
|
-
|
|
386
|
-
// Create directory if it doesn't exist
|
|
387
|
-
if (!fs.existsSync(configDir)) {
|
|
388
|
-
logger.info(`Creating directory: ${configDir}`);
|
|
389
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// Write config file
|
|
393
|
-
const configContent = JSON.stringify(config, null, 2);
|
|
394
|
-
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
395
|
-
|
|
396
|
-
logger.success('Configuration added successfully!');
|
|
397
|
-
console.log();
|
|
398
|
-
|
|
399
|
-
// Show what was added
|
|
400
|
-
logger.info('Added MCP server configuration:');
|
|
401
|
-
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
402
|
-
console.log();
|
|
403
|
-
|
|
404
|
-
// Count other MCP servers
|
|
405
|
-
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
406
|
-
if (otherServers.length > 0) {
|
|
407
|
-
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
408
|
-
console.log();
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Next steps
|
|
412
|
-
logger.section('✅ Installation Complete!');
|
|
413
|
-
console.log();
|
|
414
|
-
logger.info('Next steps:');
|
|
415
|
-
console.log();
|
|
416
|
-
console.log(' 1. ' + logger.label('Restart Claude Desktop'));
|
|
417
|
-
console.log(' Completely close and reopen Claude Desktop for changes to take effect.');
|
|
418
|
-
console.log();
|
|
419
|
-
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
420
|
-
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
421
|
-
console.log();
|
|
422
|
-
console.log(' 3. ' + logger.label('Start using Claude with Meldoc!'));
|
|
423
|
-
console.log(' Ask Claude to read, search, or update your documentation.');
|
|
424
|
-
console.log();
|
|
425
|
-
|
|
426
|
-
process.exit(0);
|
|
427
|
-
} catch (error) {
|
|
428
|
-
logger.error(`Installation failed: ${error.message}`);
|
|
429
|
-
console.log();
|
|
430
|
-
logger.info('You can manually configure Claude Desktop by:');
|
|
431
|
-
console.log(' 1. Opening the config file: ' + logger.highlight(getClaudeDesktopConfigPath()));
|
|
432
|
-
console.log(' 2. Adding this configuration:');
|
|
433
|
-
console.log(' ' + logger.highlight(JSON.stringify({
|
|
434
|
-
mcpServers: {
|
|
435
|
-
meldoc: getExpectedMeldocConfig()
|
|
436
|
-
}
|
|
437
|
-
}, null, 2)));
|
|
438
|
-
console.log();
|
|
439
|
-
process.exit(1);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* Install for Cursor (project or global)
|
|
445
|
-
*/
|
|
446
|
-
function installCursor(isGlobal = false) {
|
|
447
|
-
try {
|
|
448
|
-
const configPath = isGlobal ? getCursorGlobalConfigPath() : getCursorProjectConfigPath();
|
|
449
|
-
const configDir = path.dirname(configPath);
|
|
450
|
-
const expectedConfig = getExpectedMeldocConfigForCursor();
|
|
451
|
-
|
|
452
|
-
logger.section(`🚀 Installing Meldoc MCP for Cursor (${isGlobal ? 'global' : 'project'})`);
|
|
453
|
-
console.log();
|
|
454
|
-
|
|
455
|
-
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
456
|
-
console.log();
|
|
457
|
-
|
|
458
|
-
// Read existing config or create new one
|
|
459
|
-
let config = {};
|
|
460
|
-
let configExists = false;
|
|
461
|
-
|
|
462
|
-
if (fs.existsSync(configPath)) {
|
|
463
|
-
try {
|
|
464
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
465
|
-
config = JSON.parse(content);
|
|
466
|
-
configExists = true;
|
|
467
|
-
logger.info('Found existing Cursor MCP configuration');
|
|
468
|
-
} catch (error) {
|
|
469
|
-
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
470
|
-
logger.info('Will create a new configuration file');
|
|
471
|
-
}
|
|
472
|
-
} else {
|
|
473
|
-
logger.info('Configuration file does not exist, will create it');
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Ensure mcpServers object exists
|
|
477
|
-
if (!config.mcpServers) {
|
|
478
|
-
config.mcpServers = {};
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Check if meldoc is already configured
|
|
482
|
-
if (config.mcpServers.meldoc) {
|
|
483
|
-
const existingConfig = config.mcpServers.meldoc;
|
|
484
|
-
const isEqual = configsEqual(existingConfig, expectedConfig);
|
|
485
|
-
|
|
486
|
-
if (isEqual) {
|
|
487
|
-
logger.success('Meldoc MCP is already configured correctly!');
|
|
488
|
-
console.log();
|
|
489
|
-
logger.info('Current configuration:');
|
|
490
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
491
|
-
console.log();
|
|
492
|
-
logger.info('No changes needed. Next steps:');
|
|
493
|
-
console.log(' 1. Restart Cursor (if you haven\'t already)');
|
|
494
|
-
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
495
|
-
console.log();
|
|
496
|
-
process.exit(0);
|
|
497
|
-
} else {
|
|
498
|
-
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
499
|
-
console.log();
|
|
500
|
-
logger.info('Current configuration:');
|
|
501
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
502
|
-
console.log();
|
|
503
|
-
logger.info('Expected configuration:');
|
|
504
|
-
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
505
|
-
console.log();
|
|
506
|
-
logger.info('To update the configuration, run:');
|
|
507
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install cursor'));
|
|
508
|
-
console.log();
|
|
509
|
-
process.exit(0);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Add meldoc configuration
|
|
514
|
-
config.mcpServers.meldoc = expectedConfig;
|
|
515
|
-
|
|
516
|
-
// Create directory if it doesn't exist
|
|
517
|
-
if (!fs.existsSync(configDir)) {
|
|
518
|
-
logger.info(`Creating directory: ${configDir}`);
|
|
519
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
// Write config file
|
|
523
|
-
const configContent = JSON.stringify(config, null, 2);
|
|
524
|
-
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
525
|
-
|
|
526
|
-
logger.success('Configuration added successfully!');
|
|
527
|
-
console.log();
|
|
528
|
-
|
|
529
|
-
// Show what was added
|
|
530
|
-
logger.info('Added MCP server configuration:');
|
|
531
|
-
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
532
|
-
console.log();
|
|
533
|
-
|
|
534
|
-
// Count other MCP servers
|
|
535
|
-
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
536
|
-
if (otherServers.length > 0) {
|
|
537
|
-
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
538
|
-
console.log();
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// Next steps
|
|
542
|
-
logger.section('✅ Installation Complete!');
|
|
543
|
-
console.log();
|
|
544
|
-
logger.info('Next steps:');
|
|
545
|
-
console.log();
|
|
546
|
-
console.log(' 1. ' + logger.label('Restart Cursor'));
|
|
547
|
-
console.log(' Completely close and reopen Cursor for changes to take effect.');
|
|
548
|
-
console.log();
|
|
549
|
-
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
550
|
-
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
551
|
-
console.log();
|
|
552
|
-
console.log(' 3. ' + logger.label('Start using Cursor with Meldoc!'));
|
|
553
|
-
console.log(' Ask Cursor to read, search, or update your documentation.');
|
|
554
|
-
console.log();
|
|
555
|
-
|
|
556
|
-
process.exit(0);
|
|
557
|
-
} catch (error) {
|
|
558
|
-
const configPath = isGlobal ? getCursorGlobalConfigPath() : getCursorProjectConfigPath();
|
|
559
|
-
logger.error(`Installation failed: ${error.message}`);
|
|
560
|
-
console.log();
|
|
561
|
-
logger.info('You can manually configure Cursor by:');
|
|
562
|
-
console.log(' 1. Opening the config file: ' + logger.highlight(configPath));
|
|
563
|
-
console.log(' 2. Adding this configuration:');
|
|
564
|
-
console.log(' ' + logger.highlight(JSON.stringify({
|
|
565
|
-
mcpServers: {
|
|
566
|
-
meldoc: getExpectedMeldocConfigForCursor()
|
|
567
|
-
}
|
|
568
|
-
}, null, 2)));
|
|
569
|
-
console.log();
|
|
570
|
-
process.exit(1);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Install local mcp.json file
|
|
576
|
-
*/
|
|
577
|
-
function installLocal() {
|
|
578
|
-
try {
|
|
579
|
-
logger.section('🚀 Installing Meldoc MCP (Local mcp.json)');
|
|
580
|
-
console.log();
|
|
581
|
-
|
|
582
|
-
const configPath = getLocalMcpJsonPath();
|
|
583
|
-
const expectedConfig = getExpectedMeldocConfig();
|
|
584
|
-
|
|
585
|
-
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
586
|
-
console.log();
|
|
587
|
-
|
|
588
|
-
// Read existing config or create new one
|
|
589
|
-
let config = {};
|
|
590
|
-
let configExists = false;
|
|
591
|
-
|
|
592
|
-
if (fs.existsSync(configPath)) {
|
|
593
|
-
try {
|
|
594
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
595
|
-
config = JSON.parse(content);
|
|
596
|
-
configExists = true;
|
|
597
|
-
logger.info('Found existing mcp.json configuration');
|
|
598
|
-
} catch (error) {
|
|
599
|
-
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
600
|
-
logger.info('Will create a new configuration file');
|
|
601
|
-
}
|
|
602
|
-
} else {
|
|
603
|
-
logger.info('Configuration file does not exist, will create it');
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
// Ensure mcpServers object exists
|
|
607
|
-
if (!config.mcpServers) {
|
|
608
|
-
config.mcpServers = {};
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Check if meldoc is already configured
|
|
612
|
-
if (config.mcpServers.meldoc) {
|
|
613
|
-
const existingConfig = config.mcpServers.meldoc;
|
|
614
|
-
const isEqual = configsEqual(existingConfig, expectedConfig);
|
|
615
|
-
|
|
616
|
-
if (isEqual) {
|
|
617
|
-
logger.success('Meldoc MCP is already configured correctly!');
|
|
618
|
-
console.log();
|
|
619
|
-
logger.info('Current configuration:');
|
|
620
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
621
|
-
console.log();
|
|
622
|
-
logger.info('No changes needed. Next steps:');
|
|
623
|
-
console.log(' 1. Restart your MCP client (if needed)');
|
|
624
|
-
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
625
|
-
console.log();
|
|
626
|
-
process.exit(0);
|
|
627
|
-
} else {
|
|
628
|
-
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
629
|
-
console.log();
|
|
630
|
-
logger.info('Current configuration:');
|
|
631
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
632
|
-
console.log();
|
|
633
|
-
logger.info('Expected configuration:');
|
|
634
|
-
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
635
|
-
console.log();
|
|
636
|
-
logger.info('Updating configuration...');
|
|
637
|
-
console.log();
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// Add/update meldoc configuration
|
|
642
|
-
config.mcpServers.meldoc = expectedConfig;
|
|
643
|
-
|
|
644
|
-
// Write config file
|
|
645
|
-
const configContent = JSON.stringify(config, null, 2);
|
|
646
|
-
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
647
|
-
|
|
648
|
-
logger.success('Configuration ' + (configExists && config.mcpServers.meldoc ? 'updated' : 'added') + ' successfully!');
|
|
649
|
-
console.log();
|
|
650
|
-
|
|
651
|
-
// Show what was added
|
|
652
|
-
logger.info('MCP server configuration:');
|
|
653
|
-
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
654
|
-
console.log();
|
|
655
|
-
|
|
656
|
-
// Count other MCP servers
|
|
657
|
-
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
658
|
-
if (otherServers.length > 0) {
|
|
659
|
-
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
660
|
-
console.log();
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
// Next steps
|
|
664
|
-
logger.section('✅ Installation Complete!');
|
|
665
|
-
console.log();
|
|
666
|
-
logger.info('Next steps:');
|
|
667
|
-
console.log();
|
|
668
|
-
console.log(' 1. ' + logger.label('Use this mcp.json with your MCP client'));
|
|
669
|
-
console.log(' This file can be imported or referenced by MCP clients that support JSON configuration.');
|
|
670
|
-
console.log();
|
|
671
|
-
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
672
|
-
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
673
|
-
console.log();
|
|
674
|
-
|
|
675
|
-
process.exit(0);
|
|
676
|
-
} catch (error) {
|
|
677
|
-
logger.error(`Installation failed: ${error.message}`);
|
|
678
|
-
console.log();
|
|
679
|
-
logger.info('You can manually create mcp.json with this configuration:');
|
|
680
|
-
console.log(' ' + logger.highlight(JSON.stringify({
|
|
681
|
-
mcpServers: {
|
|
682
|
-
meldoc: getExpectedMeldocConfig()
|
|
683
|
-
}
|
|
684
|
-
}, null, 2)));
|
|
685
|
-
console.log();
|
|
686
|
-
process.exit(1);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
* Install for Claude Code (project, user, or local scope)
|
|
692
|
-
*/
|
|
693
|
-
function installClaudeCode(scope = 'project') {
|
|
694
|
-
try {
|
|
695
|
-
let configPath;
|
|
696
|
-
if (scope === 'project') {
|
|
697
|
-
configPath = getClaudeCodeProjectConfigPath();
|
|
698
|
-
} else if (scope === 'user') {
|
|
699
|
-
configPath = getClaudeCodeUserConfigPath();
|
|
700
|
-
} else {
|
|
701
|
-
// local scope
|
|
702
|
-
configPath = getClaudeCodeLocalConfigPath();
|
|
703
|
-
}
|
|
704
|
-
const configDir = path.dirname(configPath);
|
|
705
|
-
const expectedConfig = getExpectedMeldocConfigForClaudeCode();
|
|
706
|
-
|
|
707
|
-
logger.section(`🚀 Installing Meldoc MCP for Claude Code (${scope} scope)`);
|
|
708
|
-
console.log();
|
|
709
|
-
|
|
710
|
-
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
711
|
-
console.log();
|
|
712
|
-
|
|
713
|
-
// Read existing config or create new one
|
|
714
|
-
let config = {};
|
|
715
|
-
let configExists = false;
|
|
716
|
-
|
|
717
|
-
if (fs.existsSync(configPath)) {
|
|
718
|
-
try {
|
|
719
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
720
|
-
config = JSON.parse(content);
|
|
721
|
-
configExists = true;
|
|
722
|
-
logger.info('Found existing Claude Code MCP configuration');
|
|
723
|
-
} catch (error) {
|
|
724
|
-
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
725
|
-
logger.info('Will create a new configuration file');
|
|
726
|
-
}
|
|
727
|
-
} else {
|
|
728
|
-
logger.info('Configuration file does not exist, will create it');
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
// Ensure mcpServers object exists
|
|
732
|
-
if (!config.mcpServers) {
|
|
733
|
-
config.mcpServers = {};
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// Check if meldoc is already configured
|
|
737
|
-
if (config.mcpServers.meldoc) {
|
|
738
|
-
const existingConfig = config.mcpServers.meldoc;
|
|
739
|
-
// For Claude Code, compare type, command, and args
|
|
740
|
-
const isEqual = existingConfig.type === expectedConfig.type &&
|
|
741
|
-
existingConfig.command === expectedConfig.command &&
|
|
742
|
-
Array.isArray(existingConfig.args) &&
|
|
743
|
-
Array.isArray(expectedConfig.args) &&
|
|
744
|
-
existingConfig.args.length === expectedConfig.args.length &&
|
|
745
|
-
existingConfig.args.every((arg, i) => arg === expectedConfig.args[i]);
|
|
746
|
-
|
|
747
|
-
if (isEqual) {
|
|
748
|
-
logger.success('Meldoc MCP is already configured correctly!');
|
|
749
|
-
console.log();
|
|
750
|
-
logger.info('Current configuration:');
|
|
751
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
752
|
-
console.log();
|
|
753
|
-
logger.info('No changes needed. Next steps:');
|
|
754
|
-
console.log(' 1. Restart Claude Code (if you haven\'t already)');
|
|
755
|
-
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
756
|
-
console.log();
|
|
757
|
-
process.exit(0);
|
|
758
|
-
} else {
|
|
759
|
-
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
760
|
-
console.log();
|
|
761
|
-
logger.info('Current configuration:');
|
|
762
|
-
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
763
|
-
console.log();
|
|
764
|
-
logger.info('Expected configuration:');
|
|
765
|
-
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
766
|
-
console.log();
|
|
767
|
-
logger.info('Updating configuration...');
|
|
768
|
-
console.log();
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
// Add/update meldoc configuration
|
|
773
|
-
config.mcpServers.meldoc = expectedConfig;
|
|
774
|
-
|
|
775
|
-
// Create directory if it doesn't exist (for user/local scope)
|
|
776
|
-
if (scope !== 'project' && !fs.existsSync(configDir)) {
|
|
777
|
-
logger.info(`Creating directory: ${configDir}`);
|
|
778
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
// Write config file
|
|
782
|
-
const configContent = JSON.stringify(config, null, 2);
|
|
783
|
-
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
784
|
-
|
|
785
|
-
logger.success('Configuration ' + (configExists && config.mcpServers.meldoc ? 'updated' : 'added') + ' successfully!');
|
|
786
|
-
console.log();
|
|
787
|
-
|
|
788
|
-
// Show what was added
|
|
789
|
-
logger.info('MCP server configuration:');
|
|
790
|
-
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
791
|
-
console.log();
|
|
792
|
-
|
|
793
|
-
// Count other MCP servers
|
|
794
|
-
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
795
|
-
if (otherServers.length > 0) {
|
|
796
|
-
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
797
|
-
console.log();
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
// Next steps
|
|
801
|
-
logger.section('✅ Installation Complete!');
|
|
802
|
-
console.log();
|
|
803
|
-
logger.info('Next steps:');
|
|
804
|
-
console.log();
|
|
805
|
-
console.log(' 1. ' + logger.label('Restart Claude Code'));
|
|
806
|
-
console.log(' Completely close and reopen Claude Code for changes to take effect.');
|
|
807
|
-
console.log();
|
|
808
|
-
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
809
|
-
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
810
|
-
console.log();
|
|
811
|
-
console.log(' 3. ' + logger.label('Start using Claude Code with Meldoc!'));
|
|
812
|
-
console.log(' Ask Claude Code to read, search, or update your documentation.');
|
|
813
|
-
console.log();
|
|
814
|
-
|
|
815
|
-
process.exit(0);
|
|
816
|
-
} catch (error) {
|
|
817
|
-
const configPath = scope === 'project' ? getClaudeCodeProjectConfigPath() : getClaudeCodeUserConfigPath();
|
|
818
|
-
logger.error(`Installation failed: ${error.message}`);
|
|
819
|
-
console.log();
|
|
820
|
-
logger.info('You can manually configure Claude Code by:');
|
|
821
|
-
console.log(' 1. Opening the config file: ' + logger.highlight(configPath));
|
|
822
|
-
console.log(' 2. Adding this configuration:');
|
|
823
|
-
console.log(' ' + logger.highlight(JSON.stringify({
|
|
824
|
-
mcpServers: {
|
|
825
|
-
meldoc: getExpectedMeldocConfigForClaudeCode()
|
|
826
|
-
}
|
|
827
|
-
}, null, 2)));
|
|
828
|
-
console.log();
|
|
829
|
-
logger.info('Or use the CLI command:');
|
|
830
|
-
console.log(' ' + logger.highlight(`claude mcp add --transport stdio meldoc -- npx -y @meldocio/mcp-stdio-proxy@latest --scope ${scope}`));
|
|
831
|
-
console.log();
|
|
832
|
-
process.exit(1);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
|
|
836
3
|
/**
|
|
837
|
-
*
|
|
4
|
+
* CLI Entry Point
|
|
5
|
+
*
|
|
6
|
+
* This is the main entry point for the Meldoc MCP CLI.
|
|
7
|
+
* All command handlers are in lib/cli/commands.js
|
|
8
|
+
* All formatters are in lib/cli/formatters.js
|
|
838
9
|
*/
|
|
839
|
-
function handleInstall(consumer, isLocal) {
|
|
840
|
-
if (isLocal) {
|
|
841
|
-
installLocal();
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
const consumerLower = (consumer || 'claude-desktop').toLowerCase();
|
|
846
|
-
|
|
847
|
-
switch (consumerLower) {
|
|
848
|
-
case 'claude-desktop':
|
|
849
|
-
case 'claude':
|
|
850
|
-
installClaudeDesktop();
|
|
851
|
-
break;
|
|
852
|
-
case 'cursor':
|
|
853
|
-
installCursor(false); // Project-specific by default
|
|
854
|
-
break;
|
|
855
|
-
case 'cursor-global':
|
|
856
|
-
installCursor(true);
|
|
857
|
-
break;
|
|
858
|
-
case 'claude-code':
|
|
859
|
-
installClaudeCode('project'); // Project scope by default
|
|
860
|
-
break;
|
|
861
|
-
case 'claude-code-user':
|
|
862
|
-
installClaudeCode('user');
|
|
863
|
-
break;
|
|
864
|
-
case 'claude-code-local':
|
|
865
|
-
installClaudeCode('local');
|
|
866
|
-
break;
|
|
867
|
-
default:
|
|
868
|
-
logger.error(`Unknown consumer: ${consumer}`);
|
|
869
|
-
console.log();
|
|
870
|
-
logger.info('Supported consumers:');
|
|
871
|
-
console.log(' ' + logger.highlight('claude-desktop') + ' (or claude) - Claude Desktop');
|
|
872
|
-
console.log(' ' + logger.highlight('cursor') + ' - Cursor IDE (project-specific)');
|
|
873
|
-
console.log(' ' + logger.highlight('cursor-global') + ' - Cursor IDE (global)');
|
|
874
|
-
console.log(' ' + logger.highlight('claude-code') + ' - Claude Code (project scope)');
|
|
875
|
-
console.log(' ' + logger.highlight('claude-code-user') + ' - Claude Code (user scope)');
|
|
876
|
-
console.log(' ' + logger.highlight('claude-code-local') + ' - Claude Code (local scope)');
|
|
877
|
-
console.log();
|
|
878
|
-
logger.info('Or use ' + logger.highlight('--local') + ' flag to create local mcp.json');
|
|
879
|
-
console.log();
|
|
880
|
-
process.exit(1);
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
10
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
console.log();
|
|
896
|
-
|
|
897
|
-
// Check if config file exists
|
|
898
|
-
if (!fs.existsSync(configPath)) {
|
|
899
|
-
logger.warn('Claude Desktop configuration file not found');
|
|
900
|
-
logger.info('Meldoc MCP is not configured (nothing to remove)');
|
|
901
|
-
console.log();
|
|
902
|
-
process.exit(0);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
// Read existing config
|
|
906
|
-
let config = {};
|
|
907
|
-
try {
|
|
908
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
909
|
-
config = JSON.parse(content);
|
|
910
|
-
} catch (error) {
|
|
911
|
-
logger.error(`Failed to read config file: ${error.message}`);
|
|
912
|
-
process.exit(1);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// Check if meldoc is configured
|
|
916
|
-
if (!config.mcpServers || !config.mcpServers.meldoc) {
|
|
917
|
-
logger.warn('Meldoc MCP is not configured in Claude Desktop');
|
|
918
|
-
logger.info('Nothing to remove');
|
|
919
|
-
console.log();
|
|
920
|
-
process.exit(0);
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
// Show what will be removed
|
|
924
|
-
logger.info('Current Meldoc configuration:');
|
|
925
|
-
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
926
|
-
console.log();
|
|
927
|
-
|
|
928
|
-
// Remove meldoc configuration
|
|
929
|
-
delete config.mcpServers.meldoc;
|
|
930
|
-
|
|
931
|
-
// If mcpServers is now empty, remove it too
|
|
932
|
-
if (Object.keys(config.mcpServers).length === 0) {
|
|
933
|
-
delete config.mcpServers;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
// Write config file back
|
|
937
|
-
const configContent = JSON.stringify(config, null, 2);
|
|
938
|
-
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
939
|
-
|
|
940
|
-
logger.success('Meldoc MCP configuration removed successfully!');
|
|
941
|
-
console.log();
|
|
942
|
-
|
|
943
|
-
// Count remaining MCP servers
|
|
944
|
-
if (config.mcpServers && Object.keys(config.mcpServers).length > 0) {
|
|
945
|
-
const remainingServers = Object.keys(config.mcpServers);
|
|
946
|
-
logger.info(`Remaining MCP server(s): ${remainingServers.join(', ')}`);
|
|
947
|
-
console.log();
|
|
948
|
-
} else {
|
|
949
|
-
logger.info('No other MCP servers configured');
|
|
950
|
-
console.log();
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
// Next steps
|
|
954
|
-
logger.section('✅ Uninstallation Complete!');
|
|
955
|
-
console.log();
|
|
956
|
-
logger.info('Next steps:');
|
|
957
|
-
console.log(' 1. Restart Claude Desktop for changes to take effect');
|
|
958
|
-
console.log(' 2. To reinstall, run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install'));
|
|
959
|
-
console.log();
|
|
960
|
-
|
|
961
|
-
process.exit(0);
|
|
962
|
-
} catch (error) {
|
|
963
|
-
logger.error(`Uninstallation failed: ${error.message}`);
|
|
964
|
-
console.log();
|
|
965
|
-
logger.info('You can manually remove Meldoc MCP by:');
|
|
966
|
-
console.log(' 1. Opening the config file: ' + logger.highlight(getClaudeDesktopConfigPath()));
|
|
967
|
-
console.log(' 2. Removing the "meldoc" entry from "mcpServers" object');
|
|
968
|
-
console.log();
|
|
969
|
-
process.exit(1);
|
|
970
|
-
}
|
|
971
|
-
}
|
|
11
|
+
// Import command handlers
|
|
12
|
+
const {
|
|
13
|
+
handleAuthLogin,
|
|
14
|
+
handleAuthStatus,
|
|
15
|
+
handleAuthLogout,
|
|
16
|
+
handleConfigSetWorkspace,
|
|
17
|
+
handleConfigGetWorkspace,
|
|
18
|
+
handleConfigListWorkspaces,
|
|
19
|
+
handleInstall,
|
|
20
|
+
handleUninstall
|
|
21
|
+
} = require('../lib/cli/commands');
|
|
972
22
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
console.log();
|
|
982
|
-
|
|
983
|
-
console.log(' ' + logger.highlight('auth login'));
|
|
984
|
-
console.log(' Authenticate with Meldoc using device flow');
|
|
985
|
-
console.log();
|
|
986
|
-
|
|
987
|
-
console.log(' ' + logger.highlight('auth status'));
|
|
988
|
-
console.log(' Check authentication status');
|
|
989
|
-
console.log();
|
|
990
|
-
|
|
991
|
-
console.log(' ' + logger.highlight('auth logout'));
|
|
992
|
-
console.log(' Log out and clear credentials');
|
|
993
|
-
console.log();
|
|
994
|
-
|
|
995
|
-
console.log(' ' + logger.highlight('config set-workspace <alias>'));
|
|
996
|
-
console.log(' Set the active workspace alias');
|
|
997
|
-
console.log();
|
|
998
|
-
|
|
999
|
-
console.log(' ' + logger.highlight('config get-workspace'));
|
|
1000
|
-
console.log(' Get the current workspace alias');
|
|
1001
|
-
console.log();
|
|
1002
|
-
|
|
1003
|
-
console.log(' ' + logger.highlight('config list-workspaces'));
|
|
1004
|
-
console.log(' List all available workspaces');
|
|
1005
|
-
console.log();
|
|
1006
|
-
|
|
1007
|
-
console.log(' ' + logger.highlight('install [consumer] [--local]'));
|
|
1008
|
-
console.log(' Automatically configure MCP client for Meldoc MCP');
|
|
1009
|
-
console.log(' Consumers: claude-desktop (default), cursor, cursor-global, claude-code');
|
|
1010
|
-
console.log(' Use --local flag to create local mcp.json file');
|
|
1011
|
-
console.log();
|
|
1012
|
-
|
|
1013
|
-
console.log(' ' + logger.highlight('uninstall'));
|
|
1014
|
-
console.log(' Remove Meldoc MCP configuration from Claude Desktop');
|
|
1015
|
-
console.log();
|
|
1016
|
-
|
|
1017
|
-
console.log(' ' + logger.highlight('help'));
|
|
1018
|
-
console.log(' Show this help message');
|
|
1019
|
-
console.log();
|
|
1020
|
-
|
|
1021
|
-
console.log(logger.label('Examples:'));
|
|
1022
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install'));
|
|
1023
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install claude-desktop'));
|
|
1024
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install cursor'));
|
|
1025
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install claude-code'));
|
|
1026
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install --local'));
|
|
1027
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy uninstall'));
|
|
1028
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
1029
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy config set-workspace my-workspace'));
|
|
1030
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy config list-workspaces'));
|
|
1031
|
-
console.log();
|
|
1032
|
-
|
|
1033
|
-
process.exit(0);
|
|
1034
|
-
}
|
|
23
|
+
// Import formatters
|
|
24
|
+
const {
|
|
25
|
+
handleHelp,
|
|
26
|
+
showUsageHints,
|
|
27
|
+
showUnknownCommandError,
|
|
28
|
+
showUnknownAuthCommandError,
|
|
29
|
+
showUnknownConfigCommandError
|
|
30
|
+
} = require('../lib/cli/formatters');
|
|
1035
31
|
|
|
1036
|
-
|
|
1037
|
-
* Show usage hints when no arguments provided
|
|
1038
|
-
*/
|
|
1039
|
-
function showUsageHints() {
|
|
1040
|
-
console.log('\n' + logger.section('🔧 Meldoc MCP CLI'));
|
|
1041
|
-
console.log();
|
|
1042
|
-
console.log(logger.label('Available commands:'));
|
|
1043
|
-
console.log(' ' + logger.highlight('auth login') + ' - Authenticate with Meldoc');
|
|
1044
|
-
console.log(' ' + logger.highlight('auth status') + ' - Check authentication status');
|
|
1045
|
-
console.log(' ' + logger.highlight('auth logout') + ' - Log out');
|
|
1046
|
-
console.log(' ' + logger.highlight('config set-workspace') + ' - Set workspace alias');
|
|
1047
|
-
console.log(' ' + logger.highlight('config get-workspace') + ' - Get current workspace');
|
|
1048
|
-
console.log(' ' + logger.highlight('config list-workspaces') + ' - List workspaces');
|
|
1049
|
-
console.log(' ' + logger.highlight('install [consumer]') + ' - Configure MCP client');
|
|
1050
|
-
console.log(' ' + logger.highlight('uninstall') + ' - Remove configuration');
|
|
1051
|
-
console.log(' ' + logger.highlight('help') + ' - Show detailed help');
|
|
1052
|
-
console.log();
|
|
1053
|
-
console.log(logger.label('For more information, run:'));
|
|
1054
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy help') + '\n');
|
|
1055
|
-
process.exit(0);
|
|
1056
|
-
}
|
|
32
|
+
const logger = require('../lib/core/logger');
|
|
1057
33
|
|
|
1058
34
|
/**
|
|
1059
35
|
* Main CLI handler
|
|
1060
36
|
*/
|
|
1061
37
|
async function main() {
|
|
1062
38
|
const args = process.argv.slice(2);
|
|
1063
|
-
|
|
39
|
+
|
|
1064
40
|
if (args.length === 0) {
|
|
1065
41
|
// No arguments - show usage hints
|
|
1066
42
|
showUsageHints();
|
|
1067
43
|
return;
|
|
1068
44
|
}
|
|
1069
|
-
|
|
45
|
+
|
|
1070
46
|
const command = args[0];
|
|
1071
47
|
const subcommand = args[1];
|
|
1072
48
|
const value = args[2];
|
|
1073
|
-
|
|
49
|
+
|
|
1074
50
|
if (command === 'help' || command === '--help' || command === '-h') {
|
|
1075
51
|
handleHelp();
|
|
1076
52
|
} else if (command === 'install') {
|
|
1077
53
|
// Parse install arguments
|
|
1078
54
|
let consumer = null;
|
|
1079
55
|
let isLocal = false;
|
|
1080
|
-
|
|
56
|
+
|
|
1081
57
|
for (let i = 1; i < args.length; i++) {
|
|
1082
58
|
if (args[i] === '--local' || args[i] === '-l') {
|
|
1083
59
|
isLocal = true;
|
|
@@ -1085,7 +61,7 @@ async function main() {
|
|
|
1085
61
|
consumer = args[i];
|
|
1086
62
|
}
|
|
1087
63
|
}
|
|
1088
|
-
|
|
64
|
+
|
|
1089
65
|
handleInstall(consumer, isLocal);
|
|
1090
66
|
} else if (command === 'uninstall') {
|
|
1091
67
|
handleUninstall();
|
|
@@ -1097,10 +73,7 @@ async function main() {
|
|
|
1097
73
|
} else if (subcommand === 'logout') {
|
|
1098
74
|
handleAuthLogout();
|
|
1099
75
|
} else {
|
|
1100
|
-
|
|
1101
|
-
console.log('\n' + logger.label('Usage:'));
|
|
1102
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth <login|status|logout>') + '\n');
|
|
1103
|
-
process.exit(1);
|
|
76
|
+
showUnknownAuthCommandError(subcommand);
|
|
1104
77
|
}
|
|
1105
78
|
} else if (command === 'config') {
|
|
1106
79
|
if (subcommand === 'set-workspace') {
|
|
@@ -1110,24 +83,11 @@ async function main() {
|
|
|
1110
83
|
} else if (subcommand === 'list-workspaces') {
|
|
1111
84
|
await handleConfigListWorkspaces();
|
|
1112
85
|
} else {
|
|
1113
|
-
|
|
1114
|
-
console.log('\n' + logger.label('Usage:'));
|
|
1115
|
-
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy config <set-workspace|get-workspace|list-workspaces>') + '\n');
|
|
1116
|
-
process.exit(1);
|
|
86
|
+
showUnknownConfigCommandError(subcommand);
|
|
1117
87
|
}
|
|
1118
88
|
} else {
|
|
1119
89
|
// Unknown command
|
|
1120
|
-
|
|
1121
|
-
console.log('\n' + logger.label('Available commands:'));
|
|
1122
|
-
console.log(' ' + logger.highlight('install') + ' - Configure Claude Desktop');
|
|
1123
|
-
console.log(' ' + logger.highlight('uninstall') + ' - Remove configuration');
|
|
1124
|
-
console.log(' ' + logger.highlight('auth') + ' <cmd> - Authentication commands');
|
|
1125
|
-
console.log(' ' + logger.highlight('config') + ' <cmd> - Configuration commands');
|
|
1126
|
-
console.log(' ' + logger.highlight('help') + ' - Show help');
|
|
1127
|
-
console.log();
|
|
1128
|
-
console.log(logger.label('Run') + ' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy help') + ' ' + logger.label('for more information'));
|
|
1129
|
-
console.log();
|
|
1130
|
-
process.exit(1);
|
|
90
|
+
showUnknownCommandError(command);
|
|
1131
91
|
}
|
|
1132
92
|
}
|
|
1133
93
|
|
|
@@ -1137,18 +97,3 @@ main().catch((error) => {
|
|
|
1137
97
|
logger.error(`Unexpected error: ${error.message}`);
|
|
1138
98
|
process.exit(1);
|
|
1139
99
|
});
|
|
1140
|
-
|
|
1141
|
-
module.exports = {
|
|
1142
|
-
handleAuthLogin,
|
|
1143
|
-
handleAuthStatus,
|
|
1144
|
-
handleAuthLogout,
|
|
1145
|
-
handleConfigSetWorkspace,
|
|
1146
|
-
handleConfigGetWorkspace,
|
|
1147
|
-
handleConfigListWorkspaces,
|
|
1148
|
-
handleInstall,
|
|
1149
|
-
handleUninstall,
|
|
1150
|
-
installClaudeDesktop,
|
|
1151
|
-
installCursor,
|
|
1152
|
-
installClaudeCode,
|
|
1153
|
-
installLocal
|
|
1154
|
-
};
|