pi-mcp-adapter 1.5.1 → 2.0.0
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/ARCHITECTURE.md +91 -33
- package/CHANGELOG.md +33 -0
- package/README.md +60 -16
- package/cli.js +2 -0
- package/config.ts +1 -4
- package/index.ts +601 -255
- package/lifecycle.ts +34 -0
- package/metadata-cache.ts +175 -0
- package/npx-resolver.ts +419 -0
- package/package.json +3 -1
- package/resource-tools.ts +1 -29
- package/server-manager.ts +49 -5
- package/tool-registrar.ts +2 -33
- package/types.ts +29 -14
package/ARCHITECTURE.md
CHANGED
|
@@ -329,28 +329,30 @@
|
|
|
329
329
|
┌───────────────────────────────────────────────────────────────┐
|
|
330
330
|
│ mcp tool execute() - executeCall() │
|
|
331
331
|
│ │
|
|
332
|
-
│ 1. Look up tool in toolMetadata
|
|
332
|
+
│ 1. Look up tool in toolMetadata (may be from cache) │
|
|
333
333
|
│ for (const [server, metadata] of toolMetadata) { │
|
|
334
334
|
│ const found = metadata.find(m => m.name === toolName); │
|
|
335
335
|
│ if (found) { serverName = server; toolMeta = found; } │
|
|
336
336
|
│ } │
|
|
337
|
+
│ If not found: try prefix-match → lazy connect candidate │
|
|
337
338
|
│ │
|
|
338
|
-
│ 2.
|
|
339
|
+
│ 2. Ensure connection (lazy connect if needed) │
|
|
339
340
|
│ const connection = manager.getConnection(serverName); │
|
|
340
|
-
│ if (!connection ||
|
|
341
|
-
│
|
|
341
|
+
│ if (!connection || status !== "connected") │
|
|
342
|
+
│ → check failure backoff (60s) │
|
|
343
|
+
│ → connect, refresh metadata, re-resolve toolMeta │
|
|
342
344
|
│ │
|
|
343
|
-
│ 3. Call MCP server
|
|
345
|
+
│ 3. Call MCP server (with in-flight tracking) │
|
|
346
|
+
│ incrementInFlight() + touch() │
|
|
344
347
|
│ if (toolMeta.resourceUri) { │
|
|
345
|
-
│ // Resource tool - use readResource │
|
|
346
348
|
│ connection.client.readResource({ uri: resourceUri }); │
|
|
347
349
|
│ } else { │
|
|
348
|
-
│ // Regular tool - use callTool │
|
|
349
350
|
│ connection.client.callTool({ │
|
|
350
351
|
│ name: toolMeta.originalName, ◄── Original name! │
|
|
351
352
|
│ arguments: args ?? {} │
|
|
352
353
|
│ }); │
|
|
353
354
|
│ } │
|
|
355
|
+
│ finally { decrementInFlight() + touch() } │
|
|
354
356
|
└───────────────────────────┬───────────────────────────────────┘
|
|
355
357
|
│
|
|
356
358
|
▼
|
|
@@ -411,6 +413,12 @@
|
|
|
411
413
|
|
|
412
414
|
## Lifecycle & Health Checks
|
|
413
415
|
|
|
416
|
+
Servers support three lifecycle modes:
|
|
417
|
+
|
|
418
|
+
- **lazy** (default): Don't connect at startup. Connect on first tool call. Subject to idle timeout (default 10 minutes). Cached metadata enables search/list without connections.
|
|
419
|
+
- **eager**: Connect at startup. No idle timeout by default. If the connection drops, reconnects on next use (like lazy).
|
|
420
|
+
- **keep-alive**: Connect at startup. No idle timeout. Auto-reconnects via health checks if the connection drops.
|
|
421
|
+
|
|
414
422
|
```
|
|
415
423
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
416
424
|
│ Session Start │
|
|
@@ -423,11 +431,17 @@
|
|
|
423
431
|
│ 1. Load config │
|
|
424
432
|
│ 2. Create ServerManager │
|
|
425
433
|
│ 3. Create LifecycleManager │
|
|
426
|
-
│ 4.
|
|
427
|
-
│ 5.
|
|
428
|
-
│
|
|
429
|
-
│
|
|
430
|
-
│
|
|
434
|
+
│ 4. Load metadata cache │
|
|
435
|
+
│ 5. Register all servers with │
|
|
436
|
+
│ lifecycle manager │
|
|
437
|
+
│ 6. Reconstruct toolMetadata │
|
|
438
|
+
│ from cache (no connection) │
|
|
439
|
+
│ 7. Connect only eager + │
|
|
440
|
+
│ keep-alive servers │
|
|
441
|
+
│ (or all on first-run │
|
|
442
|
+
│ bootstrap) │
|
|
443
|
+
│ 8. Start health checks │
|
|
444
|
+
│ 9. Set reconnect/idle callbacks │
|
|
431
445
|
└─────────────────┬───────────────┘
|
|
432
446
|
│
|
|
433
447
|
▼
|
|
@@ -439,25 +453,39 @@
|
|
|
439
453
|
│ │ │ │
|
|
440
454
|
│ │ for each keep-alive server: │ │
|
|
441
455
|
│ │ if (status !== "connected"): │ │
|
|
442
|
-
│ │ try reconnect
|
|
443
|
-
│ │
|
|
444
|
-
│ │
|
|
456
|
+
│ │ try reconnect → onReconnect → updates toolMetadata + cache │ │
|
|
457
|
+
│ │ │ │
|
|
458
|
+
│ │ for each non-keep-alive server: │ │
|
|
459
|
+
│ │ if idle > timeout and inFlight == 0: │ │
|
|
460
|
+
│ │ close connection → onIdleShutdown │ │
|
|
461
|
+
│ │ (toolMetadata preserved for search/list) │ │
|
|
462
|
+
│ │ │ │
|
|
463
|
+
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
464
|
+
│ │
|
|
465
|
+
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
|
466
|
+
│ │ Lazy Connection (on tool call) │ │
|
|
467
|
+
│ │ │ │
|
|
468
|
+
│ │ executeCall() finds tool in cached metadata but no connection: │ │
|
|
469
|
+
│ │ 1. Check failure backoff (60s) │ │
|
|
470
|
+
│ │ 2. Connect server │ │
|
|
471
|
+
│ │ 3. Refresh metadata from live connection │ │
|
|
472
|
+
│ │ 4. Re-resolve tool (may have changed since cache) │ │
|
|
473
|
+
│ │ 5. Execute tool call with in-flight tracking │ │
|
|
445
474
|
│ │ │ │
|
|
446
|
-
│ │
|
|
447
|
-
│ │
|
|
448
|
-
│ │ │ the mcp proxy tool can find tools after reconnection. │ │ │
|
|
449
|
-
│ │ └──────────────────────────────────────────────────────────┘ │ │
|
|
475
|
+
│ │ Prefix-match fallback: if tool name has a server prefix but │ │
|
|
476
|
+
│ │ no metadata, try connecting the matching server │ │
|
|
450
477
|
│ │ │ │
|
|
451
478
|
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
452
479
|
│ │
|
|
453
480
|
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
|
454
481
|
│ │ /mcp Commands │ │
|
|
455
482
|
│ │ │ │
|
|
456
|
-
│ │ /mcp status
|
|
457
|
-
│ │ /mcp tools
|
|
458
|
-
│ │ /mcp reconnect
|
|
483
|
+
│ │ /mcp status - Show all servers and connection status │ │
|
|
484
|
+
│ │ /mcp tools - List all available MCP tools │ │
|
|
485
|
+
│ │ /mcp reconnect - Force reconnect all servers │ │
|
|
486
|
+
│ │ /mcp reconnect <name> - Connect or reconnect a single server │ │
|
|
459
487
|
│ │ │ │
|
|
460
|
-
│ │ /mcp-auth <server>
|
|
488
|
+
│ │ /mcp-auth <server> - Show OAuth setup instructions │ │
|
|
461
489
|
│ │ │ │
|
|
462
490
|
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
463
491
|
│ │
|
|
@@ -468,9 +496,9 @@
|
|
|
468
496
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
469
497
|
│ Graceful Shutdown │
|
|
470
498
|
│ │
|
|
471
|
-
│ 1.
|
|
472
|
-
│ 2.
|
|
473
|
-
│ 3.
|
|
499
|
+
│ 1. Flush metadata cache for all connected servers │
|
|
500
|
+
│ 2. Clear health check interval │
|
|
501
|
+
│ 3. Close all MCP connections (client + transport) │
|
|
474
502
|
│ │
|
|
475
503
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
476
504
|
```
|
|
@@ -498,17 +526,26 @@
|
|
|
498
526
|
│ - HTTP transport (StreamableHTTP + SSE fallback)
|
|
499
527
|
│ - connection pooling and deduplication
|
|
500
528
|
│
|
|
501
|
-
├── tool-registrar.ts
|
|
502
|
-
│ - collectToolNames() - builds name list
|
|
529
|
+
├── tool-registrar.ts MCP content transformation
|
|
503
530
|
│ - transformMcpContent() - MCP → Pi content
|
|
504
531
|
│
|
|
505
|
-
├── resource-tools.ts Resource
|
|
506
|
-
│ - collectResourceToolNames()
|
|
532
|
+
├── resource-tools.ts Resource name utilities
|
|
507
533
|
│ - resourceNameToToolName()
|
|
508
534
|
│
|
|
509
|
-
├──
|
|
510
|
-
│ -
|
|
511
|
-
│ -
|
|
535
|
+
├── metadata-cache.ts Persistent tool/resource metadata cache
|
|
536
|
+
│ - Per-server cache at ~/.pi/agent/mcp-cache.json
|
|
537
|
+
│ - Config hashing, staleness checks, reconstruction
|
|
538
|
+
│ - Read-merge-write for multi-session safety
|
|
539
|
+
│
|
|
540
|
+
├── npx-resolver.ts npx binary resolution (skip npm parent process)
|
|
541
|
+
│ - Probes ~/.npm/_npx/ cache directly
|
|
542
|
+
│ - Persistent cache at ~/.pi/agent/mcp-npx-cache.json
|
|
543
|
+
│ - JS detection (extension + shebang)
|
|
544
|
+
│
|
|
545
|
+
├── lifecycle.ts Health checks, reconnection, idle timeout
|
|
546
|
+
│ - keep-alive server tracking + auto-reconnect
|
|
547
|
+
│ - Idle timeout for lazy/eager servers
|
|
548
|
+
│ - Per-server and global timeout settings
|
|
512
549
|
│
|
|
513
550
|
├── oauth-handler.ts OAuth token file reading
|
|
514
551
|
│ - getStoredTokens() from ~/.pi/agent/mcp-oauth/
|
|
@@ -568,5 +605,26 @@
|
|
|
568
605
|
│ Lifecycle manager notifies extension after auto-reconnect. │
|
|
569
606
|
│ Extension updates tool metadata so proxy can find tools. │
|
|
570
607
|
│ │
|
|
608
|
+
│ 8. LAZY BY DEFAULT │
|
|
609
|
+
│ ─────────────── │
|
|
610
|
+
│ All servers default to lifecycle: "lazy". They only connect │
|
|
611
|
+
│ when a tool call needs them. Cached metadata enables │
|
|
612
|
+
│ search/list/describe without live connections. Idle servers │
|
|
613
|
+
│ are disconnected after 10 minutes (configurable). │
|
|
614
|
+
│ │
|
|
615
|
+
│ 9. METADATA CACHE │
|
|
616
|
+
│ ────────────── │
|
|
617
|
+
│ ~/.pi/agent/mcp-cache.json stores per-server tool/resource │
|
|
618
|
+
│ metadata with config hash validation and 7-day staleness. │
|
|
619
|
+
│ Cache stores original MCP names (not prefixed) — toolPrefix │
|
|
620
|
+
│ changes never invalidate the cache. Read-merge-write with │
|
|
621
|
+
│ per-process tmp files for multi-session safety. │
|
|
622
|
+
│ │
|
|
623
|
+
│ 10. NPX RESOLUTION │
|
|
624
|
+
│ ─────────────── │
|
|
625
|
+
│ npx-based servers resolve to direct binary paths, eliminating │
|
|
626
|
+
│ the ~143 MB npm parent process per server. Probes ~/.npm/_npx/ │
|
|
627
|
+
│ cache directly. JS files run via node, others executed directly. │
|
|
628
|
+
│ │
|
|
571
629
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
572
630
|
```
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.0] - 2026-01-29
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **BREAKING: Lazy startup by default** - All servers now default to `lifecycle: "lazy"` and only connect when a tool call needs them. Previously all servers connected eagerly on session start. Set `lifecycle: "keep-alive"` or `lifecycle: "eager"` to restore the old behavior per-server.
|
|
14
|
+
- **Idle timeout** - Connected servers are automatically disconnected after 10 minutes of inactivity (configurable via `settings.idleTimeout` or per-server `idleTimeout`). Cached metadata keeps search/list working after disconnect. Set `idleTimeout: 0` to disable.
|
|
15
|
+
- `/mcp reconnect` accepts an optional server name to connect or reconnect a single server
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **Metadata cache** - Tool and resource metadata persisted to `~/.pi/agent/mcp-cache.json`. Enables search/list/describe without live connections. Per-server config hashing with 7-day staleness. Multi-session safe via read-merge-write with per-process tmp files.
|
|
19
|
+
- **npx binary resolution** - Resolves npx package binaries to direct paths, eliminating the ~143 MB npm parent process per server. Persistent cache at `~/.pi/agent/mcp-npx-cache.json` with 24h TTL.
|
|
20
|
+
- **`mcp({ connect: "server-name" })` mode** - Explicitly trigger connection and metadata refresh for a named server
|
|
21
|
+
- **Failure backoff** - Servers that fail to connect are skipped for 60 seconds to avoid repeated connection storms
|
|
22
|
+
- **In-flight tracking** - Active tool calls prevent idle timeout from shutting down a server mid-request
|
|
23
|
+
- **Prefix-match fallback** - Tool calls with unrecognized names try to match a server prefix and lazy-connect the matching server
|
|
24
|
+
- Lifecycle options: `lazy` (default), `eager` (connect at startup, no auto-reconnect), `keep-alive` (unchanged)
|
|
25
|
+
- Per-server `idleTimeout` override and global `settings.idleTimeout`
|
|
26
|
+
- First-run bootstrap: connects all servers on first session to populate the cache
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Connection close race condition: concurrent close + connect no longer orphans server processes
|
|
30
|
+
- **Fuzzy tool name matching** - Hyphens and underscores are treated as equivalent during tool lookup. MCP tools like `resolve-library-id` are now found when called as `resolve_library_id`, which LLMs naturally guess since the prefix separator is `_`.
|
|
31
|
+
- **Better "tool not found" errors** - When a server is identified (via prefix match or override) but the tool isn't found, the error now lists that server's available tools so the LLM can self-correct immediately instead of needing a separate list call
|
|
32
|
+
|
|
33
|
+
## [1.6.0] - 2026-01-29
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- **Unified pi tool search** - `mcp({ search: "..." })` now searches both MCP tools and Pi tools (from installed extensions)
|
|
37
|
+
- Pi tools appear first in results with `[pi tool]` prefix
|
|
38
|
+
- Details object includes `server: "pi"` for pi tools
|
|
39
|
+
- Banner image for README
|
|
40
|
+
|
|
41
|
+
## [1.5.1] - 2026-01-26
|
|
42
|
+
|
|
10
43
|
### Changed
|
|
11
44
|
- Added `pi-package` keyword for npm discoverability (pi v0.50.0 package system)
|
|
12
45
|
|
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p>
|
|
2
|
+
<img src="banner.png" alt="pi-mcp-adapter" width="1100">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# Pi MCP Adapter
|
|
2
6
|
|
|
3
7
|
Use MCP servers with [Pi](https://github.com/badlogic/pi-mono/) without burning your context window.
|
|
@@ -10,15 +14,15 @@ Mario wrote about [why you might not need MCP](https://mariozechner.at/posts/202
|
|
|
10
14
|
|
|
11
15
|
His take: skip MCP entirely, write simple CLI tools instead.
|
|
12
16
|
|
|
13
|
-
But the MCP ecosystem has useful stuff - databases, browsers, APIs. This adapter gives you access without the bloat. One proxy tool (~200 tokens) instead of hundreds. The agent discovers what it needs on-demand.
|
|
17
|
+
But the MCP ecosystem has useful stuff - databases, browsers, APIs. This adapter gives you access without the bloat. One proxy tool (~200 tokens) instead of hundreds. The agent discovers what it needs on-demand. Servers only start when you actually use them.
|
|
14
18
|
|
|
15
19
|
## Install
|
|
16
20
|
|
|
17
21
|
```bash
|
|
18
|
-
|
|
22
|
+
pi install npm:pi-mcp-adapter
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
Restart Pi after installation.
|
|
22
26
|
|
|
23
27
|
## Quick Start
|
|
24
28
|
|
|
@@ -29,14 +33,13 @@ Create `~/.pi/agent/mcp.json`:
|
|
|
29
33
|
"mcpServers": {
|
|
30
34
|
"chrome-devtools": {
|
|
31
35
|
"command": "npx",
|
|
32
|
-
"args": ["-y", "chrome-devtools-mcp@latest"]
|
|
33
|
-
"lifecycle": "keep-alive"
|
|
36
|
+
"args": ["-y", "chrome-devtools-mcp@latest"]
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
```
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
Servers are **lazy by default** — they won't connect until you actually call one of their tools. The adapter caches tool metadata so search and describe work without live connections.
|
|
40
43
|
|
|
41
44
|
```
|
|
42
45
|
mcp({ search: "screenshot" })
|
|
@@ -67,7 +70,8 @@ Two calls instead of 26 tools cluttering the context.
|
|
|
67
70
|
"my-server": {
|
|
68
71
|
"command": "npx",
|
|
69
72
|
"args": ["-y", "some-mcp-server"],
|
|
70
|
-
"lifecycle": "
|
|
73
|
+
"lifecycle": "lazy",
|
|
74
|
+
"idleTimeout": 10
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
}
|
|
@@ -78,13 +82,40 @@ Two calls instead of 26 tools cluttering the context.
|
|
|
78
82
|
| `command` | Executable for stdio transport |
|
|
79
83
|
| `args` | Command arguments |
|
|
80
84
|
| `env` | Environment variables (`${VAR}` interpolation) |
|
|
85
|
+
| `cwd` | Working directory |
|
|
81
86
|
| `url` | HTTP endpoint (StreamableHTTP with SSE fallback) |
|
|
82
87
|
| `auth` | `"bearer"` or `"oauth"` |
|
|
83
|
-
| `bearerToken` / `bearerTokenEnv` | Token or env var |
|
|
84
|
-
| `lifecycle` | `"keep-alive"`
|
|
88
|
+
| `bearerToken` / `bearerTokenEnv` | Token or env var name |
|
|
89
|
+
| `lifecycle` | `"lazy"` (default), `"eager"`, or `"keep-alive"` |
|
|
90
|
+
| `idleTimeout` | Minutes before idle disconnect (overrides global) |
|
|
85
91
|
| `exposeResources` | Expose MCP resources as tools (default: true) |
|
|
86
92
|
| `debug` | Show server stderr (default: false) |
|
|
87
93
|
|
|
94
|
+
### Lifecycle Modes
|
|
95
|
+
|
|
96
|
+
- **`lazy`** (default) — Don't connect at startup. Connect on first tool call. Disconnect after idle timeout. Cached metadata keeps search/list working without connections.
|
|
97
|
+
- **`eager`** — Connect at startup but don't auto-reconnect if the connection drops. No idle timeout by default (set `idleTimeout` explicitly to enable).
|
|
98
|
+
- **`keep-alive`** — Connect at startup. Auto-reconnect via health checks. No idle timeout. Use for servers you always need available.
|
|
99
|
+
|
|
100
|
+
### Settings
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"settings": {
|
|
105
|
+
"toolPrefix": "server",
|
|
106
|
+
"idleTimeout": 10
|
|
107
|
+
},
|
|
108
|
+
"mcpServers": { }
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
| Setting | Description |
|
|
113
|
+
|---------|-------------|
|
|
114
|
+
| `toolPrefix` | `"server"` (default), `"short"` (strips `-mcp` suffix), or `"none"` |
|
|
115
|
+
| `idleTimeout` | Global idle timeout in minutes (default: 10, 0 to disable) |
|
|
116
|
+
|
|
117
|
+
Per-server `idleTimeout` overrides the global setting.
|
|
118
|
+
|
|
88
119
|
### Import Existing Configs
|
|
89
120
|
|
|
90
121
|
Already have MCP set up elsewhere? Import it:
|
|
@@ -98,16 +129,24 @@ Already have MCP set up elsewhere? Import it:
|
|
|
98
129
|
|
|
99
130
|
Supported: `cursor`, `claude-code`, `claude-desktop`, `vscode`, `windsurf`, `codex`
|
|
100
131
|
|
|
132
|
+
### Project Config
|
|
133
|
+
|
|
134
|
+
Add `.pi/mcp.json` in a project root for project-specific servers. Project config overrides global and imported servers.
|
|
135
|
+
|
|
101
136
|
## Usage
|
|
102
137
|
|
|
103
138
|
| Mode | Example |
|
|
104
139
|
|------|---------|
|
|
140
|
+
| Status | `mcp({ })` |
|
|
141
|
+
| List server | `mcp({ server: "name" })` |
|
|
105
142
|
| Search | `mcp({ search: "screenshot navigate" })` |
|
|
106
143
|
| Describe | `mcp({ describe: "tool_name" })` |
|
|
107
144
|
| Call | `mcp({ tool: "...", args: '{"key": "value"}' })` |
|
|
108
|
-
|
|
|
145
|
+
| Connect | `mcp({ connect: "server-name" })` |
|
|
146
|
+
|
|
147
|
+
Search includes both MCP tools and Pi tools (from extensions). Pi tools appear first with `[pi tool]` prefix. Space-separated words are OR'd.
|
|
109
148
|
|
|
110
|
-
|
|
149
|
+
Tool names are fuzzy-matched on hyphens and underscores — `context7_resolve_library_id` finds `context7_resolve-library-id`.
|
|
111
150
|
|
|
112
151
|
## Commands
|
|
113
152
|
|
|
@@ -115,19 +154,24 @@ Search includes parameter schemas by default. Space-separated words are OR'd.
|
|
|
115
154
|
|---------|--------------|
|
|
116
155
|
| `/mcp` | Server status |
|
|
117
156
|
| `/mcp tools` | List all tools |
|
|
118
|
-
| `/mcp reconnect` | Reconnect servers |
|
|
157
|
+
| `/mcp reconnect` | Reconnect all servers |
|
|
158
|
+
| `/mcp reconnect <server>` | Connect or reconnect a single server |
|
|
119
159
|
| `/mcp-auth <server>` | OAuth setup |
|
|
120
160
|
|
|
121
161
|
## How It Works
|
|
122
162
|
|
|
123
|
-
See [ARCHITECTURE.md](./ARCHITECTURE.md) for
|
|
163
|
+
See [ARCHITECTURE.md](./ARCHITECTURE.md) for the full picture. Short version:
|
|
124
164
|
|
|
125
|
-
- One `mcp` tool in context (~200 tokens)
|
|
126
|
-
-
|
|
127
|
-
-
|
|
165
|
+
- One `mcp` tool in context (~200 tokens) instead of hundreds
|
|
166
|
+
- Servers are lazy by default — they connect on first tool call, not at startup
|
|
167
|
+
- Tool metadata is cached to disk so search/list/describe work without live connections
|
|
168
|
+
- Idle servers disconnect after 10 minutes (configurable), reconnect automatically on next use
|
|
169
|
+
- npx-based servers resolve to direct binary paths, skipping the ~143 MB npm parent process
|
|
170
|
+
- MCP server validates arguments, not the adapter
|
|
128
171
|
- Keep-alive servers get health checks and auto-reconnect
|
|
129
172
|
|
|
130
173
|
## Limitations
|
|
131
174
|
|
|
132
175
|
- OAuth tokens obtained externally (no browser flow)
|
|
133
176
|
- No automatic token refresh
|
|
177
|
+
- Cross-session server sharing not yet implemented (each Pi session runs its own server processes)
|
package/cli.js
CHANGED
package/config.ts
CHANGED
|
@@ -109,6 +109,7 @@ function extractServers(config: unknown, kind: ImportKind): Record<string, Serve
|
|
|
109
109
|
switch (kind) {
|
|
110
110
|
case "claude-desktop":
|
|
111
111
|
case "claude-code":
|
|
112
|
+
case "codex":
|
|
112
113
|
servers = obj.mcpServers;
|
|
113
114
|
break;
|
|
114
115
|
case "cursor":
|
|
@@ -116,14 +117,10 @@ function extractServers(config: unknown, kind: ImportKind): Record<string, Serve
|
|
|
116
117
|
case "vscode":
|
|
117
118
|
servers = obj.mcpServers ?? obj["mcp-servers"];
|
|
118
119
|
break;
|
|
119
|
-
case "codex":
|
|
120
|
-
servers = obj.mcpServers;
|
|
121
|
-
break;
|
|
122
120
|
default:
|
|
123
121
|
return {};
|
|
124
122
|
}
|
|
125
123
|
|
|
126
|
-
// Validate servers is a plain object
|
|
127
124
|
if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
|
|
128
125
|
return {};
|
|
129
126
|
}
|