mcpick 0.0.21 → 0.0.23
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/CHANGELOG.md +30 -5
- package/README.md +150 -127
- package/dist/add-LJQa2my2.js +164 -0
- package/dist/add-json-TEdYweZ5.js +95 -0
- package/dist/{backup-DSDhHI5f.js → backup-kyS5IVIr.js} +4 -4
- package/dist/{cache-D6kd7qE8.js → cache-DTfzTsEE.js} +3 -3
- package/dist/cli-By-0nYNQ.js +112 -0
- package/dist/clients-qMozizys.js +30 -0
- package/dist/{clone-DYKPEsar.js → clone-BVhYjRGO.js} +5 -6
- package/dist/{config-DijVdEFn.js → config-DzMmTJYL.js} +2 -2
- package/dist/{dev-DRJRNp7y.js → dev-Cst8WkQ-.js} +5 -5
- package/dist/disable-BaOs9lrm.js +83 -0
- package/dist/enable--3mjSmTq.js +84 -0
- package/dist/{get-Bb1eOOIZ.js → get-CjhNWyRj.js} +3 -3
- package/dist/{hooks-Bmn7pUZa.js → hooks-DFmxgD0t.js} +3 -4
- package/dist/index.js +1929 -297
- package/dist/list-D5CkCXpP.js +100 -0
- package/dist/{marketplace-DcKk5dc1.js → marketplace-C3EGyIG0.js} +4 -5
- package/dist/output-HtT5HCof.js +17 -0
- package/dist/{plugin-cache-Bby9Dxm9.js → plugin-cache-BSgB42wa.js} +34 -15
- package/dist/{plugins-Dc7DN6R_.js → plugins-Dn2mPFKm.js} +4 -5
- package/dist/{profile-CX97sMGp.js → profile-Dq3ORPil.js} +4 -5
- package/dist/redact-wBMtzbno.js +88 -0
- package/dist/{reload-CYDhkCVZ.js → reload-257iU7Z7.js} +2 -2
- package/dist/remove-26XFzkPd.js +87 -0
- package/dist/{reset-project-choices-BfRSNN3m.js → reset-project-choices-D2F04LfC.js} +3 -3
- package/dist/{restore-DdMfUljI.js → restore-BYYsoNqF.js} +4 -5
- package/dist/rollback-CPdaME91.js +55 -0
- package/dist/skills-DfWk9mpk.js +216 -0
- package/package.json +22 -8
- package/.github/copilot-instructions.md +0 -32
- package/.github/workflows/ci.yml +0 -26
- package/.vscode/settings.json +0 -5
- package/dist/add-BDyaBew0.js +0 -113
- package/dist/add-json-BjgzdeG-.js +0 -58
- package/dist/atomic-write-BqEykHp9.js +0 -26
- package/dist/claude-cli-DnmBJrjg.js +0 -445
- package/dist/cli-CsFfnWBo.js +0 -84
- package/dist/disable-xJXZfUR_.js +0 -39
- package/dist/enable-RrpcN6la.js +0 -40
- package/dist/hook-state-Di8lUsPr.js +0 -171
- package/dist/list-B8YeDWt6.js +0 -64
- package/dist/output-BchYq0mR.js +0 -15
- package/dist/profile-DkY_lBEm.js +0 -70
- package/dist/redact-O35tjnRD.js +0 -26
- package/dist/registry-CfUKT7_C.js +0 -92
- package/dist/remove-D1owHLhG.js +0 -31
- package/dist/settings-DEcWtzLE.js +0 -201
package/CHANGELOG.md
CHANGED
|
@@ -1,25 +1,50 @@
|
|
|
1
1
|
# mcpick
|
|
2
2
|
|
|
3
|
+
## 0.0.23
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 291b1d4: Add config rollback command, scoped Claude removals, author
|
|
8
|
+
metadata, and rollback backup tests.
|
|
9
|
+
- 92a0d0e: Improve marketplace add validation, authentication checks,
|
|
10
|
+
and error messages for GitHub repository access failures.
|
|
11
|
+
- 1d191a5: Add safer config writes, non-Claude client mutation
|
|
12
|
+
commands, shell-free git execution, and adapter tests.
|
|
13
|
+
|
|
14
|
+
## 0.0.22
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 55a46c0: chore: remove outdated documentation and refresh README for
|
|
19
|
+
vendor-neutral MCPick architecture and current CLI flows
|
|
20
|
+
- f30675a: Add vendor-neutral skills management, client-first TUI
|
|
21
|
+
refactor, and safer redacted CLI output for agents.
|
|
22
|
+
|
|
3
23
|
## 0.0.21
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
6
26
|
|
|
7
|
-
- 47e40be: chore: reorder TUI menu and update README for agent-first
|
|
27
|
+
- 47e40be: chore: reorder TUI menu and update README for agent-first
|
|
28
|
+
usage
|
|
8
29
|
|
|
9
30
|
## 0.0.20
|
|
10
31
|
|
|
11
32
|
### Patch Changes
|
|
12
33
|
|
|
13
34
|
- 00ea930: chore: add unit tests and CI workflow with GitHub Actions
|
|
14
|
-
- 37a62e1: feat: auto-show help instead of TUI in non-TTY environments
|
|
15
|
-
|
|
35
|
+
- 37a62e1: feat: auto-show help instead of TUI in non-TTY environments
|
|
36
|
+
for LLM agents
|
|
37
|
+
- fc1db54: fix: replace exec with execFile to eliminate shell
|
|
38
|
+
injection on all platforms
|
|
16
39
|
|
|
17
40
|
## 0.0.19
|
|
18
41
|
|
|
19
42
|
### Patch Changes
|
|
20
43
|
|
|
21
|
-
- 5ed618e: Migrate build tooling from tsc/prettier to vite-plus, fix
|
|
22
|
-
|
|
44
|
+
- 5ed618e: Migrate build tooling from tsc/prettier to vite-plus, fix
|
|
45
|
+
all lint warnings
|
|
46
|
+
- 08997dc: feat: rewrite --help for LLM agents with workflow,
|
|
47
|
+
concepts, and examples sections
|
|
23
48
|
|
|
24
49
|
## 0.0.18
|
|
25
50
|
|
package/README.md
CHANGED
|
@@ -1,187 +1,210 @@
|
|
|
1
|
-
#
|
|
1
|
+
# MCPick
|
|
2
2
|
|
|
3
3
|
[](https://viteplus.dev)
|
|
4
4
|
[](https://vitest.dev)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
Vendor-neutral MCP configuration manager with first-class Claude Code
|
|
7
|
+
support.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
MCPick helps humans and LLM agents inspect, toggle, and back up MCP
|
|
10
|
+
server configuration across multiple AI clients. Claude Code-specific
|
|
11
|
+
plugins, hooks, marketplaces, and cache commands remain available, but
|
|
12
|
+
they are no longer the core product model.
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
## Install
|
|
12
15
|
|
|
13
|
-
```
|
|
14
|
-
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g mcpick
|
|
18
|
+
# or run without installing
|
|
19
|
+
npx mcpick --help
|
|
15
20
|
```
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
Use npx mcpick to list my plugins and disable the ones I'm not using
|
|
19
|
-
```
|
|
22
|
+
Requirements:
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
- Node.js 22+
|
|
25
|
+
- Claude Code is required only for Claude Code-specific commands
|
|
26
|
+
- The external `skills` CLI is used through `npx -y skills@latest` for
|
|
27
|
+
portable skills commands
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
instead of launching the interactive TUI — so LLM agents can read
|
|
27
|
-
`npx mcpick --help` and figure out the rest.
|
|
29
|
+
## Agent-first CLI
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
In non-TTY environments, MCPick shows help instead of launching the
|
|
32
|
+
interactive TUI. This makes it safer for prompts like:
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
(`/slash-commands`), hooks, agents, and MCP servers.
|
|
34
|
+
> “Use mcpick to work out how to enable this MCP server.”
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
Marketplace → Plugin → Skills, Hooks, Agents, MCP Servers
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Common Workflows
|
|
39
|
-
|
|
40
|
-
### Install skills from a marketplace
|
|
36
|
+
Start with:
|
|
41
37
|
|
|
42
38
|
```bash
|
|
43
|
-
|
|
44
|
-
npx mcpick
|
|
39
|
+
npx mcpick --help
|
|
40
|
+
npx mcpick clients
|
|
41
|
+
npx mcpick list --json
|
|
42
|
+
```
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
MCPick redacts known secret patterns before printing output. MCP
|
|
45
|
+
configs often contain env vars and authorization headers, so `env` and
|
|
46
|
+
`headers` values are shown as `***` in JSON output.
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
```
|
|
48
|
+
## MCP clients
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
Supported client adapters:
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
| Client | Scopes | Command examples |
|
|
53
|
+
| --------------------- | -------------------- | ------------------------------------------------- |
|
|
54
|
+
| Claude Code | local, project, user | `mcpick list`, `mcpick enable <server>` |
|
|
55
|
+
| Gemini CLI | project, user | `mcpick list --client gemini-cli --scope project` |
|
|
56
|
+
| VS Code / Copilot | project | `mcpick list --client vscode --scope project` |
|
|
57
|
+
| Cursor | project, user | `mcpick list --client cursor --scope user` |
|
|
58
|
+
| Windsurf | user | `mcpick list --client windsurf --scope user` |
|
|
59
|
+
| OpenCode | project, user | `mcpick list --client opencode --scope project` |
|
|
60
|
+
| Pi via pi-mcp-adapter | project, user | `mcpick list --client pi --scope user` |
|
|
57
61
|
|
|
58
|
-
|
|
62
|
+
Show known config locations:
|
|
59
63
|
|
|
60
64
|
```bash
|
|
61
|
-
npx mcpick
|
|
62
|
-
npx mcpick
|
|
63
|
-
npx mcpick disable <server> # Disable a server
|
|
64
|
-
npx mcpick add --name <n> ... # Add a new server
|
|
65
|
-
npx mcpick remove <server> # Remove a server
|
|
65
|
+
npx mcpick clients
|
|
66
|
+
npx mcpick clients --json
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
## MCP server commands
|
|
69
70
|
|
|
70
71
|
```bash
|
|
71
|
-
|
|
72
|
-
npx mcpick
|
|
73
|
-
npx mcpick
|
|
74
|
-
npx mcpick plugins update <key> # Update to latest
|
|
75
|
-
npx mcpick plugins enable <key> # Enable plugin
|
|
76
|
-
npx mcpick plugins disable <key> # Disable plugin
|
|
77
|
-
```
|
|
72
|
+
# List Claude Code registry/status
|
|
73
|
+
npx mcpick list
|
|
74
|
+
npx mcpick list --json
|
|
78
75
|
|
|
79
|
-
|
|
76
|
+
# List another client
|
|
77
|
+
npx mcpick list --client pi --scope user --json
|
|
78
|
+
npx mcpick list --client opencode --scope project
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
npx mcpick
|
|
83
|
-
npx mcpick
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
# Claude Code enable/disable
|
|
81
|
+
npx mcpick enable <server> --scope local
|
|
82
|
+
npx mcpick disable <server> --scope local
|
|
83
|
+
|
|
84
|
+
# Add/remove Claude Code server definitions
|
|
85
|
+
npx mcpick add --name <server> --command npx --args "-y,package-name"
|
|
86
|
+
npx mcpick add-json <name> '{"command":"npx","args":["-y","package-name"]}'
|
|
87
|
+
npx mcpick remove <server>
|
|
86
88
|
```
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
For secret-backed servers, prefer environment variable references and
|
|
91
|
+
secret-safe loading tools. MCPick redacts printed values, but MCP
|
|
92
|
+
client config files may still store secrets in plain text because that
|
|
93
|
+
is how many clients currently load MCP credentials.
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
npx mcpick hooks list # List all hooks
|
|
92
|
-
npx mcpick hooks add # Add a settings hook
|
|
93
|
-
npx mcpick hooks remove # Remove a hook
|
|
94
|
-
```
|
|
95
|
+
## Portable skills
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
MCPick delegates portable SKILL.md management to the external `skills`
|
|
98
|
+
CLI.
|
|
97
99
|
|
|
98
100
|
```bash
|
|
99
|
-
|
|
100
|
-
npx mcpick
|
|
101
|
-
npx mcpick cache clean-orphaned # Remove orphaned dirs
|
|
102
|
-
npx mcpick cache refresh # Git pull marketplaces
|
|
103
|
-
```
|
|
101
|
+
# List installed skills for a client
|
|
102
|
+
npx mcpick skills list --agent pi --json
|
|
104
103
|
|
|
105
|
-
|
|
104
|
+
# See available skills from a source without installing
|
|
105
|
+
npx mcpick skills add spences10/skills --list
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
# Install one skill
|
|
108
|
+
npx mcpick skills add spences10/skills --agent pi --skill svelte-runes --yes
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
npx mcpick --
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
# Install all skills for a client globally
|
|
111
|
+
npx mcpick skills add spences10/skills --agent opencode --skill '*' --global --yes
|
|
112
|
+
|
|
113
|
+
# Update/remove
|
|
114
|
+
npx mcpick skills update --global --yes
|
|
115
|
+
npx mcpick skills remove svelte-runes --agent pi --yes
|
|
113
116
|
```
|
|
114
117
|
|
|
115
|
-
|
|
118
|
+
## Claude Code-specific tools
|
|
119
|
+
|
|
120
|
+
These commands wrap Claude Code concepts and are intentionally
|
|
121
|
+
client-specific:
|
|
116
122
|
|
|
117
123
|
```bash
|
|
118
|
-
|
|
119
|
-
npx mcpick
|
|
124
|
+
# Plugins
|
|
125
|
+
npx mcpick plugins list
|
|
126
|
+
npx mcpick plugins install <name>@<marketplace>
|
|
127
|
+
npx mcpick plugins enable <name>@<marketplace>
|
|
128
|
+
npx mcpick plugins disable <name>@<marketplace>
|
|
129
|
+
|
|
130
|
+
# Marketplaces
|
|
131
|
+
npx mcpick marketplace list
|
|
132
|
+
npx mcpick marketplace add <source>
|
|
133
|
+
npx mcpick marketplace update
|
|
134
|
+
npx mcpick marketplace remove <name>
|
|
135
|
+
|
|
136
|
+
# Hooks and plugin cache
|
|
137
|
+
npx mcpick hooks list
|
|
138
|
+
npx mcpick cache status
|
|
139
|
+
npx mcpick cache refresh
|
|
120
140
|
```
|
|
121
141
|
|
|
122
|
-
|
|
142
|
+
## Profiles and backups
|
|
123
143
|
|
|
124
|
-
|
|
144
|
+
Profiles and backups currently preserve MCP server and Claude Code
|
|
145
|
+
plugin state.
|
|
125
146
|
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
```bash
|
|
148
|
+
npx mcpick --profile database
|
|
149
|
+
npx mcpick --save-profile mysetup
|
|
150
|
+
npx mcpick --list-profiles
|
|
128
151
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
│ ○ Manage marketplaces
|
|
136
|
-
│ ○ Manage hooks
|
|
137
|
-
│ ○ Manage plugin cache
|
|
138
|
-
│ ○ Backup config
|
|
139
|
-
│ ○ Add MCP server
|
|
140
|
-
│ ○ Restore from backup
|
|
141
|
-
│ ○ Load profile
|
|
142
|
-
│ ○ Save profile
|
|
143
|
-
│ ○ Exit
|
|
144
|
-
└
|
|
152
|
+
npx mcpick backup
|
|
153
|
+
npx mcpick restore [file]
|
|
154
|
+
|
|
155
|
+
# Safe-write rollback backups created before config mutations
|
|
156
|
+
npx mcpick rollback --list
|
|
157
|
+
npx mcpick rollback [file]
|
|
145
158
|
```
|
|
146
159
|
|
|
147
|
-
|
|
148
|
-
automatically shows `--help` instead.
|
|
160
|
+
## Interactive TUI
|
|
149
161
|
|
|
150
|
-
|
|
162
|
+
Running `npx mcpick` in a terminal launches the human-facing menu:
|
|
151
163
|
|
|
152
|
-
|
|
153
|
-
|
|
164
|
+
```text
|
|
165
|
+
MCPick - MCP Configuration Manager
|
|
154
166
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
167
|
+
What would you like to do?
|
|
168
|
+
Enable / Disable MCP servers
|
|
169
|
+
Skills
|
|
170
|
+
Client-specific tools
|
|
171
|
+
Load profile
|
|
172
|
+
Save profile
|
|
173
|
+
Backup config
|
|
174
|
+
Restore from backup
|
|
175
|
+
Exit
|
|
158
176
|
```
|
|
159
177
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
178
|
+
The primary TUI flow is client-first: choose a client, then toggle its
|
|
179
|
+
MCP servers. Claude Code plugins, hooks, marketplaces, and cache live
|
|
180
|
+
under “Client-specific tools”.
|
|
163
181
|
|
|
164
|
-
##
|
|
182
|
+
## Config locations
|
|
165
183
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
| **Local** | Project-specific servers (default) | `~/.claude.json` → `projects[cwd].mcpServers` |
|
|
169
|
-
| **Project** | Shared via `.mcp.json` in repo | `.mcp.json` in project root |
|
|
170
|
-
| **User** | Global servers for all projects | `~/.claude.json` → `mcpServers` |
|
|
184
|
+
MCPick reads the standard locations used by each client adapter.
|
|
185
|
+
Common paths include:
|
|
171
186
|
|
|
172
|
-
|
|
187
|
+
| Path | Purpose |
|
|
188
|
+
| ------------------------ | ----------------------------------------------- |
|
|
189
|
+
| `~/.claude.json` | Claude Code local/user MCP config |
|
|
190
|
+
| `.mcp.json` | Shared project MCP config |
|
|
191
|
+
| `.gemini/settings.json` | Gemini CLI project config |
|
|
192
|
+
| `.vscode/mcp.json` | VS Code / Copilot project config |
|
|
193
|
+
| `.cursor/mcp.json` | Cursor project config |
|
|
194
|
+
| `opencode.json` | OpenCode project config |
|
|
195
|
+
| `~/.config/mcp/mcp.json` | Shared global MCP config used by pi-mcp-adapter |
|
|
196
|
+
| `.pi/mcp.json` | Pi project override |
|
|
173
197
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
| `~/.claude.json` | Claude Code configuration |
|
|
177
|
-
| `.mcp.json` | Project-specific shared config |
|
|
178
|
-
| `~/.claude/mcpick/servers.json` | Server registry |
|
|
179
|
-
| `~/.claude/mcpick/backups/` | Configuration backups |
|
|
180
|
-
| `~/.claude/mcpick/profiles/` | Saved profiles |
|
|
181
|
-
| `~/.claude/plugins/cache/` | Cached plugin files |
|
|
182
|
-
| `~/.claude/plugins/marketplaces/` | Marketplace git clones |
|
|
198
|
+
MCPick-owned state lives under `~/.claude/mcpick/` for historical
|
|
199
|
+
compatibility.
|
|
183
200
|
|
|
184
|
-
##
|
|
201
|
+
## Development
|
|
185
202
|
|
|
186
|
-
|
|
187
|
-
|
|
203
|
+
```bash
|
|
204
|
+
pnpm install
|
|
205
|
+
pnpm test
|
|
206
|
+
pnpm run check
|
|
207
|
+
pnpm build
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
See `docs/VENDOR_NEUTRAL_ARCHITECTURE.md` for architecture notes.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { n as validate_mcp_server } from "./validation-xMlbgGCF.js";
|
|
2
|
+
import { A as add_client_server, F as resolve_client_location, M as get_client_adapter, d as add_mcp_via_cli, w as add_server_to_registry } from "./index.js";
|
|
3
|
+
import { n as output, t as error } from "./output-HtT5HCof.js";
|
|
4
|
+
import { defineCommand } from "citty";
|
|
5
|
+
//#region src/cli/commands/add.ts
|
|
6
|
+
var add_default = defineCommand({
|
|
7
|
+
meta: {
|
|
8
|
+
name: "add",
|
|
9
|
+
description: "Add a new MCP server to the registry and enable it"
|
|
10
|
+
},
|
|
11
|
+
args: {
|
|
12
|
+
name: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Server name",
|
|
15
|
+
required: true
|
|
16
|
+
},
|
|
17
|
+
command: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Command to run (for stdio transport)"
|
|
20
|
+
},
|
|
21
|
+
args: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Comma-separated arguments (e.g. \"npx,-y,mcp-sqlite\")"
|
|
24
|
+
},
|
|
25
|
+
url: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "URL (for sse or http transport)"
|
|
28
|
+
},
|
|
29
|
+
type: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Transport type: stdio, sse, or http (default: stdio)",
|
|
32
|
+
default: "stdio"
|
|
33
|
+
},
|
|
34
|
+
env: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Environment variables as KEY=val,KEY=val"
|
|
37
|
+
},
|
|
38
|
+
headers: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "HTTP headers as KEY=val,KEY=val"
|
|
41
|
+
},
|
|
42
|
+
description: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: "Server description"
|
|
45
|
+
},
|
|
46
|
+
client: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Client to edit: claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi",
|
|
49
|
+
default: "claude-code"
|
|
50
|
+
},
|
|
51
|
+
scope: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "Scope: local, project, or user (default: local for Claude Code)"
|
|
54
|
+
},
|
|
55
|
+
location: {
|
|
56
|
+
type: "string",
|
|
57
|
+
description: "Exact config path when a client has multiple matching locations"
|
|
58
|
+
},
|
|
59
|
+
json: {
|
|
60
|
+
type: "boolean",
|
|
61
|
+
description: "Output as JSON",
|
|
62
|
+
default: false
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
async run({ args }) {
|
|
66
|
+
const transport = args.type;
|
|
67
|
+
if (![
|
|
68
|
+
"stdio",
|
|
69
|
+
"sse",
|
|
70
|
+
"http"
|
|
71
|
+
].includes(transport)) error(`Invalid type: ${transport}. Use stdio, sse, or http.`);
|
|
72
|
+
const add_args = args;
|
|
73
|
+
const portable = build_portable_server(add_args, transport);
|
|
74
|
+
if (add_args.client && add_args.client !== "claude-code") {
|
|
75
|
+
await add_to_client(add_args.client, portable, add_args.scope, add_args.location, add_args.json);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const scope = add_args.scope || "local";
|
|
79
|
+
if (![
|
|
80
|
+
"local",
|
|
81
|
+
"project",
|
|
82
|
+
"user"
|
|
83
|
+
].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
|
|
84
|
+
const server_data = {
|
|
85
|
+
name: portable.name,
|
|
86
|
+
...transport !== "stdio" ? { type: transport } : {},
|
|
87
|
+
...portable.command ? { command: portable.command } : {},
|
|
88
|
+
...portable.args ? { args: portable.args } : {},
|
|
89
|
+
...portable.url ? { url: portable.url } : {},
|
|
90
|
+
...portable.env ? { env: portable.env } : {},
|
|
91
|
+
...portable.headers ? { headers: portable.headers } : {},
|
|
92
|
+
...portable.description ? { description: portable.description } : {}
|
|
93
|
+
};
|
|
94
|
+
let server;
|
|
95
|
+
try {
|
|
96
|
+
server = validate_mcp_server(server_data);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
error(`Invalid server config: ${err instanceof Error ? err.message : "validation failed"}`);
|
|
99
|
+
}
|
|
100
|
+
await add_server_to_registry(server);
|
|
101
|
+
const result = await add_mcp_via_cli(server, scope);
|
|
102
|
+
if (add_args.json) output({
|
|
103
|
+
added: server.name,
|
|
104
|
+
client: "claude-code",
|
|
105
|
+
scope,
|
|
106
|
+
cli: result.success,
|
|
107
|
+
error: result.error
|
|
108
|
+
}, true);
|
|
109
|
+
else if (result.success) console.log(`Added '${server.name}' and enabled (scope: ${scope})`);
|
|
110
|
+
else console.log(`Added '${server.name}' to registry but CLI failed: ${result.error}`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
function build_portable_server(args, transport) {
|
|
114
|
+
const server = {
|
|
115
|
+
name: args.name,
|
|
116
|
+
transport
|
|
117
|
+
};
|
|
118
|
+
if (transport === "stdio") {
|
|
119
|
+
if (!args.command) error("--command is required for stdio transport");
|
|
120
|
+
server.command = args.command;
|
|
121
|
+
if (args.args) server.args = args.args.split(",");
|
|
122
|
+
} else {
|
|
123
|
+
if (!args.url) error(`--url is required for ${transport} transport`);
|
|
124
|
+
server.url = args.url;
|
|
125
|
+
if (args.headers) server.headers = parse_key_value_pairs(args.headers);
|
|
126
|
+
}
|
|
127
|
+
if (args.env) server.env = parse_key_value_pairs(args.env);
|
|
128
|
+
if (args.description) server.description = args.description;
|
|
129
|
+
return server;
|
|
130
|
+
}
|
|
131
|
+
async function add_to_client(client, server, scope, location_path, json) {
|
|
132
|
+
const adapter = get_client_adapter(client);
|
|
133
|
+
if (!adapter) error(`Invalid client: ${client}. Use claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi.`);
|
|
134
|
+
if (scope && ![
|
|
135
|
+
"local",
|
|
136
|
+
"project",
|
|
137
|
+
"user"
|
|
138
|
+
].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
|
|
139
|
+
try {
|
|
140
|
+
const location = resolve_client_location(adapter, scope, location_path);
|
|
141
|
+
await add_client_server(adapter, location, server);
|
|
142
|
+
if (json) output({
|
|
143
|
+
added: server.name,
|
|
144
|
+
client: adapter.id,
|
|
145
|
+
scope: location.scope,
|
|
146
|
+
location: location.path
|
|
147
|
+
}, true);
|
|
148
|
+
else console.log(`Added '${server.name}' (${adapter.id}:${location.scope})`);
|
|
149
|
+
} catch (err) {
|
|
150
|
+
error(err instanceof Error ? err.message : "Failed to add server");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function parse_key_value_pairs(input) {
|
|
154
|
+
const result = {};
|
|
155
|
+
for (const pair of input.split(",")) {
|
|
156
|
+
const eq = pair.indexOf("=");
|
|
157
|
+
if (eq > 0) result[pair.substring(0, eq)] = pair.substring(eq + 1);
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
export { add_default as default };
|
|
163
|
+
|
|
164
|
+
//# sourceMappingURL=add-LJQa2my2.js.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { F as resolve_client_location, M as get_client_adapter, _ as mcp_add_json_via_cli, j as add_client_server_config } from "./index.js";
|
|
2
|
+
import { n as output, t as error } from "./output-HtT5HCof.js";
|
|
3
|
+
import { defineCommand } from "citty";
|
|
4
|
+
//#region src/cli/commands/add-json.ts
|
|
5
|
+
var add_json_default = defineCommand({
|
|
6
|
+
meta: {
|
|
7
|
+
name: "add-json",
|
|
8
|
+
description: "Add an MCP server from a JSON configuration string"
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
name: {
|
|
12
|
+
type: "positional",
|
|
13
|
+
description: "Server name",
|
|
14
|
+
required: true
|
|
15
|
+
},
|
|
16
|
+
config: {
|
|
17
|
+
type: "positional",
|
|
18
|
+
description: "JSON configuration string",
|
|
19
|
+
required: true
|
|
20
|
+
},
|
|
21
|
+
client: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Client to edit: claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi",
|
|
24
|
+
default: "claude-code"
|
|
25
|
+
},
|
|
26
|
+
scope: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Scope: local, project, or user (default: local for Claude Code)"
|
|
29
|
+
},
|
|
30
|
+
location: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Exact config path when a client has multiple matching locations"
|
|
33
|
+
},
|
|
34
|
+
json: {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Output as JSON",
|
|
37
|
+
default: false
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
async run({ args }) {
|
|
41
|
+
let parsed;
|
|
42
|
+
try {
|
|
43
|
+
parsed = JSON.parse(args.config);
|
|
44
|
+
} catch {
|
|
45
|
+
error("Invalid JSON configuration. Provide a valid JSON string.");
|
|
46
|
+
}
|
|
47
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) error("JSON configuration must be an object.");
|
|
48
|
+
if (args.client && args.client !== "claude-code") {
|
|
49
|
+
await add_json_to_client(args.client, args.name, parsed, args.scope, args.location, args.json);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const scope = args.scope || "local";
|
|
53
|
+
if (![
|
|
54
|
+
"local",
|
|
55
|
+
"project",
|
|
56
|
+
"user"
|
|
57
|
+
].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
|
|
58
|
+
const result = await mcp_add_json_via_cli(args.name, args.config, scope);
|
|
59
|
+
if (args.json) output({
|
|
60
|
+
added: args.name,
|
|
61
|
+
client: "claude-code",
|
|
62
|
+
scope,
|
|
63
|
+
success: result.success,
|
|
64
|
+
error: result.error
|
|
65
|
+
}, true);
|
|
66
|
+
else if (result.success) console.log(`Added '${args.name}' from JSON (scope: ${scope})`);
|
|
67
|
+
else error(result.error || "Unknown error");
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
async function add_json_to_client(client, name, config, scope, location_path, json) {
|
|
71
|
+
const adapter = get_client_adapter(client);
|
|
72
|
+
if (!adapter) error(`Invalid client: ${client}. Use claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi.`);
|
|
73
|
+
if (scope && ![
|
|
74
|
+
"local",
|
|
75
|
+
"project",
|
|
76
|
+
"user"
|
|
77
|
+
].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
|
|
78
|
+
try {
|
|
79
|
+
const location = resolve_client_location(adapter, scope, location_path);
|
|
80
|
+
await add_client_server_config(adapter, location, name, config);
|
|
81
|
+
if (json) output({
|
|
82
|
+
added: name,
|
|
83
|
+
client: adapter.id,
|
|
84
|
+
scope: location.scope,
|
|
85
|
+
location: location.path
|
|
86
|
+
}, true);
|
|
87
|
+
else console.log(`Added '${name}' from JSON (${adapter.id}:${location.scope})`);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
error(err instanceof Error ? err.message : "Failed to add server");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { add_json_default as default };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=add-json-TEdYweZ5.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { m as get_plugin_backup_filename, n as get_backup_filename, r as get_backups_dir, t as ensure_directory_exists } from "./paths-BPISiJi4.js";
|
|
2
|
-
import { s as read_claude_config } from "./config-
|
|
3
|
-
import {
|
|
4
|
-
import { n as output } from "./output-
|
|
2
|
+
import { s as read_claude_config } from "./config-DzMmTJYL.js";
|
|
3
|
+
import { V as read_claude_settings } from "./index.js";
|
|
4
|
+
import { n as output } from "./output-HtT5HCof.js";
|
|
5
5
|
import { readdir, unlink, writeFile } from "node:fs/promises";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { defineCommand } from "citty";
|
|
@@ -61,4 +61,4 @@ var backup_default = defineCommand({
|
|
|
61
61
|
//#endregion
|
|
62
62
|
export { backup_default as default };
|
|
63
63
|
|
|
64
|
-
//# sourceMappingURL=backup-
|
|
64
|
+
//# sourceMappingURL=backup-kyS5IVIr.js.map
|