hsh19900502 1.0.21 → 1.0.22
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.md +38 -1
- package/README.md +158 -0
- package/dist/commands/mcp.d.ts +4 -0
- package/dist/commands/mcp.js +79 -0
- package/dist/hsh.js +11 -0
- package/package.json +1 -1
- package/src/commands/mcp.ts +118 -0
- package/src/hsh.ts +13 -0
package/CLAUDE.md
CHANGED
|
@@ -47,7 +47,8 @@ src/
|
|
|
47
47
|
├── commands/
|
|
48
48
|
│ ├── git.ts # Git workflow commands (gcm, push, merge, mr, branchout)
|
|
49
49
|
│ ├── mono.ts # Monorepo management (init, cd)
|
|
50
|
-
│
|
|
50
|
+
│ ├── ide.ts # IDE integration (cursor, surf)
|
|
51
|
+
│ └── mcp.ts # MCP server synchronization
|
|
51
52
|
├── types/
|
|
52
53
|
│ └── index.ts # TypeScript type definitions
|
|
53
54
|
└── util.ts # Utility functions (package.json reading)
|
|
@@ -91,6 +92,14 @@ The CLI follows a modular command structure using Commander.js:
|
|
|
91
92
|
- `cursor`: Open project in Cursor editor with config-based project selection
|
|
92
93
|
- `surf`: Open project in Windsurf editor with config-based project selection
|
|
93
94
|
|
|
95
|
+
### MCP Server Management
|
|
96
|
+
|
|
97
|
+
- `mcp sync`: Synchronize MCP server configurations from `~/.mcp/servers.json` to all projects in `~/.claude.json`
|
|
98
|
+
- This addresses the limitation that Claude Code cannot install MCP servers globally
|
|
99
|
+
- Automatically updates all project configurations with centralized MCP server definitions
|
|
100
|
+
- Idempotent operation - safe to run multiple times
|
|
101
|
+
- Useful for maintaining consistent MCP configurations across multiple projects
|
|
102
|
+
|
|
94
103
|
## Configuration Requirements
|
|
95
104
|
|
|
96
105
|
### IDE Configuration
|
|
@@ -116,6 +125,34 @@ For monorepo commands, projects should have:
|
|
|
116
125
|
- `.hsh` marker file in the root (created by `mono init`)
|
|
117
126
|
- Directory structure: `<repo-name>/client/` and `<repo-name>/server/`
|
|
118
127
|
|
|
128
|
+
### MCP Server Configuration
|
|
129
|
+
|
|
130
|
+
MCP (Model Context Protocol) servers can be centrally managed:
|
|
131
|
+
|
|
132
|
+
- Create `~/.mcp/servers.json` with your global MCP server configurations
|
|
133
|
+
- Run `hsh mcp sync` to propagate configurations to all projects in `~/.claude.json`
|
|
134
|
+
- Each project's `mcpServers` field will be updated with the latest configuration
|
|
135
|
+
|
|
136
|
+
Example `~/.mcp/servers.json`:
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"chrome-devtools": {
|
|
140
|
+
"type": "stdio",
|
|
141
|
+
"command": "npx",
|
|
142
|
+
"args": ["chrome-devtools-mcp@latest"],
|
|
143
|
+
"env": {}
|
|
144
|
+
},
|
|
145
|
+
"GitLab communication server": {
|
|
146
|
+
"command": "npx",
|
|
147
|
+
"args": ["-y", "@zereight/mcp-gitlab"],
|
|
148
|
+
"env": {
|
|
149
|
+
"GITLAB_PERSONAL_ACCESS_TOKEN": "your-token",
|
|
150
|
+
"GITLAB_API_URL": "https://gitlab.example.com/api/v4"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
119
156
|
## External Dependencies
|
|
120
157
|
|
|
121
158
|
### Required CLI Tools
|
package/README.md
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# hsh - CLI Workflow Automation Tool
|
|
2
|
+
|
|
3
|
+
A TypeScript-based CLI tool that provides Git workflow automation, IDE project management, and MCP server configuration synchronization.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
yarn install
|
|
9
|
+
yarn build:install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
### Git Workflow Automation
|
|
15
|
+
- `hsh gcm <message> [--push]` - Add all, commit with message, optionally push
|
|
16
|
+
- `hsh push` - Interactive branch selection for pushing to remote
|
|
17
|
+
- `hsh merge <branch>` - Safe merge with branch switching and pulling
|
|
18
|
+
- `hsh mr create` - Create merge requests with JIRA integration
|
|
19
|
+
- `hsh branchout <branch>` - Create new branch from master
|
|
20
|
+
|
|
21
|
+
### Monorepo Management
|
|
22
|
+
- `hsh mono init` - Initialize workspace with `.hsh` marker file
|
|
23
|
+
- `hsh mono cd <level> [--repo <name>]` - Navigate to repo directories (root/client/server)
|
|
24
|
+
|
|
25
|
+
### IDE Integration
|
|
26
|
+
- `hsh cursor` - Open project in Cursor editor with config-based project selection
|
|
27
|
+
- `hsh claude` - Open project in Claude Code editor with config-based project selection
|
|
28
|
+
|
|
29
|
+
### MCP Server Management
|
|
30
|
+
|
|
31
|
+
**NEW!** Solve the problem of having to configure MCP servers individually for each project.
|
|
32
|
+
|
|
33
|
+
#### The Problem
|
|
34
|
+
Claude Code doesn't support global MCP server installation. You have to configure MCP servers in each project's `.claude.json` file individually, which is tedious and error-prone.
|
|
35
|
+
|
|
36
|
+
#### The Solution
|
|
37
|
+
`hsh mcp sync` - Synchronize MCP server configurations from a central location to all your projects
|
|
38
|
+
|
|
39
|
+
#### How It Works
|
|
40
|
+
|
|
41
|
+
1. Create a central MCP configuration file at `~/.mcp/servers.json`:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"chrome-devtools": {
|
|
46
|
+
"type": "stdio",
|
|
47
|
+
"command": "npx",
|
|
48
|
+
"args": ["chrome-devtools-mcp@latest"],
|
|
49
|
+
"env": {}
|
|
50
|
+
},
|
|
51
|
+
"GitLab communication server": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["-y", "@zereight/mcp-gitlab"],
|
|
54
|
+
"env": {
|
|
55
|
+
"GITLAB_PERSONAL_ACCESS_TOKEN": "your-token",
|
|
56
|
+
"GITLAB_API_URL": "https://gitlab.example.com/api/v4"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"jira": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "@aashari/mcp-server-atlassian-jira"],
|
|
62
|
+
"env": {
|
|
63
|
+
"ATLASSIAN_SITE_NAME": "your-site",
|
|
64
|
+
"ATLASSIAN_USER_EMAIL": "your-email",
|
|
65
|
+
"ATLASSIAN_API_TOKEN": "your-token"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. Run the sync command:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
hsh mcp sync
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
3. The command will:
|
|
78
|
+
- Read all MCP server configurations from `~/.mcp/servers.json`
|
|
79
|
+
- Update the `mcpServers` field for all projects in `~/.claude.json`
|
|
80
|
+
- Show you which servers were synced and how many projects were updated
|
|
81
|
+
|
|
82
|
+
#### Features
|
|
83
|
+
- ✅ Idempotent - Safe to run multiple times
|
|
84
|
+
- ✅ Atomic updates - Updates all projects at once
|
|
85
|
+
- ✅ Clear feedback - Shows which servers and projects were updated
|
|
86
|
+
- ✅ Validation - Checks for file existence and valid JSON
|
|
87
|
+
|
|
88
|
+
#### Example Output
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
$ hsh mcp sync
|
|
92
|
+
✔ Successfully synced MCP servers to 21 projects
|
|
93
|
+
|
|
94
|
+
MCP Servers synced:
|
|
95
|
+
• chrome-devtools
|
|
96
|
+
• Playwright
|
|
97
|
+
• figma-mcp
|
|
98
|
+
• GitLab communication server
|
|
99
|
+
• jira
|
|
100
|
+
• confluence
|
|
101
|
+
|
|
102
|
+
Projects updated:
|
|
103
|
+
• /Users/you/project1
|
|
104
|
+
• /Users/you/project2
|
|
105
|
+
• /Users/you/project3
|
|
106
|
+
... and 18 more
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Configuration
|
|
110
|
+
|
|
111
|
+
### IDE Configuration
|
|
112
|
+
Create `~/hsh.config.json` for IDE project management:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"work": {
|
|
117
|
+
"project1": "/path/to/work/project1",
|
|
118
|
+
"project2": "/path/to/work/project2"
|
|
119
|
+
},
|
|
120
|
+
"personal": {
|
|
121
|
+
"project3": "/path/to/personal/project3"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Monorepo Setup
|
|
127
|
+
For monorepo commands, projects should have:
|
|
128
|
+
- `.hsh` marker file in the root (created by `hsh mono init`)
|
|
129
|
+
- Directory structure: `<repo-name>/client/` and `<repo-name>/server/`
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Install dependencies
|
|
135
|
+
yarn install
|
|
136
|
+
|
|
137
|
+
# Build the project
|
|
138
|
+
yarn build
|
|
139
|
+
|
|
140
|
+
# Build and install globally
|
|
141
|
+
yarn build:install
|
|
142
|
+
|
|
143
|
+
# Development mode
|
|
144
|
+
yarn dev
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Requirements
|
|
148
|
+
|
|
149
|
+
- Node.js with ES module support
|
|
150
|
+
- Git
|
|
151
|
+
- GitLab CLI (`glab`) for merge request features
|
|
152
|
+
- Cursor editor (for `cursor` command)
|
|
153
|
+
- Claude Code editor (for `claude` command)
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT
|
|
158
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
/**
|
|
7
|
+
* Sync MCP servers from ~/.mcp/servers.json to all projects in ~/.claude.json
|
|
8
|
+
*/
|
|
9
|
+
export async function syncMcpServers() {
|
|
10
|
+
const spinner = ora('Syncing MCP servers...').start();
|
|
11
|
+
try {
|
|
12
|
+
// Read MCP servers configuration
|
|
13
|
+
const mcpConfigPath = join(homedir(), '.mcp', 'servers.json');
|
|
14
|
+
const claudeConfigPath = join(homedir(), '.claude.json');
|
|
15
|
+
let mcpServers;
|
|
16
|
+
try {
|
|
17
|
+
const mcpConfigContent = readFileSync(mcpConfigPath, 'utf-8');
|
|
18
|
+
mcpServers = JSON.parse(mcpConfigContent);
|
|
19
|
+
spinner.text = `Found ${Object.keys(mcpServers).length} MCP servers`;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
spinner.fail(chalk.red(`Failed to read MCP servers from ${mcpConfigPath}`));
|
|
23
|
+
console.error(chalk.yellow(`Please ensure ${mcpConfigPath} exists and is valid JSON`));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Read Claude configuration
|
|
27
|
+
let claudeConfig;
|
|
28
|
+
try {
|
|
29
|
+
const claudeConfigContent = readFileSync(claudeConfigPath, 'utf-8');
|
|
30
|
+
claudeConfig = JSON.parse(claudeConfigContent);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
spinner.fail(chalk.red(`Failed to read Claude config from ${claudeConfigPath}`));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Check if there are any projects
|
|
37
|
+
if (!claudeConfig.projects || Object.keys(claudeConfig.projects).length === 0) {
|
|
38
|
+
spinner.warn(chalk.yellow('No projects found in ~/.claude.json'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Update each project with MCP servers
|
|
42
|
+
const projectPaths = Object.keys(claudeConfig.projects);
|
|
43
|
+
spinner.text = `Updating ${projectPaths.length} projects...`;
|
|
44
|
+
let updatedCount = 0;
|
|
45
|
+
for (const projectPath of projectPaths) {
|
|
46
|
+
const project = claudeConfig.projects[projectPath];
|
|
47
|
+
// Check if mcpServers need to be updated
|
|
48
|
+
const currentServers = JSON.stringify(project.mcpServers || {});
|
|
49
|
+
const newServers = JSON.stringify(mcpServers);
|
|
50
|
+
if (currentServers !== newServers) {
|
|
51
|
+
project.mcpServers = mcpServers;
|
|
52
|
+
updatedCount++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Write back to ~/.claude.json
|
|
56
|
+
if (updatedCount > 0) {
|
|
57
|
+
writeFileSync(claudeConfigPath, JSON.stringify(claudeConfig, null, 2), 'utf-8');
|
|
58
|
+
spinner.succeed(chalk.green(`✓ Successfully synced MCP servers to ${updatedCount} project${updatedCount > 1 ? 's' : ''}`));
|
|
59
|
+
console.log(chalk.cyan('\nMCP Servers synced:'));
|
|
60
|
+
Object.keys(mcpServers).forEach(serverName => {
|
|
61
|
+
console.log(chalk.gray(` • ${serverName}`));
|
|
62
|
+
});
|
|
63
|
+
console.log(chalk.cyan('\nProjects updated:'));
|
|
64
|
+
projectPaths.slice(0, 5).forEach(path => {
|
|
65
|
+
console.log(chalk.gray(` • ${path}`));
|
|
66
|
+
});
|
|
67
|
+
if (projectPaths.length > 5) {
|
|
68
|
+
console.log(chalk.gray(` ... and ${projectPaths.length - 5} more`));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
spinner.info(chalk.blue('All projects already have the latest MCP servers configuration'));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
spinner.fail(chalk.red('Failed to sync MCP servers'));
|
|
77
|
+
console.error(chalk.red(error.message));
|
|
78
|
+
}
|
|
79
|
+
}
|
package/dist/hsh.js
CHANGED
|
@@ -5,6 +5,7 @@ import { initMonoRepo, monoCd } from './commands/mono.js';
|
|
|
5
5
|
import { getPackageJson } from './util.js';
|
|
6
6
|
import { openIDE } from './commands/ide.js';
|
|
7
7
|
import { cloudLogin, cloudScp } from './commands/cloud.js';
|
|
8
|
+
import { syncMcpServers } from './commands/mcp.js';
|
|
8
9
|
const packageJson = getPackageJson();
|
|
9
10
|
const program = new Command();
|
|
10
11
|
program.usage('<command> [options]');
|
|
@@ -90,4 +91,14 @@ cloudCommand
|
|
|
90
91
|
.action(async (localPath, remotePath, options) => {
|
|
91
92
|
await cloudScp(localPath, remotePath, options);
|
|
92
93
|
});
|
|
94
|
+
// MCP management commands
|
|
95
|
+
const mcpCommand = program
|
|
96
|
+
.command('mcp')
|
|
97
|
+
.description('MCP (Model Context Protocol) server management');
|
|
98
|
+
mcpCommand
|
|
99
|
+
.command('sync')
|
|
100
|
+
.description('Sync MCP servers from ~/.mcp/servers.json to all projects in ~/.claude.json')
|
|
101
|
+
.action(async () => {
|
|
102
|
+
await syncMcpServers();
|
|
103
|
+
});
|
|
93
104
|
program.parse();
|
package/package.json
CHANGED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { $ } from 'zx';
|
|
2
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
|
|
8
|
+
interface McpServerConfig {
|
|
9
|
+
[serverName: string]: {
|
|
10
|
+
type?: string;
|
|
11
|
+
command: string;
|
|
12
|
+
args: string[];
|
|
13
|
+
env?: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ClaudeConfig {
|
|
18
|
+
projects: {
|
|
19
|
+
[projectPath: string]: {
|
|
20
|
+
mcpServers?: McpServerConfig;
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Sync MCP servers from ~/.mcp/servers.json to all projects in ~/.claude.json
|
|
29
|
+
*/
|
|
30
|
+
export async function syncMcpServers() {
|
|
31
|
+
const spinner = ora('Syncing MCP servers...').start();
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// Read MCP servers configuration
|
|
35
|
+
const mcpConfigPath = join(homedir(), '.mcp', 'servers.json');
|
|
36
|
+
const claudeConfigPath = join(homedir(), '.claude.json');
|
|
37
|
+
|
|
38
|
+
let mcpServers: McpServerConfig;
|
|
39
|
+
try {
|
|
40
|
+
const mcpConfigContent = readFileSync(mcpConfigPath, 'utf-8');
|
|
41
|
+
mcpServers = JSON.parse(mcpConfigContent);
|
|
42
|
+
spinner.text = `Found ${Object.keys(mcpServers).length} MCP servers`;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
spinner.fail(chalk.red(`Failed to read MCP servers from ${mcpConfigPath}`));
|
|
45
|
+
console.error(chalk.yellow(`Please ensure ${mcpConfigPath} exists and is valid JSON`));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Read Claude configuration
|
|
50
|
+
let claudeConfig: ClaudeConfig;
|
|
51
|
+
try {
|
|
52
|
+
const claudeConfigContent = readFileSync(claudeConfigPath, 'utf-8');
|
|
53
|
+
claudeConfig = JSON.parse(claudeConfigContent);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
spinner.fail(chalk.red(`Failed to read Claude config from ${claudeConfigPath}`));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Check if there are any projects
|
|
60
|
+
if (!claudeConfig.projects || Object.keys(claudeConfig.projects).length === 0) {
|
|
61
|
+
spinner.warn(chalk.yellow('No projects found in ~/.claude.json'));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Update each project with MCP servers
|
|
66
|
+
const projectPaths = Object.keys(claudeConfig.projects);
|
|
67
|
+
spinner.text = `Updating ${projectPaths.length} projects...`;
|
|
68
|
+
|
|
69
|
+
let updatedCount = 0;
|
|
70
|
+
for (const projectPath of projectPaths) {
|
|
71
|
+
const project = claudeConfig.projects[projectPath];
|
|
72
|
+
|
|
73
|
+
// Check if mcpServers need to be updated
|
|
74
|
+
const currentServers = JSON.stringify(project.mcpServers || {});
|
|
75
|
+
const newServers = JSON.stringify(mcpServers);
|
|
76
|
+
|
|
77
|
+
if (currentServers !== newServers) {
|
|
78
|
+
project.mcpServers = mcpServers;
|
|
79
|
+
updatedCount++;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Write back to ~/.claude.json
|
|
84
|
+
if (updatedCount > 0) {
|
|
85
|
+
writeFileSync(
|
|
86
|
+
claudeConfigPath,
|
|
87
|
+
JSON.stringify(claudeConfig, null, 2),
|
|
88
|
+
'utf-8'
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
spinner.succeed(
|
|
92
|
+
chalk.green(
|
|
93
|
+
`✓ Successfully synced MCP servers to ${updatedCount} project${updatedCount > 1 ? 's' : ''}`
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
console.log(chalk.cyan('\nMCP Servers synced:'));
|
|
98
|
+
Object.keys(mcpServers).forEach(serverName => {
|
|
99
|
+
console.log(chalk.gray(` • ${serverName}`));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
console.log(chalk.cyan('\nProjects updated:'));
|
|
103
|
+
projectPaths.slice(0, 5).forEach(path => {
|
|
104
|
+
console.log(chalk.gray(` • ${path}`));
|
|
105
|
+
});
|
|
106
|
+
if (projectPaths.length > 5) {
|
|
107
|
+
console.log(chalk.gray(` ... and ${projectPaths.length - 5} more`));
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
spinner.info(chalk.blue('All projects already have the latest MCP servers configuration'));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
} catch (error: any) {
|
|
114
|
+
spinner.fail(chalk.red('Failed to sync MCP servers'));
|
|
115
|
+
console.error(chalk.red(error.message));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
package/src/hsh.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { RepoDirLevel } from './types/index.js';
|
|
|
6
6
|
import { getPackageJson } from './util.js';
|
|
7
7
|
import { openIDE } from './commands/ide.js';
|
|
8
8
|
import { cloudLogin, cloudScp } from './commands/cloud.js';
|
|
9
|
+
import { syncMcpServers } from './commands/mcp.js';
|
|
9
10
|
|
|
10
11
|
const packageJson = getPackageJson();
|
|
11
12
|
|
|
@@ -108,4 +109,16 @@ cloudCommand
|
|
|
108
109
|
await cloudScp(localPath, remotePath, options);
|
|
109
110
|
});
|
|
110
111
|
|
|
112
|
+
// MCP management commands
|
|
113
|
+
const mcpCommand = program
|
|
114
|
+
.command('mcp')
|
|
115
|
+
.description('MCP (Model Context Protocol) server management');
|
|
116
|
+
|
|
117
|
+
mcpCommand
|
|
118
|
+
.command('sync')
|
|
119
|
+
.description('Sync MCP servers from ~/.mcp/servers.json to all projects in ~/.claude.json')
|
|
120
|
+
.action(async () => {
|
|
121
|
+
await syncMcpServers();
|
|
122
|
+
});
|
|
123
|
+
|
|
111
124
|
program.parse();
|