Commit 4072dae
feat(inspector): stdio MCP server transport support (#132)
* feat(inspector): stdio MCP server transport support
Add stdio transport alongside existing HTTP for connecting to MCP servers
that communicate over stdin/stdout.
## Architecture
- ConnectionParams discriminated union: { transport: 'http', url } | { transport: 'stdio', command, args?, env?, cwd? }
- ONE branch point at createTestClient() — all other code is transport-agnostic
- Auto-restart for stdio with exponential backoff (1s, 2s, 4s, max 3 retries)
## Changes
### Types & Transport (Phase 1)
- Add ConnectionParams type to @mcp-apps-kit/testing
- createTestClient() accepts ConnectionParams, branches to StdioClientTransport or StreamableHTTPClientTransport
- Add onTransportClose callback to TestClientOptions
- Add connectionParams field to ConnectionState
### Connection Chain (Phase 2)
- ConnectionManager.connect() accepts ConnectionParams with input validation
- Auto-restart logic: onTransportClose → exponential backoff reconnect (stdio only)
- ConnectionRegistry.createConnection() accepts ConnectionParams
- All callers updated (28+ test files, 4 source files)
### Tool API (Phase 3)
- connect_to_server tool supports both transports via Zod union schema
- Backward compatible: plain { url } still works (defaults to HTTP)
### Dashboard API (Phase 4)
- POST /dashboard/connections accepts ConnectionParams body
- Backward compat: { url } without transport field defaults to HTTP
- Response includes transport type
### Dashboard UI (Phase 5)
- Transport dropdown (HTTP/stdio) in ConnectionBar
- stdio mode: command + args inputs replace URL input
- Advanced Settings toggle: env vars + cwd (stdio only)
- Server history stores transport type, shows stdio: badge
- Selecting stdio history entry populates command/args fields
* fix(inspector): resolve stdio auto-restart race condition and label inconsistency
- Add connectionGeneration counter to ConnectionManager to prevent
stale restart attempts after explicit disconnect()
- Align label format in test-client.ts to match connection.ts
('stdio: command' with space)
- Add stdio-transport behavioral test suite (18 tests)
* fix(inspector): remove unnecessary type assertion in connect tool
* test(testing): improve test-client coverage for stdio transport paths
Add mocked unit tests covering stdio/HTTP transport creation, env
merging, cwd forwarding, onTransportClose wiring, connection error
labels, and client operations (callTool, history, disconnect).
Branches coverage: 49.73% → 52.41% (above 50% threshold).
* fix(inspector): address PR review comments
- Throw error for missing HTTP URL instead of falling back to empty
string (connect.ts)
- Use element-wise args comparison in server history dedup instead of
join(' ') which can collide different arrays (useServerHistory.ts)
- Reset autoRestartAttempts on successful reconnect so subsequent
crashes get full retry budget (connection.ts)
- Wrap disconnect() in auto-restart catch with .catch() to prevent
swallowed errors (connection.ts)
- Standardize stdio label format with space after colon (connect.ts)
* fix(inspector): convert advanced settings to popover dropdown
- Replace inline collapsible with floating Popover component
- Settings gear button on right side of connection bar
- Popover: dark bg, shadow, z-1000, dismiss on click-outside/Escape
- Reusable Popover accepts panelStyle for future settings
- Button order: connect/disconnect → settings → close
- No header layout shift when settings are open
* fix(inspector): address PR review comments — security docs, label consistency, UI guards
- Standardize stdio display label to 'stdio:command args' (no space after colon)
across connection.ts, connect.ts, test-client.ts and all tests
- Hoist argsEqual() to module scope in useServerHistory.ts for proper
element-wise array comparison (prevents join collision)
- Add type guard for non-string args in history filter
- Add isCreating guard on handleKeyDown and handleSelectHistory in
ConnectionBar.tsx to prevent duplicate connection requests
- Add JSDoc security warning on ConnectionParams.env about process.env merge
- Add inline SECURITY NOTE in test-client.ts env merging code
* security(testing): allowlist parent env vars for stdio child processes
Replace full process.env merge with explicit safe-var allowlist (PATH, HOME,
LANG, NODE_ENV, XDG dirs, etc.) when spawning stdio child processes.
Sensitive variables (API keys, credentials, tokens) are never inherited
automatically.
Add inheritEnv flag to ConnectionParams for explicit control:
- When env is provided: only safe parent vars + user overrides (default)
- When inheritEnv=false: only safe parent vars
- When neither env nor inheritEnv set: Node.js default (full process.env)
Addresses PR #132 security review comment on env var leakage.
---------
Co-authored-by: Sirius <sirius@clawd.bot>1 parent 223a076 commit 4072dae
54 files changed
Lines changed: 2068 additions & 377 deletions
File tree
- examples
- minimal/tests
- integration
- weather-app/tests/integration
- packages
- create-app/src
- inspector
- src
- dashboard
- react
- components
- hooks
- tools
- types
- tests
- testing
- src
- eval/mcp
- server
- ui
- tests/unit/server
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
393 | 393 | | |
394 | 394 | | |
395 | 395 | | |
396 | | - | |
397 | | - | |
398 | | - | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
399 | 402 | | |
400 | 403 | | |
401 | 404 | | |
| |||
418 | 421 | | |
419 | 422 | | |
420 | 423 | | |
421 | | - | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
422 | 428 | | |
423 | 429 | | |
424 | 430 | | |
| |||
435 | 441 | | |
436 | 442 | | |
437 | 443 | | |
438 | | - | |
439 | | - | |
440 | | - | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
441 | 450 | | |
442 | 451 | | |
443 | 452 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
20 | | - | |
21 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
22 | 25 | | |
23 | 26 | | |
24 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
20 | | - | |
21 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
22 | 25 | | |
23 | 26 | | |
24 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
22 | 25 | | |
23 | 26 | | |
24 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
27 | 33 | | |
28 | 34 | | |
29 | 35 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
24 | 27 | | |
25 | 28 | | |
26 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
556 | 556 | | |
557 | 557 | | |
558 | 558 | | |
559 | | - | |
| 559 | + | |
560 | 560 | | |
561 | 561 | | |
562 | 562 | | |
| |||
1106 | 1106 | | |
1107 | 1107 | | |
1108 | 1108 | | |
1109 | | - | |
| 1109 | + | |
1110 | 1110 | | |
1111 | 1111 | | |
1112 | 1112 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
61 | 62 | | |
62 | 63 | | |
63 | 64 | | |
64 | | - | |
| 65 | + | |
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
68 | 69 | | |
69 | | - | |
| 70 | + | |
70 | 71 | | |
71 | 72 | | |
72 | 73 | | |
| |||
80 | 81 | | |
81 | 82 | | |
82 | 83 | | |
83 | | - | |
| 84 | + | |
84 | 85 | | |
85 | 86 | | |
86 | 87 | | |
| |||
0 commit comments