Docs

MCP servers

MCP (Model Context Protocol) lets the agent call external tools. pi owns the protocol; Orbit owns the management surface — a native page, a local secret store, live status, and a safe way to apply changes.

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/N chip whenever servers are enabled; click it to open the page.
  • Transcript cards show the actual calls — MCP · <server> for direct and deferred tools, and Run code for 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:

ScopeFile
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:

TransportFields
stdiocommand (a single executable, never a shell string), args, env, and cwd.
HTTPurl, 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 0600 on 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 --json on 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.json are 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.

ModeMeaning
Codemode (default)Tools stay out of the model's tool list and are called from pi's JavaScript codemode sandbox.
Codemode-deferredLike codemode, loaded on demand.
DeferredTools are undeclared until pi's tool_search loads them.
DirectTools are declared to the model directly.
HiddenThe 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 for npx) or use an absolute path.
  • Connection failed with 401 or 403 — check the Authorization header 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 list may 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 autoEnableCodemode setting.
  • Logs — pi appends server logs to ~/.pi/agent/mcp.log. Orbit adds no secret values to any log.