@meldocio/mcp-stdio-proxy 1.0.15 → 1.0.17
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/README.md +44 -8
- package/bin/cli.js +557 -8
- package/lib/workspace.js +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Meldoc MCP for Claude Desktop
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@meldocio/mcp-stdio-proxy)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
3
6
|
This package allows you to connect Claude Desktop to your Meldoc account, so you can use all your documentation directly in Claude.
|
|
4
7
|
|
|
5
8
|
## What is this?
|
|
@@ -13,6 +16,35 @@ This is a bridge between Claude Desktop and Meldoc. After setup, Claude will be
|
|
|
13
16
|
|
|
14
17
|
**No additional installation required** - everything works automatically through Claude Desktop.
|
|
15
18
|
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
### Via Claude Marketplace (Recommended) 🚀
|
|
22
|
+
|
|
23
|
+
The easiest way to install Meldoc MCP is through the Claude Marketplace:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Add the marketplace
|
|
27
|
+
claude plugin marketplace add meldoc/mcp-stdio-proxy
|
|
28
|
+
|
|
29
|
+
# Install the plugin
|
|
30
|
+
claude plugin install meldoc-mcp@meldoc
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
After installation:
|
|
34
|
+
|
|
35
|
+
1. Restart Claude Desktop (or your MCP client)
|
|
36
|
+
2. Run `npx @meldocio/mcp-stdio-proxy@latest auth login` to authenticate
|
|
37
|
+
|
|
38
|
+
### Via NPM
|
|
39
|
+
|
|
40
|
+
You can also install directly via npm:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g @meldocio/mcp-stdio-proxy
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Then add to your Claude Desktop config file (see Manual Installation below).
|
|
47
|
+
|
|
16
48
|
## Quick Setup
|
|
17
49
|
|
|
18
50
|
### Automatic Installation (Recommended) ✨
|
|
@@ -24,6 +56,7 @@ npx @meldocio/mcp-stdio-proxy@latest install
|
|
|
24
56
|
```
|
|
25
57
|
|
|
26
58
|
This command will:
|
|
59
|
+
|
|
27
60
|
- ✅ Automatically find your Claude Desktop configuration file
|
|
28
61
|
- ✅ Add Meldoc MCP configuration (preserving existing MCP servers)
|
|
29
62
|
- ✅ Create the config file and directory if needed
|
|
@@ -31,6 +64,7 @@ This command will:
|
|
|
31
64
|
- ✅ Show you the next steps
|
|
32
65
|
|
|
33
66
|
After running `install`, you just need to:
|
|
67
|
+
|
|
34
68
|
1. Restart Claude Desktop
|
|
35
69
|
2. Run `npx @meldocio/mcp-stdio-proxy@latest auth login`
|
|
36
70
|
|
|
@@ -45,6 +79,7 @@ npx @meldocio/mcp-stdio-proxy@latest uninstall
|
|
|
45
79
|
```
|
|
46
80
|
|
|
47
81
|
This will:
|
|
82
|
+
|
|
48
83
|
- ✅ Remove Meldoc MCP configuration from Claude Desktop
|
|
49
84
|
- ✅ Preserve other MCP servers
|
|
50
85
|
- ✅ Clean up empty `mcpServers` object if needed
|
|
@@ -266,7 +301,7 @@ npx @meldocio/mcp-stdio-proxy@latest config set-workspace workspace-name
|
|
|
266
301
|
npx @meldocio/mcp-stdio-proxy@latest config get-workspace
|
|
267
302
|
```
|
|
268
303
|
|
|
269
|
-
### Installation
|
|
304
|
+
### Quick Installation Commands
|
|
270
305
|
|
|
271
306
|
```bash
|
|
272
307
|
# Automatically configure Claude Desktop
|
|
@@ -292,10 +327,12 @@ If you have multiple workspaces in Meldoc, you need to specify which one to use.
|
|
|
292
327
|
The system selects a workspace in this order:
|
|
293
328
|
|
|
294
329
|
1. **Specified in request** - if you explicitly specified `workspaceAlias` or `workspaceId`
|
|
295
|
-
2. **Project file** - if there's a
|
|
330
|
+
2. **Project file** - if there's a `meldoc.config.yml` file in the project folder (or git repository directory)
|
|
296
331
|
3. **Global setting** - if you set a default workspace
|
|
297
332
|
4. **Automatically** - if you only have one workspace, it will be selected automatically
|
|
298
333
|
|
|
334
|
+
**Note:** When MCP is used in a git project or directory (e.g., Claude Desktop terminal or any other LLM), the workspace is automatically taken from the `meldoc.config.yml` configuration file if it exists.
|
|
335
|
+
|
|
299
336
|
### Setting default workspace
|
|
300
337
|
|
|
301
338
|
If you have multiple workspaces, set one as default:
|
|
@@ -308,14 +345,13 @@ After this, Claude will automatically use this workspace.
|
|
|
308
345
|
|
|
309
346
|
### Workspace for a specific project
|
|
310
347
|
|
|
311
|
-
If you want different projects to use different workspaces, create a
|
|
348
|
+
If you want different projects to use different workspaces, create a `meldoc.config.yml` file in the project root:
|
|
312
349
|
|
|
313
350
|
```yaml
|
|
314
|
-
|
|
315
|
-
workspace: workspace-name-for-this-project
|
|
351
|
+
workspaceAlias: workspace-name-for-this-project
|
|
316
352
|
```
|
|
317
353
|
|
|
318
|
-
Now when working from this folder, the specified workspace will be used.
|
|
354
|
+
Now when working from this folder (or when MCP is used in a git repository), the specified workspace will be used.
|
|
319
355
|
|
|
320
356
|
## What can Claude do with your documentation?
|
|
321
357
|
|
|
@@ -489,9 +525,9 @@ Global settings:
|
|
|
489
525
|
|
|
490
526
|
Can be edited manually or through CLI commands.
|
|
491
527
|
|
|
492
|
-
###
|
|
528
|
+
### `meldoc.config.yml` (optional)
|
|
493
529
|
|
|
494
|
-
Project-specific settings. Create in the project root if you need to use a different workspace for this project.
|
|
530
|
+
Project-specific settings. Create in the project root if you need to use a different workspace for this project. When MCP is used in a git project or directory, the workspace is automatically taken from this configuration file if it exists.
|
|
495
531
|
|
|
496
532
|
## Requirements
|
|
497
533
|
|
package/bin/cli.js
CHANGED
|
@@ -219,7 +219,54 @@ function getClaudeDesktopConfigPath() {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
|
-
* Get
|
|
222
|
+
* Get Cursor config file path (project-specific)
|
|
223
|
+
*/
|
|
224
|
+
function getCursorProjectConfigPath() {
|
|
225
|
+
const cwd = process.cwd();
|
|
226
|
+
return path.join(cwd, '.cursor', 'mcp.json');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get Cursor global config file path
|
|
231
|
+
*/
|
|
232
|
+
function getCursorGlobalConfigPath() {
|
|
233
|
+
const homeDir = os.homedir();
|
|
234
|
+
return path.join(homeDir, '.cursor', 'mcp.json');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Get local mcp.json path (in current directory)
|
|
239
|
+
*/
|
|
240
|
+
function getLocalMcpJsonPath() {
|
|
241
|
+
return path.join(process.cwd(), 'mcp.json');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get Claude Code project config path (.mcp.json)
|
|
246
|
+
*/
|
|
247
|
+
function getClaudeCodeProjectConfigPath() {
|
|
248
|
+
return path.join(process.cwd(), '.mcp.json');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get Claude Code user config path (~/.claude.json)
|
|
253
|
+
*/
|
|
254
|
+
function getClaudeCodeUserConfigPath() {
|
|
255
|
+
return path.join(os.homedir(), '.claude.json');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Get Claude Code local config path (~/.claude.json in project path)
|
|
260
|
+
* Note: Local scope uses ~/.claude.json but stores project-specific paths
|
|
261
|
+
*/
|
|
262
|
+
function getClaudeCodeLocalConfigPath() {
|
|
263
|
+
// For local scope, Claude Code uses ~/.claude.json with project-specific paths
|
|
264
|
+
// This is the same file as user scope, but with different path context
|
|
265
|
+
return path.join(os.homedir(), '.claude.json');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Get expected Meldoc MCP configuration for Claude Desktop
|
|
223
270
|
*/
|
|
224
271
|
function getExpectedMeldocConfig() {
|
|
225
272
|
return {
|
|
@@ -228,6 +275,27 @@ function getExpectedMeldocConfig() {
|
|
|
228
275
|
};
|
|
229
276
|
}
|
|
230
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Get expected Meldoc MCP configuration for Cursor (stdio)
|
|
280
|
+
*/
|
|
281
|
+
function getExpectedMeldocConfigForCursor() {
|
|
282
|
+
return {
|
|
283
|
+
command: 'npx',
|
|
284
|
+
args: ['-y', '@meldocio/mcp-stdio-proxy@latest']
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Get expected Meldoc MCP configuration for Claude Code (stdio)
|
|
290
|
+
*/
|
|
291
|
+
function getExpectedMeldocConfigForClaudeCode() {
|
|
292
|
+
return {
|
|
293
|
+
type: 'stdio',
|
|
294
|
+
command: 'npx',
|
|
295
|
+
args: ['-y', '@meldocio/mcp-stdio-proxy@latest']
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
231
299
|
/**
|
|
232
300
|
* Check if two configurations are equal (deep comparison)
|
|
233
301
|
*/
|
|
@@ -240,9 +308,27 @@ function configsEqual(config1, config2) {
|
|
|
240
308
|
}
|
|
241
309
|
|
|
242
310
|
/**
|
|
243
|
-
*
|
|
311
|
+
* Merge MCP server configurations (preserve existing, add new)
|
|
312
|
+
*/
|
|
313
|
+
function mergeMcpServers(existing, newServer) {
|
|
314
|
+
const merged = { ...existing };
|
|
315
|
+
if (!merged.meldoc) {
|
|
316
|
+
merged.meldoc = newServer;
|
|
317
|
+
} else {
|
|
318
|
+
// Check if it's the same config
|
|
319
|
+
if (configsEqual(merged.meldoc, newServer)) {
|
|
320
|
+
return { merged, changed: false };
|
|
321
|
+
}
|
|
322
|
+
// Update if different
|
|
323
|
+
merged.meldoc = newServer;
|
|
324
|
+
}
|
|
325
|
+
return { merged, changed: true };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Install for Claude Desktop
|
|
244
330
|
*/
|
|
245
|
-
function
|
|
331
|
+
function installClaudeDesktop() {
|
|
246
332
|
try {
|
|
247
333
|
logger.section('🚀 Installing Meldoc MCP for Claude Desktop');
|
|
248
334
|
console.log();
|
|
@@ -370,6 +456,447 @@ function handleInstall() {
|
|
|
370
456
|
}
|
|
371
457
|
}
|
|
372
458
|
|
|
459
|
+
/**
|
|
460
|
+
* Install for Cursor (project or global)
|
|
461
|
+
*/
|
|
462
|
+
function installCursor(isGlobal = false) {
|
|
463
|
+
try {
|
|
464
|
+
const configPath = isGlobal ? getCursorGlobalConfigPath() : getCursorProjectConfigPath();
|
|
465
|
+
const configDir = path.dirname(configPath);
|
|
466
|
+
const expectedConfig = getExpectedMeldocConfigForCursor();
|
|
467
|
+
|
|
468
|
+
logger.section(`🚀 Installing Meldoc MCP for Cursor (${isGlobal ? 'global' : 'project'})`);
|
|
469
|
+
console.log();
|
|
470
|
+
|
|
471
|
+
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
472
|
+
console.log();
|
|
473
|
+
|
|
474
|
+
// Read existing config or create new one
|
|
475
|
+
let config = {};
|
|
476
|
+
let configExists = false;
|
|
477
|
+
|
|
478
|
+
if (fs.existsSync(configPath)) {
|
|
479
|
+
try {
|
|
480
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
481
|
+
config = JSON.parse(content);
|
|
482
|
+
configExists = true;
|
|
483
|
+
logger.info('Found existing Cursor MCP configuration');
|
|
484
|
+
} catch (error) {
|
|
485
|
+
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
486
|
+
logger.info('Will create a new configuration file');
|
|
487
|
+
}
|
|
488
|
+
} else {
|
|
489
|
+
logger.info('Configuration file does not exist, will create it');
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Ensure mcpServers object exists
|
|
493
|
+
if (!config.mcpServers) {
|
|
494
|
+
config.mcpServers = {};
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Check if meldoc is already configured
|
|
498
|
+
if (config.mcpServers.meldoc) {
|
|
499
|
+
const existingConfig = config.mcpServers.meldoc;
|
|
500
|
+
const isEqual = configsEqual(existingConfig, expectedConfig);
|
|
501
|
+
|
|
502
|
+
if (isEqual) {
|
|
503
|
+
logger.success('Meldoc MCP is already configured correctly!');
|
|
504
|
+
console.log();
|
|
505
|
+
logger.info('Current configuration:');
|
|
506
|
+
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
507
|
+
console.log();
|
|
508
|
+
logger.info('No changes needed. Next steps:');
|
|
509
|
+
console.log(' 1. Restart Cursor (if you haven\'t already)');
|
|
510
|
+
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
511
|
+
console.log();
|
|
512
|
+
process.exit(0);
|
|
513
|
+
} else {
|
|
514
|
+
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
515
|
+
console.log();
|
|
516
|
+
logger.info('Current configuration:');
|
|
517
|
+
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
518
|
+
console.log();
|
|
519
|
+
logger.info('Expected configuration:');
|
|
520
|
+
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
521
|
+
console.log();
|
|
522
|
+
logger.info('To update the configuration, run:');
|
|
523
|
+
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install cursor'));
|
|
524
|
+
console.log();
|
|
525
|
+
process.exit(0);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Add meldoc configuration
|
|
530
|
+
config.mcpServers.meldoc = expectedConfig;
|
|
531
|
+
|
|
532
|
+
// Create directory if it doesn't exist
|
|
533
|
+
if (!fs.existsSync(configDir)) {
|
|
534
|
+
logger.info(`Creating directory: ${configDir}`);
|
|
535
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Write config file
|
|
539
|
+
const configContent = JSON.stringify(config, null, 2);
|
|
540
|
+
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
541
|
+
|
|
542
|
+
logger.success('Configuration added successfully!');
|
|
543
|
+
console.log();
|
|
544
|
+
|
|
545
|
+
// Show what was added
|
|
546
|
+
logger.info('Added MCP server configuration:');
|
|
547
|
+
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
548
|
+
console.log();
|
|
549
|
+
|
|
550
|
+
// Count other MCP servers
|
|
551
|
+
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
552
|
+
if (otherServers.length > 0) {
|
|
553
|
+
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
554
|
+
console.log();
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Next steps
|
|
558
|
+
logger.section('✅ Installation Complete!');
|
|
559
|
+
console.log();
|
|
560
|
+
logger.info('Next steps:');
|
|
561
|
+
console.log();
|
|
562
|
+
console.log(' 1. ' + logger.label('Restart Cursor'));
|
|
563
|
+
console.log(' Completely close and reopen Cursor for changes to take effect.');
|
|
564
|
+
console.log();
|
|
565
|
+
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
566
|
+
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
567
|
+
console.log();
|
|
568
|
+
console.log(' 3. ' + logger.label('Start using Cursor with Meldoc!'));
|
|
569
|
+
console.log(' Ask Cursor to read, search, or update your documentation.');
|
|
570
|
+
console.log();
|
|
571
|
+
|
|
572
|
+
process.exit(0);
|
|
573
|
+
} catch (error) {
|
|
574
|
+
const configPath = isGlobal ? getCursorGlobalConfigPath() : getCursorProjectConfigPath();
|
|
575
|
+
logger.error(`Installation failed: ${error.message}`);
|
|
576
|
+
console.log();
|
|
577
|
+
logger.info('You can manually configure Cursor by:');
|
|
578
|
+
console.log(' 1. Opening the config file: ' + logger.highlight(configPath));
|
|
579
|
+
console.log(' 2. Adding this configuration:');
|
|
580
|
+
console.log(' ' + logger.highlight(JSON.stringify({
|
|
581
|
+
mcpServers: {
|
|
582
|
+
meldoc: getExpectedMeldocConfigForCursor()
|
|
583
|
+
}
|
|
584
|
+
}, null, 2)));
|
|
585
|
+
console.log();
|
|
586
|
+
process.exit(1);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Install local mcp.json file
|
|
592
|
+
*/
|
|
593
|
+
function installLocal() {
|
|
594
|
+
try {
|
|
595
|
+
logger.section('🚀 Installing Meldoc MCP (Local mcp.json)');
|
|
596
|
+
console.log();
|
|
597
|
+
|
|
598
|
+
const configPath = getLocalMcpJsonPath();
|
|
599
|
+
const expectedConfig = getExpectedMeldocConfig();
|
|
600
|
+
|
|
601
|
+
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
602
|
+
console.log();
|
|
603
|
+
|
|
604
|
+
// Read existing config or create new one
|
|
605
|
+
let config = {};
|
|
606
|
+
let configExists = false;
|
|
607
|
+
|
|
608
|
+
if (fs.existsSync(configPath)) {
|
|
609
|
+
try {
|
|
610
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
611
|
+
config = JSON.parse(content);
|
|
612
|
+
configExists = true;
|
|
613
|
+
logger.info('Found existing mcp.json configuration');
|
|
614
|
+
} catch (error) {
|
|
615
|
+
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
616
|
+
logger.info('Will create a new configuration file');
|
|
617
|
+
}
|
|
618
|
+
} else {
|
|
619
|
+
logger.info('Configuration file does not exist, will create it');
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Ensure mcpServers object exists
|
|
623
|
+
if (!config.mcpServers) {
|
|
624
|
+
config.mcpServers = {};
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Check if meldoc is already configured
|
|
628
|
+
if (config.mcpServers.meldoc) {
|
|
629
|
+
const existingConfig = config.mcpServers.meldoc;
|
|
630
|
+
const isEqual = configsEqual(existingConfig, expectedConfig);
|
|
631
|
+
|
|
632
|
+
if (isEqual) {
|
|
633
|
+
logger.success('Meldoc MCP is already configured correctly!');
|
|
634
|
+
console.log();
|
|
635
|
+
logger.info('Current configuration:');
|
|
636
|
+
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
637
|
+
console.log();
|
|
638
|
+
logger.info('No changes needed. Next steps:');
|
|
639
|
+
console.log(' 1. Restart your MCP client (if needed)');
|
|
640
|
+
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
641
|
+
console.log();
|
|
642
|
+
process.exit(0);
|
|
643
|
+
} else {
|
|
644
|
+
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
645
|
+
console.log();
|
|
646
|
+
logger.info('Current configuration:');
|
|
647
|
+
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
648
|
+
console.log();
|
|
649
|
+
logger.info('Expected configuration:');
|
|
650
|
+
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
651
|
+
console.log();
|
|
652
|
+
logger.info('Updating configuration...');
|
|
653
|
+
console.log();
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Add/update meldoc configuration
|
|
658
|
+
config.mcpServers.meldoc = expectedConfig;
|
|
659
|
+
|
|
660
|
+
// Write config file
|
|
661
|
+
const configContent = JSON.stringify(config, null, 2);
|
|
662
|
+
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
663
|
+
|
|
664
|
+
logger.success('Configuration ' + (configExists && config.mcpServers.meldoc ? 'updated' : 'added') + ' successfully!');
|
|
665
|
+
console.log();
|
|
666
|
+
|
|
667
|
+
// Show what was added
|
|
668
|
+
logger.info('MCP server configuration:');
|
|
669
|
+
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
670
|
+
console.log();
|
|
671
|
+
|
|
672
|
+
// Count other MCP servers
|
|
673
|
+
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
674
|
+
if (otherServers.length > 0) {
|
|
675
|
+
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
676
|
+
console.log();
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Next steps
|
|
680
|
+
logger.section('✅ Installation Complete!');
|
|
681
|
+
console.log();
|
|
682
|
+
logger.info('Next steps:');
|
|
683
|
+
console.log();
|
|
684
|
+
console.log(' 1. ' + logger.label('Use this mcp.json with your MCP client'));
|
|
685
|
+
console.log(' This file can be imported or referenced by MCP clients that support JSON configuration.');
|
|
686
|
+
console.log();
|
|
687
|
+
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
688
|
+
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
689
|
+
console.log();
|
|
690
|
+
|
|
691
|
+
process.exit(0);
|
|
692
|
+
} catch (error) {
|
|
693
|
+
logger.error(`Installation failed: ${error.message}`);
|
|
694
|
+
console.log();
|
|
695
|
+
logger.info('You can manually create mcp.json with this configuration:');
|
|
696
|
+
console.log(' ' + logger.highlight(JSON.stringify({
|
|
697
|
+
mcpServers: {
|
|
698
|
+
meldoc: getExpectedMeldocConfig()
|
|
699
|
+
}
|
|
700
|
+
}, null, 2)));
|
|
701
|
+
console.log();
|
|
702
|
+
process.exit(1);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Install for Claude Code (project, user, or local scope)
|
|
708
|
+
*/
|
|
709
|
+
function installClaudeCode(scope = 'project') {
|
|
710
|
+
try {
|
|
711
|
+
let configPath;
|
|
712
|
+
if (scope === 'project') {
|
|
713
|
+
configPath = getClaudeCodeProjectConfigPath();
|
|
714
|
+
} else if (scope === 'user') {
|
|
715
|
+
configPath = getClaudeCodeUserConfigPath();
|
|
716
|
+
} else {
|
|
717
|
+
// local scope
|
|
718
|
+
configPath = getClaudeCodeLocalConfigPath();
|
|
719
|
+
}
|
|
720
|
+
const configDir = path.dirname(configPath);
|
|
721
|
+
const expectedConfig = getExpectedMeldocConfigForClaudeCode();
|
|
722
|
+
|
|
723
|
+
logger.section(`🚀 Installing Meldoc MCP for Claude Code (${scope} scope)`);
|
|
724
|
+
console.log();
|
|
725
|
+
|
|
726
|
+
logger.info(`Config file location: ${logger.highlight(configPath)}`);
|
|
727
|
+
console.log();
|
|
728
|
+
|
|
729
|
+
// Read existing config or create new one
|
|
730
|
+
let config = {};
|
|
731
|
+
let configExists = false;
|
|
732
|
+
|
|
733
|
+
if (fs.existsSync(configPath)) {
|
|
734
|
+
try {
|
|
735
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
736
|
+
config = JSON.parse(content);
|
|
737
|
+
configExists = true;
|
|
738
|
+
logger.info('Found existing Claude Code MCP configuration');
|
|
739
|
+
} catch (error) {
|
|
740
|
+
logger.warn(`Failed to parse existing config: ${error.message}`);
|
|
741
|
+
logger.info('Will create a new configuration file');
|
|
742
|
+
}
|
|
743
|
+
} else {
|
|
744
|
+
logger.info('Configuration file does not exist, will create it');
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// Ensure mcpServers object exists
|
|
748
|
+
if (!config.mcpServers) {
|
|
749
|
+
config.mcpServers = {};
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// Check if meldoc is already configured
|
|
753
|
+
if (config.mcpServers.meldoc) {
|
|
754
|
+
const existingConfig = config.mcpServers.meldoc;
|
|
755
|
+
// For Claude Code, compare type, command, and args
|
|
756
|
+
const isEqual = existingConfig.type === expectedConfig.type &&
|
|
757
|
+
existingConfig.command === expectedConfig.command &&
|
|
758
|
+
Array.isArray(existingConfig.args) &&
|
|
759
|
+
Array.isArray(expectedConfig.args) &&
|
|
760
|
+
existingConfig.args.length === expectedConfig.args.length &&
|
|
761
|
+
existingConfig.args.every((arg, i) => arg === expectedConfig.args[i]);
|
|
762
|
+
|
|
763
|
+
if (isEqual) {
|
|
764
|
+
logger.success('Meldoc MCP is already configured correctly!');
|
|
765
|
+
console.log();
|
|
766
|
+
logger.info('Current configuration:');
|
|
767
|
+
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
768
|
+
console.log();
|
|
769
|
+
logger.info('No changes needed. Next steps:');
|
|
770
|
+
console.log(' 1. Restart Claude Code (if you haven\'t already)');
|
|
771
|
+
console.log(' 2. Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
772
|
+
console.log();
|
|
773
|
+
process.exit(0);
|
|
774
|
+
} else {
|
|
775
|
+
logger.warn('Meldoc MCP is already configured, but with different settings');
|
|
776
|
+
console.log();
|
|
777
|
+
logger.info('Current configuration:');
|
|
778
|
+
console.log(' ' + logger.highlight(JSON.stringify(existingConfig, null, 2)));
|
|
779
|
+
console.log();
|
|
780
|
+
logger.info('Expected configuration:');
|
|
781
|
+
console.log(' ' + logger.highlight(JSON.stringify(expectedConfig, null, 2)));
|
|
782
|
+
console.log();
|
|
783
|
+
logger.info('Updating configuration...');
|
|
784
|
+
console.log();
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// Add/update meldoc configuration
|
|
789
|
+
config.mcpServers.meldoc = expectedConfig;
|
|
790
|
+
|
|
791
|
+
// Create directory if it doesn't exist (for user/local scope)
|
|
792
|
+
if (scope !== 'project' && !fs.existsSync(configDir)) {
|
|
793
|
+
logger.info(`Creating directory: ${configDir}`);
|
|
794
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Write config file
|
|
798
|
+
const configContent = JSON.stringify(config, null, 2);
|
|
799
|
+
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
800
|
+
|
|
801
|
+
logger.success('Configuration ' + (configExists && config.mcpServers.meldoc ? 'updated' : 'added') + ' successfully!');
|
|
802
|
+
console.log();
|
|
803
|
+
|
|
804
|
+
// Show what was added
|
|
805
|
+
logger.info('MCP server configuration:');
|
|
806
|
+
console.log(' ' + logger.highlight(JSON.stringify(config.mcpServers.meldoc, null, 2)));
|
|
807
|
+
console.log();
|
|
808
|
+
|
|
809
|
+
// Count other MCP servers
|
|
810
|
+
const otherServers = Object.keys(config.mcpServers).filter(key => key !== 'meldoc');
|
|
811
|
+
if (otherServers.length > 0) {
|
|
812
|
+
logger.info(`Found ${otherServers.length} other MCP server(s): ${otherServers.join(', ')}`);
|
|
813
|
+
console.log();
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// Next steps
|
|
817
|
+
logger.section('✅ Installation Complete!');
|
|
818
|
+
console.log();
|
|
819
|
+
logger.info('Next steps:');
|
|
820
|
+
console.log();
|
|
821
|
+
console.log(' 1. ' + logger.label('Restart Claude Code'));
|
|
822
|
+
console.log(' Completely close and reopen Claude Code for changes to take effect.');
|
|
823
|
+
console.log();
|
|
824
|
+
console.log(' 2. ' + logger.label('Authenticate with Meldoc'));
|
|
825
|
+
console.log(' Run: ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
826
|
+
console.log();
|
|
827
|
+
console.log(' 3. ' + logger.label('Start using Claude Code with Meldoc!'));
|
|
828
|
+
console.log(' Ask Claude Code to read, search, or update your documentation.');
|
|
829
|
+
console.log();
|
|
830
|
+
|
|
831
|
+
process.exit(0);
|
|
832
|
+
} catch (error) {
|
|
833
|
+
const configPath = scope === 'project' ? getClaudeCodeProjectConfigPath() : getClaudeCodeUserConfigPath();
|
|
834
|
+
logger.error(`Installation failed: ${error.message}`);
|
|
835
|
+
console.log();
|
|
836
|
+
logger.info('You can manually configure Claude Code by:');
|
|
837
|
+
console.log(' 1. Opening the config file: ' + logger.highlight(configPath));
|
|
838
|
+
console.log(' 2. Adding this configuration:');
|
|
839
|
+
console.log(' ' + logger.highlight(JSON.stringify({
|
|
840
|
+
mcpServers: {
|
|
841
|
+
meldoc: getExpectedMeldocConfigForClaudeCode()
|
|
842
|
+
}
|
|
843
|
+
}, null, 2)));
|
|
844
|
+
console.log();
|
|
845
|
+
logger.info('Or use the CLI command:');
|
|
846
|
+
console.log(' ' + logger.highlight(`claude mcp add --transport stdio meldoc -- npx -y @meldocio/mcp-stdio-proxy@latest --scope ${scope}`));
|
|
847
|
+
console.log();
|
|
848
|
+
process.exit(1);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* Handle install command - automatically configure MCP client
|
|
854
|
+
*/
|
|
855
|
+
function handleInstall(consumer, isLocal) {
|
|
856
|
+
if (isLocal) {
|
|
857
|
+
installLocal();
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
const consumerLower = (consumer || 'claude-desktop').toLowerCase();
|
|
862
|
+
|
|
863
|
+
switch (consumerLower) {
|
|
864
|
+
case 'claude-desktop':
|
|
865
|
+
case 'claude':
|
|
866
|
+
installClaudeDesktop();
|
|
867
|
+
break;
|
|
868
|
+
case 'cursor':
|
|
869
|
+
installCursor(false); // Project-specific by default
|
|
870
|
+
break;
|
|
871
|
+
case 'cursor-global':
|
|
872
|
+
installCursor(true);
|
|
873
|
+
break;
|
|
874
|
+
case 'claude-code':
|
|
875
|
+
installClaudeCode('project'); // Project scope by default
|
|
876
|
+
break;
|
|
877
|
+
case 'claude-code-user':
|
|
878
|
+
installClaudeCode('user');
|
|
879
|
+
break;
|
|
880
|
+
case 'claude-code-local':
|
|
881
|
+
installClaudeCode('local');
|
|
882
|
+
break;
|
|
883
|
+
default:
|
|
884
|
+
logger.error(`Unknown consumer: ${consumer}`);
|
|
885
|
+
console.log();
|
|
886
|
+
logger.info('Supported consumers:');
|
|
887
|
+
console.log(' ' + logger.highlight('claude-desktop') + ' (or claude) - Claude Desktop');
|
|
888
|
+
console.log(' ' + logger.highlight('cursor') + ' - Cursor IDE (project-specific)');
|
|
889
|
+
console.log(' ' + logger.highlight('cursor-global') + ' - Cursor IDE (global)');
|
|
890
|
+
console.log(' ' + logger.highlight('claude-code') + ' - Claude Code (project scope)');
|
|
891
|
+
console.log(' ' + logger.highlight('claude-code-user') + ' - Claude Code (user scope)');
|
|
892
|
+
console.log(' ' + logger.highlight('claude-code-local') + ' - Claude Code (local scope)');
|
|
893
|
+
console.log();
|
|
894
|
+
logger.info('Or use ' + logger.highlight('--local') + ' flag to create local mcp.json');
|
|
895
|
+
console.log();
|
|
896
|
+
process.exit(1);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
373
900
|
/**
|
|
374
901
|
* Handle uninstall command - remove Meldoc MCP configuration from Claude Desktop
|
|
375
902
|
*/
|
|
@@ -493,8 +1020,10 @@ function handleHelp() {
|
|
|
493
1020
|
console.log(' List all available workspaces');
|
|
494
1021
|
console.log();
|
|
495
1022
|
|
|
496
|
-
console.log(' ' + logger.highlight('install'));
|
|
497
|
-
console.log(' Automatically configure
|
|
1023
|
+
console.log(' ' + logger.highlight('install [consumer] [--local]'));
|
|
1024
|
+
console.log(' Automatically configure MCP client for Meldoc MCP');
|
|
1025
|
+
console.log(' Consumers: claude-desktop (default), cursor, cursor-global, claude-code');
|
|
1026
|
+
console.log(' Use --local flag to create local mcp.json file');
|
|
498
1027
|
console.log();
|
|
499
1028
|
|
|
500
1029
|
console.log(' ' + logger.highlight('uninstall'));
|
|
@@ -507,6 +1036,10 @@ function handleHelp() {
|
|
|
507
1036
|
|
|
508
1037
|
console.log(logger.label('Examples:'));
|
|
509
1038
|
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install'));
|
|
1039
|
+
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install claude-desktop'));
|
|
1040
|
+
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install cursor'));
|
|
1041
|
+
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install claude-code'));
|
|
1042
|
+
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy install --local'));
|
|
510
1043
|
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy uninstall'));
|
|
511
1044
|
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy auth login'));
|
|
512
1045
|
console.log(' ' + logger.highlight('npx @meldocio/mcp-stdio-proxy config set-workspace my-workspace'));
|
|
@@ -529,7 +1062,7 @@ function showUsageHints() {
|
|
|
529
1062
|
console.log(' ' + logger.highlight('config set-workspace') + ' - Set workspace alias');
|
|
530
1063
|
console.log(' ' + logger.highlight('config get-workspace') + ' - Get current workspace');
|
|
531
1064
|
console.log(' ' + logger.highlight('config list-workspaces') + ' - List workspaces');
|
|
532
|
-
console.log(' ' + logger.highlight('install') + '
|
|
1065
|
+
console.log(' ' + logger.highlight('install [consumer]') + ' - Configure MCP client');
|
|
533
1066
|
console.log(' ' + logger.highlight('uninstall') + ' - Remove configuration');
|
|
534
1067
|
console.log(' ' + logger.highlight('help') + ' - Show detailed help');
|
|
535
1068
|
console.log();
|
|
@@ -557,7 +1090,19 @@ async function main() {
|
|
|
557
1090
|
if (command === 'help' || command === '--help' || command === '-h') {
|
|
558
1091
|
handleHelp();
|
|
559
1092
|
} else if (command === 'install') {
|
|
560
|
-
|
|
1093
|
+
// Parse install arguments
|
|
1094
|
+
let consumer = null;
|
|
1095
|
+
let isLocal = false;
|
|
1096
|
+
|
|
1097
|
+
for (let i = 1; i < args.length; i++) {
|
|
1098
|
+
if (args[i] === '--local' || args[i] === '-l') {
|
|
1099
|
+
isLocal = true;
|
|
1100
|
+
} else if (!args[i].startsWith('--') && !args[i].startsWith('-')) {
|
|
1101
|
+
consumer = args[i];
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
handleInstall(consumer, isLocal);
|
|
561
1106
|
} else if (command === 'uninstall') {
|
|
562
1107
|
handleUninstall();
|
|
563
1108
|
} else if (command === 'auth') {
|
|
@@ -617,5 +1162,9 @@ module.exports = {
|
|
|
617
1162
|
handleConfigGetWorkspace,
|
|
618
1163
|
handleConfigListWorkspaces,
|
|
619
1164
|
handleInstall,
|
|
620
|
-
handleUninstall
|
|
1165
|
+
handleUninstall,
|
|
1166
|
+
installClaudeDesktop,
|
|
1167
|
+
installCursor,
|
|
1168
|
+
installClaudeCode,
|
|
1169
|
+
installLocal
|
|
621
1170
|
};
|
package/lib/workspace.js
CHANGED
|
@@ -4,16 +4,16 @@ const yaml = require('js-yaml');
|
|
|
4
4
|
const { getWorkspaceAlias: getConfigWorkspaceAlias } = require('./config');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Find
|
|
7
|
+
* Find meldoc.config.yml file in current directory or parent directories
|
|
8
8
|
* @param {string} startDir - Starting directory
|
|
9
|
-
* @returns {string|null} Path to
|
|
9
|
+
* @returns {string|null} Path to meldoc.config.yml or null if not found
|
|
10
10
|
*/
|
|
11
11
|
function findRepoConfig(startDir = process.cwd()) {
|
|
12
12
|
let currentDir = path.resolve(startDir);
|
|
13
13
|
const root = path.parse(currentDir).root;
|
|
14
14
|
|
|
15
15
|
while (currentDir !== root) {
|
|
16
|
-
const configPath = path.join(currentDir, '
|
|
16
|
+
const configPath = path.join(currentDir, 'meldoc.config.yml');
|
|
17
17
|
if (fs.existsSync(configPath)) {
|
|
18
18
|
return configPath;
|
|
19
19
|
}
|
|
@@ -24,15 +24,15 @@ function findRepoConfig(startDir = process.cwd()) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Read workspace alias from
|
|
28
|
-
* @param {string} configPath - Path to
|
|
27
|
+
* Read workspace alias from meldoc.config.yml
|
|
28
|
+
* @param {string} configPath - Path to meldoc.config.yml
|
|
29
29
|
* @returns {string|null} Workspace alias or null
|
|
30
30
|
*/
|
|
31
31
|
function readRepoConfig(configPath) {
|
|
32
32
|
try {
|
|
33
33
|
const content = fs.readFileSync(configPath, 'utf8');
|
|
34
34
|
const config = yaml.load(content);
|
|
35
|
-
return config?.
|
|
35
|
+
return config?.workspaceAlias || null;
|
|
36
36
|
} catch (error) {
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
@@ -41,7 +41,7 @@ function readRepoConfig(configPath) {
|
|
|
41
41
|
/**
|
|
42
42
|
* Resolve workspace alias for request
|
|
43
43
|
* Priority:
|
|
44
|
-
* 1. Repo config (
|
|
44
|
+
* 1. Repo config (meldoc.config.yml) - optional, can be skipped
|
|
45
45
|
* 2. Global config (~/.meldoc/config.json)
|
|
46
46
|
* 3. No header (let server choose automatically)
|
|
47
47
|
* @param {boolean} useRepoConfig - Whether to check repo config (optional)
|