mcpick 0.0.2 → 0.0.3
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/.github/copilot-instructions.md +32 -0
- package/CHANGELOG.md +7 -0
- package/README.md +21 -3
- package/dist/commands/add-server.js +41 -24
- package/dist/commands/launch.js +1 -1
- package/dist/core/validation.js +28 -22
- package/dist/index.js +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# McPick Development Instructions
|
|
2
|
+
|
|
3
|
+
**Always reference these instructions first and fallback to search or
|
|
4
|
+
bash commands only when you encounter unexpected information that does
|
|
5
|
+
not match the info here.**
|
|
6
|
+
|
|
7
|
+
## Working Effectively
|
|
8
|
+
|
|
9
|
+
### Prerequisites and Setup
|
|
10
|
+
|
|
11
|
+
- Install Node.js >=22.0.0
|
|
12
|
+
- Install pnpm globally: `npm install -g pnpm` (takes ~2 seconds)
|
|
13
|
+
|
|
14
|
+
### Development Commands
|
|
15
|
+
|
|
16
|
+
- **Format code**: `pnpm run format`
|
|
17
|
+
- **Build**: `pnpm run build`
|
|
18
|
+
|
|
19
|
+
## Validation Requirements
|
|
20
|
+
|
|
21
|
+
### ALWAYS run these before submitting changes:
|
|
22
|
+
|
|
23
|
+
1. `pnpm run format` - Auto-format all code
|
|
24
|
+
2. `pnpm run build` - Check for build issues
|
|
25
|
+
|
|
26
|
+
#### Add changeset once you're done
|
|
27
|
+
|
|
28
|
+
Run `pnpm changeset` then follow the prompts. Use this after having
|
|
29
|
+
finished the task. Most of the time this is a patch release for
|
|
30
|
+
`mcpick`. Use a short and descriptive message. Always prefix the
|
|
31
|
+
message with either `fix`, `feat`, `breaking`, or `chore` (most likely
|
|
32
|
+
`fix` since you're mostly working on bugfixes).
|
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
-
#
|
|
1
|
+
# McPick
|
|
2
2
|
|
|
3
3
|
A CLI tool for dynamically managing MCP server configurations in
|
|
4
4
|
Claude Code. Enable and disable MCP servers on-demand to optimize
|
|
5
5
|
context usage and performance.
|
|
6
6
|
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### One-time Usage
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm dlx mcpick
|
|
13
|
+
# or
|
|
14
|
+
npx mcpick
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Global Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm install -g mcpick
|
|
21
|
+
# or
|
|
22
|
+
npm install -g mcpick
|
|
23
|
+
```
|
|
24
|
+
|
|
7
25
|
## The Problem
|
|
8
26
|
|
|
9
27
|
Using the Claude Code `/doctor` command you may see something like
|
|
@@ -31,7 +49,7 @@ This can lead to:
|
|
|
31
49
|
|
|
32
50
|
## The Solution
|
|
33
51
|
|
|
34
|
-
|
|
52
|
+
McPick provides an intuitive CLI menu to:
|
|
35
53
|
|
|
36
54
|
- ✅ **Toggle servers on/off** - Enable only the MCP servers you need
|
|
37
55
|
for your current task
|
|
@@ -49,7 +67,7 @@ MCPick provides an intuitive CLI menu to:
|
|
|
49
67
|
### Interactive Menu
|
|
50
68
|
|
|
51
69
|
```bash
|
|
52
|
-
┌
|
|
70
|
+
┌ McPick - MCP Server Configuration Manager
|
|
53
71
|
│
|
|
54
72
|
◆ What would you like to do?
|
|
55
73
|
│ ● Edit config (Toggle MCP servers on/off)
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import { confirm, note, select, text } from '@clack/prompts';
|
|
2
2
|
import { add_server_to_registry } from '../core/registry.js';
|
|
3
3
|
import { validate_mcp_server } from '../core/validation.js';
|
|
4
|
+
function format_server_details(server) {
|
|
5
|
+
const details = [`Name: ${server.name}`];
|
|
6
|
+
if ('command' in server) {
|
|
7
|
+
details.push(`Command: ${server.command} ${(server.args || []).join(' ')}`);
|
|
8
|
+
}
|
|
9
|
+
if ('url' in server) {
|
|
10
|
+
details.push(`URL: ${server.url}`);
|
|
11
|
+
}
|
|
12
|
+
details.push(`Description: ${server.description || 'None'}`);
|
|
13
|
+
if (server.type) {
|
|
14
|
+
details.push(`Transport: ${server.type}`);
|
|
15
|
+
}
|
|
16
|
+
if (server.env) {
|
|
17
|
+
details.push(`Environment: ${Object.keys(server.env).length} variables`);
|
|
18
|
+
}
|
|
19
|
+
if ('headers' in server && server.headers) {
|
|
20
|
+
details.push(`Headers: ${Object.keys(server.headers).length} headers`);
|
|
21
|
+
}
|
|
22
|
+
return details;
|
|
23
|
+
}
|
|
4
24
|
export async function add_server() {
|
|
5
25
|
try {
|
|
6
26
|
// First, ask how they want to configure the server
|
|
@@ -75,6 +95,7 @@ export async function add_server() {
|
|
|
75
95
|
return;
|
|
76
96
|
let server_data = {
|
|
77
97
|
name: name.trim(),
|
|
98
|
+
type: 'stdio',
|
|
78
99
|
command: command.trim(),
|
|
79
100
|
args,
|
|
80
101
|
...(description &&
|
|
@@ -97,11 +118,12 @@ export async function add_server() {
|
|
|
97
118
|
});
|
|
98
119
|
if (typeof transport_type === 'symbol')
|
|
99
120
|
return;
|
|
100
|
-
|
|
101
|
-
server_data.type = transport_type;
|
|
102
|
-
}
|
|
121
|
+
server_data.type = transport_type;
|
|
103
122
|
// URL for non-stdio transports
|
|
104
|
-
if (transport_type
|
|
123
|
+
if (transport_type === 'sse' || transport_type === 'http') {
|
|
124
|
+
// Remove stdio-specific fields
|
|
125
|
+
delete server_data.command;
|
|
126
|
+
delete server_data.args;
|
|
105
127
|
const url = await text({
|
|
106
128
|
message: 'Server URL:',
|
|
107
129
|
placeholder: 'e.g., http://localhost:3000',
|
|
@@ -158,10 +180,8 @@ export async function add_server() {
|
|
|
158
180
|
}
|
|
159
181
|
}
|
|
160
182
|
const validated_server = validate_mcp_server(server_data);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
`Command: ${validated_server.command} ${validated_server.args.join(' ')}\n` +
|
|
164
|
-
`Description: ${validated_server.description || 'None'}`);
|
|
183
|
+
const details = format_server_details(validated_server);
|
|
184
|
+
note(`Server to add:\n${details.join('\n')}`);
|
|
165
185
|
const should_add = await confirm({
|
|
166
186
|
message: 'Add this server to the registry?',
|
|
167
187
|
});
|
|
@@ -213,23 +233,20 @@ async function add_server_from_json() {
|
|
|
213
233
|
}
|
|
214
234
|
const parsed = JSON.parse(jsonString);
|
|
215
235
|
const server_data = parsed;
|
|
236
|
+
// Normalize the data to match schema expectations
|
|
237
|
+
if (!server_data.type && server_data.command) {
|
|
238
|
+
server_data.type = 'stdio';
|
|
239
|
+
}
|
|
240
|
+
if (server_data.type !== 'stdio') {
|
|
241
|
+
delete server_data.command;
|
|
242
|
+
delete server_data.args;
|
|
243
|
+
}
|
|
244
|
+
if (server_data.command && !server_data.args) {
|
|
245
|
+
server_data.args = [];
|
|
246
|
+
}
|
|
216
247
|
const validated_server = validate_mcp_server(server_data);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
`Command: ${validated_server.command} ${validated_server.args.join(' ')}\n` +
|
|
220
|
-
`Description: ${validated_server.description || 'None'}` +
|
|
221
|
-
(validated_server.type
|
|
222
|
-
? `\nTransport: ${validated_server.type}`
|
|
223
|
-
: '') +
|
|
224
|
-
(validated_server.url
|
|
225
|
-
? `\nURL: ${validated_server.url}`
|
|
226
|
-
: '') +
|
|
227
|
-
(validated_server.env
|
|
228
|
-
? `\nEnvironment: ${Object.keys(validated_server.env).length} variables`
|
|
229
|
-
: '') +
|
|
230
|
-
(validated_server.headers
|
|
231
|
-
? `\nHeaders: ${Object.keys(validated_server.headers).length} headers`
|
|
232
|
-
: ''));
|
|
248
|
+
const details = format_server_details(validated_server);
|
|
249
|
+
note(`Server to add:\n${details.join('\n')}`);
|
|
233
250
|
const should_add = await confirm({
|
|
234
251
|
message: 'Add this server to the registry?',
|
|
235
252
|
});
|
package/dist/commands/launch.js
CHANGED
package/dist/core/validation.js
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
|
-
export const
|
|
3
|
-
|
|
4
|
-
type: v.optional(v.union([
|
|
5
|
-
v.literal('stdio'),
|
|
6
|
-
v.literal('sse'),
|
|
7
|
-
v.literal('http'),
|
|
8
|
-
])),
|
|
2
|
+
export const mcp_server_schema_stdio = v.object({
|
|
3
|
+
type: v.optional(v.literal('stdio')),
|
|
9
4
|
command: v.pipe(v.string(), v.minLength(1)),
|
|
10
|
-
args: v.array(v.string()),
|
|
5
|
+
args: v.optional(v.array(v.string())),
|
|
11
6
|
env: v.optional(v.record(v.string(), v.string())),
|
|
12
|
-
|
|
7
|
+
description: v.optional(v.string()),
|
|
8
|
+
});
|
|
9
|
+
export const mcp_server_schema_sse = v.object({
|
|
10
|
+
type: v.literal('sse'),
|
|
11
|
+
env: v.optional(v.record(v.string(), v.string())),
|
|
12
|
+
url: v.pipe(v.string(), v.minLength(1)),
|
|
13
|
+
headers: v.optional(v.record(v.string(), v.string())),
|
|
14
|
+
description: v.optional(v.string()),
|
|
15
|
+
});
|
|
16
|
+
export const mcp_server_schema_http = v.object({
|
|
17
|
+
type: v.literal('http'),
|
|
18
|
+
env: v.optional(v.record(v.string(), v.string())),
|
|
19
|
+
url: v.pipe(v.string(), v.minLength(1)),
|
|
13
20
|
headers: v.optional(v.record(v.string(), v.string())),
|
|
14
21
|
description: v.optional(v.string()),
|
|
15
22
|
});
|
|
23
|
+
export const mcp_server_schema_base = v.union([
|
|
24
|
+
mcp_server_schema_stdio,
|
|
25
|
+
mcp_server_schema_sse,
|
|
26
|
+
mcp_server_schema_http,
|
|
27
|
+
]);
|
|
28
|
+
export const mcp_server_schema = v.intersect([
|
|
29
|
+
v.object({
|
|
30
|
+
name: v.pipe(v.string(), v.minLength(1)),
|
|
31
|
+
}),
|
|
32
|
+
mcp_server_schema_base,
|
|
33
|
+
]);
|
|
16
34
|
export const claude_config_schema = v.object({
|
|
17
|
-
mcpServers: v.optional(v.record(v.string(),
|
|
18
|
-
type: v.optional(v.union([
|
|
19
|
-
v.literal('stdio'),
|
|
20
|
-
v.literal('sse'),
|
|
21
|
-
v.literal('http'),
|
|
22
|
-
])),
|
|
23
|
-
command: v.pipe(v.string(), v.minLength(1)),
|
|
24
|
-
args: v.array(v.string()),
|
|
25
|
-
env: v.optional(v.record(v.string(), v.string())),
|
|
26
|
-
url: v.optional(v.string()),
|
|
27
|
-
headers: v.optional(v.record(v.string(), v.string())),
|
|
28
|
-
description: v.optional(v.string()),
|
|
29
|
-
}))),
|
|
35
|
+
mcpServers: v.optional(v.record(v.string(), mcp_server_schema_base)),
|
|
30
36
|
});
|
|
31
37
|
export const server_registry_schema = v.object({
|
|
32
38
|
servers: v.array(mcp_server_schema),
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcpick",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Dynamic MCP server configuration manager for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@changesets/cli": "^2.29.7",
|
|
28
|
-
"@types/node": "^24.
|
|
28
|
+
"@types/node": "^24.6.1",
|
|
29
29
|
"prettier": "^3.6.2",
|
|
30
|
-
"typescript": "^5.9.
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsc",
|