@fitchmultz/pi-mcp-adapter 5.0.0 → 7.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/CHANGELOG.md +50 -0
- package/OAUTH.md +3 -3
- package/README.md +160 -88
- package/dist/app-bridge.bundle.js +75 -33
- package/dist/commands.js +9 -6
- package/dist/config.js +41 -16
- package/dist/direct-tools.d.ts +2 -4
- package/dist/direct-tools.js +21 -319
- package/dist/gateway-arguments.d.ts +33 -0
- package/dist/gateway-arguments.js +63 -0
- package/dist/index.js +181 -276
- package/dist/init.js +6 -20
- package/dist/lifecycle.d.ts +2 -2
- package/dist/lifecycle.js +2 -2
- package/dist/mcp-auth-flow.js +2 -2
- package/dist/mcp-auth.d.ts +1 -1
- package/dist/mcp-auth.js +3 -3
- package/dist/mcp-code.d.ts +7 -6
- package/dist/mcp-code.js +98 -51
- package/dist/mcp-oauth-provider.d.ts +5 -5
- package/dist/mcp-oauth-provider.js +5 -5
- package/dist/mcp-output-guard.d.ts +57 -2
- package/dist/mcp-output-guard.js +129 -24
- package/dist/mcp-panel.d.ts +3 -3
- package/dist/mcp-panel.js +36 -99
- package/dist/mcp-script-worker.mjs +5 -2
- package/dist/mcp-setup-panel.d.ts +5 -4
- package/dist/mcp-setup-panel.js +15 -7
- package/dist/mcp-status.js +2 -1
- package/dist/mcp-trace.d.ts +1 -1
- package/dist/mcp-trace.js +1 -1
- package/dist/metadata-cache.d.ts +1 -1
- package/dist/metadata-cache.js +25 -88
- package/dist/npx-resolver.js +8 -4
- package/dist/prompts.d.ts +1 -1
- package/dist/prompts.js +1 -1
- package/dist/proxy-modes.d.ts +41 -7
- package/dist/proxy-modes.js +275 -490
- package/dist/resource-tools.d.ts +15 -0
- package/dist/resource-tools.js +26 -1
- package/dist/sampling-handler.js +5 -1
- package/dist/search-ranking.d.ts +0 -2
- package/dist/search-ranking.js +70 -137
- package/dist/server-manager.d.ts +2 -2
- package/dist/server-manager.js +44 -27
- package/dist/session-recovery.d.ts +7 -4
- package/dist/session-recovery.js +76 -10
- package/dist/state.d.ts +1 -1
- package/dist/tool-loader.d.ts +32 -0
- package/dist/tool-loader.js +152 -0
- package/dist/tool-metadata.d.ts +67 -0
- package/dist/tool-metadata.js +23 -17
- package/dist/tool-registrar.d.ts +4 -4
- package/dist/tool-registrar.js +18 -13
- package/dist/tool-result-renderer.d.ts +6 -3
- package/dist/tool-result-renderer.js +11 -6
- package/dist/types.d.ts +11 -36
- package/dist/ui-resource-handler.d.ts +2 -2
- package/dist/ui-resource-handler.js +2 -2
- package/dist/ui-server.js +4 -3
- package/dist/ui-stream-types.d.ts +8 -8
- package/dist/unix-socket-transport.d.ts +1 -1
- package/dist/unix-socket-transport.js +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +16 -4
- package/package.json +37 -96
- package/skills/mcp-scripting/SKILL.md +67 -20
- package/abort.ts +0 -34
- package/agent-dir.ts +0 -24
- package/app-bridge.bundle.js +0 -67
- package/banner.png +0 -0
- package/checkpoint.ts +0 -55
- package/commands.ts +0 -619
- package/config.ts +0 -1204
- package/consent-manager.ts +0 -25
- package/direct-tools.ts +0 -408
- package/dist/ts-shape.d.ts +0 -2
- package/dist/ts-shape.js +0 -147
- package/elicitation-handler.ts +0 -349
- package/error-signal.ts +0 -21
- package/glimpse-ui.ts +0 -80
- package/host-html-template.ts +0 -456
- package/index.ts +0 -900
- package/init.ts +0 -627
- package/legacy-migration.ts +0 -47
- package/lifecycle.ts +0 -165
- package/logger.ts +0 -127
- package/mcp-auth-flow.ts +0 -975
- package/mcp-auth.ts +0 -793
- package/mcp-callback-server.ts +0 -450
- package/mcp-code.ts +0 -386
- package/mcp-keyring-helper.cjs +0 -89
- package/mcp-oauth-provider.ts +0 -774
- package/mcp-output-guard.ts +0 -412
- package/mcp-panel.ts +0 -978
- package/mcp-script-worker.mjs +0 -128
- package/mcp-setup-panel.ts +0 -666
- package/mcp-status.ts +0 -109
- package/mcp-trace.ts +0 -295
- package/metadata-cache.ts +0 -333
- package/npx-resolver.ts +0 -488
- package/onboarding-state.ts +0 -58
- package/panel-keys.ts +0 -37
- package/prompts.ts +0 -337
- package/proxy-modes.ts +0 -1361
- package/resource-tools.ts +0 -17
- package/runtime-owner.ts +0 -123
- package/sampling-handler.ts +0 -273
- package/scripts/build.mjs +0 -131
- package/scripts/prepare.mjs +0 -102
- package/search-ranking.ts +0 -196
- package/server-manager.ts +0 -1320
- package/session-recovery.ts +0 -316
- package/state.ts +0 -64
- package/tool-approval.ts +0 -78
- package/tool-metadata.ts +0 -235
- package/tool-registrar.ts +0 -69
- package/tool-result-renderer.ts +0 -286
- package/ts-shape.ts +0 -145
- package/tsconfig.build.json +0 -13
- package/tsconfig.json +0 -16
- package/types.ts +0 -810
- package/ui-resource-handler.ts +0 -249
- package/ui-server.ts +0 -808
- package/ui-session.ts +0 -568
- package/ui-stream-types.ts +0 -89
- package/ui-tool-visibility.ts +0 -25
- package/unix-socket-transport.ts +0 -85
- package/utils.ts +0 -309
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Fitch MCP Adapter
|
|
6
6
|
|
|
7
|
-
Use MCP servers with [Pi](https://github.com/
|
|
7
|
+
Use MCP servers with [Pi](https://github.com/earendil-works/pi) without burning your context window.
|
|
8
8
|
|
|
9
9
|
An independently maintained distribution of [Nico's Pi MCP Adapter](https://github.com/nicobailon/pi-mcp-adapter), under the original MIT license.
|
|
10
10
|
|
|
@@ -16,11 +16,17 @@ Mario wrote about [why you might not need MCP](https://mariozechner.at/posts/202
|
|
|
16
16
|
|
|
17
17
|
His take: skip MCP entirely, write simple CLI tools instead.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The MCP ecosystem has useful databases, browsers, and APIs. This adapter keeps their full tool schemas out of context until needed. `mcp_search` discovers and loads typed tools for the next request; `mcp` handles explicit gateway actions, and `mcp_script` composes MCP calls in JavaScript. Lazy servers stay disconnected until selected discovery or a call needs them.
|
|
20
|
+
|
|
21
|
+
## Pi release qualification
|
|
22
|
+
|
|
23
|
+
The development baseline is official Pi **0.87.1**; host peers remain wildcard. `npm run check:compat` verifies the installed SDK and CLI identity, builds and typechecks, runs Vitest and memory-only OAuth tests, then loads a packed consumer through the native SDK and CLI.
|
|
24
|
+
|
|
25
|
+
GitHub CI runs that contract on Node 24 against both official Pi and the maintained fork through the shared Pi compatibility automation, including fresh Git and npm installations loaded by the real Pi CLI. A second job checks lockfile registry hosts, published type declarations, the built interactive visualizer, and MCP protocol conformance. These checks use local MCP fixtures and disposable agent directories, never live credentials or paid providers.
|
|
20
26
|
|
|
21
27
|
## Install
|
|
22
28
|
|
|
23
|
-
Requires Pi 0.
|
|
29
|
+
Requires Pi 0.87.1 or later and Node.js 24 or later.
|
|
24
30
|
|
|
25
31
|
```bash
|
|
26
32
|
pi install npm:@fitchmultz/pi-mcp-adapter
|
|
@@ -30,9 +36,19 @@ Or install from Git: `pi install git:github.com/fitchmultz/pi-mcp-adapter`.
|
|
|
30
36
|
|
|
31
37
|
Restart Pi after installation. Existing v4 users should migrate first.
|
|
32
38
|
|
|
39
|
+
### Upgrading from v5
|
|
40
|
+
|
|
41
|
+
Version 6 keeps v5's package, config paths, and OAuth namespace. No credential migration is needed.
|
|
42
|
+
|
|
43
|
+
- Use `mcp_search({ query: "...", server: "name" })` to discover and load typed tools. It loads matches for the next request; it never executes a search hit. `directTools` now pins tools at startup rather than deciding which tools can ever be loaded.
|
|
44
|
+
- Give every new gateway call an explicit `action`: `mcp({ action: "search", query: "..." })`, `mcp({ action: "describe", tool: "..." })`, or `mcp({ action: "call", tool: "...", args: {} })`. Arguments are objects. Stored v5 calls with optional mode fields or JSON-string arguments are normalized at the ingress compatibility boundary; they are not the advertised v6 interface.
|
|
45
|
+
- Resources use `resources` and `read-resource` actions, or `tools.resources` and `tools.readResource` in scripts. Generated `read_<resource>` aliases remain callable through gateway/script compatibility, but no longer appear as functions or panel checkboxes. Remove resource aliases from `directTools`; legacy resource pins keep the gateway available even with `disableProxyTool: true`.
|
|
46
|
+
- Script descriptions always return complete JSON Schema in `inputSchema`, with `outputSchema` and other descriptor fields when supplied. Replace `inputTypeScript` consumers. Calls keep raw MCP results, including error-result data; use returned result references for bounded readback without another server call.
|
|
47
|
+
- Global search reports partial catalog coverage instead of starting every uncached lazy server. Select a server to discover it. Cache format 2 preserves raw descriptors and still reads format 1; downgrading to v5 ignores format 2 and requires rediscovery.
|
|
48
|
+
|
|
33
49
|
### Upgrading from v4
|
|
34
50
|
|
|
35
|
-
|
|
51
|
+
The Fitch distribution uses its own package, state paths and OAuth credential namespace. Remove the previous adapter package entry from Pi settings (for example, `pi remove npm:pi-mcp-adapter` for the unscoped npm source), then install the distribution above. Keep only one adapter loaded in a Pi host.
|
|
36
52
|
|
|
37
53
|
After installation, **before restarting Pi**, run from your project directory:
|
|
38
54
|
|
|
@@ -94,30 +110,29 @@ Precedence is:
|
|
|
94
110
|
5. `.mcp.json`
|
|
95
111
|
6. `.pi/fitch-mcp-adapter/mcp.json`
|
|
96
112
|
|
|
113
|
+
If a higher-precedence config changes a stdio server's `command`, `args`, or `cwd`, it must explicitly supply any `env` values that the new process needs; the previous definition's `env` is not inherited. An OpenCode `environment` override also replaces the previous map rather than merging its keys.
|
|
114
|
+
|
|
97
115
|
Project layers and project-local host imports are read only after Pi marks the project trusted. Until then, the adapter uses global configuration only, does not start project-defined servers, and blocks project configuration panels and writes.
|
|
98
116
|
|
|
99
117
|
`/mcp disable <server>` and `/mcp enable <server>` persist only the `disabled` field in the project-local `.pi/fitch-mcp-adapter/mcp.json`, which is the highest-precedence Pi layer. Enabling removes the project flag when lower layers are enabled, or writes `false` when needed to override a disabled lower source. This applies even when the effective server came from a shared global/project file, an imported host config, or `configPath`; the source file is never rewritten and credentials are never copied. Run `/reload` after changing the flag so registered tool surfaces are refreshed. The manual equivalent is to add `{ "disabled": true }` to a server in any normal MCP config. Supplied in-memory `createMcpAdapter({ config })` configurations are isolated and do not read or write this project override; the commands are unavailable in that mode.
|
|
100
118
|
|
|
101
|
-
Servers are **lazy by default
|
|
119
|
+
Servers are **lazy by default**. Cached tool descriptors can be searched without a live connection. To discover an uncached server and load the tools relevant to a task:
|
|
102
120
|
|
|
121
|
+
```js
|
|
122
|
+
mcp_search({ query: "take screenshot", server: "chrome-devtools" })
|
|
103
123
|
```
|
|
104
|
-
mcp({ search: "screenshot" })
|
|
105
|
-
```
|
|
106
|
-
```
|
|
107
|
-
chrome_devtools_take_screenshot
|
|
108
|
-
Take a screenshot of the page or element.
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
```
|
|
115
|
-
mcp({ tool: "chrome_devtools_take_screenshot", args: { format: "png" } })
|
|
116
|
-
```
|
|
125
|
+
The returned exact tool references become available with their full argument schemas on the next model request. The agent then calls the chosen typed tool normally. Discovery does not run it.
|
|
126
|
+
|
|
127
|
+
If the host only permits `mcp`, use explicit gateway actions instead:
|
|
117
128
|
|
|
118
|
-
|
|
129
|
+
```js
|
|
130
|
+
mcp({ action: "search", query: "take screenshot", server: "chrome-devtools" })
|
|
131
|
+
mcp({ action: "describe", tool: "chrome_devtools_take_screenshot" })
|
|
132
|
+
mcp({ action: "call", tool: "chrome_devtools_take_screenshot", args: { format: "png" } })
|
|
133
|
+
```
|
|
119
134
|
|
|
120
|
-
|
|
135
|
+
Gateway search returns schemas without activating direct tools. All paths preserve the same authentication, approval, and call-capture behavior.
|
|
121
136
|
|
|
122
137
|
## Config
|
|
123
138
|
|
|
@@ -159,7 +174,7 @@ const extension = createMcpAdapter({
|
|
|
159
174
|
// Register `extension` with the host SDK.
|
|
160
175
|
```
|
|
161
176
|
|
|
162
|
-
The package
|
|
177
|
+
The package exports compiled ESM and declarations from `dist/`, so a standalone Node process can import it directly.
|
|
163
178
|
|
|
164
179
|
A supplied `config` is a complete, isolated snapshot. It is not merged with files, imports, global config, project config, or `--mcp-config`, and it is never mutated. Each adapter factory and session receives its own clone, so separate integrations can use different servers and settings safely. In this mode, server status, reconnect, explicit `/mcp-auth <server>`, proxy calls, and direct tools continue to work; setup and no-argument auth/status panels report the limitation instead of discovering or writing ambient config.
|
|
165
180
|
|
|
@@ -223,7 +238,7 @@ Before any asynchronous flush, the adapter fences owned activity and pauses its
|
|
|
223
238
|
|
|
224
239
|
### Runtime status snapshots
|
|
225
240
|
|
|
226
|
-
Extensions can subscribe to the adapter's versioned shared event-bus channel instead of parsing `/mcp` or `mcp({})` output:
|
|
241
|
+
Extensions can subscribe to the adapter's versioned shared event-bus channel instead of parsing `/mcp` or `mcp({ action: "status" })` output:
|
|
227
242
|
|
|
228
243
|
```ts
|
|
229
244
|
import { MCP_STATUS_EVENT, type McpStatusSnapshot } from "@fitchmultz/pi-mcp-adapter";
|
|
@@ -235,7 +250,7 @@ pi.events.on(MCP_STATUS_EVENT, (snapshot) => {
|
|
|
235
250
|
});
|
|
236
251
|
```
|
|
237
252
|
|
|
238
|
-
`MCP_STATUS_EVENT` is `fitch-mcp-adapter/status/v1`. The snapshot is read-only machine-readable data with copied per-server entries. It includes `totalTools`, `totalResources`, `connectedCount`, and `disabledCount`; each server includes `name`, `status`, `toolCount`, and `disabled`, with `resourceCount` when known and `failedAgoSeconds` only for an active failure. Reading status never connects a lazy server, starts authentication, or exposes SDK clients, transports, credentials, or server definitions. An initial snapshot is emitted after initialization, updates are emitted for status and metadata changes, and an empty snapshot is emitted when the session shuts down.
|
|
253
|
+
`MCP_STATUS_EVENT` is `fitch-mcp-adapter/status/v1`. The snapshot is read-only machine-readable data with copied per-server entries. It includes `totalTools`, `totalResources`, `connectedCount`, and `disabledCount`; each server includes `name`, `status`, `toolCount`, and `disabled`, with `resourceCount` when known, `catalogKnown` indicating whether discovery has completed, and `failedAgoSeconds` only for an active failure. An unknown catalog is not a confirmed zero-tool server. Reading status never connects a lazy server, starts authentication, or exposes SDK clients, transports, credentials, or server definitions. An initial snapshot is emitted after initialization, updates are emitted for status and metadata changes, and an empty snapshot is emitted when the session shuts down.
|
|
239
254
|
|
|
240
255
|
In the configuration examples below, `30000` is illustrative only. If `requestTimeoutMs` is omitted or set to `<= 0`, the MCP SDK default timeout is used.
|
|
241
256
|
|
|
@@ -257,11 +272,11 @@ For known legacy servers, set `protocolVersion: "legacy"`. This is also the work
|
|
|
257
272
|
|
|
258
273
|
`retryOnTransportFailure` is off by default. Enabling it trusts the configured server's explicit `readOnlyHint: true` or `idempotentHint: true` tool annotations for at most one new `callTool` request on the same modern HTTP client. Annotations are retained in live/cached metadata and describe output; the live catalog takes precedence over frozen direct-tool metadata. Eligible failures are a rejected tool POST fetch before response headers arrive, an HTTP 5xx tool response without a JSON-RPC error, or an SSE response body disconnecting before its JSON-RPC response arrives. The first attempt may already have run. Fresh SDK request IDs are not idempotency keys.
|
|
259
274
|
|
|
260
|
-
Unknown or non-idempotent tools remain callable but are never automatically redispatched after those failures. An unresolved transport failure returns internal `ambiguous_outcome` details with server/tool/call identity and readback instructions. Use the original saved arguments and the provider's supported operation/resource identity to read the prior result, then continue the remaining work; do not blindly repeat a write or rerun its whole script. Missing annotations are not permission denial. Confirmed pre-dispatch legacy-session and authentication recovery remain available.
|
|
275
|
+
Unknown or non-idempotent tools remain callable but are never automatically redispatched after those failures. An unresolved transport failure, interrupted JSON response body, closed connection, or cancellation/deadline while a dispatched tool request awaits its response returns internal `ambiguous_outcome` details with server/tool/call identity and readback instructions. Scripts retain these outcomes in their `calls` trace even when stopped by an overall timeout, cancellation, or early return. Use the original saved arguments and the provider's supported operation/resource identity to read the prior result, then continue the remaining work; do not blindly repeat a write or rerun its whole script. Missing annotations are not permission denial. Confirmed pre-dispatch legacy-session and authentication recovery remain available.
|
|
261
276
|
|
|
262
277
|
A broken SSE body fails only the affected request, even when retries are disabled. Completed responses and later stream notifications remain intact. Native SSE resumption stays SDK-owned: a server-provided event ID lets the SDK resume the existing stream before any adapter retry.
|
|
263
278
|
|
|
264
|
-
This transport-failure option does not retry OAuth failures, JSON-RPC errors, tool error results, invalid responses, cancellation, or expired deadlines. Permission recovery uses the separate existing `autoAuth` gate, not this option. JSON response-body failures, clean SSE endings without a response, and streams that merely stop making progress are not replayed. The original tool deadline covers SDK subrequests and retries, and modern retry never stacks with legacy expired-session recovery. Native header-schema refresh and multi-round-trip input handling remain SDK-owned.
|
|
279
|
+
This transport-failure option does not retry OAuth failures, JSON-RPC errors, tool error results, invalid responses, closed connections, cancellation, or expired deadlines. Permission recovery uses the separate existing `autoAuth` gate, not this option. JSON response-body failures, clean SSE endings without a response, and streams that merely stop making progress are not replayed. The original tool deadline covers SDK subrequests and retries, and modern retry never stacks with legacy expired-session recovery. Native header-schema refresh and multi-round-trip input handling remain SDK-owned.
|
|
265
280
|
|
|
266
281
|
### Server Options
|
|
267
282
|
|
|
@@ -306,10 +321,10 @@ This transport-failure option does not retry OAuth failures, JSON-RPC errors, to
|
|
|
306
321
|
| `lifecycle` | `"lazy"` (default), `"eager"`, `"keep-alive"`, or `"lazy-keep-alive"` |
|
|
307
322
|
| `idleTimeout` | Minutes before idle disconnect (overrides global) |
|
|
308
323
|
| `requestTimeoutMs` | Request timeout in milliseconds for live MCP calls (overrides global; if omitted or `<= 0`, the MCP SDK default timeout is used) |
|
|
309
|
-
| `exposeResources` |
|
|
310
|
-
| `directTools` | `true`, `string[]`, or `false` —
|
|
324
|
+
| `exposeResources` | Make MCP resources available through resource listing/reading (default: true) |
|
|
325
|
+
| `directTools` | `true`, `string[]`, or `false` — pin real tools into the initial active tool set |
|
|
311
326
|
| `toolPrefix` | Override global `settings.toolPrefix` for this server (`"server"`, `"short"`, `"none"`, or `"mcp"`) |
|
|
312
|
-
| `includeTools` | `string[]` of tool names or glob patterns to expose (matches original names like `get_screenshot`,
|
|
327
|
+
| `includeTools` | `string[]` of tool names or glob patterns to expose (matches original names like `get_screenshot`, legacy resource filter aliases like `read_figjam`, and prefixed names like `figma_get_screenshot`) |
|
|
313
328
|
| `excludeTools` | `string[]` of tool names or glob patterns to hide (applied after `includeTools`) |
|
|
314
329
|
| `debug` | Show server stderr (default: false) |
|
|
315
330
|
| `trace` | Enable metadata-only JSONL protocol tracing for this server; payloads, prompts, tool arguments/results, authorization data, and URLs are never persisted |
|
|
@@ -424,10 +439,10 @@ Persistent OAuth is unsupported out of the box on Android/Termux because `@napi-
|
|
|
424
439
|
|
|
425
440
|
### Lifecycle Modes
|
|
426
441
|
|
|
427
|
-
- **`lazy`** (default) —
|
|
442
|
+
- **`lazy`** (default) — Connect on selected discovery or first call, then disconnect after idle timeout. Cached metadata keeps search/list working without connections. Configured pins can intentionally discover their server at startup.
|
|
428
443
|
- **`eager`** — Connect at startup but don't auto-reconnect if the connection drops. No idle timeout by default (set `idleTimeout` explicitly to enable).
|
|
429
444
|
- **`keep-alive`** — Connect at startup. Auto-reconnect via health checks. No idle timeout. Use for servers you always need available.
|
|
430
|
-
- **`lazy-keep-alive`** —
|
|
445
|
+
- **`lazy-keep-alive`** — Connect on selected discovery or first call (like `lazy`); configured pins can discover it at startup. Once spawned, never idle-shut down and auto-reconnect via health checks if the process dies (like `keep-alive`). Use for servers that are expensive to start but should stay resident after their first use.
|
|
431
446
|
|
|
432
447
|
### Settings
|
|
433
448
|
|
|
@@ -465,9 +480,9 @@ Persistent OAuth is unsupported out of the box on Android/Termux because `@napi-
|
|
|
465
480
|
| `oauthDir` | Parent directory for legacy OAuth imports. Runtime uses its `fitch-mcp-adapter/` child; explicit v4 migration reads the original directory. Relative paths resolve from the active project cwd. `FITCH_MCP_OAUTH_DIR` overrides the final runtime import path; the old `MCP_OAUTH_DIR` is read only by explicit migration. Persistent credentials live in the OS credential store. |
|
|
466
481
|
| `mcpServers.<name>.oauth.authorizationParams` | Extra authorization URL parameters for provider-specific OAuth extensions. Flow-owned parameters such as `client_id`, `redirect_uri`, `scope`, `state`, `code_challenge`, `response_type`, and `resource` cannot be overridden. |
|
|
467
482
|
| `directTools` | Global default for all servers (default: false). Per-server overrides this. |
|
|
468
|
-
| `freezeDirectTools` | Keep direct-tool registration stable after the initial sync so automatic reconnects and list-change notifications do not rebuild the system prompt. Use `mcp({ connect: "server" })` or `/mcp reconnect <server>` to refresh deliberately. Default: false. |
|
|
483
|
+
| `freezeDirectTools` | Keep direct-tool registration stable after the initial sync so automatic reconnects and list-change notifications do not rebuild the system prompt. Use `mcp({ action: "connect", server: "server" })` or `/mcp reconnect <server>` to refresh deliberately. Default: false. |
|
|
469
484
|
| `scriptMode` | Register the MCP-only `mcp_script` plain-JavaScript tool (default: true). Set to `false` to hide it. |
|
|
470
|
-
| `disableProxyTool` | Hide
|
|
485
|
+
| `disableProxyTool` | Hide `mcp` once configured pinned tools are available. Legacy resource pins keep it available for resource access. |
|
|
471
486
|
| `autoAuth` | Auto-run OAuth on `connect`/tool calls when a server needs auth, then retry once (default: false). |
|
|
472
487
|
| `sampling` | Allow MCP servers to sample through Pi models, honoring `modelPreferences.hints` before current/default fallback (default: true when UI approval is available). |
|
|
473
488
|
| `samplingAutoApprove` | Skip sampling confirmation prompts. Required for sampling in non-UI sessions (default: false). |
|
|
@@ -501,7 +516,8 @@ Oversized MCP tool/resource results are guarded by default so a single huge resp
|
|
|
501
516
|
|
|
502
517
|
- Inline text output is capped at **50 KiB / 2,000 lines** (matching Pi's built-in `bash` guard). Larger output is truncated to a head preview and the full text is saved to a temp file whose path is included in the result, so the agent can `read`/`grep` it.
|
|
503
518
|
- **Image content blocks pass through unchanged** — only text output is guarded. Images are delivered to the provider as native image content.
|
|
504
|
-
- In
|
|
519
|
+
- In gateway and direct modes, `details.mcpResult` is kept raw when its JSON is **≤ 16 KiB**; larger results use a compact summary and retain the full raw JSON in a file. Scripts receive the raw result before model-facing rendering, so they can reduce it without creating an unused text preview.
|
|
520
|
+
- Structured data, media, resources, extra protocol fields, and oversized results include a model-visible **result reference** to the saved raw result. Tiny plain-text results remain inline without an artifact. `structuredContent` is shown even when the server also returns content blocks.
|
|
505
521
|
|
|
506
522
|
Tune the limits with the object form:
|
|
507
523
|
|
|
@@ -513,11 +529,19 @@ Tune the limits with the object form:
|
|
|
513
529
|
}
|
|
514
530
|
```
|
|
515
531
|
|
|
516
|
-
Set `"outputGuard": false` — or the env kill switch `MCP_OUTPUT_GUARD=0` — to disable the guard and restore raw output behavior. Saved files are created with mode `0600` under the system temp directory (or the SDK host's `outputDirectory`) and are not cleaned up automatically; note that spilled MCP output may contain sensitive data.
|
|
532
|
+
Set `"outputGuard": false` — or the env kill switch `MCP_OUTPUT_GUARD=0` — to disable the guard and restore raw output behavior. Recovery notices remain visible even when a configured cap is too small to fit them. Saved files are created with mode `0600` under the system temp directory (or the SDK host's `outputDirectory`) and are not cleaned up automatically; note that spilled MCP output may contain sensitive data.
|
|
533
|
+
|
|
534
|
+
Read a retained result without repeating the MCP operation:
|
|
535
|
+
|
|
536
|
+
```js
|
|
537
|
+
mcp({ action: "read-result", ref: "/returned/result/path", path: "/structuredContent/rows", fields: ["id", "title"], offset: 0, limit: 12000 })
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
`path` is an RFC 6901 JSON Pointer; `fields` keeps immediate keys on the selected object or each object in an array. Selection happens before paging. `offset` and `limit` count **characters in the selected, pretty-printed JSON**, starting at zero—not rows, lines, or bytes. Readback defaults to 12,000 characters and remains bounded by the output byte/line caps. Continue with `details.nextOffset` until it is `null`. Readback requires an existing adapter output artifact in this host's output directory; it never calls the server again. The same operation is available as `tools.readResult` in scripts.
|
|
517
541
|
|
|
518
542
|
### MCP Scripting
|
|
519
543
|
|
|
520
|
-
For multi-call MCP work, write ordinary JavaScript: discover, inspect, call, loop, filter, chain, or fan out, then return one result. Run that code with the default-on `mcp_script` tool.
|
|
544
|
+
For multi-call MCP work, write ordinary JavaScript: discover, inspect, call, loop, filter, chain, or fan out, then return one result. Run that code with the default-on `mcp_script` tool. Use `mcp_search` for typed discovery, a loaded typed tool for a single call, and `mcp` for explicit gateway actions. Set `settings.scriptMode` to `false` to hide the scripting tool.
|
|
521
545
|
|
|
522
546
|
The bundled `mcp-scripting` skill is a separate Pi package resource. To hide that skill while keeping the adapter extension installed, replace the package entry in Pi settings with the object form and disable package skills:
|
|
523
547
|
|
|
@@ -531,29 +555,65 @@ The bundled `mcp-scripting` skill is a separate Pi package resource. To hide tha
|
|
|
531
555
|
|
|
532
556
|
Preserve any version pin in `source` if your existing package entry has one. You can also disable package resources through `pi config`.
|
|
533
557
|
|
|
534
|
-
|
|
558
|
+
First inspect candidate schemas. This script discovers and describes without executing a search hit:
|
|
535
559
|
|
|
536
560
|
```js
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
|
|
561
|
+
const found = await tools.search({ query: "search issues", server: "github" });
|
|
562
|
+
if (found.error) return found;
|
|
563
|
+
emit(found.coverage);
|
|
564
|
+
for (const item of found.items) {
|
|
565
|
+
emit(await tools.describe({ path: item.path, server: item.server }));
|
|
566
|
+
}
|
|
567
|
+
```
|
|
540
568
|
|
|
541
|
-
|
|
542
|
-
if (details.error) return details;
|
|
569
|
+
After choosing a tool and checking its schema, pass ordinary JavaScript as `mcp_script`'s `code` argument:
|
|
543
570
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
571
|
+
```js
|
|
572
|
+
const results = [];
|
|
573
|
+
for (const query of ["is:open label:bug", "is:open label:docs"]) {
|
|
574
|
+
const result = await tools.call("github_search_issues", { query });
|
|
575
|
+
if (!result.ok) return result;
|
|
576
|
+
results.push({ query, data: result.data });
|
|
577
|
+
}
|
|
578
|
+
return results;
|
|
548
579
|
```
|
|
549
580
|
|
|
550
|
-
|
|
581
|
+
The script API is:
|
|
582
|
+
|
|
583
|
+
| Method | Result |
|
|
584
|
+
|--------|--------|
|
|
585
|
+
| `tools.search({ query, server?, limit?, offset? })` | `{ items, total, hasMore, nextOffset, coverage }`; items include `path`, `name`, and `server`; discovery errors include `error` |
|
|
586
|
+
| `tools.describe({ path, server? })` | Complete descriptor with `path`, `server`, `name`, and the server's `inputSchema`, `outputSchema`, `title`, annotations, `_meta`, and other fields when present; failures contain `error` |
|
|
587
|
+
| `tools.call(path, args, server?)` or `tools.exact_flat_name(args)` | `{ ok: true, data, resultRef? }` or `{ ok: false, error: { code, message, ... }, data?, resultRef? }` |
|
|
588
|
+
| `tools.resources({ server, limit?, offset? })` | `{ mode: "resources", server, items, total, hasMore, nextOffset }`; failures contain `error` |
|
|
589
|
+
| `tools.readResource({ server, uri })` | The call envelope above, with raw resource data in `data.contents` |
|
|
590
|
+
| `tools.readResult({ ref, path?, fields?, offset?, limit? })` | `{ content, details }`; readback text and `details.nextOffset`, or `details.error` on failure |
|
|
591
|
+
| `emit(value)` / `console.log(value)` | Captured output before the final return value |
|
|
592
|
+
|
|
593
|
+
For an ambiguous flat name, call `tools.call(descriptor.name, args, descriptor.server)` using the original name and server returned by describe.
|
|
594
|
+
|
|
595
|
+
Search/resource pages default to 12 items, maximum 100. `coverage` contains `complete`, `knownServers`, and `unknownServers`. Selecting an uncached server discovers it; global search does not connect every lazy server. Script discovery does not activate typed tools. Descriptions retain JSON Schema rather than a lossy TypeScript projection.
|
|
596
|
+
|
|
597
|
+
`data` is the raw MCP result: tool calls usually return `{ content, structuredContent?, isError?, ... }`; resource reads return `{ contents, ... }`. Error results retain their raw data when available. Handle `ok: false`; ordinary call failures do not automatically stop the script. Capture failures stop dependent work, and ambiguous outcomes require provider readback instead of blindly repeating a call. Result details include a concise `calls` trace and saved result references. Reduce raw results before emitting them; the final output uses the normal output guard.
|
|
598
|
+
|
|
599
|
+
Use JavaScript loops and Promise utilities; fluent helpers such as `tools.find(...).one()`, `tools.parallel(...)`, and `tools.retry(...)` are not provided. Await every call before returning. The default timeout is 30 seconds unless the SDK host overrides it with `defaultScriptTimeoutMs`; an explicit per-script `timeoutMs` wins. Each script runs in a local worker that is terminated on timeout or cancellation, including infinite loops.
|
|
600
|
+
|
|
601
|
+
For a tool-restricted subagent, a host can allow only `mcp_script`; include the relevant exact tool names or let the script use its discovery methods. A gateway-only host can use `mcp({ action: "search", query: "..." })` without activating tools outside its allowlist. Authentication, approvals, filters, and cancellation apply to every call.
|
|
602
|
+
|
|
603
|
+
`mcp_script` is a trusted agent-authored MCP scripting layer, not an isolation boundary. The worker exposes no Node, filesystem, or network globals such as `process`, `Buffer`, or `fetch`. Run Pi in an isolated environment if you need isolation. This is local orchestration, not provider-native programmatic tool calling; it does not claim Codex native PTC support. Pi's general code-mode skill is separate and batches general Pi tools.
|
|
551
604
|
|
|
552
|
-
See the bundled `mcp-scripting` skill for the
|
|
605
|
+
See the bundled `mcp-scripting` skill for the workflow and exact return shapes.
|
|
553
606
|
|
|
554
|
-
|
|
607
|
+
### MCP Resources
|
|
555
608
|
|
|
556
|
-
|
|
609
|
+
Resources are catalog entries addressed by URI, separate from tools:
|
|
610
|
+
|
|
611
|
+
```js
|
|
612
|
+
mcp({ action: "resources", server: "docs", limit: 12, offset: 0 })
|
|
613
|
+
mcp({ action: "read-resource", server: "docs", uri: "docs://guide" })
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
List first, then use the exact URI. Listings preserve the server's resource descriptor fields, including name, title, MIME type, icons, and `_meta` when supplied. `exposeResources`, include/exclude filters, disabled servers, authentication, and approval policy remain binding. Existing `read_<resource>` filter names still select resources, but these compatibility aliases are not typed functions and cannot be pinned in `/mcp`. Scripts use `tools.resources` and `tools.readResource`.
|
|
557
617
|
|
|
558
618
|
### MCP Prompts
|
|
559
619
|
|
|
@@ -573,9 +633,17 @@ When Pi exposes dialog-capable UI, the adapter advertises form elicitation suppo
|
|
|
573
633
|
|
|
574
634
|
URL mode is advertised only in TUI mode. The adapter displays the requesting server, target host, and full URL, and always requires consent before opening the browser. It also handles URL-required tool errors (`-32042`) and completion notifications; after completing the browser interaction, retry the original tool call.
|
|
575
635
|
|
|
576
|
-
###
|
|
636
|
+
### Typed Discovery and Pinned Tools
|
|
637
|
+
|
|
638
|
+
`mcp_search({ query, server?, limit?, offset? })` searches real tools and loads the matching typed functions for the next request. It defaults to five matches, with a maximum of 100 and zero-based pagination. Use a specific query, or an empty query with `server` to browse that server. It does not execute a hit or rewrite dynamic instructions into the system prompt.
|
|
577
639
|
|
|
578
|
-
|
|
640
|
+
Cached eligible schemas register inactive; only pins and tools selected for the current branch are active. The adapter persists canonical `{ server, tool }` selections in native Pi session entries and restores them across resume, reload, branch navigation, and working-directory changes. Host tool allowlists remain binding.
|
|
641
|
+
|
|
642
|
+
On hosts with native tool-search support, lazy tools use exact references in namespace `mcp_<server>` with the original tool name as the leaf. Existing direct pins retain their flat prefixed names. On official Pi 0.87.1, which has no native tool search, the ordinary `mcp_search` loader activates flat tools with the same discover-then-call workflow. Always use the exact reference returned by discovery rather than constructing names.
|
|
643
|
+
|
|
644
|
+
Typed tools may opt into native asynchronous execution only when both the host's pending-call API and the selected model route support it. Tools requiring configured approval, an MCP App UI, or the `beforeExecute` sequential checkpoint barrier keep ordinary awaited execution. This is separate from local `mcp_script` orchestration.
|
|
645
|
+
|
|
646
|
+
Add `directTools` to pin frequently used tools into the initial active set:
|
|
579
647
|
|
|
580
648
|
Per-server:
|
|
581
649
|
|
|
@@ -602,9 +670,9 @@ Per-server:
|
|
|
602
670
|
|
|
603
671
|
| Value | Behavior |
|
|
604
672
|
|-------|----------|
|
|
605
|
-
| `true` |
|
|
606
|
-
| `["tool_a", "tool_b"]` |
|
|
607
|
-
| Omitted or `false` |
|
|
673
|
+
| `true` | Pin all eligible real tools from this server |
|
|
674
|
+
| `["tool_a", "tool_b"]` | Pin these tools (use original MCP names) |
|
|
675
|
+
| Omitted or `false` | No initial pins; load tools with `mcp_search` when needed (default) |
|
|
608
676
|
|
|
609
677
|
To set a global default for all servers:
|
|
610
678
|
|
|
@@ -621,11 +689,11 @@ To set a global default for all servers:
|
|
|
621
689
|
}
|
|
622
690
|
```
|
|
623
691
|
|
|
624
|
-
Per-server `directTools` overrides the global setting. The example above
|
|
692
|
+
Per-server `directTools` overrides the global setting. The example above pins tools for every server except `huge-server`, whose tools remain discoverable.
|
|
625
693
|
|
|
626
|
-
Set `MCP_DIRECT_TOOLS=__none__` before loading the adapter to suppress all direct-tool registration, including
|
|
694
|
+
Set `MCP_DIRECT_TOOLS=__none__` before loading the adapter to suppress all direct-tool registration, including pins and search-driven activation. `mcp_search` can still discover schemas and report that no functions were loaded; use gateway or script calls instead. Normal tool filters, host allowlists, and disabled-server settings still apply.
|
|
627
695
|
|
|
628
|
-
To expose only a subset of a
|
|
696
|
+
To expose only a subset of a server, add `includeTools`. Values can be exact original names, prefixed names, or simple glob patterns. Legacy `read_<resource>` names continue to filter resource access:
|
|
629
697
|
|
|
630
698
|
```json
|
|
631
699
|
{
|
|
@@ -653,17 +721,15 @@ To hide specific tools while still using `directTools: true`, add `excludeTools`
|
|
|
653
721
|
}
|
|
654
722
|
```
|
|
655
723
|
|
|
656
|
-
`includeTools` and `excludeTools` filter
|
|
724
|
+
`includeTools` and `excludeTools` filter typed tools, gateway/script discovery, resource access, and the `/mcp` panel. App-only tools stay out of the model catalog and pin choices.
|
|
657
725
|
|
|
658
|
-
|
|
726
|
+
Active schemas consume context; inactive cached schemas do not. Pin the tools you routinely need and discover the rest as the task requires.
|
|
659
727
|
|
|
660
|
-
|
|
728
|
+
Valid cached descriptors avoid startup connections. Missing or stale metadata for configured pins is discovered intentionally at startup; eager and keep-alive servers also connect as configured. An empty cache does not trigger discovery of every lazy server. Search coverage reports which configured servers are still unknown.
|
|
661
729
|
|
|
662
|
-
|
|
730
|
+
MCP catalog notifications and reconnects refresh eligible metadata. Removed tools leave the active set. `settings.freezeDirectTools: true` keeps the automatic registered surface stable after initial sync; deliberate `mcp({ action: "connect", server: "name" })` or `/mcp reconnect <server>` refreshes remain available.
|
|
663
731
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
**Interactive configuration:** 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.
|
|
732
|
+
Run `/mcp` to see known tools, pinned counts, resource counts, and connection state. Uncached servers say **undiscovered**. Expand a server to pin or unpin real tools; resources have no checkboxes and use the resource actions instead. Pin changes apply to the current session and persist through `directTools`. Discovered session selections are separate from these startup pins: unpinning leaves a tool active if discovery already selected it for the current branch. Press Enter on a server that needs auth or `ctrl+a` on an OAuth server to authenticate; `ctrl+r` reconnects. Broader setup changes still use Pi's normal reload flow.
|
|
667
733
|
|
|
668
734
|
**Guided first-run setup:** 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`, add a curated known server (DeepWiki, Context7, Notion, GitHub, or Chrome DevTools), or quick-add RepoPrompt into a standard/shared MCP file.
|
|
669
735
|
|
|
@@ -671,7 +737,7 @@ When you change direct-tool toggles in `/mcp`, the extension updates direct tool
|
|
|
671
737
|
|
|
672
738
|
### MCP UI Integration
|
|
673
739
|
|
|
674
|
-
MCP servers can ship interactive UIs via
|
|
740
|
+
MCP servers can ship interactive UIs via [MCP Apps](https://github.com/modelcontextprotocol/ext-apps). The adapter uses MCP Apps 2.0.0 with the split MCP SDK 2.0.0 runtime. 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.
|
|
675
741
|
|
|
676
742
|
**How it works:**
|
|
677
743
|
|
|
@@ -715,7 +781,7 @@ Returns accumulated messages from UI sessions. Each message includes `type`, `se
|
|
|
715
781
|
- Tool consent gates whether UIs can call MCP tools (never/once-per-server/always)
|
|
716
782
|
- `_meta.ui.visibility` controls audience: tools marked app-only stay out of the model tool list, and tools marked model-only cannot be called from the UI iframe.
|
|
717
783
|
- Works with both stdio and HTTP MCP servers
|
|
718
|
-
- Uses a local
|
|
784
|
+
- Uses a local MCP Apps AppBridge bundle for browser↔server communication
|
|
719
785
|
- Enforces CSP from standard `_meta.ui.csp` and OpenAI-compatible `_meta["openai/widgetCSP"]` metadata in the response header while preserving provider HTML.
|
|
720
786
|
|
|
721
787
|
### Local Example: Interactive Visualizer
|
|
@@ -751,32 +817,36 @@ Prefer `.mcp.json` for project-local shared MCP config. Use `.pi/fitch-mcp-adapt
|
|
|
751
817
|
|
|
752
818
|
## Usage
|
|
753
819
|
|
|
754
|
-
|
|
|
755
|
-
|
|
756
|
-
|
|
|
757
|
-
|
|
|
758
|
-
|
|
|
759
|
-
|
|
|
760
|
-
|
|
|
761
|
-
|
|
|
762
|
-
|
|
|
820
|
+
| Action | Example |
|
|
821
|
+
|--------|---------|
|
|
822
|
+
| Discover and load typed tools | `mcp_search({ query: "screenshot", server: "chrome-devtools", limit: 5 })` |
|
|
823
|
+
| Status | `mcp({ action: "status" })` |
|
|
824
|
+
| List server tools | `mcp({ action: "list", server: "name", limit: 12, offset: 0 })` |
|
|
825
|
+
| Search without activation | `mcp({ action: "search", query: "screenshot navigate", limit: 12 })` |
|
|
826
|
+
| Describe | `mcp({ action: "describe", tool: "tool_name", server: "name" })` |
|
|
827
|
+
| Instructions | `mcp({ action: "instructions", server: "name" })` |
|
|
828
|
+
| Call | `mcp({ action: "call", tool: "tool_name", args: { key: "value" } })` |
|
|
829
|
+
| Connect or refresh | `mcp({ action: "connect", server: "name", limit: 12, offset: 0 })` |
|
|
830
|
+
| List resources | `mcp({ action: "resources", server: "name" })` |
|
|
831
|
+
| Read resource | `mcp({ action: "read-resource", server: "name", uri: "docs://guide" })` |
|
|
832
|
+
| Read saved result | `mcp({ action: "read-result", ref: "/returned/result/path", path: "/structuredContent" })` |
|
|
763
833
|
| UI messages | `mcp({ action: "ui-messages" })` |
|
|
764
834
|
| Auth start | `mcp({ action: "auth-start", server: "name" })` |
|
|
765
835
|
| Auth complete | `mcp({ action: "auth-complete", server: "name" })` after the browser callback, or supply `args: { redirectUrl: "..." }` |
|
|
766
836
|
|
|
767
|
-
`
|
|
837
|
+
`action` is required. Search requires `query`; describe/call require `tool`; list/connect/instructions/resources/auth require `server`; resource reads require `server` and `uri`; saved-result reads require `ref`. Pass object `args`. Optional `server` disambiguates tool calls and descriptions.
|
|
768
838
|
|
|
769
|
-
|
|
839
|
+
`connect` refreshes an already connected server, including tools, resources, prompts, and instructions. Server-scoped discovery connects that server if its catalog is unknown. Global search uses known catalogs and returns `coverage: { complete, knownServers, unknownServers }`; partial coverage is never presented as an exhaustive result. Gateway search provides schemas without activating functions, so it works for gateway-only hosts.
|
|
770
840
|
|
|
771
|
-
Search
|
|
841
|
+
Search ranks names, descriptions, and parameter guidance using MiniSearch. Catalog pages use item offsets: gateway/script search and lists default to 12, while `mcp_search` defaults to 5; maximum 100. Follow the returned `nextOffset`. Saved-result readback uses character offsets instead.
|
|
772
842
|
|
|
773
|
-
|
|
843
|
+
An exact, case-sensitive public tool name ranks before lexical matches; with `server`, an exact original tool name also ranks first within that server. Unscoped original names do not select an account. All remaining matches retain MiniSearch order. Search continuation and retry calls preserve their entry point: `mcp_search` loads the next page, while gateway search remains metadata-only.
|
|
774
844
|
|
|
775
|
-
|
|
845
|
+
Describe preserves the complete server descriptor, including JSON Schemas, annotations, `_meta`, and extensions when present. Search and typed-tool discovery exclude app-only tools and resources. Legacy hyphen/underscore matching remains a compatibility convenience; ambiguous names require an explicit server rather than executing an arbitrary match. Use the exact names returned by discovery.
|
|
776
846
|
|
|
777
|
-
The
|
|
847
|
+
The gateway description stays stable as catalogs and credentials change. Server instructions are available through `action: "instructions"` and previews in server listings, rather than injected dynamically into the prompt.
|
|
778
848
|
|
|
779
|
-
|
|
849
|
+
Gateway and typed-tool results render compactly in the terminal: long text shows the first three terminal-wrapped lines with Pi's `app.tools.expand` hint. Expanding reveals the guarded result. Structured data and saved-result references remain visible to the model.
|
|
780
850
|
|
|
781
851
|
## Commands
|
|
782
852
|
|
|
@@ -784,7 +854,8 @@ Servers that provide usage guidance via the MCP `instructions` field surface it
|
|
|
784
854
|
|---------|--------------|
|
|
785
855
|
| `/mcp` | Interactive panel and first-run onboarding surface |
|
|
786
856
|
| `/mcp setup` | Guided setup for imports, a minimal `.mcp.json`, curated known servers, RepoPrompt quick-add, and config-path inspection |
|
|
787
|
-
| `/mcp tools` | List
|
|
857
|
+
| `/mcp tools` | List discovered real tools, excluding resource aliases |
|
|
858
|
+
| `/mcp status` | Show connection state and separate tool/resource counts |
|
|
788
859
|
| `/mcp prompts` | List all MCP prompts registered as slash commands |
|
|
789
860
|
| `/mcp reconnect` | Reconnect all servers |
|
|
790
861
|
| `/mcp reconnect <server>` | Connect or reconnect a single server |
|
|
@@ -794,24 +865,25 @@ Servers that provide usage guidance via the MCP `instructions` field surface it
|
|
|
794
865
|
| `/mcp-auth` | Open an OAuth server picker in interactive UI sessions |
|
|
795
866
|
| `/mcp-auth <server>` | OAuth setup for a specific server |
|
|
796
867
|
|
|
797
|
-
If `settings.autoAuth` is `true`, `mcp({ connect: ... })`,
|
|
868
|
+
If `settings.autoAuth` is `true`, `mcp({ action: "connect", server: "..." })`, gateway calls, and typed/script tool calls may run OAuth when needed, with at most one automatic auth attempt per invocation and one post-auth retry. Browser authorization requires an interactive host. Auth-only replacement preserves accepted work on the old client; ordinary `/mcp reconnect` and panel `ctrl+r` remain hard resets.
|
|
798
869
|
|
|
799
870
|
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. Complete without arguments when the browser reaches Pi's callback, or paste the redirect URL when it cannot. `/mcp-auth` without a server only opens a picker in the interactive UI.
|
|
800
871
|
|
|
801
872
|
### MCP output schemas
|
|
802
873
|
|
|
803
|
-
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.
|
|
874
|
+
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. Any JSON structured value—including `null`, `false`, and `0`—is rendered as text, including alongside non-empty content or images. The raw result remains available for script reduction and saved-result readback.
|
|
804
875
|
|
|
805
876
|
## How It Works
|
|
806
877
|
|
|
807
|
-
-
|
|
808
|
-
-
|
|
878
|
+
- Stable `mcp_search`, `mcp`, and optional `mcp_script` entry points; full typed schemas load when selected
|
|
879
|
+
- Lazy servers connect on selected discovery or calls; configured pins and eager/keep-alive servers can bootstrap intentionally
|
|
809
880
|
- Tool metadata is cached to disk so search/list/describe work without live connections
|
|
810
881
|
- Idle servers disconnect after 10 minutes (configurable), reconnect automatically on next use
|
|
811
882
|
- npx-based servers resolve to direct binary paths, skipping the ~143 MB npm parent process
|
|
812
|
-
-
|
|
883
|
+
- Pi validates loaded typed-tool arguments against their schemas; gateway and script arguments are validated by the MCP server
|
|
813
884
|
- Keep-alive servers get health checks and auto-reconnect
|
|
814
|
-
-
|
|
885
|
+
- `directTools` pins initial tools; search-driven selections persist separately on the native session branch
|
|
886
|
+
- Resources use explicit URI-based listing and reading, without synthetic function definitions
|
|
815
887
|
|
|
816
888
|
## Limitations
|
|
817
889
|
|