mcpick 0.0.1 → 0.0.2
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 +10 -0
- package/dist/commands/add-server.js +174 -19
- package/package.json +1 -1
- package/mcpick-plan.md +0 -223
- package/plan.md +0 -102
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# mcpick
|
|
2
2
|
|
|
3
|
+
## 0.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6a3eec7: paste json server config
|
|
8
|
+
- a62953b: Removed estimated_tokens prompt and references, Enhanced
|
|
9
|
+
add-server dialogue
|
|
10
|
+
- 491d543: make json first options for adding server
|
|
11
|
+
- 3242ff1: remove unused docs
|
|
12
|
+
|
|
3
13
|
## 0.0.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
-
import { confirm, note, text } from '@clack/prompts';
|
|
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
4
|
export async function add_server() {
|
|
5
5
|
try {
|
|
6
|
+
// First, ask how they want to configure the server
|
|
7
|
+
const config_method = await select({
|
|
8
|
+
message: 'How would you like to add the server?',
|
|
9
|
+
options: [
|
|
10
|
+
{
|
|
11
|
+
value: 'json',
|
|
12
|
+
label: 'Paste JSON configuration',
|
|
13
|
+
hint: 'Paste complete server config as JSON',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
value: 'form',
|
|
17
|
+
label: 'Step-by-step form',
|
|
18
|
+
hint: 'Fill out fields one by one',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
initialValue: 'json',
|
|
22
|
+
});
|
|
23
|
+
if (typeof config_method === 'symbol')
|
|
24
|
+
return;
|
|
25
|
+
if (config_method === 'json') {
|
|
26
|
+
return await add_server_from_json();
|
|
27
|
+
}
|
|
6
28
|
const name = await text({
|
|
7
29
|
message: 'Server name:',
|
|
8
30
|
placeholder: 'e.g., mcp-sqlite-tools',
|
|
@@ -44,32 +66,97 @@ export async function add_server() {
|
|
|
44
66
|
});
|
|
45
67
|
if (typeof description === 'symbol')
|
|
46
68
|
return;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (value && value.trim().length > 0) {
|
|
52
|
-
const num = parseInt(value.trim());
|
|
53
|
-
if (isNaN(num) || num < 0) {
|
|
54
|
-
return 'Must be a positive number';
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return undefined;
|
|
58
|
-
},
|
|
69
|
+
// Advanced configuration
|
|
70
|
+
const configure_advanced = await confirm({
|
|
71
|
+
message: 'Configure advanced settings (env variables, transport, etc.)?',
|
|
72
|
+
initialValue: false,
|
|
59
73
|
});
|
|
60
|
-
if (typeof
|
|
74
|
+
if (typeof configure_advanced === 'symbol')
|
|
61
75
|
return;
|
|
62
|
-
|
|
76
|
+
let server_data = {
|
|
63
77
|
name: name.trim(),
|
|
64
78
|
command: command.trim(),
|
|
65
79
|
args,
|
|
66
80
|
...(description &&
|
|
67
81
|
description.trim() && { description: description.trim() }),
|
|
68
|
-
...(estimated_tokens_input &&
|
|
69
|
-
estimated_tokens_input.trim() && {
|
|
70
|
-
estimated_tokens: parseInt(estimated_tokens_input.trim()),
|
|
71
|
-
}),
|
|
72
82
|
};
|
|
83
|
+
if (configure_advanced) {
|
|
84
|
+
// Transport type
|
|
85
|
+
const transport_type = await select({
|
|
86
|
+
message: 'Transport type:',
|
|
87
|
+
options: [
|
|
88
|
+
{
|
|
89
|
+
value: 'stdio',
|
|
90
|
+
label: 'stdio (default)',
|
|
91
|
+
hint: 'Standard input/output',
|
|
92
|
+
},
|
|
93
|
+
{ value: 'sse', label: 'sse', hint: 'Server-sent events' },
|
|
94
|
+
{ value: 'http', label: 'http', hint: 'HTTP transport' },
|
|
95
|
+
],
|
|
96
|
+
initialValue: 'stdio',
|
|
97
|
+
});
|
|
98
|
+
if (typeof transport_type === 'symbol')
|
|
99
|
+
return;
|
|
100
|
+
if (transport_type !== 'stdio') {
|
|
101
|
+
server_data.type = transport_type;
|
|
102
|
+
}
|
|
103
|
+
// URL for non-stdio transports
|
|
104
|
+
if (transport_type !== 'stdio') {
|
|
105
|
+
const url = await text({
|
|
106
|
+
message: 'Server URL:',
|
|
107
|
+
placeholder: 'e.g., http://localhost:3000',
|
|
108
|
+
validate: (value) => {
|
|
109
|
+
if (!value || value.trim().length === 0) {
|
|
110
|
+
return 'URL is required for non-stdio transport';
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
if (typeof url === 'symbol')
|
|
116
|
+
return;
|
|
117
|
+
server_data.url = url.trim();
|
|
118
|
+
}
|
|
119
|
+
// Environment variables
|
|
120
|
+
const env_input = await text({
|
|
121
|
+
message: 'Environment variables (KEY=value, comma-separated):',
|
|
122
|
+
placeholder: 'e.g., API_KEY=abc123, TIMEOUT=30',
|
|
123
|
+
});
|
|
124
|
+
if (typeof env_input === 'symbol')
|
|
125
|
+
return;
|
|
126
|
+
if (env_input && env_input.trim()) {
|
|
127
|
+
const env = {};
|
|
128
|
+
env_input.split(',').forEach((pair) => {
|
|
129
|
+
const [key, ...valueParts] = pair.split('=');
|
|
130
|
+
if (key && valueParts.length > 0) {
|
|
131
|
+
env[key.trim()] = valueParts.join('=').trim();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
if (Object.keys(env).length > 0) {
|
|
135
|
+
server_data.env = env;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Headers for HTTP transport
|
|
139
|
+
if (transport_type === 'http') {
|
|
140
|
+
const headers_input = await text({
|
|
141
|
+
message: 'HTTP headers (KEY=value, comma-separated):',
|
|
142
|
+
placeholder: 'e.g., Authorization=Bearer token, Content-Type=application/json',
|
|
143
|
+
});
|
|
144
|
+
if (typeof headers_input === 'symbol')
|
|
145
|
+
return;
|
|
146
|
+
if (headers_input && headers_input.trim()) {
|
|
147
|
+
const headers = {};
|
|
148
|
+
headers_input.split(',').forEach((pair) => {
|
|
149
|
+
const [key, ...valueParts] = pair.split('=');
|
|
150
|
+
if (key && valueParts.length > 0) {
|
|
151
|
+
headers[key.trim()] = valueParts.join('=').trim();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
if (Object.keys(headers).length > 0) {
|
|
155
|
+
server_data.headers = headers;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
73
160
|
const validated_server = validate_mcp_server(server_data);
|
|
74
161
|
note(`Server to add:\n` +
|
|
75
162
|
`Name: ${validated_server.name}\n` +
|
|
@@ -88,4 +175,72 @@ export async function add_server() {
|
|
|
88
175
|
throw new Error(`Failed to add server: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
89
176
|
}
|
|
90
177
|
}
|
|
178
|
+
async function add_server_from_json() {
|
|
179
|
+
const json_input = await text({
|
|
180
|
+
message: 'Paste JSON configuration:',
|
|
181
|
+
placeholder: '{ "name": "mcp-sqlite-tools", "command": "npx", "args": ["-y", "mcp-sqlite-tools"] }',
|
|
182
|
+
validate: (value) => {
|
|
183
|
+
if (!value || value.trim().length === 0) {
|
|
184
|
+
return 'JSON configuration is required';
|
|
185
|
+
}
|
|
186
|
+
let jsonString = value.trim();
|
|
187
|
+
// If it doesn't start with {, wrap it in braces
|
|
188
|
+
if (!jsonString.startsWith('{')) {
|
|
189
|
+
jsonString = `{${jsonString}}`;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const parsed = JSON.parse(jsonString);
|
|
193
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
194
|
+
return 'JSON must be an object';
|
|
195
|
+
}
|
|
196
|
+
if (!parsed.command) {
|
|
197
|
+
return 'Server configuration must include a "command" field';
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
return 'Invalid JSON format';
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
if (typeof json_input === 'symbol')
|
|
207
|
+
return;
|
|
208
|
+
try {
|
|
209
|
+
let jsonString = json_input.trim();
|
|
210
|
+
// If it doesn't start with {, wrap it in braces
|
|
211
|
+
if (!jsonString.startsWith('{')) {
|
|
212
|
+
jsonString = `{${jsonString}}`;
|
|
213
|
+
}
|
|
214
|
+
const parsed = JSON.parse(jsonString);
|
|
215
|
+
const server_data = parsed;
|
|
216
|
+
const validated_server = validate_mcp_server(server_data);
|
|
217
|
+
note(`Server to add:\n` +
|
|
218
|
+
`Name: ${validated_server.name}\n` +
|
|
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
|
+
: ''));
|
|
233
|
+
const should_add = await confirm({
|
|
234
|
+
message: 'Add this server to the registry?',
|
|
235
|
+
});
|
|
236
|
+
if (typeof should_add === 'symbol' || !should_add) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
await add_server_to_registry(validated_server);
|
|
240
|
+
note(`Server "${validated_server.name}" added to registry successfully!`);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
throw new Error(`Failed to parse or validate JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
91
246
|
//# sourceMappingURL=add-server.js.map
|
package/package.json
CHANGED
package/mcpick-plan.md
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
# MCPick Implementation Plan
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Build a minimal Node.js CLI tool using TypeScript and Clack prompts to
|
|
6
|
-
dynamically manage MCP server configurations for Claude Code sessions.
|
|
7
|
-
|
|
8
|
-
## The Problem
|
|
9
|
-
|
|
10
|
-
Claude Code loads ALL configured MCP servers at session startup,
|
|
11
|
-
consuming massive amounts of context tokens (66,687+ tokens reported)
|
|
12
|
-
regardless of whether you actually use those tools. Users need a way
|
|
13
|
-
to dynamically select which MCP servers to load per session.
|
|
14
|
-
|
|
15
|
-
## Architecture - Minimal Dependencies
|
|
16
|
-
|
|
17
|
-
**Only 2 Dependencies:**
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"@clack/prompts": "^0.7.0",
|
|
22
|
-
"valibot": "^0.25.0"
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**Use Node.js Built-ins:**
|
|
27
|
-
|
|
28
|
-
- `fs/promises` for all file operations
|
|
29
|
-
- `path`, `os.homedir()` for path handling
|
|
30
|
-
- `child_process.spawn` to launch Claude Code
|
|
31
|
-
- `JSON.parse/stringify` for config files
|
|
32
|
-
|
|
33
|
-
## TypeScript Configuration
|
|
34
|
-
|
|
35
|
-
**tsconfig.json:**
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"compilerOptions": {
|
|
40
|
-
"target": "ES2022",
|
|
41
|
-
"module": "ESNext",
|
|
42
|
-
"moduleResolution": "node16",
|
|
43
|
-
"strict": true,
|
|
44
|
-
"outDir": "./dist",
|
|
45
|
-
"sourceMap": true,
|
|
46
|
-
"esModuleInterop": true,
|
|
47
|
-
"allowSyntheticDefaultImports": true,
|
|
48
|
-
"skipLibCheck": true
|
|
49
|
-
},
|
|
50
|
-
"include": ["src/**/*"],
|
|
51
|
-
"exclude": ["node_modules", "dist"]
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**package.json additions:**
|
|
56
|
-
|
|
57
|
-
- `"type": "module"` for ESM
|
|
58
|
-
- `"bin": { "mcpick": "./dist/index.js" }`
|
|
59
|
-
- `"engines": { "node": ">=22.0.0" }`
|
|
60
|
-
|
|
61
|
-
## User Flow - Pure Interactive
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
mcpick # Single entry point - no CLI arguments
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**Main Menu (Clack select):**
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
┌ What would you like to do?
|
|
71
|
-
│ ○ Edit config
|
|
72
|
-
│ ○ Backup config
|
|
73
|
-
│ ○ Add MCP server
|
|
74
|
-
│ ○ Restore from backup
|
|
75
|
-
│ ○ Launch Claude Code
|
|
76
|
-
└ ○ Exit
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Edit Config Flow:
|
|
80
|
-
|
|
81
|
-
1. Read `.claude.json` from current directory
|
|
82
|
-
2. Show multiselect with all servers (currently enabled ones checked)
|
|
83
|
-
3. User toggles servers on/off with spacebar
|
|
84
|
-
4. Save deselected servers to `~/.claude/mcpick/servers.json` registry
|
|
85
|
-
5. Update `.claude.json` with only selected servers
|
|
86
|
-
6. Show token count reduction
|
|
87
|
-
|
|
88
|
-
### Backup Config Flow:
|
|
89
|
-
|
|
90
|
-
1. Create timestamped backup of current `.claude.json`
|
|
91
|
-
2. Store in `~/.claude/mcpick/backups/`
|
|
92
|
-
3. Confirm backup location to user
|
|
93
|
-
|
|
94
|
-
### Add MCP Server Flow:
|
|
95
|
-
|
|
96
|
-
1. Text prompts for server details:
|
|
97
|
-
- Name
|
|
98
|
-
- Command
|
|
99
|
-
- Arguments (array)
|
|
100
|
-
- Description (optional)
|
|
101
|
-
2. Validate configuration with Valibot
|
|
102
|
-
3. Add to both `.claude.json` and servers registry
|
|
103
|
-
|
|
104
|
-
### Restore Flow:
|
|
105
|
-
|
|
106
|
-
1. List available backups with timestamps
|
|
107
|
-
2. User selects backup to restore
|
|
108
|
-
3. Confirm destructive operation
|
|
109
|
-
4. Restore `.claude.json` from backup
|
|
110
|
-
|
|
111
|
-
## File Structure
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
mcpick/
|
|
115
|
-
├── src/
|
|
116
|
-
│ ├── commands/
|
|
117
|
-
│ │ ├── edit-config.ts # Toggle servers on/off
|
|
118
|
-
│ │ ├── backup.ts # Create config backups
|
|
119
|
-
│ │ ├── add-server.ts # Add new MCP server
|
|
120
|
-
│ │ ├── restore.ts # Restore from backup
|
|
121
|
-
│ │ └── launch.ts # Launch Claude Code
|
|
122
|
-
│ ├── core/
|
|
123
|
-
│ │ ├── config.ts # .claude.json read/write operations
|
|
124
|
-
│ │ ├── registry.ts # servers.json management
|
|
125
|
-
│ │ └── validation.ts # Valibot schemas
|
|
126
|
-
│ ├── utils/
|
|
127
|
-
│ │ └── paths.ts # Path resolution utilities
|
|
128
|
-
│ ├── types.ts # TypeScript type definitions
|
|
129
|
-
│ └── index.ts # Main entry point with menu
|
|
130
|
-
├── package.json
|
|
131
|
-
├── tsconfig.json
|
|
132
|
-
└── README.md
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Configuration Storage
|
|
136
|
-
|
|
137
|
-
**Current directory: `.claude.json`**
|
|
138
|
-
|
|
139
|
-
- Standard Claude Code configuration file
|
|
140
|
-
- Only contains currently selected MCP servers
|
|
141
|
-
|
|
142
|
-
**~/.claude/mcpick/servers.json** - Registry of all available servers:
|
|
143
|
-
|
|
144
|
-
```json
|
|
145
|
-
{
|
|
146
|
-
"servers": [
|
|
147
|
-
{
|
|
148
|
-
"name": "mcp-sqlite-tools",
|
|
149
|
-
"command": "uvx",
|
|
150
|
-
"args": ["mcp-sqlite-tools"],
|
|
151
|
-
"description": "SQLite database tools",
|
|
152
|
-
"estimatedTokens": 9872
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
"name": "mcp-omnisearch",
|
|
156
|
-
"command": "npx",
|
|
157
|
-
"args": ["-y", "@modelcontextprotocol/server-omnisearch"],
|
|
158
|
-
"description": "Web search capabilities",
|
|
159
|
-
"estimatedTokens": 10454
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
**~/.claude/mcpick/backups/** - Timestamped backup files:
|
|
166
|
-
|
|
167
|
-
- Format: `claude-YYYY-MM-DD-HHMMSS.json`
|
|
168
|
-
- Keep last 10 backups automatically
|
|
169
|
-
|
|
170
|
-
## Error Handling Strategy
|
|
171
|
-
|
|
172
|
-
- **Valibot schemas** for all configuration validation
|
|
173
|
-
- **Try/catch blocks** with Clack `cancel()` for user-friendly error
|
|
174
|
-
messages
|
|
175
|
-
- **File permission checks** before attempting operations
|
|
176
|
-
- **Create missing directories/files** with sensible defaults
|
|
177
|
-
- **Graceful handling** of malformed JSON files
|
|
178
|
-
|
|
179
|
-
## Token Estimation
|
|
180
|
-
|
|
181
|
-
- Static analysis of MCP server tool definitions
|
|
182
|
-
- Cache estimates in servers.json to avoid repeated calculations
|
|
183
|
-
- Display real-time totals during server selection
|
|
184
|
-
- Show before/after token counts
|
|
185
|
-
|
|
186
|
-
## Implementation Steps
|
|
187
|
-
|
|
188
|
-
1. **Project Setup**
|
|
189
|
-
- Initialize Node.js/TypeScript project with minimal dependencies
|
|
190
|
-
- Configure ESM, TypeScript, and build scripts
|
|
191
|
-
|
|
192
|
-
2. **Core Infrastructure**
|
|
193
|
-
- Implement config file I/O using only Node.js built-ins
|
|
194
|
-
- Create server registry management
|
|
195
|
-
- Build backup/restore functionality
|
|
196
|
-
|
|
197
|
-
3. **Clack Interface**
|
|
198
|
-
- Main interactive menu system
|
|
199
|
-
- Multiselect for server toggling
|
|
200
|
-
- Text prompts for server addition
|
|
201
|
-
|
|
202
|
-
4. **Config Management**
|
|
203
|
-
- Edit existing configurations
|
|
204
|
-
- Add new MCP servers
|
|
205
|
-
- Backup and restore operations
|
|
206
|
-
|
|
207
|
-
5. **Polish & Testing**
|
|
208
|
-
- Error handling and validation
|
|
209
|
-
- User experience improvements
|
|
210
|
-
- Documentation
|
|
211
|
-
|
|
212
|
-
## Benefits
|
|
213
|
-
|
|
214
|
-
- **95% token reduction** by loading only needed tools
|
|
215
|
-
- **Zero session restarts** for MCP configuration changes
|
|
216
|
-
- **Intuitive interface** with beautiful Clack prompts
|
|
217
|
-
- **Minimal dependencies** - only 2 external packages
|
|
218
|
-
- **Fast startup** with lightweight codebase
|
|
219
|
-
- **Backup safety** for configuration changes
|
|
220
|
-
|
|
221
|
-
This approach transforms MCP configuration from a static, manual
|
|
222
|
-
process into a dynamic, user-friendly workflow that maximizes both
|
|
223
|
-
functionality and efficiency.
|
package/plan.md
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
# MCP Session Manager: Dynamic Tool Configuration for Claude Code
|
|
2
|
-
|
|
3
|
-
## The Problem
|
|
4
|
-
|
|
5
|
-
Claude Code loads ALL configured MCP servers at session startup,
|
|
6
|
-
consuming massive amounts of context tokens regardless of whether you
|
|
7
|
-
actually use those tools. Users report:
|
|
8
|
-
|
|
9
|
-
- **66,687 tokens consumed** by 20+ MCP tools before even starting
|
|
10
|
-
work
|
|
11
|
-
- **25-30% of context window** used by unused tool definitions
|
|
12
|
-
- **No way to dynamically enable/disable** MCP servers during sessions
|
|
13
|
-
- **Session restart required** for any MCP configuration changes
|
|
14
|
-
- **Forced to choose** between comprehensive tool access and efficient
|
|
15
|
-
resource usage
|
|
16
|
-
|
|
17
|
-
This creates a fundamental workflow problem: you either load
|
|
18
|
-
everything (wasting tokens) or manually edit JSON configs before each
|
|
19
|
-
session (time-consuming and error-prone).
|
|
20
|
-
|
|
21
|
-
## The Solution: Session-Specific MCP Configuration Manager
|
|
22
|
-
|
|
23
|
-
A CLI tool that manages your MCP server configurations dynamically by
|
|
24
|
-
manipulating the `.claude.json` file before Claude Code sessions
|
|
25
|
-
start.
|
|
26
|
-
|
|
27
|
-
### Core Concept
|
|
28
|
-
|
|
29
|
-
Instead of fighting Claude Code's static loading, work with it by
|
|
30
|
-
making configuration changes fast and intelligent:
|
|
31
|
-
|
|
32
|
-
1. **Store all available MCP servers** in a separate configuration
|
|
33
|
-
repository
|
|
34
|
-
2. **Select servers per session** using an interactive interface
|
|
35
|
-
3. **Automatically update** `.claude.json` with only selected servers
|
|
36
|
-
4. **Launch Claude Code** with optimized configuration
|
|
37
|
-
5. **Save successful combinations** as reusable presets
|
|
38
|
-
|
|
39
|
-
### Key Features
|
|
40
|
-
|
|
41
|
-
**Interactive Server Selection**
|
|
42
|
-
|
|
43
|
-
- Checkbox interface showing all available MCP servers
|
|
44
|
-
- Real-time token usage estimates for each server
|
|
45
|
-
- Smart warnings when approaching context limits
|
|
46
|
-
- Tag-based filtering (e.g., "web-dev", "data-analysis", "automation")
|
|
47
|
-
|
|
48
|
-
**Preset Management**
|
|
49
|
-
|
|
50
|
-
- Save frequently used server combinations
|
|
51
|
-
- Load preset configurations instantly
|
|
52
|
-
- Project-specific presets (auto-detect based on directory)
|
|
53
|
-
- Share presets with team members
|
|
54
|
-
|
|
55
|
-
**Intelligent Recommendations**
|
|
56
|
-
|
|
57
|
-
- Suggest optimal server combinations for detected project types
|
|
58
|
-
- Learn from usage patterns to recommend relevant tools
|
|
59
|
-
- Context-aware suggestions based on file types in current directory
|
|
60
|
-
|
|
61
|
-
**Seamless Integration**
|
|
62
|
-
|
|
63
|
-
- One command to select servers and launch Claude Code
|
|
64
|
-
- Backup and restore previous configurations
|
|
65
|
-
- Zero impact on existing Claude Code functionality
|
|
66
|
-
|
|
67
|
-
### User Experience
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# Interactive selection for this session
|
|
71
|
-
mcp-manager select
|
|
72
|
-
|
|
73
|
-
# Quick preset loading
|
|
74
|
-
mcp-manager start --preset "web-development"
|
|
75
|
-
|
|
76
|
-
# Enable specific servers by name
|
|
77
|
-
mcp-manager enable context7 github filesystem
|
|
78
|
-
|
|
79
|
-
# Save current successful combination
|
|
80
|
-
mcp-manager save-preset "data-pipeline" --current
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Benefits
|
|
84
|
-
|
|
85
|
-
- **95% token reduction** by loading only needed tools
|
|
86
|
-
- **No session restarts** for configuration changes
|
|
87
|
-
- **Faster startup times** with fewer servers to initialize
|
|
88
|
-
- **Better resource utilization** and longer conversation capacity
|
|
89
|
-
- **Experimentation-friendly** - try new tool combinations easily
|
|
90
|
-
- **Team collaboration** through shared preset configurations
|
|
91
|
-
|
|
92
|
-
### Storage Location
|
|
93
|
-
|
|
94
|
-
Extends existing Claude configuration structure:
|
|
95
|
-
|
|
96
|
-
- Available servers stored in `~/.claude/mcp-manager/`
|
|
97
|
-
- Presets and settings in `~/.claude/settings.json`
|
|
98
|
-
- No modification to Claude Code's core configuration patterns
|
|
99
|
-
|
|
100
|
-
This solution transforms the MCP configuration experience from a
|
|
101
|
-
static, all-or-nothing choice into a dynamic, session-optimized
|
|
102
|
-
workflow that maximizes both functionality and efficiency.
|