@njuptlzf/mcp-adapter 2.29.0-0.0.1
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 +1205 -0
- package/LICENSE +21 -0
- package/MAPPING.md +73 -0
- package/README.md +564 -0
- package/abort.ts +34 -0
- package/adapters/pi-renderer.ts +7 -0
- package/adapters/protocol-elicitation-forwarder.ts +164 -0
- package/adapters/protocol-sampling-forwarder.ts +108 -0
- package/adapters/universal-host.ts +213 -0
- package/agent-dir.ts +68 -0
- package/agent-plugin-loader.ts +377 -0
- package/app-bridge.bundle.js +67 -0
- package/banner.png +0 -0
- package/bin/mcp-server.ts +282 -0
- package/cli.js +392 -0
- package/commands.ts +735 -0
- package/config.ts +1284 -0
- package/consent-manager.ts +64 -0
- package/direct-tools.ts +619 -0
- package/dist/agent-dir.d.ts +10 -0
- package/dist/agent-dir.js +63 -0
- package/dist/agent-dir.js.map +1 -0
- package/dist/agent-plugin-loader.d.ts +8 -0
- package/dist/agent-plugin-loader.js +356 -0
- package/dist/agent-plugin-loader.js.map +1 -0
- package/dist/config.d.ts +123 -0
- package/dist/config.js +1087 -0
- package/dist/config.js.map +1 -0
- package/dist/metadata-cache.d.ts +19 -0
- package/dist/metadata-cache.js +319 -0
- package/dist/metadata-cache.js.map +1 -0
- package/dist/package-mcp-loader.d.ts +2 -0
- package/dist/package-mcp-loader.js +156 -0
- package/dist/package-mcp-loader.js.map +1 -0
- package/dist/resource-tools.d.ts +1 -0
- package/dist/resource-tools.js +15 -0
- package/dist/resource-tools.js.map +1 -0
- package/dist/types.d.ts +564 -0
- package/dist/types.js +287 -0
- package/dist/types.js.map +1 -0
- package/dist/ui-app-bridge-helpers.d.ts +6 -0
- package/dist/ui-app-bridge-helpers.js +37 -0
- package/dist/ui-app-bridge-helpers.js.map +1 -0
- package/dist/ui-stream-types.d.ts +104 -0
- package/dist/ui-stream-types.js +59 -0
- package/dist/ui-stream-types.js.map +1 -0
- package/dist/ui-tool-visibility.d.ts +4 -0
- package/dist/ui-tool-visibility.js +27 -0
- package/dist/ui-tool-visibility.js.map +1 -0
- package/dist/utils.d.ts +32 -0
- package/dist/utils.js +338 -0
- package/dist/utils.js.map +1 -0
- package/elicitation-handler.ts +348 -0
- package/error-signal.ts +21 -0
- package/errors.ts +223 -0
- package/failure-backoff.ts +23 -0
- package/glimpse-ui.ts +80 -0
- package/host-html-template.ts +461 -0
- package/index.ts +1291 -0
- package/init.ts +692 -0
- package/interfaces/agent-paths.ts +67 -0
- package/interfaces/host-types.ts +102 -0
- package/interfaces/sampling.ts +57 -0
- package/json-schema-validator.ts +69 -0
- package/lifecycle.ts +446 -0
- package/logger.ts +169 -0
- package/mcp-auth-flow.ts +1026 -0
- package/mcp-auth.ts +1000 -0
- package/mcp-bearer-store.ts +387 -0
- package/mcp-callback-server.ts +534 -0
- package/mcp-code.ts +360 -0
- package/mcp-keyring-helper.cjs +89 -0
- package/mcp-oauth-provider.ts +666 -0
- package/mcp-output-guard.ts +496 -0
- package/mcp-panel.ts +1044 -0
- package/mcp-probe.ts +201 -0
- package/mcp-references.ts +368 -0
- package/mcp-script-worker.mjs +130 -0
- package/mcp-server.mjs +2133 -0
- package/mcp-setup-panel.ts +667 -0
- package/mcp-status.ts +98 -0
- package/mcp-trace.ts +306 -0
- package/metadata-cache.ts +382 -0
- package/namespace-tools.ts +276 -0
- package/npx-resolver.ts +543 -0
- package/oauth-handler.ts +30 -0
- package/oauth.ts +48 -0
- package/onboarding-state.ts +76 -0
- package/package-mcp-loader.ts +168 -0
- package/package.json +225 -0
- package/panel-keys.ts +53 -0
- package/prompts.ts +353 -0
- package/proxy-modes.ts +1418 -0
- package/request-headers-command.ts +330 -0
- package/resource-tools.ts +17 -0
- package/runtime-owner.ts +91 -0
- package/sampling-handler.ts +284 -0
- package/search-ranking.ts +278 -0
- package/server-manager.ts +1318 -0
- package/session-recovery.ts +158 -0
- package/skills/README.md +64 -0
- package/skills/mcp-adapter/SKILL.md +332 -0
- package/skills/mcp-adapter/references/deploy-examples.md +259 -0
- package/skills/mcp-adapter/references/deploy.md +89 -0
- package/skills/mcp-adapter/references/generate.md +144 -0
- package/skills/mcp-adapter/references/resolver.md +105 -0
- package/skills/mcp-adapter/references/verify.md +157 -0
- package/skills/mcp-scripting/SKILL.md +38 -0
- package/skills/resolve-conflicts/SKILL.md +482 -0
- package/skills/resolve-conflicts/references/patterns.md +432 -0
- package/skills/resolve-conflicts/references/sample-plan.md +96 -0
- package/skills/resolve-conflicts/scripts/handle-deleted-modified.sh +183 -0
- package/skills/resolve-conflicts/scripts/validate-conflicts.sh +120 -0
- package/skills/upstream-merge/SKILL.md +486 -0
- package/skills/upstream-merge/references/pi-coupling-markers.md +129 -0
- package/skills/upstream-merge/references/special-cases.md +39 -0
- package/state.ts +60 -0
- package/tool-approval.ts +195 -0
- package/tool-metadata.ts +296 -0
- package/tool-registrar.ts +253 -0
- package/tool-result-renderer.ts +477 -0
- package/ts-shape.ts +149 -0
- package/types.ts +991 -0
- package/ui-app-bridge-helpers.ts +40 -0
- package/ui-resource-handler.ts +250 -0
- package/ui-server.ts +852 -0
- package/ui-session.ts +571 -0
- package/ui-stream-types.ts +89 -0
- package/ui-tool-visibility.ts +25 -0
- package/unix-socket-transport.ts +85 -0
- package/utils.ts +382 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nico Bailon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/MAPPING.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Universal Host Shim — ExtensionAPI Mapping
|
|
2
|
+
|
|
3
|
+
This file documents how the fork-owned universal MCP-stdio host
|
|
4
|
+
(`adapters/universal-host.ts`) satisfies the upstream Pi `ExtensionAPI`
|
|
5
|
+
surface, so the upstream engine (`index.ts` `installMcpAdapter`) runs
|
|
6
|
+
unchanged against a non-Pi host.
|
|
7
|
+
|
|
8
|
+
> Direction (Phase 1): **fork the host, not the engine.** The retired
|
|
9
|
+
> `AgentAPI` abstraction (`interfaces/agent-api.ts` / `adapters/pi-adapter.ts`)
|
|
10
|
+
> is gone. The sole adapter surface is now `UniversalMcpHost`, which
|
|
11
|
+
> impersonates `ExtensionAPI` directly; `bin/mcp-server.ts` casts to
|
|
12
|
+
> `ExtensionAPI` at the boundary. The shared fork-owned types live in
|
|
13
|
+
> `interfaces/host-types.ts`.
|
|
14
|
+
|
|
15
|
+
This is the source of truth for verifying the host surface. When the
|
|
16
|
+
upstream Pi ecosystem changes its public surface, update both the host
|
|
17
|
+
and the corresponding row below.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## UniversalHostSurface → ExtensionAPI
|
|
22
|
+
|
|
23
|
+
| Host member (host-types.ts / universal-host.ts) | Satisfies | Upstream call sites (evidence) | Notes |
|
|
24
|
+
| --- | --- | --- | --- |
|
|
25
|
+
| `registerTool` | `pi.registerTool` | `index.ts` registerDirectTool / registerMcpScript / registerProxyTool | Renderer boundary keeps 3 `as (tool: unknown)` casts — fork `RenderTheme` ≠ pi-* `Theme`. |
|
|
26
|
+
| `registerCommand` | `pi.registerCommand` | `index.ts` `mcp` / `mcp-auth` / `pi-mcp` | Direct pass-through; no-op surface on MCP stdio. |
|
|
27
|
+
| `registerFlag` | `pi.registerFlag` | `index.ts` / `init.ts` | Direct pass-through. |
|
|
28
|
+
| `on` | `pi.on` | `index.ts` `session_start` / `tool_result` / `input` | Event-name generics erased. |
|
|
29
|
+
| `events` | `pi.events` (`McpStatusEventBus`) | `index.ts` `publishMcpStatusShutdown` | `UniversalStatusEventBus` = `EventEmitter` subset (`emit` / `on` / `removeAllListeners`). |
|
|
30
|
+
| `getAllTools` | `pi.getAllTools` | `index.ts` | `ToolInfo[]`. |
|
|
31
|
+
| `setActiveTools` | `pi.setActiveTools` | `index.ts` `syncProxyTool` / `syncNamespaceTools` | Drives MCP `ListTools` filtering. |
|
|
32
|
+
| `getActiveTools` | `pi.getActiveTools` | `index.ts` | — |
|
|
33
|
+
| `unregisterTool` | `pi.unregisterTool` | `index.ts` dynamic proxy/direct removal | Returns `boolean`. |
|
|
34
|
+
| `getFlag` | `pi.getFlag` | `init.ts` | `string \| undefined`. |
|
|
35
|
+
| `sendMessage` | `pi.sendMessage` | `init.ts` | Both `message` / `options` are `unknown`. |
|
|
36
|
+
| `exec` | `pi.exec` | `utils.ts` | `Promise<unknown>`. |
|
|
37
|
+
|
|
38
|
+
## UISystem / Form → ExtensionUIContext
|
|
39
|
+
|
|
40
|
+
| Host member (host-types.ts) | Pi member | Call site | Optional? |
|
|
41
|
+
| --- | --- | --- | --- |
|
|
42
|
+
| `UISystem.notify` | `ctx.ui.notify` | `commands.ts`, `init.ts` | Required. |
|
|
43
|
+
| `UISystem.setStatus` | `ctx.ui.setStatus` | `init.ts` | Optional. |
|
|
44
|
+
| `UISystem.form` | `ctx.ui.form` → `elicitation-handler.ts` | `bin/mcp-server.ts` → `protocol-elicitation-forwarder.ts` | Optional. |
|
|
45
|
+
| `UISystem.custom` | `ctx.ui.custom` | (reserved, no current use) | Optional. |
|
|
46
|
+
| `UISystem.theme.fg` | `ctx.ui.theme.fg` | `init.ts` | Optional. |
|
|
47
|
+
| `FormConfig` / `FormResult` | `ExtensionUIFormRequest` / `ExtensionUIFormResult` | `elicitation-handler.ts` | — |
|
|
48
|
+
|
|
49
|
+
## Type Mappings
|
|
50
|
+
|
|
51
|
+
| Fork-owned type (`interfaces/host-types.ts`) | Pi type | Source |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `UniversalHostSurface` | `ExtensionAPI` | boundary cast in `bin/mcp-server.ts` |
|
|
54
|
+
| `ToolInfo` | `getAllTools` element | `index.ts` |
|
|
55
|
+
| `ToolRegistration` | `ToolDefinition` | `index.ts` registerTool |
|
|
56
|
+
| `CommandConfig` | `RegisteredCommand` | `index.ts` registerCommand |
|
|
57
|
+
| `FlagConfig` | `ExtensionFlag` | `index.ts` registerFlag |
|
|
58
|
+
| `AgentChannel` | (host → owning stdio process) | `bin/mcp-server.ts` (host `sendMessage` → stderr) |
|
|
59
|
+
| `FormConfig` / `FormResult` | `ExtensionUIFormRequest` / `ExtensionUIFormResult` | `elicitation-handler.ts` |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Upstream Update Checklist
|
|
64
|
+
|
|
65
|
+
When upstream Pi changes land, walk this list:
|
|
66
|
+
|
|
67
|
+
- [ ] `UniversalHostSurface` members vs `index.ts` / `init.ts` / `utils.ts` `pi.*` call sites
|
|
68
|
+
- [ ] the 3 `as (tool: unknown)` renderer-boundary casts in `index.ts`
|
|
69
|
+
- [ ] `events` bus shape (`McpStatusEventBus`)
|
|
70
|
+
- [ ] upstream v2.28.0 `MCP_RUNTIME_REGISTER_EVENT` runtime registration (deferred merge)
|
|
71
|
+
|
|
72
|
+
For any new `pi.*` / `ctx.ui.*` call site, add a row to the tables above and a
|
|
73
|
+
corresponding member on `UniversalMcpHost` (or in `host-types.ts`).
|
package/README.md
ADDED
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
<p>
|
|
2
|
+
<img src="banner.png" alt="pi-mcp-adapter" width="1100">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Universal MCP Adapter
|
|
6
|
+
|
|
7
|
+
A universal MCP (Model Context Protocol) adapter with **Pi as a first-class host** (native extension) — and every other MCP-compatible coding agent via the universal `mcp-server` stdio entry point.
|
|
8
|
+
|
|
9
|
+
Use MCP servers without burning your context window, from Pi today and from any MCP-compatible coding agent via the [Supported Agents](#supported-agents) matrix below.
|
|
10
|
+
|
|
11
|
+
## Supported Agents
|
|
12
|
+
|
|
13
|
+
Pi is a first-class host (Branch A, native extension). **Any other MCP-compatible agent** works via Branch C — the universal `mcp-server` stdio entry point. No per-agent adapter code is needed; the server discovers client capabilities at runtime via the MCP protocol.
|
|
14
|
+
|
|
15
|
+
A single upstream engine (`index.ts` `installMcpAdapter`) drives both paths: on Pi it runs as a native extension; on other agents a small host shim (`adapters/universal-host.ts`) impersonates Pi's `ExtensionAPI` so the same engine runs unchanged behind the `mcp-server` stdio layer. See [MAPPING.md](MAPPING.md) for the host-surface contract.
|
|
16
|
+
|
|
17
|
+
| Branch | Agent | Config path | Integration | Sampling | Elicitation |
|
|
18
|
+
|--------|-------|-------------|-------------|----------|-------------|
|
|
19
|
+
| Branch A | Pi | `~/.pi/agent/mcp.json` | Native Pi extension (`pi install`) | ✅ In-process | ✅ Pi UI forms |
|
|
20
|
+
| Branch C | Any MCP-compatible agent | `~/.config/mcp/mcp.json` or `.mcp.json` | Universal MCP stdio server (`mcp-server`) | Runtime-discovered | Runtime-discovered |
|
|
21
|
+
|
|
22
|
+
> **Branch C is a complete implementation** (D-08): the `mcp` proxy tool is always available.
|
|
23
|
+
> Sampling is forwarded via MCP `sampling/createMessage` reverse call when the agent
|
|
24
|
+
> declares `sampling` capability. Elicitation is forwarded via `elicitation/create` when
|
|
25
|
+
> the agent declares `elicitation.form` capability. Capabilities are discovered at runtime
|
|
26
|
+
> — no static matrix needed.
|
|
27
|
+
|
|
28
|
+
See [Verification](#verification) below for the latest matrix results.
|
|
29
|
+
|
|
30
|
+
## Agent Skills
|
|
31
|
+
|
|
32
|
+
`mcp-adapter` ships three project-level Agent Skills to automate common maintainer and integration workflows. Copy a skill into your agent's global skills directory, then trigger it with the prompt.
|
|
33
|
+
|
|
34
|
+
| Skill | Purpose | Trigger | Flow |
|
|
35
|
+
|-------|---------|---------|------|
|
|
36
|
+
| `mcp-adapter` | Universal agent integration — config generation, adapter deployment, verification | `integrate agent` · `deploy mcp-adapter` · `configure MCP servers` · `verify mcp-adapter` | Identify agent + capability-gate → Generate `mcp.json` → Deploy adapter → Verify |
|
|
37
|
+
| `upstream-merge` | Sync upstream [`nicobailon/pi-mcp-adapter`](https://github.com/nicobailon/pi-mcp-adapter) into this fork with conflict resolution (e.g. reverse-merging the source repo) | `merge upstream` · `sync fork` · `upstream conflict` · `/upstream-merge` | Run divergence check → Apply 12-category resolution matrix → Delegate conflicts to `/resolve-conflicts` → Validate with §5 checklist |
|
|
38
|
+
| `resolve-conflicts` | Professional Git conflict resolution — 7 conflict type patterns, plan-first, user-approved | `merge conflict` · `/resolve-conflicts` | Assess conflicts → Create resolution plan → Get user approval → Execute resolution → Validate with tests |
|
|
39
|
+
|
|
40
|
+
> **`upstream-merge` is the recommended way to reverse-merge the source repo.** When upstream `pi-mcp-adapter` cuts a new release, run `/upstream-merge` from your agent — it creates a `upstream-merge/<version>` branch (no direct commits to `main`, per `AGENTS.md` branch policy), runs `npm run upstream:check` to surface live divergence, and walks the per-file decision tree before delegating to `/resolve-conflicts`. Both `upstream-merge` and `resolve-conflicts` must be installed together.
|
|
41
|
+
|
|
42
|
+
Install & use:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# 1. Copy the skills you need into your agent's global skills directory
|
|
46
|
+
cp -r skills/mcp-adapter ~/.qoder/skills/ # or your agent's equivalent path
|
|
47
|
+
cp -r skills/upstream-merge ~/.qoder/skills/ # also copy resolve-conflicts
|
|
48
|
+
cp -r skills/resolve-conflicts ~/.qoder/skills/
|
|
49
|
+
|
|
50
|
+
# 2. Trigger the skill from your agent
|
|
51
|
+
# /mcp-adapter — integrate an agent (Phase 0 → 1 → 2 → 3)
|
|
52
|
+
# /upstream-merge — sync this fork with upstream pi-mcp-adapter
|
|
53
|
+
# /resolve-conflicts — resolve Git merge conflicts professionally
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
See [`skills/README.md`](skills/README.md) for the full skill directory, dependency graph, and `Skill Usage Order` diagram.
|
|
57
|
+
|
|
58
|
+
https://github.com/user-attachments/assets/4b7c66ff-e27e-4639-b195-22c3db406a5a
|
|
59
|
+
|
|
60
|
+
## Why This Exists
|
|
61
|
+
|
|
62
|
+
Mario wrote about [why you might not need MCP](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/). The problem: tool definitions are verbose. A single MCP server can burn 10k+ tokens, and you're paying that cost whether you use those tools or not. Connect a few servers and you've burned half your context window before the conversation starts.
|
|
63
|
+
|
|
64
|
+
His take: skip MCP entirely, write simple CLI tools instead.
|
|
65
|
+
|
|
66
|
+
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. The same engine drives Pi today; other agents plug in through the universal `mcp-server` stdio entry without touching MCP server code.
|
|
67
|
+
|
|
68
|
+
## Install
|
|
69
|
+
|
|
70
|
+
### For Pi users (recommended)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pi install npm:@njuptlzf/mcp-adapter
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Restart Pi after installation. The rest of this README focuses on the Pi integration; for other agents see the next section.
|
|
77
|
+
|
|
78
|
+
### For other agents (Branch C — universal MCP stdio server)
|
|
79
|
+
|
|
80
|
+
Any MCP-compatible agent can use the universal `mcp-server` bin entry. Register it in the agent's MCP config:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"mcp-adapter": {
|
|
86
|
+
"command": "mcp-server"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`mcp-server` auto-discovers its config (`.mcp.json` in the CWD, or `~/.config/mcp/mcp.json`). To point it at an explicit config file, pass `--config`:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"mcpServers": {
|
|
97
|
+
"mcp-adapter": {
|
|
98
|
+
"command": "mcp-server",
|
|
99
|
+
"args": ["--config", "/path/to/config.json"]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For a standalone deployment that needs no `node_modules` (e.g. side-loading a single file onto another machine), build `bin/mcp-server.ts` into one self-contained `.mjs` bundle:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run build:mcp-server
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This bundles `bin/mcp-server.ts` into a single self-contained `./mcp-server.mjs` via the `scripts/build-mcp-server.mjs` esbuild pipeline.
|
|
112
|
+
|
|
113
|
+
The bundle inlines all dependencies (MCP SDK, Zod, adapters), so the single `.mjs` runs on any machine with just Node.js.
|
|
114
|
+
|
|
115
|
+
Then register it with `node` and the `--config` flag pointing at the file that lists the servers to proxy:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"mcp-adapter": {
|
|
121
|
+
"command": "node",
|
|
122
|
+
"args": [
|
|
123
|
+
"/home/.local/lib/mcp-server/mcp-server.mjs",
|
|
124
|
+
"--config",
|
|
125
|
+
"/home/.local/lib/mcp-server/config.json"
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Config discovery order for `--config` is: `--config` flag → `MCP_CONFIG_PATH` env var → `.mcp.json` in the CWD → `~/.config/mcp/mcp.json`.
|
|
133
|
+
|
|
134
|
+
The server is agent-agnostic — it speaks MCP protocol and discovers client capabilities at runtime. Sampling and elicitation are forwarded via MCP Server→Client reverse calls when the agent declares those capabilities.
|
|
135
|
+
|
|
136
|
+
## What happens on first run (Pi)
|
|
137
|
+
|
|
138
|
+
The adapter reads standard MCP files automatically. No extra setup needed if you already have them.
|
|
139
|
+
|
|
140
|
+
| You already have... | What happens |
|
|
141
|
+
|---------------------|--------------|
|
|
142
|
+
| `.mcp.json` or `~/.config/mcp/mcp.json` | The shared MCP files are picked up immediately. The first time you open `/mcp`, you'll see a short heads-up explaining which file was detected and that the adapter only writes host-specific overrides to its own files (Pi: `~/.pi/agent/mcp.json`). |
|
|
143
|
+
| Host-specific configs (Cursor, Claude Code, Codex, etc.) but no standard MCP files | Run `/mcp setup` to adopt those host configs into the shared MCP format. The setup flow shows exactly what it found, lets you pick which ones to import, and previews the exact file changes before writing. |
|
|
144
|
+
| Nothing configured yet | Run `/mcp setup` to scaffold a minimal `.mcp.json`, quick-add RepoPrompt, or inspect what the adapter discovered on your machine. |
|
|
145
|
+
|
|
146
|
+
If you prefer the terminal, you can also run `pi-mcp-adapter init` after install to scan for host-specific configs and add missing compatibility imports to the host agent dir (Pi: `~/.pi/agent/mcp.json` by default, or `$PI_CODING_AGENT_DIR/mcp.json` when set).
|
|
147
|
+
|
|
148
|
+
## Quick Start
|
|
149
|
+
|
|
150
|
+
The adapter ships one upstream engine with two entry points: the Pi-native `mcpAdapter(pi)` (backward-compatible) and the universal `mcp-server` stdio binary for any MCP-compatible agent.
|
|
151
|
+
|
|
152
|
+
### Pi users (Pi-native entry point)
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { mcpAdapter } from "@njuptlzf/mcp-adapter";
|
|
156
|
+
|
|
157
|
+
export default mcpAdapter(pi); // Pi's ExtensionAPI — backward-compatible
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
To supply config explicitly instead of relying on Pi's standard MCP files:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { createMcpAdapter } from "@njuptlzf/mcp-adapter";
|
|
164
|
+
|
|
165
|
+
export default createMcpAdapter({ config })(pi); // factory, then install onto `pi`
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Universal entry point (any MCP-compatible agent)
|
|
169
|
+
|
|
170
|
+
For any other MCP-compatible agent, register the `mcp-server` bin in the agent's MCP config (see [Install](#install)) — no adapter code needed:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"mcpServers": {
|
|
175
|
+
"mcp-adapter": { "command": "mcp-server" }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
The examples below show the Pi path's tool-call syntax. The same MCP server config and the same `mcp` proxy tool shape are reused across agents through the [Supported Agents](#supported-agents) matrix above.
|
|
183
|
+
|
|
184
|
+
Preferred project config: `.mcp.json`
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"mcpServers": {
|
|
189
|
+
"chrome-devtools": {
|
|
190
|
+
"command": "npx",
|
|
191
|
+
"args": ["-y", "chrome-devtools-mcp@latest"]
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Preferred user-global shared config: `~/.config/mcp/mcp.json`
|
|
198
|
+
|
|
199
|
+
Pi also reads Pi-owned override files for settings and host-specific compatibility:
|
|
200
|
+
|
|
201
|
+
- `<Pi agent dir>/mcp.json` — Pi global override (`~/.pi/agent/mcp.json` by default)
|
|
202
|
+
- `.pi/mcp.json` — Pi project override
|
|
203
|
+
|
|
204
|
+
Precedence is:
|
|
205
|
+
|
|
206
|
+
1. `~/.config/mcp/mcp.json`
|
|
207
|
+
2. `<Pi agent dir>/mcp.json`
|
|
208
|
+
3. `.mcp.json`
|
|
209
|
+
4. `.pi/mcp.json`
|
|
210
|
+
|
|
211
|
+
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.
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
mcp({ search: "screenshot" })
|
|
215
|
+
```
|
|
216
|
+
```
|
|
217
|
+
chrome_devtools_take_screenshot
|
|
218
|
+
Take a screenshot of the page or element.
|
|
219
|
+
|
|
220
|
+
Parameters:
|
|
221
|
+
format (enum: "png", "jpeg", "webp") [default: "png"]
|
|
222
|
+
fullPage (boolean) - Full page instead of viewport
|
|
223
|
+
```
|
|
224
|
+
```
|
|
225
|
+
mcp({ tool: "chrome_devtools_take_screenshot", args: '{"format": "png"}' })
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Note: `args` is a JSON string, not an object.
|
|
229
|
+
|
|
230
|
+
Two calls instead of 26 tools cluttering the context.
|
|
231
|
+
|
|
232
|
+
## Verification
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run test:prebuild # build visualizer dist/
|
|
236
|
+
npx vitest run # full suite
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The suite covers the upstream engine (`__tests__/index-lifecycle.test.ts`, `__tests__/mcp-code.test.ts`), the universal host wiring (`__tests__/universal-host-acceptance.test.ts`), runtime registration (`__tests__/runtime-register.test.ts`), and the protocol forwarders. Token-savings numbers are baseline-bound; see `docs/mcp-adapter-token-savings.md`.
|
|
240
|
+
|
|
241
|
+
## Config
|
|
242
|
+
|
|
243
|
+
### File Layout
|
|
244
|
+
|
|
245
|
+
Use the shared MCP files when you want one setup to work across hosts, and host-owned files when a specific agent needs its own overrides or settings.
|
|
246
|
+
|
|
247
|
+
| File | Purpose | Owner |
|
|
248
|
+
|------|---------|-------|
|
|
249
|
+
| `~/.config/mcp/mcp.json` | User-global shared MCP config | Shared |
|
|
250
|
+
| `.mcp.json` | Project-local shared MCP config | Shared |
|
|
251
|
+
| `<Pi agent dir>/mcp.json` | Pi global override and compatibility imports (`~/.pi/agent/mcp.json` by default) | Pi |
|
|
252
|
+
| `.pi/mcp.json` | Pi project override | Pi |
|
|
253
|
+
|
|
254
|
+
Pi-specific files are the write targets for imported or shared global servers when Pi needs to persist adapter-only settings such as `directTools`. Other agents use the `mcp-server` stdio path (Branch C) and don't write host-specific files.
|
|
255
|
+
|
|
256
|
+
### Server Options
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"mcpServers": {
|
|
261
|
+
"my-server": {
|
|
262
|
+
"command": "npx",
|
|
263
|
+
"args": ["-y", "some-mcp-server"],
|
|
264
|
+
"lifecycle": "lazy",
|
|
265
|
+
"idleTimeout": 10
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
| Field | Description |
|
|
272
|
+
|-------|-------------|
|
|
273
|
+
| `command` | Executable for stdio transport |
|
|
274
|
+
| `args` | Command arguments |
|
|
275
|
+
| `env` | Environment variables; supports `${VAR}` and `$env:VAR` interpolation |
|
|
276
|
+
| `cwd` | Working directory; supports `${VAR}`, `$env:VAR`, and `~` expansion |
|
|
277
|
+
| `url` | HTTP endpoint (StreamableHTTP with SSE fallback) |
|
|
278
|
+
| `headers` | HTTP headers; supports `${VAR}` and `$env:VAR` interpolation |
|
|
279
|
+
| `auth` | `"bearer"` or `"oauth"` |
|
|
280
|
+
| `oauth.grantType` | `"authorization_code"` (default) or `"client_credentials"` for non-interactive machine auth |
|
|
281
|
+
| `oauth.clientId` | Pre-registered OAuth client ID; dynamic registration is used when omitted |
|
|
282
|
+
| `oauth.clientSecret` | OAuth client secret for confidential clients |
|
|
283
|
+
| `oauth.scope` | Requested OAuth scopes |
|
|
284
|
+
| `oauth.redirectUri` | Exact localhost redirect URI for browser OAuth, including port and path, for providers that pre-register callbacks |
|
|
285
|
+
| `oauth.clientName` | Client display name advertised during dynamic registration |
|
|
286
|
+
| `oauth.clientUri` | Client homepage URI advertised during dynamic registration |
|
|
287
|
+
| `bearerToken` / `bearerTokenEnv` | Token or env var name; `bearerToken` supports `${VAR}` and `$env:VAR` interpolation |
|
|
288
|
+
| `lifecycle` | `"lazy"` (default), `"eager"`, or `"keep-alive"` |
|
|
289
|
+
| `idleTimeout` | Minutes before idle disconnect (overrides global) |
|
|
290
|
+
| `exposeResources` | Expose MCP resources as tools (default: true) |
|
|
291
|
+
| `directTools` | `true`, `string[]`, or `false` — register tools individually instead of through proxy |
|
|
292
|
+
| `excludeTools` | `string[]` of tool names to hide (matches original names like `get_screenshot` and prefixed names like `figma_get_screenshot`) |
|
|
293
|
+
| `debug` | Show server stderr (default: false) |
|
|
294
|
+
|
|
295
|
+
For pre-registered browser OAuth clients, set `oauth.redirectUri` to the exact callback registered with the provider, for example `"http://localhost:3118/callback"`. Dynamic clients normally omit it and use a lazy OS-assigned localhost callback port.
|
|
296
|
+
|
|
297
|
+
### Remote/headless OAuth
|
|
298
|
+
|
|
299
|
+
If Pi is running on a remote server and cannot open a local browser, start OAuth through the proxy tool:
|
|
300
|
+
|
|
301
|
+
```js
|
|
302
|
+
mcp({ action: "auth-start", server: "linear-server" })
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Open the returned authorization URL in your local browser. After approval, your browser redirects to a localhost URL. On a remote server that local page may fail to load; copy the full URL from the browser address bar anyway and complete the flow in the same Pi session:
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
mcp({
|
|
309
|
+
action: "auth-complete",
|
|
310
|
+
server: "linear-server",
|
|
311
|
+
args: '{"redirectUrl":"http://localhost:19876/callback?code=...&state=..."}'
|
|
312
|
+
})
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
You can also pass only the `code` query parameter with `args: '{"code":"..."}'`. Treat authorization URLs and codes as sensitive; they can grant access to the MCP server until the flow expires or completes.
|
|
316
|
+
|
|
317
|
+
### Lifecycle Modes
|
|
318
|
+
|
|
319
|
+
- **`lazy`** (default) — Don't connect at startup. Connect on first tool call. Disconnect after idle timeout. Cached metadata keeps search/list working without connections.
|
|
320
|
+
- **`eager`** — Connect at startup but don't auto-reconnect if the connection drops. No idle timeout by default (set `idleTimeout` explicitly to enable).
|
|
321
|
+
- **`keep-alive`** — Connect at startup. Auto-reconnect via health checks. No idle timeout. Use for servers you always need available.
|
|
322
|
+
|
|
323
|
+
### Settings
|
|
324
|
+
|
|
325
|
+
```json
|
|
326
|
+
{
|
|
327
|
+
"settings": {
|
|
328
|
+
"toolPrefix": "server",
|
|
329
|
+
"idleTimeout": 10
|
|
330
|
+
},
|
|
331
|
+
"mcpServers": { }
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
| Setting | Description |
|
|
336
|
+
|---------|-------------|
|
|
337
|
+
| `toolPrefix` | `"server"` (default), `"short"` (strips `-mcp` suffix), or `"none"` |
|
|
338
|
+
| `idleTimeout` | Global idle timeout in minutes (default: 10, 0 to disable) |
|
|
339
|
+
| `directTools` | Global default for all servers (default: false). Per-server overrides this. |
|
|
340
|
+
| `disableProxyTool` | Hide the `mcp` proxy tool once configured direct tools are fully available from cache. |
|
|
341
|
+
| `autoAuth` | Auto-run OAuth on `connect`/tool calls when a server needs auth, then retry once (default: false). |
|
|
342
|
+
| `sampling` | Allow MCP servers to sample through Pi models, honoring `modelPreferences.hints` before current/default fallback (default: true when UI approval is available). |
|
|
343
|
+
| `samplingAutoApprove` | Skip sampling confirmation prompts. Required for sampling in non-UI sessions (default: false). |
|
|
344
|
+
| `elicitation` | Allow MCP servers to request user input through Pi dialogs (default: true when Pi UI is available). |
|
|
345
|
+
|
|
346
|
+
Per-server `idleTimeout` overrides the global setting.
|
|
347
|
+
|
|
348
|
+
### MCP Elicitation
|
|
349
|
+
|
|
350
|
+
When the host agent exposes UI (e.g. Pi's `ctx.ui.form()`), the adapter advertises MCP elicitation support. Form elicitations are rendered through the host's UI primitive and map agent actions to MCP actions: submit → `accept`, secondary → `decline`, cancel → `cancel`. URL elicitations prompt before opening a browser unless `elicitationAutoOpenUrls` is enabled. Hosts that don't ship a UI form capability simply don't advertise the form elicitation path.
|
|
351
|
+
|
|
352
|
+
### Direct Tools
|
|
353
|
+
|
|
354
|
+
By default, all MCP tools are accessed through the single `mcp` proxy tool. This keeps context small but means the LLM has to discover MCP tools via proxy search. If you want specific tools to show up directly in the host agent's tool list — alongside `read`, `bash`, `edit`, etc. — add `directTools` to your config.
|
|
355
|
+
|
|
356
|
+
Per-server:
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{
|
|
360
|
+
"mcpServers": {
|
|
361
|
+
"chrome-devtools": {
|
|
362
|
+
"command": "npx",
|
|
363
|
+
"args": ["-y", "chrome-devtools-mcp@latest"],
|
|
364
|
+
"directTools": true
|
|
365
|
+
},
|
|
366
|
+
"github": {
|
|
367
|
+
"command": "npx",
|
|
368
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
369
|
+
"directTools": ["search_repositories", "get_file_contents"]
|
|
370
|
+
},
|
|
371
|
+
"huge-server": {
|
|
372
|
+
"command": "npx",
|
|
373
|
+
"args": ["-y", "mega-mcp@latest"]
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
| Value | Behavior |
|
|
380
|
+
|-------|----------|
|
|
381
|
+
| `true` | Register all tools from this server as individual host-agent tools |
|
|
382
|
+
| `["tool_a", "tool_b"]` | Register only these tools (use original MCP names) |
|
|
383
|
+
| Omitted or `false` | Proxy only (default) |
|
|
384
|
+
|
|
385
|
+
To set a global default for all servers:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"settings": {
|
|
390
|
+
"directTools": true
|
|
391
|
+
},
|
|
392
|
+
"mcpServers": {
|
|
393
|
+
"huge-server": {
|
|
394
|
+
"directTools": false
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Per-server `directTools` overrides the global setting. The example above registers direct tools for every server except `huge-server`.
|
|
401
|
+
|
|
402
|
+
To exclude specific tools while still using `directTools: true`, add `excludeTools` on the server:
|
|
403
|
+
|
|
404
|
+
```json
|
|
405
|
+
{
|
|
406
|
+
"mcpServers": {
|
|
407
|
+
"figma": {
|
|
408
|
+
"url": "http://localhost:3845/mcp",
|
|
409
|
+
"directTools": true,
|
|
410
|
+
"excludeTools": ["get_figjam", "figma_get_code_connect_map"]
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
`excludeTools` filters direct tools, proxy search/list/describe, and the `/mcp` panel view.
|
|
417
|
+
|
|
418
|
+
Each direct tool costs ~150-300 tokens in the system prompt (name + description + schema). Good for targeted sets of 5-20 tools. For servers with 75+ tools, stick with the proxy or pick specific tools with a `string[]`.
|
|
419
|
+
|
|
420
|
+
Direct tools register from the metadata cache in the host agent dir (Pi: `~/.pi/agent/mcp-cache.json` by default, or `$PI_CODING_AGENT_DIR/mcp-cache.json` when set), so no server connections are needed at startup. On the first session after adding `directTools` to a new server, the cache won't exist yet — tools fall back to proxy-only and the cache populates in the background. To force it: `/mcp reconnect <server>` (Pi) or the equivalent reconnect action on your host agent.
|
|
421
|
+
|
|
422
|
+
When you change direct-tool toggles in `/mcp` (Pi) or write new config through `/mcp setup`, the extension triggers the host agent's normal reload flow automatically. That refreshes extensions, prompts, skills, and MCP tool registration in one shot, so newly configured direct tools can appear without a manual restart.
|
|
423
|
+
|
|
424
|
+
**Interactive configuration (Pi):** Run `/mcp` to open an interactive panel showing all servers with connection status, tools, and direct/proxy toggles. You can reconnect servers and toggle tools between direct and proxy from the same overlay. For OAuth, press Enter on a server that needs auth or `ctrl+a` on any OAuth server. Other agents expose equivalent affordances through their own UI surfaces.
|
|
425
|
+
|
|
426
|
+
**Guided first-run setup (Pi):** Run `/mcp setup` to inspect detected shared MCP files, adopt compatibility imports from other hosts, open discovered config paths, preview exact before/after file diffs for writes, scaffold a minimal project `.mcp.json`, or quick-add RepoPrompt into a standard/shared MCP file.
|
|
427
|
+
|
|
428
|
+
**Subagent integration (Pi subagent extension):** If you use the subagent extension, agents can request direct MCP tools in their frontmatter with `mcp:server-name` syntax. See the subagent README for details.
|
|
429
|
+
|
|
430
|
+
### MCP UI Integration
|
|
431
|
+
|
|
432
|
+
MCP servers can ship interactive UIs via the [MCP UI](https://github.com/MCP-UI-Org/mcp-ui) standard. When you call a tool that has a UI resource, the adapter opens it in a native macOS window via [Glimpse](https://github.com/hazat/glimpse) if available, otherwise falls back to the browser.
|
|
433
|
+
|
|
434
|
+
**How it works:**
|
|
435
|
+
|
|
436
|
+
1. Agent calls a tool like `launch_dashboard`
|
|
437
|
+
2. The tool's metadata includes `_meta.ui.resourceUri` pointing to a UI resource
|
|
438
|
+
3. mcp-adapter fetches the UI HTML and opens it in an iframe
|
|
439
|
+
4. The UI can call MCP tools and send messages back to the agent
|
|
440
|
+
|
|
441
|
+
**Native rendering:** On macOS, if [Glimpse](https://github.com/hazat/glimpse) is installed (`pi install npm:glimpseui`), UIs open in a native WKWebView window instead of a browser tab. Set `MCP_UI_VIEWER=browser` to force the browser, or `MCP_UI_VIEWER=glimpse` to require native rendering.
|
|
442
|
+
|
|
443
|
+
**Bidirectional communication:** The UI talks back. When it sends a prompt or intent, the message is stored and `triggerTurn()` wakes the agent. The agent retrieves messages via `mcp({ action: "ui-messages" })` and responds, enabling conversational UIs where the app and agent collaborate in real-time.
|
|
444
|
+
|
|
445
|
+
**Session reuse:** When the agent calls the same tool again while its UI is already open, the adapter pushes the new result to the existing window instead of replacing it. This enables live updates — the agent can refine a chart, add data, or respond to user input without losing the current view. Different tools still replace the session as before.
|
|
446
|
+
|
|
447
|
+
**Message types from UI:**
|
|
448
|
+
|
|
449
|
+
| Type | Purpose |
|
|
450
|
+
|------|---------|
|
|
451
|
+
| `prompt` | User message that triggers an agent response |
|
|
452
|
+
| `intent` | Structured action with name + params |
|
|
453
|
+
| `notify` | Fire-and-forget notification |
|
|
454
|
+
| `message` | Generic message payload |
|
|
455
|
+
| (custom) | Any other type forwarded as intent |
|
|
456
|
+
|
|
457
|
+
**Retrieving UI messages:**
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
mcp({ action: "ui-messages" })
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
Returns accumulated messages from UI sessions. Each message includes `type`, `sessionId`, `serverName`, `toolName`, and `timestamp`. Prompt messages include `prompt`, intent messages include `intent` and `params`.
|
|
464
|
+
|
|
465
|
+
**Browser controls:**
|
|
466
|
+
|
|
467
|
+
- **Cmd/Ctrl+Enter** — Complete and close
|
|
468
|
+
- **Escape** — Cancel and close
|
|
469
|
+
- **Done/Cancel buttons** — Same as keyboard shortcuts
|
|
470
|
+
|
|
471
|
+
**Technical notes:**
|
|
472
|
+
|
|
473
|
+
- Tool consent gates whether UIs can call MCP tools (never/once-per-server/always)
|
|
474
|
+
- Works with both stdio and HTTP MCP servers
|
|
475
|
+
- Uses a local 408KB AppBridge bundle (MCP SDK + Zod) for browser↔server communication
|
|
476
|
+
|
|
477
|
+
### Local Example: Interactive Visualizer
|
|
478
|
+
|
|
479
|
+
A minimal MCP UI example at `examples/interactive-visualizer` demonstrating charts, bidirectional messaging, and streaming. From that directory:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
npm install
|
|
483
|
+
npm run build
|
|
484
|
+
npm run install-local
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
Restart pi, then ask the agent to show a chart — it calls `show_chart` and opens the UI in Glimpse (macOS) or the browser. Use `npm run uninstall-local` to remove the MCP entry.
|
|
488
|
+
|
|
489
|
+
### Import Existing Configs
|
|
490
|
+
|
|
491
|
+
Shared MCP files are loaded automatically. Use `imports` only for host-specific config formats that are not already covered by `.mcp.json` or `~/.config/mcp/mcp.json`.
|
|
492
|
+
|
|
493
|
+
```json
|
|
494
|
+
{
|
|
495
|
+
"imports": ["cursor", "claude-code", "claude-desktop"],
|
|
496
|
+
"mcpServers": { }
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
Supported compatibility imports: `cursor`, `claude-code`, `claude-desktop`, `vscode`, `windsurf`, `codex`
|
|
501
|
+
|
|
502
|
+
`pi-mcp-adapter init` detects these host-specific configs and adds missing imports to the host agent dir config (Pi: `~/.pi/agent/mcp.json`) for you. The `opencode` import reads OpenCode V1 `mcp` entries from both `~/.config/opencode/opencode.json` and the project `opencode.json`, with project fields taking precedence. It is explicit-import only; OpenCode V2, inline content, managed configs, and remote discovery are not supported.
|
|
503
|
+
|
|
504
|
+
### Project Config
|
|
505
|
+
|
|
506
|
+
Prefer `.mcp.json` for project-local shared MCP config. Use `.pi/mcp.json` only when you need a Pi-specific project override. Project files override both user-global shared MCP config and Pi global overrides.
|
|
507
|
+
|
|
508
|
+
## Usage
|
|
509
|
+
|
|
510
|
+
| Mode | Example |
|
|
511
|
+
|------|---------|
|
|
512
|
+
| Status | `mcp({ })` |
|
|
513
|
+
| List server | `mcp({ server: "name" })` |
|
|
514
|
+
| Search | `mcp({ search: "screenshot navigate" })` |
|
|
515
|
+
| Describe | `mcp({ describe: "tool_name" })` |
|
|
516
|
+
| Call | `mcp({ tool: "...", args: '{"key": "value"}' })` |
|
|
517
|
+
| Connect | `mcp({ connect: "server-name" })` |
|
|
518
|
+
| UI messages | `mcp({ action: "ui-messages" })` |
|
|
519
|
+
| Auth start | `mcp({ action: "auth-start", server: "name" })` |
|
|
520
|
+
| Auth complete | `mcp({ action: "auth-complete", server: "name", args: '{"redirectUrl":"..."}' })` |
|
|
521
|
+
|
|
522
|
+
MCP proxy and direct-tool results render compactly by default: long text shows the first three lines plus a `Ctrl+O to expand` hint, while the full result remains available when expanded and is still returned unchanged to the model. Set `settings.toolResultRendering` to `"boxed"` to restore the legacy boxed Pi row, or set `settings.collapsedResultLines` to `2` or `3` when you want more collapsed text.
|
|
523
|
+
|
|
524
|
+
Search includes both MCP tools and host-agent tools (from extensions). Host-agent tools appear first with `[host tool]` prefix. Space-separated words are OR'd.
|
|
525
|
+
|
|
526
|
+
Tool names are fuzzy-matched on hyphens and underscores — `context7_resolve_library_id` finds `context7_resolve-library-id`.
|
|
527
|
+
|
|
528
|
+
## Commands (Pi)
|
|
529
|
+
|
|
530
|
+
The `/mcp` and `/mcp-auth` slash commands are Pi-specific UI shortcuts. On other agents, call the equivalent MCP actions directly via the proxy tool or the agent's own command surface — the underlying behaviour is identical; only the trigger differs.
|
|
531
|
+
|
|
532
|
+
| Command | What it does |
|
|
533
|
+
|---------|--------------|
|
|
534
|
+
| `/mcp` | Interactive panel and first-run onboarding surface |
|
|
535
|
+
| `/mcp setup` | Guided setup for imports, a minimal `.mcp.json`, RepoPrompt quick-add, and config-path inspection |
|
|
536
|
+
| `/mcp tools` | List all tools |
|
|
537
|
+
| `/mcp reconnect` | Reconnect all servers |
|
|
538
|
+
| `/mcp reconnect <server>` | Connect or reconnect a single server |
|
|
539
|
+
| `/mcp logout <server>` | Clear stored OAuth credentials for a server and disconnect it |
|
|
540
|
+
| `/mcp-auth` | Open an OAuth server picker in interactive UI sessions |
|
|
541
|
+
| `/mcp-auth <server>` | OAuth setup for a specific server |
|
|
542
|
+
|
|
543
|
+
If `settings.autoAuth` is `true`, `mcp({ connect: ... })`, `mcp({ tool: ... })`, and direct tool calls automatically run OAuth when needed and retry once.
|
|
544
|
+
|
|
545
|
+
In interactive sessions, you can also authenticate from `/mcp` with `ctrl+a` or Enter on a server that needs auth. In remote/headless sessions, use the proxy tool's `auth-start` and `auth-complete` actions to copy the authorization URL locally and paste the redirect URL back into Pi. `/mcp-auth` without a server only opens a picker in the interactive UI.
|
|
546
|
+
|
|
547
|
+
### MCP output schemas
|
|
548
|
+
|
|
549
|
+
Advertised tool `outputSchema` values support JSON Schema draft-07 and 2020-12. Unstamped schemas use the SDK's 2020-12 default. Returned `structuredContent` is validated against the advertised schema for both proxy and direct-tool calls.
|
|
550
|
+
|
|
551
|
+
Additional implementation notes:
|
|
552
|
+
|
|
553
|
+
- Idle servers disconnect after 10 minutes (configurable), reconnect automatically on next use
|
|
554
|
+
- npx-based servers resolve to direct binary paths, skipping the ~143 MB npm parent process
|
|
555
|
+
- MCP server validates arguments, not the adapter
|
|
556
|
+
- Remote keep-alive servers force-refresh their tool catalog during health checks, before user input, and before adapter-triggered turns, with bounded reconnect backoff
|
|
557
|
+
- Specific tools can be promoted from the proxy to first-class host tools via `directTools` config, so the LLM sees them directly instead of having to search
|
|
558
|
+
|
|
559
|
+
## Limitations
|
|
560
|
+
|
|
561
|
+
- Cross-session server sharing not yet implemented (each agent session runs its own server processes)
|
|
562
|
+
- Compact MCP result rendering summarizes text, but inline images are still controlled by Pi's image display settings and may render below the compact text summary.
|
|
563
|
+
- Pi still owns one separator row before self-rendered tool output, so compact mode reduces adapter rendering height but cannot promise true zero-gap rows.
|
|
564
|
+
- MCP sampling support is text-only; context inclusion, tools, stop sequences, audio, and image content are rejected with explicit errors.
|