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 +33 -364
- package/dist/index.js +2216 -1091
- package/docs/authentication.md +175 -0
- package/docs/behavior.md +114 -0
- package/docs/commands.md +171 -0
- package/docs/configuration.md +150 -0
- package/docs/tool-reference.md +147 -0
- package/docs/troubleshooting.md +67 -0
- package/package.json +2 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Authentication
|
|
2
|
+
|
|
3
|
+
[Back to the README](../README.md)
|
|
4
|
+
|
|
5
|
+
You manage authentication through `/mcp login` and `/mcp logout`. The assistant
|
|
6
|
+
can't initiate an OAuth login: only your explicit login command opens the browser.
|
|
7
|
+
For externally managed bearer tokens, use
|
|
8
|
+
[headers and secret commands](configuration.md#secret-commands) instead.
|
|
9
|
+
|
|
10
|
+
## Sign in with OAuth
|
|
11
|
+
|
|
12
|
+
Add the HTTP server, then log in:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
/mcp add --scope global slack https://mcp.slack.com/mcp
|
|
16
|
+
/mcp login slack
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Login uses the effective server definition (the trusted project override, if
|
|
20
|
+
present; otherwise the global definition) and starts the SDK's OAuth discovery
|
|
21
|
+
and authorization flow. It doesn't change configuration files. Adding a server
|
|
22
|
+
still doesn't connect or open a browser.
|
|
23
|
+
|
|
24
|
+
HTTP servers use automatic authentication by default:
|
|
25
|
+
|
|
26
|
+
- Configured Authorization headers take precedence over OAuth.
|
|
27
|
+
- Otherwise, connections reuse stored OAuth tokens when available. The SDK
|
|
28
|
+
handles authentication challenges and refreshes existing grants.
|
|
29
|
+
- Without a grant, an authentication challenge asks you to run `/mcp login`.
|
|
30
|
+
Discovery and tool calls never register a new client or open a browser.
|
|
31
|
+
- A missing or locked keyring doesn't block public servers. If the server
|
|
32
|
+
requires OAuth, an unavailable keyring is an error; no credentials are stored
|
|
33
|
+
outside the OS credential store.
|
|
34
|
+
|
|
35
|
+
The `oauth` configuration field and `--oauth` switch aren't supported. Remove
|
|
36
|
+
these from existing definitions and commands; HTTP authentication is automatic.
|
|
37
|
+
|
|
38
|
+
If the server uses an Authorization header, login asks you to remove that header
|
|
39
|
+
before switching to OAuth; it never replaces existing header credentials.
|
|
40
|
+
Stdio servers manage their own authentication and don't support OAuth login.
|
|
41
|
+
|
|
42
|
+
The extension supports public clients with dynamic registration or a
|
|
43
|
+
pre-registered client ID. Both use PKCE and a loopback callback at
|
|
44
|
+
`http://127.0.0.1:19847/callback` by default. Normal login opens a local listener
|
|
45
|
+
that your browser must be able to reach.
|
|
46
|
+
|
|
47
|
+
Authentication times out after two minutes; you can cancel it with Escape in the
|
|
48
|
+
terminal UI. Explicit login always starts a fresh authorization flow, even if a
|
|
49
|
+
refresh token is already stored. The browser callback page identifies **Pi MCP
|
|
50
|
+
Client** and asks you to return to Pi; receiving a callback doesn't yet mean the
|
|
51
|
+
token exchange succeeded.
|
|
52
|
+
|
|
53
|
+
OAuth tokens and client registrations are stored in the operating system
|
|
54
|
+
credential store, bound to the server URL, configured client ID (if any), and
|
|
55
|
+
authorization-server issuer. There is no plaintext credential fallback. PKCE
|
|
56
|
+
verifiers and callback state stay in memory. Linux requires a working Secret
|
|
57
|
+
Service/keyring session.
|
|
58
|
+
|
|
59
|
+
### Upgrade from earlier versions
|
|
60
|
+
|
|
61
|
+
Credentials now use an identity based only on the server URL and optional client
|
|
62
|
+
ID. Earlier credential-store entries aren't migrated or deleted. Run
|
|
63
|
+
`/mcp login <server>` again after upgrading; revoke old grants at the service if
|
|
64
|
+
needed. Changing scopes or the callback port doesn't select a different store.
|
|
65
|
+
|
|
66
|
+
## Use a pre-registered client
|
|
67
|
+
|
|
68
|
+
For a server without dynamic registration, register a **public/native** client
|
|
69
|
+
with the service, using the exact callback URL and token endpoint authentication
|
|
70
|
+
method `none`. Then configure its client ID:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"example": {
|
|
76
|
+
"url": "https://mcp.example.com/mcp",
|
|
77
|
+
"oauthClientId": "${EXAMPLE_OAUTH_CLIENT_ID}"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Run `/mcp reload`, then `/mcp login example`. The configured ID is used for login,
|
|
84
|
+
token refresh, and revocation; the extension never falls back to dynamic
|
|
85
|
+
registration if it is rejected. `/mcp get example` identifies the client as
|
|
86
|
+
pre-registered without printing the ID.
|
|
87
|
+
|
|
88
|
+
Changing the client ID selects separate credentials and requires a new login.
|
|
89
|
+
Log out before changing or removing the ID if you want to delete its old
|
|
90
|
+
credentials. After the first successful grant, a pre-registered client is pinned
|
|
91
|
+
to its authorization-server issuer. If that issuer changes, verify the server
|
|
92
|
+
configuration before logging out and logging in again to trust the replacement.
|
|
93
|
+
|
|
94
|
+
## Set scopes and callback ports
|
|
95
|
+
|
|
96
|
+
Configure scopes and a callback port in the server definition:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"example": {
|
|
102
|
+
"url": "https://mcp.example.com/mcp",
|
|
103
|
+
"oauthScopes": ["read", "write"],
|
|
104
|
+
"oauthCallbackPort": 19848
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Or set them when adding the server:
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
/mcp add --scope global --oauth-scope read --oauth-scope write --oauth-callback-port 19848 example https://mcp.example.com/mcp
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The callback becomes `http://127.0.0.1:19848/callback`. Pre-registered clients must
|
|
117
|
+
allow that exact URL. The listener stays bound to loopback; arbitrary callback
|
|
118
|
+
hosts and paths aren't supported. If the port is occupied, choose another port or
|
|
119
|
+
use manual login.
|
|
120
|
+
|
|
121
|
+
Scopes are case-sensitive OAuth tokens, each up to 256 characters, without spaces,
|
|
122
|
+
quotes, or backslashes. Omit `oauthScopes` to retain SDK/server-driven selection;
|
|
123
|
+
an empty array is rejected. The SDK may also request `offline_access` when the
|
|
124
|
+
service advertises refresh-token support. Requested scopes aren't a guarantee of
|
|
125
|
+
granted permissions or a per-tool permission policy.
|
|
126
|
+
|
|
127
|
+
After changing these options, run `/mcp reload`, then `/mcp login example`.
|
|
128
|
+
Changing configuration never starts authorization or revokes existing grants.
|
|
129
|
+
Scopes and callback ports don't select separate credential stores: definitions
|
|
130
|
+
sharing a URL and client ID still share credentials. Explicit login renews a
|
|
131
|
+
dynamic registration when its requested options change. `/mcp get example` shows
|
|
132
|
+
the requested scopes and callback address without connecting.
|
|
133
|
+
|
|
134
|
+
## Sign in remotely or without launching a browser
|
|
135
|
+
|
|
136
|
+
When Pi runs over SSH, or you don't want it to launch a browser, use:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
/mcp login example --no-browser
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
1. Open the authorization URL shown in Pi's interactive dialog in your browser.
|
|
143
|
+
2. Complete sign-in. The browser may show a connection error at the loopback
|
|
144
|
+
callback address; this is expected when the browser and Pi run on different
|
|
145
|
+
machines.
|
|
146
|
+
3. Copy the full callback URL from the browser's address bar and paste it into
|
|
147
|
+
the **Callback URL** dialog in Pi, not into chat or a slash command.
|
|
148
|
+
|
|
149
|
+
Manual login doesn't open a browser or bind a callback port. The extension
|
|
150
|
+
validates the callback address, state, and authorization response before
|
|
151
|
+
exchanging the code. It doesn't write authorization URLs or pasted callbacks to
|
|
152
|
+
session entries, catalogs, notifications, or logs. Treat the callback URL as
|
|
153
|
+
sensitive; your browser history and clipboard may still contain it.
|
|
154
|
+
|
|
155
|
+
`--no-browser` still requires an interactive UI and an available OS credential
|
|
156
|
+
store. It isn't unattended authentication: print and JSON modes refuse OAuth
|
|
157
|
+
login. Use externally managed bearer headers for unattended access. Confidential
|
|
158
|
+
clients requiring a client secret aren't supported yet.
|
|
159
|
+
|
|
160
|
+
## Sign out
|
|
161
|
+
|
|
162
|
+
Run `/mcp logout <server>` to remove stored tokens and client registrations. Logout
|
|
163
|
+
also closes connections and deactivates tools for OAuth servers sharing
|
|
164
|
+
the same URL and configured client ID, since they share credentials. Configuration
|
|
165
|
+
and enabled state stay unchanged. Disabled servers accept logout too. Header and
|
|
166
|
+
server-managed credentials remain untouched.
|
|
167
|
+
|
|
168
|
+
Local removal happens before a bounded attempt to revoke tokens at the original
|
|
169
|
+
authorization server. The result distinguishes accepted revocation, unsupported
|
|
170
|
+
revocation, and unconfirmed revocation. When revocation isn't confirmed, remove the
|
|
171
|
+
grant at the service if needed. Repeating logout is safe. Other running Pi sessions
|
|
172
|
+
may need to reconnect; logout cannot recall requests already sent to a server.
|
|
173
|
+
|
|
174
|
+
Removing a server definition doesn't remove its credentials. Log out before
|
|
175
|
+
[removing the definition](commands.md#add-and-remove-servers) if you want both.
|
package/docs/behavior.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Behavior and permissions
|
|
2
|
+
|
|
3
|
+
[Back to the README](../README.md)
|
|
4
|
+
|
|
5
|
+
This page explains how the extension manages state and displays results. For the
|
|
6
|
+
assistant's tool-call interface, see the [tool reference](tool-reference.md).
|
|
7
|
+
|
|
8
|
+
## Sessions
|
|
9
|
+
|
|
10
|
+
- Active tools accumulate rather than rotating with each prompt.
|
|
11
|
+
- Resume and branch navigation restore tools activated through `mcp_tools` on
|
|
12
|
+
the selected branch. Discovery results never restore tools.
|
|
13
|
+
- Compaction retains the acquired tool set. New sessions start fresh.
|
|
14
|
+
- Pi uses native deferred loading where supported by the model and provider.
|
|
15
|
+
Other providers receive the expanded tool list normally.
|
|
16
|
+
- Discovery respects server filters; activation also respects Pi's tool exclusions.
|
|
17
|
+
An explicit tool allowlist must include both `mcp_tools` and the native tools
|
|
18
|
+
the assistant needs to load.
|
|
19
|
+
|
|
20
|
+
## Resource snapshots
|
|
21
|
+
|
|
22
|
+
Resource reads never start OAuth login, follow links in resource bodies, or
|
|
23
|
+
subscribe to live updates. Repeated reads fetch fresh content; earlier results
|
|
24
|
+
stay as snapshots. Resuming a session or navigating its branches doesn't re-read
|
|
25
|
+
resources. Watches have their own
|
|
26
|
+
[memory-only lifecycle](commands.md#watch-resource-changes) and never fetch content
|
|
27
|
+
automatically.
|
|
28
|
+
|
|
29
|
+
Resource content and selected metadata, including URIs, become session data and
|
|
30
|
+
may be sensitive. [Private spill files](troubleshooting.md#large-results) can also
|
|
31
|
+
contain sensitive data and aren't automatically deleted.
|
|
32
|
+
|
|
33
|
+
## Discovery and caching
|
|
34
|
+
|
|
35
|
+
Connections start on demand, never while the extension factory loads. A search
|
|
36
|
+
without the requested cached metadata contacts configured servers, with at most
|
|
37
|
+
four server discoveries in flight. A server-scoped search only contacts that
|
|
38
|
+
server. Activation discovers only the servers named by its identifiers, with the
|
|
39
|
+
same concurrency bound. Failed servers are reported as unavailable, not mistaken
|
|
40
|
+
for an empty catalog.
|
|
41
|
+
|
|
42
|
+
Tool catalogs are cached privately under `~/.pi/agent/cache/pi-mcp-client/`, keyed
|
|
43
|
+
by server configuration and working directory. Disk caches expire after 24 hours.
|
|
44
|
+
They contain tool metadata, not configured credentials. Cached tool-only discovery
|
|
45
|
+
and activation need no connection; invocation refreshes the live catalog before
|
|
46
|
+
calling the tool.
|
|
47
|
+
|
|
48
|
+
Resource metadata, including template catalogs, is held only in memory for up to
|
|
49
|
+
five minutes, not written to the tool catalog cache. Mixed discovery therefore
|
|
50
|
+
may connect even when tools are cached on disk. Resource-list notifications,
|
|
51
|
+
disconnection, and explicit refresh invalidate resource metadata without reading
|
|
52
|
+
content. Tool and resource catalog failures are reported independently; healthy
|
|
53
|
+
candidates remain available. The SDK handles pagination. Resource catalogs are
|
|
54
|
+
limited to 10,000 entries and 4 MiB of descriptor data; oversized catalogs fail
|
|
55
|
+
rather than silently returning a partial list. Reads bypass the SDK content cache.
|
|
56
|
+
Connections remain open until shutdown or an explicit lifecycle action such as
|
|
57
|
+
reconnection or configuration reload.
|
|
58
|
+
|
|
59
|
+
When a connected server reports a tool-list change, the extension invalidates its
|
|
60
|
+
memory and disk catalogs. The next discovery or activation fetches the current
|
|
61
|
+
list, including new or removed tools. Notifications don't replace active tool
|
|
62
|
+
definitions: the assistant must activate changed schemas again before use. Calls
|
|
63
|
+
validate the live catalog before execution and refuse removed or changed tools.
|
|
64
|
+
Disconnected, cache-only searches can't receive notifications and still use the
|
|
65
|
+
24-hour disk-cache expiry.
|
|
66
|
+
|
|
67
|
+
## Result display
|
|
68
|
+
|
|
69
|
+
The UI labels discovery calls **mcp discover**, activation calls **mcp activate**,
|
|
70
|
+
resource reads **mcp read**, and argument completions **mcp complete**.
|
|
71
|
+
|
|
72
|
+
Discovery rows show `○` for inactive candidates and `●` for already active tools,
|
|
73
|
+
without a status suffix. These reflect the state when discovery runs; earlier
|
|
74
|
+
results don't update retroactively. Activation results use `✔︎` for success and
|
|
75
|
+
`✘︎` for failure. Descriptions stay gray; identifiers remain prominent.
|
|
76
|
+
|
|
77
|
+
Exact and template reads use the same compact status row:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
mcp read
|
|
81
|
+
✔︎ warehouse · schema://tables/events
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Expand a tool result to see JSON objects and arrays formatted with two-space
|
|
85
|
+
indentation and syntax highlighting. Explicit JSON resource MIME types (including
|
|
86
|
+
`application/*+json`) and structured content identify JSON without guessing.
|
|
87
|
+
Other explicit MIME types stay plain text; unlabeled text is checked for JSON.
|
|
88
|
+
|
|
89
|
+
Formatting changes only the display, not the response sent to the assistant.
|
|
90
|
+
Invalid or truncated JSON stays plain text. Results that would exceed formatting
|
|
91
|
+
limits also stay plain text. Resource-link MIME types describe the linked content,
|
|
92
|
+
not the displayed link label. Supported images use the existing result display;
|
|
93
|
+
see [large results](troubleshooting.md#large-results) for size limits.
|
|
94
|
+
|
|
95
|
+
## Trust and permissions
|
|
96
|
+
|
|
97
|
+
Only load configuration you trust. Server executables and secret commands run
|
|
98
|
+
with your user permissions; trusted project configuration can replace global
|
|
99
|
+
connections and settings.
|
|
100
|
+
|
|
101
|
+
Server metadata and resource content are untrusted data. Discovery never
|
|
102
|
+
activates tools. Explicit activation exposes schemas but doesn't approve tool
|
|
103
|
+
side effects or provide per-call confirmation. Use tool filters and Pi permission
|
|
104
|
+
extensions for additional controls. Cancelling a call doesn't guarantee that the
|
|
105
|
+
server rolled back its effects. The extension doesn't retry failed tool
|
|
106
|
+
invocations; verify an interrupted operation's outcome before trying again.
|
|
107
|
+
|
|
108
|
+
`includeTools` and `excludeTools` apply only to tools, not resources. Keeping
|
|
109
|
+
`mcp_tools` available permits resource reads from enabled servers, subject to the
|
|
110
|
+
server's authorization. `kind: "tools"` filters one search; it isn't an access
|
|
111
|
+
restriction. Disable a server to prevent all access, or exclude `mcp_tools` through
|
|
112
|
+
Pi's tool restrictions to prevent discovery and resource operations. Already active
|
|
113
|
+
native tools have their own tool restrictions. Per-resource permission policies
|
|
114
|
+
aren't implemented.
|
package/docs/commands.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Commands
|
|
2
|
+
|
|
3
|
+
[Back to the README](../README.md)
|
|
4
|
+
|
|
5
|
+
These are commands **you run in Pi**, not tools the assistant calls. Use them to
|
|
6
|
+
manage servers, inspect capabilities, and watch resource changes. The assistant's
|
|
7
|
+
separate interface is documented in the [tool reference](tool-reference.md).
|
|
8
|
+
|
|
9
|
+
## Command reference
|
|
10
|
+
|
|
11
|
+
| Command | Purpose |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `/mcp`, `/mcp list`, `/mcp status` | Show a server status matrix with catalog and loaded-tool counts. |
|
|
14
|
+
| `/mcp add --scope <scope> [options] <server> <url>` | Save an HTTP server without connecting. For stdio, use `<server> -- <command> [args...]`. |
|
|
15
|
+
| `/mcp remove --scope <scope> <server>` | Remove a definition from the selected scope, retaining credentials. |
|
|
16
|
+
| `/mcp get <server>` | Inspect status and configuration, including disabled servers. Connection values are hidden. |
|
|
17
|
+
| `/mcp tools <server>` | Browse the server's tools and inspect descriptions without activating tools. |
|
|
18
|
+
| `/mcp reload` | Apply configuration changes without restarting Pi. |
|
|
19
|
+
| `/mcp enable <server>` | Enable a server in its effective configuration file. |
|
|
20
|
+
| `/mcp disable <server>` | Disable a server, close its connection, and deactivate its tools. |
|
|
21
|
+
| `/mcp login <server> [--no-browser]` | Authenticate an HTTP server without changing its configuration; optionally paste the callback URL in an interactive dialog. |
|
|
22
|
+
| `/mcp logout <server>` | Remove local OAuth credentials and attempt remote revocation, including for disabled servers. |
|
|
23
|
+
| `/mcp reconnect <server>` | Replace a connection and refresh its catalog. |
|
|
24
|
+
| `/mcp refresh <server>` | Refresh tool and resource metadata without reading resources or loading additional tools. |
|
|
25
|
+
| `/mcp subscribe <server> <uri>` | Watch changes to one exact resource URI without fetching content. |
|
|
26
|
+
| `/mcp unsubscribe <server> <uri>` | Stop watching one resource. |
|
|
27
|
+
| `/mcp subscriptions` | List active resource watches and their change markers. |
|
|
28
|
+
|
|
29
|
+
See [Authentication](authentication.md) for login and logout procedures, and
|
|
30
|
+
[Apply changes](configuration.md#apply-changes) for reload behavior.
|
|
31
|
+
|
|
32
|
+
## Inspect servers and tools
|
|
33
|
+
|
|
34
|
+
The `/mcp` status matrix distinguishes idle (`○`), connected (`●`), connecting
|
|
35
|
+
(`▶︎`), disabled (`○`), and failed (`✘︎`) servers. Idle is normal: connections open
|
|
36
|
+
on demand. A dash (`—`) means the catalog hasn't been fetched, not that the server
|
|
37
|
+
has no tools. The **Loaded** column counts tools currently active for the
|
|
38
|
+
assistant.
|
|
39
|
+
|
|
40
|
+
Use `/mcp get <server>` to check the effective transport, protocol, filters,
|
|
41
|
+
and connection status without connecting or running secret commands. Connection
|
|
42
|
+
values—including commands, arguments, URLs, headers, and environment variables—
|
|
43
|
+
are hidden because any of them can contain credentials. Authentication status
|
|
44
|
+
shows whether OAuth tokens are stored, not whether they are valid. A locked or
|
|
45
|
+
unavailable credential store is reported separately from missing tokens. Header
|
|
46
|
+
and stdio credentials are identified as externally managed; inspection never
|
|
47
|
+
executes them.
|
|
48
|
+
|
|
49
|
+
Use `/mcp tools <server>` to fetch the current catalog and browse a scrollable
|
|
50
|
+
list. Rows show tool names and descriptions, trimmed to the terminal width with
|
|
51
|
+
an ellipsis. Select a tool to see a multiline signature and parameter details,
|
|
52
|
+
with each parameter in a separate paragraph. Browsing respects your include and
|
|
53
|
+
exclude filters and doesn't activate tools or add their schemas to the assistant's
|
|
54
|
+
context. This command requires an interactive UI.
|
|
55
|
+
|
|
56
|
+
Refreshing a catalog doesn't replace active tool definitions. After a schema
|
|
57
|
+
change, ask the assistant to activate the exact tool again. See
|
|
58
|
+
[tool changes and caching](behavior.md#discovery-and-caching). Failed tool calls
|
|
59
|
+
aren't retried automatically; verify whether an interrupted operation completed
|
|
60
|
+
before trying again.
|
|
61
|
+
|
|
62
|
+
## Enable and disable servers
|
|
63
|
+
|
|
64
|
+
Use `/mcp disable <server>` or `/mcp enable <server>` to change the `disabled`
|
|
65
|
+
option without editing JSON. The command reports which scope changed: the trusted
|
|
66
|
+
project's `.mcp.json` if it defines the server, otherwise the global
|
|
67
|
+
`~/.pi/agent/mcp.json`. Untrusted project files are neither read nor changed.
|
|
68
|
+
|
|
69
|
+
Toggles preserve other values, including secret references, and reformat the file
|
|
70
|
+
as indented JSON. Repeating a toggle that's already set leaves the file unchanged.
|
|
71
|
+
Both commands wait for active agent work to finish, then
|
|
72
|
+
[apply the configuration](configuration.md#apply-changes).
|
|
73
|
+
|
|
74
|
+
Disabling removes the server from discovery and deactivates its tools. Enabling
|
|
75
|
+
doesn't connect, authenticate, or load tools; ask the assistant to discover the
|
|
76
|
+
capabilities you need.
|
|
77
|
+
|
|
78
|
+
## Add and remove servers
|
|
79
|
+
|
|
80
|
+
Both commands require an explicit `--scope global` or `--scope project`:
|
|
81
|
+
|
|
82
|
+
- **Global:** `~/.pi/agent/mcp.json`.
|
|
83
|
+
- **Project:** `.mcp.json` in the current trusted project. Untrusted project files
|
|
84
|
+
are neither read nor changed.
|
|
85
|
+
|
|
86
|
+
Add an HTTP server by URL, or a stdio server after `--`:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
/mcp add --scope global docs https://docs.mcp.cloudflare.com/mcp
|
|
90
|
+
/mcp add --scope project local -- node "/path with spaces/server.js"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Put options before the server name. `--transport http` or `--transport stdio` is
|
|
94
|
+
optional; the URL form selects HTTP and the `--` form selects stdio. Arguments
|
|
95
|
+
support single and double quotes and backslash escaping, but are never evaluated
|
|
96
|
+
by a shell. Shell syntax such as `$(...)`, pipes, and globs stays literal. For
|
|
97
|
+
Windows paths with backslashes, single quotes preserve the path verbatim.
|
|
98
|
+
|
|
99
|
+
| Option | Purpose |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `--replace` | Replace the complete definition in the selected scope, or create an override of a same-named definition in the other scope. Existing fields aren't merged. |
|
|
102
|
+
| `--header 'Name: value'` | Add an HTTP header. Repeat for different header names. |
|
|
103
|
+
| `--env KEY=value` | Add a stdio environment override. Repeat for different variable names. |
|
|
104
|
+
| `--oauth-client-id ID` | Use a pre-registered public client. |
|
|
105
|
+
| `--oauth-scope SCOPE` | Request an OAuth scope. Repeat for additional scopes. |
|
|
106
|
+
| `--oauth-callback-port PORT` | Set the loopback callback port. |
|
|
107
|
+
|
|
108
|
+
Retain environment references rather than typing tokens:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
/mcp add --scope global --header 'Authorization: Bearer ${DOCS_TOKEN}' docs https://mcp.example.com/mcp
|
|
112
|
+
/mcp add --scope global --oauth-client-id '${CLIENT_ID}' service https://mcp.example.com/mcp
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Define referenced environment variables before running the command. Validation
|
|
116
|
+
checks the resolved configuration, but saves the references, not their values.
|
|
117
|
+
Secret commands in headers or environment overrides are saved without running
|
|
118
|
+
them. Avoid literal credentials in command input or project files; use
|
|
119
|
+
[environment references and secret commands](configuration.md#secret-commands).
|
|
120
|
+
|
|
121
|
+
Adding never starts a server, opens a browser, or activates tools. Duplicate names
|
|
122
|
+
in global or trusted project configuration are rejected unless you supply
|
|
123
|
+
`--replace`. Project definitions take precedence; writing a global definition
|
|
124
|
+
doesn't replace a project override. Other server options, such as tool filters,
|
|
125
|
+
remain available by editing the configuration file.
|
|
126
|
+
|
|
127
|
+
Remove a definition from a specific scope:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
/mcp remove --scope project local
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Removal is distinct from disabling and logout: it deletes the selected definition,
|
|
134
|
+
not its OAuth credentials. Run `/mcp logout <server>` first if you also want to
|
|
135
|
+
remove credentials. Removing a project override exposes any same-named global
|
|
136
|
+
definition; the command reports when a definition in the other scope remains.
|
|
137
|
+
Removing a name absent from the selected scope fails without changing either file.
|
|
138
|
+
|
|
139
|
+
Successful edits [apply immediately](configuration.md#apply-changes). Writes
|
|
140
|
+
preserve unrelated settings, follow existing file symlinks, and replace files
|
|
141
|
+
atomically. New files are private; existing file permissions are preserved. If
|
|
142
|
+
global and project configuration point to the same file, scoped edits are refused
|
|
143
|
+
until you separate them. Empty configuration files are retained rather than deleted.
|
|
144
|
+
|
|
145
|
+
## Watch resource changes
|
|
146
|
+
|
|
147
|
+
Subscriptions are explicit user commands, not model-facing tool operations:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
/mcp subscribe warehouse schema://tables/events
|
|
151
|
+
/mcp subscriptions
|
|
152
|
+
/mcp unsubscribe warehouse schema://tables/events
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Use an exact absolute URI from discovery, a template read, or a resource link.
|
|
156
|
+
The configured server must support resource subscriptions. The extension uses the
|
|
157
|
+
SDK's negotiated protocol: legacy resource subscriptions or modern filtered
|
|
158
|
+
streams. It never opens the URI as a file or generic URL.
|
|
159
|
+
|
|
160
|
+
An update marks the watch as changed (`↻`) and shows a UI notification. Repeated
|
|
161
|
+
updates coalesce into that marker until you unsubscribe. No content is fetched,
|
|
162
|
+
no model turn starts, and existing resource results remain unchanged. Ask the
|
|
163
|
+
assistant to read the resource for a new snapshot; unsubscribe and subscribe again
|
|
164
|
+
to reset the change marker.
|
|
165
|
+
|
|
166
|
+
Watches are memory-only, limited to 50 per server connection, and require an
|
|
167
|
+
interactive UI (TUI or RPC). Repeating a subscribe command is idempotent. Session
|
|
168
|
+
replacement, tree navigation, configuration reload, disconnection, and exit clear
|
|
169
|
+
the affected watches. They are never restored or automatically retried; use
|
|
170
|
+
`/mcp subscriptions` to inspect active watches. Cancellation and connection
|
|
171
|
+
failures can leave an uncertain server-side outcome; cleanup is best-effort.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
[Back to the README](../README.md)
|
|
4
|
+
|
|
5
|
+
You configure which servers the assistant can access. Add connections to
|
|
6
|
+
`~/.pi/agent/mcp.json`, or `.mcp.json` in a trusted project. For command-based
|
|
7
|
+
setup, see [Add and remove servers](commands.md#add-and-remove-servers).
|
|
8
|
+
|
|
9
|
+
## Files and transports
|
|
10
|
+
|
|
11
|
+
The files use the common Claude/Cursor-style `mcpServers` format, not a universal
|
|
12
|
+
MCP configuration standard. VS Code's `servers` format and Codex's TOML format
|
|
13
|
+
aren't supported. `PI_CODING_AGENT_DIR` overrides the global Pi directory.
|
|
14
|
+
Project definitions replace same-named global definitions in full; fields and
|
|
15
|
+
filters aren't merged. Untrusted project files are neither read nor changed.
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"mcpServers": {
|
|
20
|
+
"docs": {
|
|
21
|
+
"url": "https://mcp.example.com/mcp",
|
|
22
|
+
"headers": {
|
|
23
|
+
"Authorization": "Bearer ${DOCS_TOKEN}"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"local": {
|
|
27
|
+
"command": "node",
|
|
28
|
+
"args": ["/absolute/path/to/server.js"],
|
|
29
|
+
"env": {
|
|
30
|
+
"DATABASE_URL": "${DATABASE_URL}"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
| Field | Purpose |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| `type` | Optional `stdio` or `http`. If omitted, inferred from `command` or `url`. A conflicting type is rejected. |
|
|
40
|
+
| `command`, `args` | Executable and arguments for a stdio server. No shell is used. |
|
|
41
|
+
| `cwd` | Working directory for stdio; defaults to Pi's current directory. Relative paths resolve there. |
|
|
42
|
+
| `env` | Additional environment variables for stdio. |
|
|
43
|
+
| `url` | Streamable HTTP endpoint; mutually exclusive with `command`. |
|
|
44
|
+
| `headers` | HTTP request headers, including optional bearer authentication. |
|
|
45
|
+
|
|
46
|
+
Strings in `command`, `args`, `cwd`, `env`, `url`, and `headers` support `${VAR}`
|
|
47
|
+
interpolation. Missing variables prevent that server from connecting.
|
|
48
|
+
|
|
49
|
+
Only stdio and Streamable HTTP are supported. The extension rejects `type: "sse"`
|
|
50
|
+
and unsupported connection fields rather than silently changing their meaning.
|
|
51
|
+
|
|
52
|
+
The extension uses `@modelcontextprotocol/client` 2.0.0 and defaults to automatic
|
|
53
|
+
SDK protocol-version negotiation. On stdio, negotiation probes using an additional
|
|
54
|
+
short-lived process. Set `"protocol": "legacy"` if the server requires an explicit
|
|
55
|
+
legacy handshake.
|
|
56
|
+
|
|
57
|
+
## Secret commands
|
|
58
|
+
|
|
59
|
+
In **`headers` and stdio `env` values only**, a leading `!` runs a secret-generating
|
|
60
|
+
shell command when the server connects:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"mcpServers": {
|
|
65
|
+
"example": {
|
|
66
|
+
"url": "https://mcp.example.com/mcp",
|
|
67
|
+
"headers": {
|
|
68
|
+
"Authorization": "!token=$(op read 'op://Private/Example/token') && printf 'Bearer %s' \"$token\""
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
These two fields also support Pi-style `$VAR` interpolation, `$$` for a literal
|
|
76
|
+
`$`, and `$!` for a literal `!`. Only a leading `!` in the original configuration
|
|
77
|
+
triggers execution; interpolated values and command output never do. Shell
|
|
78
|
+
commands handle their own variable expansion.
|
|
79
|
+
|
|
80
|
+
Commands use `/bin/sh` on Unix or Pi's shell selection on Windows, inherit Pi's
|
|
81
|
+
process environment, and run in the server's configured `cwd` (the project
|
|
82
|
+
directory by default). They run once per connection, including reconnections,
|
|
83
|
+
not during configuration loading, status display, or cached discovery. Cold
|
|
84
|
+
searches and activations can connect and therefore execute commands. Concurrent
|
|
85
|
+
connection requests share the same resolution.
|
|
86
|
+
|
|
87
|
+
The extension trims stdout and rejects empty output, nonzero exits, output above
|
|
88
|
+
64 KiB, and resolution taking more than 10 seconds (or a shorter `timeoutMs`).
|
|
89
|
+
Session shutdown cancels pending commands. Cancelling an individual search or
|
|
90
|
+
activation stops waiting but leaves shared connection work running for other
|
|
91
|
+
callers.
|
|
92
|
+
|
|
93
|
+
The extension discards command stderr and doesn't include resolved secrets in
|
|
94
|
+
errors, session records, or catalog caches. Commands themselves remain responsible
|
|
95
|
+
for avoiding side effects or writing secrets to disk. Only configure commands you
|
|
96
|
+
trust; project configuration still requires project trust.
|
|
97
|
+
|
|
98
|
+
## Pi-specific options
|
|
99
|
+
|
|
100
|
+
Put descriptions, authentication choices, filters, and timeouts directly in each
|
|
101
|
+
server definition:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"docs": {
|
|
107
|
+
"url": "https://mcp.example.com/mcp",
|
|
108
|
+
"description": "Search product documentation",
|
|
109
|
+
"includeTools": ["get_*", "search_*"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
| Field | Purpose |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| `description` | Short capability description for the assistant's server directory. |
|
|
118
|
+
| `oauthClientId` | Optional pre-registered public client ID. Supports `${ENV_VAR}` interpolation, not secret commands. |
|
|
119
|
+
| `oauthScopes` | Optional array of 1–100 unique OAuth scope tokens to request at login. Omitted scopes use SDK/server defaults. Values are literal, without interpolation. |
|
|
120
|
+
| `oauthCallbackPort` | Optional loopback callback port, from 1 to 65535. Defaults to `19847`. |
|
|
121
|
+
| `disabled` | Prevent this server from connecting or exposing tools and resources. |
|
|
122
|
+
| `includeTools` | Optional allowlist of original MCP tool names; `*` matches any sequence. An empty list exposes no tools. |
|
|
123
|
+
| `excludeTools` | Denylist applied after `includeTools`. |
|
|
124
|
+
| `timeoutMs` | Request timeout, from 100 to 600000 ms. Defaults: 15 seconds for discovery/HTTP requests, 30 seconds for stdio tool calls. |
|
|
125
|
+
| `protocol` | `auto` (default) for SDK protocol-version negotiation, or `legacy` for an explicit legacy handshake. |
|
|
126
|
+
|
|
127
|
+
OAuth client IDs, scopes, and callback ports require HTTP without an Authorization
|
|
128
|
+
header. HTTP authentication is automatic; remove the obsolete `oauth` field from
|
|
129
|
+
existing definitions. See [authentication](authentication.md).
|
|
130
|
+
|
|
131
|
+
Every definition must include a `url` or `command`, even when `disabled` is true.
|
|
132
|
+
These options are specific to Pi MCP Client, not standardized MCP connection
|
|
133
|
+
fields. Other clients may reject them when you copy a definition.
|
|
134
|
+
|
|
135
|
+
Tool filters don't restrict resource reads. See
|
|
136
|
+
[trust and permissions](behavior.md#trust-and-permissions) for access boundaries
|
|
137
|
+
and [authentication](authentication.md) for OAuth setup.
|
|
138
|
+
|
|
139
|
+
## Apply changes
|
|
140
|
+
|
|
141
|
+
After editing a file, run `/mcp reload`. The extension validates the new
|
|
142
|
+
configuration before replacing the current setup; invalid configuration leaves
|
|
143
|
+
the previous setup intact. Reload closes connections, which reopen on demand,
|
|
144
|
+
and deactivates tools from changed, removed, or disabled definitions. Unchanged
|
|
145
|
+
active tools remain available.
|
|
146
|
+
|
|
147
|
+
Server-management commands apply saved changes using the same reconciliation.
|
|
148
|
+
Other running Pi sessions pick up those changes when you reload their MCP
|
|
149
|
+
configuration. See [Commands](commands.md) for toggling, inspecting, adding, and
|
|
150
|
+
removing servers.
|