Skip to content

Commit 739fd42

Browse files
committed
feat: add tools for discovering MCP client configs
Add comprehensive tooling to help discover and add new MCP clients: Tools: - mcp-client-sniffer.cjs: Minimal MCP server to capture clientInfo - verify-client-configs.js: Check which clients are installed - npm run verify-clients: Convenience script Documentation: - docs/discovering-new-clients.md: Complete guide for adding clients - How to capture clientInfo.name - How to find config paths - Testing and validation steps - Examples with Cursor and Enconvo These tools enable contributors to easily add support for new MCP clients by discovering their handshake details and config locations.
1 parent 2eae4af commit 739fd42

4 files changed

Lines changed: 656 additions & 0 deletions

File tree

docs/discovering-new-clients.md

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
# Discovering New MCP Clients
2+
3+
This guide explains how to add support for new MCP clients to NCP's auto-import feature.
4+
5+
## Overview
6+
7+
To support a new MCP client, we need two key pieces of information:
8+
1. **Client Name**: What `clientInfo.name` the client sends during MCP handshake
9+
2. **Config Path**: Where the client stores its MCP server configurations
10+
11+
## Step 1: Capture Client Name
12+
13+
### Method A: Use the MCP Client Sniffer (Recommended)
14+
15+
The sniffer is a minimal MCP server that logs initialization requests.
16+
17+
1. **Add sniffer to client config**:
18+
19+
```json
20+
{
21+
"mcpServers": {
22+
"client-sniffer": {
23+
"command": "node",
24+
"args": ["/path/to/ncp/scripts/mcp-client-sniffer.cjs"]
25+
}
26+
}
27+
}
28+
```
29+
30+
2. **Restart the client** or reload MCP connections
31+
32+
3. **Check the output**:
33+
- Console will show: `✨ CLIENT DETECTED!`
34+
- Details saved to: `client-info-log.json`
35+
36+
4. **Review captured data**:
37+
```bash
38+
cat client-info-log.json
39+
```
40+
41+
Example output:
42+
```json
43+
[
44+
{
45+
"timestamp": "2025-10-31T12:00:00.000Z",
46+
"clientInfo": {
47+
"name": "cursor",
48+
"version": "0.42.0"
49+
},
50+
"protocolVersion": "2024-11-05"
51+
}
52+
]
53+
```
54+
55+
### Method B: Check Client Documentation
56+
57+
Some clients document their `clientInfo.name`:
58+
- Claude Desktop: `claude-desktop` or `claude-ai`
59+
- Cursor: `cursor`
60+
- Cline: `cline`
61+
- Continue: `continue`
62+
63+
### Method C: Monitor MCP Logs
64+
65+
If the client creates logs, check for initialization messages:
66+
67+
```bash
68+
# Example: Check Windsurf logs
69+
find ~/Library/Application\ Support/Windsurf/logs -name "*mcp*" | head -5
70+
```
71+
72+
## Step 2: Find Config Path
73+
74+
### Search Strategy
75+
76+
1. **Check home directory**:
77+
```bash
78+
ls -la ~ | grep -i <client-name>
79+
```
80+
81+
2. **Check .config directory**:
82+
```bash
83+
ls -la ~/.config | grep -i <client-name>
84+
```
85+
86+
3. **Check Application Support** (macOS):
87+
```bash
88+
ls -la ~/Library/Application\ Support/ | grep -i <client-name>
89+
```
90+
91+
4. **Check AppData** (Windows):
92+
```powershell
93+
ls $env:APPDATA | Select-String <client-name>
94+
```
95+
96+
5. **Search for MCP-related files**:
97+
```bash
98+
find ~ -name "*mcp*.json" 2>/dev/null | grep -i <client-name>
99+
```
100+
101+
### Common Patterns
102+
103+
| Location | Example |
104+
|----------|---------|
105+
| Home dotfiles | `~/.cursor/mcp.json` |
106+
| .config | `~/.config/enconvo/mcp_config.json` |
107+
| Application Support | `~/Library/Application Support/Claude/claude_desktop_config.json` |
108+
| VSCode-like | `~/Library/Application Support/<IDE>/User/globalStorage/<extension>/settings/*.json` |
109+
110+
### Verify Config Format
111+
112+
Once you find the config file:
113+
114+
```bash
115+
cat <config-path> | jq '.mcpServers'
116+
```
117+
118+
Check:
119+
- ✅ Is it JSON or TOML?
120+
- ✅ Where are MCP servers stored? (root level? nested path?)
121+
- ✅ What's the structure? (object with MCP names as keys?)
122+
123+
Example structures:
124+
125+
**Standard format** (Claude Desktop, Cursor):
126+
```json
127+
{
128+
"mcpServers": {
129+
"filesystem": {
130+
"command": "npx",
131+
"args": ["-y", "@modelcontextprotocol/server-filesystem"]
132+
}
133+
}
134+
}
135+
```
136+
137+
**Nested format** (Continue):
138+
```json
139+
{
140+
"experimental": {
141+
"modelContextProtocolServers": {
142+
"filesystem": { ... }
143+
}
144+
}
145+
}
146+
```
147+
148+
**Array format** (Perplexity):
149+
```json
150+
{
151+
"servers": [
152+
{ "name": "filesystem", "command": "..." }
153+
]
154+
}
155+
```
156+
157+
## Step 3: Add to Client Registry
158+
159+
Update `src/utils/client-registry.ts`:
160+
161+
```typescript
162+
'<client-id>': {
163+
displayName: '<Client Name>',
164+
configPaths: {
165+
darwin: '~/path/to/config.json', // macOS
166+
win32: '%APPDATA%/path/to/config.json', // Windows
167+
linux: '~/.config/path/to/config.json' // Linux
168+
},
169+
configFormat: 'json', // or 'toml'
170+
mcpServersPath: 'mcpServers' // JSON path to servers object
171+
}
172+
```
173+
174+
### Important Notes
175+
176+
1. **Client ID normalization**: NCP normalizes client names by:
177+
- Converting to lowercase
178+
- Removing spaces and dashes
179+
- Example: `"Claude Desktop"``"claudedesktop"`
180+
181+
2. **Add all aliases**: Some clients send different names:
182+
```typescript
183+
'claude-desktop': { ... },
184+
'claude-ai': { ... }, // Alias pointing to same paths
185+
```
186+
187+
3. **Platform-specific paths**: Only include paths for supported platforms
188+
189+
## Step 4: Test Auto-Import
190+
191+
### Build and Verify
192+
193+
```bash
194+
# 1. Build
195+
npm run build
196+
197+
# 2. Check detection
198+
node scripts/verify-client-configs.js
199+
200+
# Expected output:
201+
# ✅ INSTALLED CLIENTS (Can Test Auto-Import)
202+
# 📦 <Your Client>
203+
# Client ID: <client-id>
204+
# Config: /actual/path/to/config.json
205+
```
206+
207+
### Manual Test
208+
209+
```bash
210+
# 1. Clear NCP profile
211+
rm ~/.ncp/profiles/all.json
212+
213+
# 2. Start NCP with client's name
214+
# (or configure client to use NCP and restart)
215+
216+
# 3. Check if MCPs were imported
217+
cat ~/.ncp/profiles/all.json | jq '.mcpServers'
218+
```
219+
220+
### Integration Test
221+
222+
Add test to `tests/integration/comprehensive-dxt-test.cjs`:
223+
224+
```javascript
225+
const id = test.sendRequest('initialize', {
226+
protocolVersion: '2024-11-05',
227+
clientInfo: {
228+
name: '<client-id>',
229+
version: '1.0.0'
230+
}
231+
});
232+
```
233+
234+
## Step 5: Document
235+
236+
Update docs:
237+
1. **docs/testing-client-auto-import.md** - Add config path reference
238+
2. **README.md** - Add client to supported list
239+
3. **docs/clients/<client>.md** - Create setup guide (optional)
240+
241+
## Examples
242+
243+
### Example 1: Cursor
244+
245+
**Discovery**:
246+
```bash
247+
# Found config
248+
ls ~/.cursor/
249+
# Output: mcp.json
250+
251+
# Verified format
252+
cat ~/.cursor/mcp.json
253+
# Shows: { "mcpServers": { ... } }
254+
```
255+
256+
**Captured clientInfo** (using sniffer):
257+
```json
258+
{
259+
"clientInfo": {
260+
"name": "cursor",
261+
"version": "0.42.0"
262+
}
263+
}
264+
```
265+
266+
**Added to registry**:
267+
```typescript
268+
'cursor': {
269+
displayName: 'Cursor',
270+
configPaths: {
271+
darwin: '~/.cursor/mcp.json',
272+
win32: '%USERPROFILE%/.cursor/mcp.json',
273+
linux: '~/.cursor/mcp.json'
274+
},
275+
configFormat: 'json',
276+
mcpServersPath: 'mcpServers'
277+
}
278+
```
279+
280+
### Example 2: Enconvo
281+
282+
**Discovery**:
283+
```bash
284+
# Search for config
285+
find ~ -name "*enconvo*" -type d
286+
# Found: ~/.config/enconvo
287+
288+
# Check contents
289+
ls ~/.config/enconvo/
290+
# Found: mcp_config.json
291+
292+
# Verify format
293+
cat ~/.config/enconvo/mcp_config.json
294+
# Shows: { "mcpServers": {} }
295+
```
296+
297+
**Added to registry**:
298+
```typescript
299+
'enconvo': {
300+
displayName: 'Enconvo',
301+
configPaths: {
302+
darwin: '~/.config/enconvo/mcp_config.json'
303+
},
304+
configFormat: 'json',
305+
mcpServersPath: 'mcpServers'
306+
}
307+
```
308+
309+
## Troubleshooting
310+
311+
### Client not detected
312+
313+
1. **Check client name normalization**:
314+
```javascript
315+
// In src/utils/client-registry.ts
316+
export function normalizeClientName(name: string): string {
317+
return name.toLowerCase().replace(/[\s-]/g, '');
318+
}
319+
```
320+
321+
2. **Verify config exists**:
322+
```bash
323+
ls -la <config-path>
324+
```
325+
326+
3. **Check NCP logs**:
327+
```bash
328+
export NCP_DEBUG=true
329+
cat ~/.ncp/debug.log | grep -i "client"
330+
```
331+
332+
### MCPs not imported
333+
334+
1. **Check mcpServersPath**: Verify JSON path is correct
335+
```bash
336+
cat <config> | jq '.<mcpServersPath>'
337+
```
338+
339+
2. **Test config parsing**:
340+
```javascript
341+
import { importFromClient } from './dist/utils/client-importer.js';
342+
const result = await importFromClient('<client-id>');
343+
console.log(result);
344+
```
345+
346+
### Config format issues
347+
348+
1. **TOML support**: Use `configFormat: 'toml'` and install parser
349+
2. **Custom format**: Add custom parser in `client-importer.ts`
350+
3. **Array format**: Update `mcpServersPath` to handle arrays
351+
352+
## Tools Reference
353+
354+
### Scripts
355+
356+
| Script | Purpose |
357+
|--------|---------|
358+
| `scripts/mcp-client-sniffer.cjs` | Capture clientInfo from any MCP client |
359+
| `scripts/verify-client-configs.js` | Check which clients are installed and detectable |
360+
| `scripts/capture-client-info.js` | Advanced monitoring with NCP server |
361+
362+
### Files to Update
363+
364+
| File | What to Add |
365+
|------|-------------|
366+
| `src/utils/client-registry.ts` | Client definition with paths |
367+
| `src/utils/client-importer.ts` | Custom parsers (if needed) |
368+
| `docs/testing-client-auto-import.md` | Testing instructions |
369+
| `tests/integration/comprehensive-dxt-test.cjs` | Integration test |
370+
371+
## Best Practices
372+
373+
1. **Test on actual installations** - Don't guess paths
374+
2. **Document platform differences** - Note any OS-specific quirks
375+
3. **Handle edge cases** - Client might not have MCPs configured yet
376+
4. **Validate data** - Ensure MCPs have required `command` field
377+
5. **Preserve user data** - Don't overwrite existing configs during import

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"test:client-registry": "node scripts/test-client-registry.js",
4242
"test:registry-security": "node scripts/test-registry-security.js",
4343
"test:http-auth": "node scripts/test-http-auth.js",
44+
"verify-clients": "npm run build && node scripts/verify-client-configs.js",
4445
"build:dxt": "bash scripts/build-dxt-clean.sh",
4546
"build:dxt:patched": "npm run build:dxt && ./scripts/patch-dxt-zip.sh",
4647
"build:dxt:signed": "npm run build:dxt:patched && npx @anthropic-ai/mcpb sign ncp.dxt --self-signed && npm run test:dxt",

0 commit comments

Comments
 (0)