Where MCP shows up
- Settings → MCP — the full page: every server, its tools, errors, and actions.
- The usage pill in the top bar opens a popover with Providers and MCP tabs. The MCP pane is one row per server — status, scope, tool count, and a contextual sign-in button.
- The status bar carries a quiet
MCP n/Nchip whenever servers are enabled; click it to open the page. - Transcript cards show the actual calls —
MCP · <server>for direct and deferred tools, andRun codefor codemode scripts.
Scopes and files
Orbit reads and writes exactly the files pi reads, so a config edited here is visible to the CLI and vice versa:
| Scope | File |
|---|---|
| Global | ~/.pi/agent/mcp.json — available in every project. |
| This project | <project>/.pi/mcp.json — available only in that project. Project entries replace global entries with the same name. |
Adding a server
Open Settings → MCP and choose Add MCP Server, then pick a transport:
| Transport | Fields |
|---|---|
| stdio | command (a single executable, never a shell string), args, env, and cwd. |
| HTTP | url, headers, and optional oauth. The legacy SSE transport is not supported. |
You can also set enabled (off keeps the entry without connecting) and an exposure mode. Descriptions are not part of pi's schema, so Orbit keeps them in ~/.orbit-pi/mcp-metadata.json and never writes them into mcp.json.
Secrets
mcp.json is configuration, not a credential store. Orbit writes ${NAME} references and keeps the values in ~/.orbit-pi/mcp-secrets.json:
- A literal value typed into an Environment or Headers field is stored under a generated name and the field is written as a reference. Global and per-project secrets never share a stored value, even for the same server and field.
- Values that already contain a
${NAME}reference (or a!command) are written through verbatim. - Every pi spawn and probe receives the store's values as environment variables, so pi expands references as it would for a shell export. Values are masked in the UI, and errors are redacted before they reach the screen or a log.
- The store is
0600on Unix and lives in your user profile on Windows — the same local, user-scoped model as pi's own credential files.
Applying changes
A configuration change follows one path:
validate → persist (atomic write) → re-read → probe → restart pi if stale
→ switch_session back to the same conversation- Writes are atomic and preserve unrelated entries and the file's indentation; a parse or I/O error aborts untouched.
- The probe runs
pi mcp list --jsonon a background executor, debounced, so it never blocks rendering. - Applying is coalesced and waits for an in-flight run to settle, so a restart can never abort work. pi is restarted only when the running process is actually stale, and the session is preserved with
switch_session. - External edits to
mcp.jsonare detected while the page is open. Orbit shows a notice and applies them only when you ask — it never overwrites them.
Exposure modes
Exposure controls how a server's tools reach the model. Orbit writes the mode; pi implements the tools.
| Mode | Meaning |
|---|---|
| Codemode (default) | Tools stay out of the model's tool list and are called from pi's JavaScript codemode sandbox. |
| Codemode-deferred | Like codemode, loaded on demand. |
| Deferred | Tools are undeclared until pi's tool_search loads them. |
| Direct | Tools are declared to the model directly. |
| Hidden | The server connects but contributes no tools. |
OAuth sign-in
pi is the OAuth client. An HTTP server without an Authorization header is OAuth-capable, and no credential belongs in mcp.json. When such a server needs a login, its row shows Sign-in required with a Sign in button:
- Sign in runs
pi mcp login <server>. pi opens the authorization page, handles the loopback callback, and stores tokens in~/.pi/agent/mcp-auth.json. Orbit waits and offers Cancel. - Sign out (in the expanded detail) runs
pi mcp logout <server>and restarts a running session so live access is dropped too. - For authorization servers without dynamic client registration, the form has collapsed OAuth client settings for a client id, secret, callback port or URL, and scopes.
Troubleshooting
- Connection failed with ENOENT — the stdio command is not installed or not on pi's
PATH. Install it (for example Node.js fornpx) or use an absolute path. - Connection failed with 401 or 403 — check the
Authorizationheader and the secret it references. Use Test connection; the toast carries pi's status. - Sign-in required — an OAuth server. Use Sign in; the next probe picks up the credentials.
- Project servers missing — the standalone
pi mcp listmay not trust the project. Orbit sessions pass--approve, so they still load; the page shows pi's note. - Tools do not reach the model — check the server's exposure and the global
autoEnableCodemodesetting. - Logs — pi appends server logs to
~/.pi/agent/mcp.log. Orbit adds no secret values to any log.