Skip to main content
Guides

Running Pi

This guide covers running the Pi coding agent in a Moat container.

Pi is a model-agnostic, bring-your-own-key coding agent. Unlike the other agents, Pi has no credential of its own — it runs against whichever model backend you grant. Moat supports two Pi backends today: anthropic and openai. Any other backend fails hard.

Prerequisites

Granting a backend

Pi uses your existing anthropic or openai grant — the same credential the other agents use. Grant one:

export ANTHROPIC_API_KEY="sk-ant-..."
moat grant anthropic

# ...or
export OPENAI_API_KEY="sk-..."
moat grant openai

The credential is stored encrypted and never enters the container. Moat’s proxy injects the real token at the network layer. See Credential management for details.

Choosing a backend

Pi decides which backend to use as follows:

  1. --provider flag or pi.provider in moat.yaml, if set. Must be anthropic or openai, and the matching grant must be configured.
  2. Otherwise, the backend is inferred from the single configured grant.
  3. If both grants are configured and no provider is set, the run fails hard and asks you to choose.
  4. If no supported grant is configured, the run fails before a container is created.
# One grant configured — inferred automatically
moat pi

# Both grants configured — choose explicitly
moat pi --provider openai

# Pin a model
moat pi --provider anthropic --model claude-opus-4-8

These checks run before any container is created, so misconfiguration fails fast with an actionable message.

Running Pi

Interactive:

moat pi
moat pi ./my-project

Non-interactive (headless):

moat pi -p "explain this codebase"
moat pi -p "fix the bug in main.py"

Configuration

# moat.yaml
agent: pi
grants:
  - anthropic
pi:
  provider: anthropic      # optional; inferred from the grant when unset
  model: claude-opus-4-8   # optional; Pi's per-provider default when unset

See the moat.yaml reference for the full field list.

Packages

Declare Pi packages (extensions, skills, prompt templates, themes) in pi.packages. Moat runs pi install for each at image build time, so they are baked into a reproducible, cached layer — no runtime install, no network needed at run time.

pi:
  provider: anthropic
  packages:
    - "npm:@acme/pi-reviewer@1.2.0"
    - "git:github.com/acme/pi-skills@v3"

Only remote sources are accepted (npm: / git: / https:// / ssh://); local paths are rejected. Pin exact versions/refs — Pi has no lockfile. If a package needs a runtime tool, add it to dependencies:.

Safety defaults

Every moat pi image bakes a safe ~/.pi/agent/settings.json:

  • defaultProjectTrust: never — a checked-out repo’s own .pi/ config and extensions (which are arbitrary code) do not auto-load. Your project’s AGENTS.md/CLAUDE.md still load (that is inherent to Pi).
  • Telemetry and analytics off; quiet startup.

Pi config can redirect model traffic to any host (via baseUrl, custom providers, or extensions), so only the network policy actually constrains egress. moat pi warns when it runs under a permissive policy — prefer network.policy: strict for untrusted work.

Runtime context

Moat injects a description of the sandbox (workspace, grants, network policy, Docker access) into Pi’s system prompt via Pi’s --append-system-prompt, so it augments rather than replaces your own AGENTS.md / CLAUDE.md.

Not yet supported

  • Other backends — only anthropic and openai are wired up. Gemini, Bedrock, and the rest are planned.
  • pi.mcp — Pi core has no MCP configuration format to target.
  • pi.sync_logs — session-log syncing is a planned follow-up.
  • Subscription (OAuth) login — v1 uses API-key grants only.