pi-mcp-client 0.3.3 → 0.5.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/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # 🔌 Pi MCP Client
2
2
 
3
- MCP tools for Pi, discovered on demand and called natively through the official
4
- TypeScript SDK. No bridge process and no invocation proxy.
3
+ Connect Pi to MCP servers. The assistant discovers tools and resources on demand,
4
+ reads resources as context, and calls tools natively through the official
5
+ TypeScript SDK. No bridge process or invocation proxy.
5
6
 
6
7
  ## 🚀 Installation
7
8
 
@@ -11,318 +12,51 @@ pi install npm:pi-mcp-client
11
12
 
12
13
  ## ✨ Usage
13
14
 
14
- First, add a server to `~/.pi/agent/mcp.json`. This public documentation server
15
- does not require credentials:
15
+ Start a new Pi session, then add Cloudflare's public documentation server:
16
16
 
17
- ```json
18
- {
19
- "mcpServers": {
20
- "cloudflare-docs": {
21
- "type": "http",
22
- "url": "https://docs.mcp.cloudflare.com/mcp"
23
- }
24
- }
25
- }
26
- ```
27
-
28
- Start a new Pi session and ask it to search Cloudflare's documentation. Use `/mcp`
29
- to inspect the connection. For authenticated services, see [OAuth](#oauth) or
30
- [secret commands](#secret-commands).
31
-
32
- Pi discovers candidates, explicitly activates the tools it needs, then calls
33
- those tools natively. One `mcp_tools` tool supports both steps:
34
-
35
- ```js
36
- // Discover candidates. Never activates, even for an exact-name query.
37
- mcp_tools({ query: "list teams", server: "linear", limit: 5 })
38
-
39
- // Activate exact identifiers. Never invokes.
40
- mcp_tools({ activate: ["linear.list_teams", "linear.get_team"] })
17
+ ```text
18
+ /mcp add --scope global cloudflare-docs https://docs.mcp.cloudflare.com/mcp
41
19
  ```
42
20
 
43
- Pass exactly one of `query` or `activate`. The optional `server` and `limit`
44
- fields are valid only with `query`. Discovery returns up to five candidates by
45
- default, or up to 50 with `limit`. Each candidate shows its exact activation
46
- identifier, a short description, required parameter names only, and `[loaded]`
47
- if already active. Results use local BM25-based ranking, with tool names weighted
48
- more strongly than descriptions and support for prefix matching.
49
-
50
- Activation accepts 1–50 exact `server.tool` or `mcp__server__tool` identifiers,
51
- ignores duplicates, and works without a prior search. Typos never activate fuzzy
52
- matches: failures list nearby catalog names when available so the assistant can
53
- retry with an exact identifier. Each identifier reports `loaded`, `already loaded`,
54
- or `not loaded` with a reason. Partial success keeps the tools that loaded.
55
-
56
- Full schemas become available on the model turn after activation. First use of a
57
- capability now takes three turns—discover, activate, call—so a fuzzy search match
58
- can never become an active tool. Previously loaded tools remain available.
59
-
60
- `mcp_tools` replaces `mcp_search` without backward compatibility. Update explicit
61
- Pi tool allowlists to use `mcp_tools` and activate the tools you need again in
62
- existing sessions. The UI labels discovery calls **mcp discover** and activation
63
- calls **mcp activate**.
21
+ This server doesn't require credentials. Ask Pi:
64
22
 
65
- ### Result display
23
+ > Search Cloudflare's documentation for how to deploy a Worker.
66
24
 
67
- Discovery rows show `○` for inactive candidates and `●` for already active tools,
68
- without a status suffix. These reflect the state when discovery runs; earlier
69
- results don't update retroactively. Activation results use `✔︎` for success and
70
- `✘︎` for failure. Descriptions stay gray; identifiers remain prominent.
25
+ You configure servers and manage authentication. The assistant discovers
26
+ capabilities, reads resources, and activates tools as needed. You don't need to
27
+ type tool calls or select tools before asking a question.
71
28
 
72
- Expand a tool result to see JSON objects and arrays formatted with two-space
73
- indentation and syntax highlighting. Explicit JSON resource MIME types (including
74
- `application/*+json`) and structured content identify JSON without guessing.
75
- Other explicit MIME types stay plain text; unlabeled text is checked for JSON.
76
-
77
- Formatting changes only the display, not the response sent to the assistant.
78
- Invalid or truncated JSON stays plain text. Results that would exceed formatting
79
- limits also stay plain text. Resource-link MIME types describe the linked content,
80
- not the displayed link label.
81
-
82
- ### Session behavior
83
-
84
- - Tools accumulate rather than rotating with each prompt.
85
- - Resume and branch navigation restore tools activated through `mcp_tools` on
86
- the selected branch. Discovery results never restore tools.
87
- - Compaction retains the acquired tool set. New sessions start fresh.
88
- - Pi uses native deferred loading where supported by the model and provider.
89
- Other providers receive the expanded tool list normally.
90
- - Discovery respects server filters; activation also respects Pi's tool exclusions. An explicit tool
91
- allowlist must include both `mcp_tools` and the native tools you want to load.
92
-
93
- ### Commands
29
+ Use these commands in Pi to manage your connections:
94
30
 
95
31
  | Command | Purpose |
96
32
  | --- | --- |
97
- | `/mcp`, `/mcp list`, `/mcp status` | Show a server status matrix with catalog and loaded-tool counts. |
98
- | `/mcp inspect <server>` | Inspect status and configuration, including disabled servers. Connection values are hidden. |
99
- | `/mcp tools <server>` | Browse the server's tools and inspect descriptions without activating tools. |
100
- | `/mcp reload` | Apply configuration changes without restarting Pi. |
101
- | `/mcp enable <server>` | Enable a server in its effective configuration file. |
102
- | `/mcp disable <server>` | Disable a server, close its connection, and deactivate its tools. |
103
- | `/mcp auth <server>` | Authenticate an OAuth-enabled HTTP server. |
104
- | `/mcp reconnect <server>` | Replace a connection and refresh its catalog. |
105
- | `/mcp refresh <server>` | Refresh a server's catalog without loading additional tools. |
33
+ | `/mcp` | Inspect server status and loaded-tool counts. Idle connections are normal; servers connect on demand. |
34
+ | `/mcp login <server>` | Sign in to an HTTP server. Only this command opens the login browser. |
35
+ | `/mcp reload` | Apply changes after editing your MCP configuration files. |
106
36
 
107
- The status matrix uses glyphs to distinguish idle (`○`), connected (`●`),
108
- connecting (`▶︎`), disabled (`○`), and failed (`✘︎`) servers. Idle is normal:
109
- connections open on demand. A dash (`—`) means the catalog hasn't been fetched,
110
- not that the server has no tools. The **Loaded** column counts tools currently
111
- active for the assistant.
112
-
113
- After refreshing a changed schema, activate the tool again with its exact
114
- identifier to load its current definition. Calls validate the live catalog before execution and refuse removed
115
- or changed tools. The extension does not retry failed tool invocations; after an
116
- interrupted call, check whether the operation completed before trying again.
37
+ Only configure servers you trust: local servers and secret commands run with your
38
+ permissions. Tool activation isn't a per-call approval prompt. See
39
+ [trust and permissions](docs/behavior.md#trust-and-permissions).
117
40
 
118
41
  ## ⚙️ Configuration
119
42
 
120
- Add connections to `~/.pi/agent/mcp.json`, or `.mcp.json` in a trusted project.
121
- These files use the common Claude/Cursor-style `mcpServers` format, not a universal
122
- MCP configuration standard. VS Code's `servers` format and Codex's TOML format
123
- are not supported.
124
-
125
- `PI_CODING_AGENT_DIR` overrides the global Pi directory. Project connections
126
- replace same-named global connections in full; connection fields are not merged.
127
-
128
- ```json
129
- {
130
- "mcpServers": {
131
- "docs": {
132
- "type": "http",
133
- "url": "https://mcp.example.com/mcp",
134
- "headers": {
135
- "Authorization": "Bearer ${DOCS_TOKEN}"
136
- }
137
- },
138
- "local": {
139
- "type": "stdio",
140
- "command": "node",
141
- "args": ["/absolute/path/to/server.js"],
142
- "env": {
143
- "DATABASE_URL": "${DATABASE_URL}"
144
- }
145
- }
146
- }
147
- }
148
- ```
149
-
150
- | Field | Purpose |
151
- | --- | --- |
152
- | `type` | Optional `stdio` or `http`. If omitted, inferred from `command` or `url`. A conflicting type is rejected. |
153
- | `command`, `args` | Executable and arguments for a stdio server. No shell is used. |
154
- | `cwd` | Working directory for stdio; defaults to Pi's current directory. Relative paths resolve there. |
155
- | `env` | Additional environment variables for stdio. |
156
- | `url` | Streamable HTTP endpoint; mutually exclusive with `command`. |
157
- | `headers` | HTTP request headers, including optional bearer authentication. |
158
-
159
- Strings in `command`, `args`, `cwd`, `env`, `url`, and `headers` support `${VAR}`
160
- interpolation. Missing variables prevent that server from connecting.
161
-
162
- Only stdio and Streamable HTTP are supported; `type: "sse"` is rejected rather
163
- than treated as HTTP. Unsupported connection fields cause a configuration error
164
- rather than silently changing their meaning.
165
-
166
- ### Secret commands
167
-
168
- In **`headers` and stdio `env` values only**, a leading `!` runs a secret-generating
169
- shell command when the server connects:
170
-
171
- ```json
172
- {
173
- "mcpServers": {
174
- "example": {
175
- "type": "http",
176
- "url": "https://mcp.example.com/mcp",
177
- "headers": {
178
- "Authorization": "!token=$(op read 'op://Private/Example/token') && printf 'Bearer %s' \"$token\""
179
- }
180
- }
181
- }
182
- }
183
- ```
184
-
185
- These two fields also support Pi-style `$VAR` interpolation, `$$` for a literal
186
- `$`, and `$!` for a literal `!`. Only a leading `!` in the original configuration
187
- triggers execution; interpolated values and command output never do. Shell
188
- commands handle their own variable expansion.
189
-
190
- Commands use `/bin/sh` on Unix or Pi's shell selection on Windows, inherit Pi's
191
- process environment, and run in the server's configured `cwd` (the project
192
- directory by default). They run once per connection, including reconnections,
193
- not during configuration loading, status display, or cached discovery. Cold
194
- searches and activations can connect and therefore execute commands. Concurrent connection
195
- requests share the same resolution.
196
-
197
- The client trims stdout and rejects empty output, nonzero exits, output above
198
- 64 KiB, and resolution taking more than 10 seconds (or a shorter `timeoutMs`).
199
- Session shutdown cancels pending commands. Cancelling an individual search or activation stops
200
- waiting but leaves shared connection work running for other callers. The client
201
- discards command stderr and does not include resolved secrets in errors, session
202
- records, or catalog caches. Commands themselves remain responsible for avoiding
203
- side effects or writing secrets to disk. Only configure commands you trust;
204
- project configuration still requires project trust.
205
-
206
- ### Pi-specific options
207
-
208
- Put descriptions, authentication choices, filters, and timeouts directly in each
209
- `mcpServers.<server>` definition in `~/.pi/agent/mcp.json` (or a trusted project's
210
- `.mcp.json`):
211
-
212
- ```json
213
- {
214
- "mcpServers": {
215
- "docs": {
216
- "type": "http",
217
- "url": "https://mcp.example.com/mcp",
218
- "description": "Search product documentation",
219
- "oauth": true,
220
- "includeTools": ["get_*", "search_*"]
221
- }
222
- }
223
- }
224
- ```
225
-
226
- | Field | Purpose |
227
- | --- | --- |
228
- | `description` | Short capability description for Pi's server directory. |
229
- | `oauth` | Set to `true` to use OAuth instead of an Authorization header on an HTTP connection. |
230
- | `disabled` | Prevent this server from connecting or exposing tools. |
231
- | `includeTools` | Optional allowlist of original MCP tool names; `*` matches any sequence. An empty list exposes nothing. |
232
- | `excludeTools` | Denylist applied after `includeTools`. |
233
- | `timeoutMs` | Request timeout, from 100 to 600000 ms. Defaults: 15 seconds for discovery/HTTP requests, 30 seconds for stdio tool calls. |
234
- | `protocol` | `auto` (default) for SDK protocol-version negotiation, or `legacy` for an explicit legacy handshake. |
235
-
236
- A trusted project's server definition replaces the same-named global definition
237
- in full, including these options. Fields and tool-filter lists are not merged.
238
- Every definition must include a `url` or `command`, even when `disabled` is true.
239
-
240
- These options are specific to Pi MCP Client, not standardized MCP connection
241
- fields. Other clients may reject them when you copy a definition.
242
-
243
- After editing your configuration, run `/mcp reload` to apply it without restarting
244
- Pi. Reload validates the new configuration before replacing the current setup;
245
- invalid configuration leaves the previous setup intact. It closes existing
246
- connections, which reopen on demand, and deactivates tools from changed, removed,
247
- or disabled server definitions. Unchanged active tools remain available.
248
-
249
- To toggle a server without editing JSON, use `/mcp disable <server>` or
250
- `/mcp enable <server>`. The change persists in the trusted project's `.mcp.json`
251
- if that file defines the server; otherwise, it persists in the global
252
- `~/.pi/agent/mcp.json`. Untrusted project files are neither read nor changed.
253
- The command reports which scope changed. It updates only the `disabled` option,
254
- preserves other values (including secret references), and reformats the file as
255
- indented JSON. Repeating a toggle that's already set leaves the file unchanged.
256
-
257
- Both commands wait for active agent work to finish, then apply configuration as
258
- `/mcp reload` does: connections close and reopen on demand, while unchanged active
259
- tools from other servers remain available. Disabling removes the server from
260
- search and deactivates its tools. Enabling does not connect, authenticate, or load
261
- tools; ask the assistant to discover the capabilities you need. Other running Pi
262
- sessions pick up the saved change when they reload their MCP configuration.
263
-
264
- Use `/mcp inspect <server>` to check the effective transport, protocol, filters,
265
- and connection status without connecting or running secret commands. Connection
266
- values—including commands, arguments, URLs, headers, and environment variables—
267
- are hidden because any of them can contain credentials.
268
-
269
- Use `/mcp tools <server>` to fetch the current catalog and browse a scrollable
270
- list. Each row shows the tool name and description, trimmed to the terminal width
271
- with an ellipsis. Select a tool to see a multiline signature and parameter details,
272
- with each parameter in a separate paragraph. Browsing respects your include and
273
- exclude filters and doesn't activate tools or add their schemas to the assistant's
274
- context. This command requires an interactive UI.
275
-
276
- ### Discovery and caching
277
-
278
- Connections start on demand, never while the extension factory loads. A search
279
- without a cached catalog contacts configured servers, with at most four discoveries
280
- in flight. A server-scoped search only contacts that server. Activation discovers
281
- only the servers named by its identifiers, with the same concurrency bound.
282
- Failed servers are reported as unavailable, not mistaken for an empty catalog.
43
+ Store server definitions in `~/.pi/agent/mcp.json` or a trusted project's
44
+ `.mcp.json`. Project definitions replace same-named global definitions in full.
45
+ You can edit these files or use `/mcp add` and `/mcp remove`.
283
46
 
284
- Catalogs are cached privately under `~/.pi/agent/cache/pi-mcp-client/`, keyed by
285
- server configuration and working directory. Disk caches expire after 24 hours.
286
- They contain tool metadata, not configured credentials. Cached discovery and
287
- activation need no connection; invocation refreshes the live catalog before
288
- calling the tool.
289
- Connections remain open until shutdown or explicit reconnection.
47
+ Detailed guides:
290
48
 
291
- When a connected server reports a tool-list change, the extension invalidates its
292
- memory and disk catalogs. The next discovery or activation fetches the current
293
- list, including new or removed tools. Notifications don't replace active tool
294
- definitions: changed schemas require another `mcp_tools({activate: [...]})` before use. Disconnected, cache-only searches
295
- can't receive notifications and still use the 24-hour disk-cache expiry.
296
-
297
- ### OAuth
298
-
299
- Set `"oauth": true` under `mcpServers.<server>` in `mcp.json`, without an
300
- Authorization header in its connection, then run `/mcp auth <server>`. Pi opens the
301
- browser only for this explicit command. Automatic discovery never opens a browser.
302
-
303
- OAuth tokens and client registrations are stored in the operating system
304
- credential store, bound to the server URL and authorization-server issuer.
305
- There is no plaintext credential fallback. PKCE verifiers and callback state stay
306
- in memory.
307
-
308
- The initial implementation supports dynamically registered public clients with a
309
- local callback at `http://127.0.0.1:19847/callback`. The browser must be able to
310
- reach that address on the Pi machine. Authentication times out after two minutes;
311
- you can cancel it with Escape in the terminal UI.
312
- Pre-registered OAuth clients, remote callback pasting, and headless interactive
313
- OAuth are not supported yet. Use bearer headers for headless access.
314
-
315
- ### Trust and permissions
316
-
317
- Only load configuration you trust. Server executables and secret commands run
318
- with your user permissions; trusted project configuration can replace global
319
- connections and settings.
320
-
321
- Server metadata is untrusted. Discovery never activates tools. Explicit
322
- activation exposes schemas but does not approve tool side effects or provide
323
- per-call confirmation. Use tool filters and Pi permission
324
- extensions for additional controls. Cancelling a call does not guarantee that the
325
- server rolled back its effects.
49
+ - [Configuration](docs/configuration.md): HTTP and stdio servers, environment
50
+ variables, secret commands, tool filters, and timeouts.
51
+ - [Authentication](docs/authentication.md): OAuth setup, pre-registered clients,
52
+ remote login, and logout.
53
+ - [Commands](docs/commands.md): Server management, tool browsing, and resource
54
+ watches. These are commands **you** run in Pi.
55
+ - [Tool reference](docs/tool-reference.md): Discovery, activation, resource reads,
56
+ and argument completions. This is the **assistant's** interface, not a user API.
57
+ - [Behavior](docs/behavior.md): Sessions, caching, result display, and permissions.
58
+ - [Troubleshooting](docs/troubleshooting.md): Error codes, recovery, and large
59
+ results.
326
60
 
327
61
  ## 🧰 Requirements
328
62
 
@@ -332,71 +66,6 @@ server rolled back its effects.
332
66
  - An available OS credential store for OAuth. Linux requires a working Secret
333
67
  Service/keyring session.
334
68
 
335
- This extension uses `@modelcontextprotocol/client` 2.0.0 and defaults to automatic
336
- SDK protocol-version negotiation. On stdio, negotiation probes using an additional
337
- short-lived process. Set `"protocol": "legacy"` in a server definition if that
338
- server requires an explicit legacy handshake.
339
-
340
- ## 🩺 Troubleshooting
341
-
342
- Start with `/mcp`. Failures use a consistent code, a short explanation, and a
343
- recovery hint, for example:
344
-
345
- ```text
346
- linear: [authentication_required] Authentication is required. Run /mcp auth linear.
347
- ```
348
-
349
- Search and tool results also carry structured diagnostics in their result details:
350
- `code`, `operation`, optional `server`, `message`, and `hint`. Partial discovery
351
- keeps healthy servers' results and identifies servers it could not search. An
352
- unavailable server is not an empty catalog.
353
-
354
- | Code | What to check |
355
- | --- | --- |
356
- | `configuration_invalid` | JSON syntax, supported fields, transport type, and required environment variables. Reload Pi after editing. |
357
- | `authentication_required` | Run `/mcp auth <server>` for OAuth, or check the Authorization header. |
358
- | `permission_denied` | Account permissions, OAuth scopes, and service access policy. |
359
- | `credential_store_unavailable` | Unlock or enable the OS keyring; Linux needs a Secret Service session. |
360
- | `secret_lookup_failed` | Secret helper installation, login, exit status, nonempty stdout, and output size. |
361
- | `connection_failed` | Server executable, working directory, endpoint, network, and TLS configuration. |
362
- | `timeout` | Server responsiveness and the applicable request, secret-command, or OAuth time limit. |
363
- | `protocol_error` | Server compatibility and the `protocol` setting. |
364
- | `tool_changed` | Server filters and the current tool schema; activate the exact identifier again. Reload Pi if connection configuration changed. |
365
- | `tool_error` | The server's tool result and inputs; verify the outcome before retrying. |
366
- | `oauth_failed` | Browser access to the callback and support for dynamically registered public clients. |
367
- | `callback_unavailable` | Another process using local port 19847. |
368
- | `busy` | Wait for discovery to finish before reconnecting. |
369
- | `cancelled` | Retry when ready; verify any interrupted tool operation first. |
370
- | `operation_failed` | An unclassified failure; inspect server status and configuration. |
371
-
372
- Diagnostics never echo raw exception messages, HTTP bodies, command stderr,
373
- credential values, or stack traces. Unknown errors stay generic rather than
374
- being classified by potentially sensitive message text. Tool-call failures are
375
- not replayed automatically; verify the outcome before retrying. Server-provided tool
376
- results remain visible as content, even when the tool reports an error; they are
377
- not sanitized transport diagnostics.
378
-
379
- ### Large results
380
-
381
- Text results are limited to 2,000 lines or 50 KiB. Larger results are saved as
382
- private temporary JSON files, with their paths included in the output. Supported
383
- images pass through within an 8 MiB base64 budget; other binary content is kept in
384
- the full result file. Temporary result files are not automatically deleted and
385
- may contain sensitive data.
386
-
387
- ### v0.1 scope
388
-
389
- The first release focuses on tools. Legacy SSE transport, MCP Apps, resource
390
- browsing, prompt commands, roots, sampling, and elicitation are not supported.
391
- See the [post-v0.1 backlog](https://github.com/mavam/pi-mcp-client/blob/main/TODO.md)
392
- for follow-up work; it is not a release commitment.
393
-
394
- ## 🧹 Uninstall
395
-
396
- ```sh
397
- pi remove npm:pi-mcp-client
398
- ```
399
-
400
69
  ## 📄 License
401
70
 
402
71
  [MIT](LICENSE)