Pi — AI Agent Harness

Terminal
AI
Published

July 16, 2026

Modified

July 16, 2026

Overview

Pi is an AI agent toolkit that provides a unified API for multiple LLM providers, an agent runtime with tool calling, and an interactive coding agent CLI1. Beyond cloud providers like OpenAI, Anthropic, and Google, it supports local inference engines such as vLLM, Ollama, and LM Studio through its OpenAI-compatible interface.

Compared with other open terminal-based AI coding agents
Feature Pi OpenCode2 Hermes3
Language TypeScript TypeScript Python (+ Node TUI)
Runtime TUI TUI, desktop app, IDE ext. CLI, TUI, messaging gateways
Local models Yes Yes Limited
Built-in permissions No Yes (plan agent = read-only) Yes (safe-mode, worktrees)
LSP integration No Yes Yes
Messaging platforms No No Yes
Voice mode No No Yes (record + TTS)
Subagents No Yes Yes
Web search No Yes Yes
Skills system Yes Yes Yes
Cron / scheduling No No Yes

Pi follows a minimal core, aggressively extensible approach.

Adapt Pi to your workflow, not the other way around. Features other agents bake in are intentionally left out and available through extensions, skills, or third-party packages. Key principles:

  • No MCP — Skills with READMEs replace MCP; MCP support can be added via extensions
  • No sub-agents — Spawn Pi instances via tmux, or build/install them as extensions
  • No permission popups — External sandboxing (containers) instead of inline confirmations
  • No plan mode — Write plans to files, or build one with extensions
  • No built-in to-dos — They confuse models; use a TODO.md file instead
  • No background bash — Use tmux for full observability and direct interaction

Pi extends its behavior through two mechanisms:

  • Extensions — TypeScript modules that modify Pi’s runtime. They can register custom tools, subscribe to lifecycle events, add commands, or modify the UI. Extensions are what you write to change how Pi works.
  • Packages — Distribution units that bundle one or more extensions, skills, prompt templates, and themes together for sharing via npm or git. Packages are how you ship extensions and resources to others.

Install

pi-install4 extracts to ~/opt/pi-<version>/, and symlinks the binary into ~/bin/pi. Pi does not include a built-in permission system by default5. It is recommended to run inside a firejail6 container using the custom pi.profile and pi.local7 installed to ~/.config/firejail.

# run Pi sandboxed with
firejail --profile=pi.profile --whitelist=$(pwd) ~/bin/pi

The Firejail profile mounts a tmpfs-backed home-directory with only three whitelisted directories:

Path Description
~/bin Path to the pi executable
~/opt Installation directory, e.g. ~/opt/pi-0.80.7
~/.pi/agent Configuration files (user scope)

Customize pi.local to your needs, to white list user specific project directories.

Configuration

Models

Local models are defined using a dedicated configuration file8:

File Description
~/.pi/agent/models.json User Pi Agent model configuration

Use the /model command to switch between models.

The configuration nests providers under providers.<name>, each containing a models array. Only the model id is required; the rest are optional compatibility tuners for streaming, role handling, and reasoning.

Example for a vLLM server running on localhost:8000:

{
  "providers": {
    "vllm": {
      "baseUrl": "http://localhost:8000/api/v1/",
      "api": "openai-completions",
      "apiKey": "!cat ~/.pi/agent/api-key.txt",
      "models": [
        {
          "id": "qwen3.6-27b",
          "name": "Qwen3.6 27B",
          "contextWindow": 262144,
          "maxTokens": 65536,
          "reasoning": true,
          "compat": {
            "supportsDeveloperRole": false
          }
        }
      ]
    }
  }
}

Provider-level fields:

Field Description
baseUrl Endpoint of the inference server (vLLM, Ollama, LM Studio, etc.)
api API protocol; Pi uses OpenAI-compatible completions for local engines
apiKey API key; the ! prefix runs a shell command to read it from disk

Model-level fields:

Field Description
id Required. Must match the model name registered on the server
name Human-readable display name shown in the Pi UI
contextWindow Maximum input context length in tokens
maxTokens Maximum output tokens per response
reasoning Enables reasoning/thinking mode if the model supports it
compat Set supportsDeveloperRole:false when the engine does not recognize the developer message role

Settings

Pi uses JSON settings files with project settings overriding global ones9.

Edit directly or use /settings for common options.

File Description
~/.pi/agent/settings.json Global Pi Agent settings (all projects)
.pi/settings.json Project-local settings (overrides global)

Key setting categories include model & thinking, UI & display, compaction, retry, shell, sessions, and resources. Nested objects are merged rather than replaced when project settings override global ones.

Resources in the settings define where Pi loads extensions, skills, and packages:

Setting Description
packages npm or git packages to load resources from
extensions Local extension file paths or directories
skills Local skill file paths or directories

Usage

The Pi editor provides several shortcuts and conveniences for interactive use:

Feature Shortcut
File reference Type @ to fuzzy-search project files
Path completion Press Tab to complete paths
Copy last response Ctrl-X or /copy command
Shell command (visible) Prefix with !command — output sent to model
Shell command (hidden) Prefix with !!command — output not sent to model
External editor Ctrl+G opens $VISUAL, $EDITOR, or fallback

See the keybindings documentation10 for the full list of shortcuts.

Pi also supports slash commands typed in the editor:

Command Description
/new Start a new session
/quit Quit Pi
/compact Summarize older messages to free context
/export Export session to HTML or JSONL
/import Import and resume a session from a JSONL file

Skills

A skill is a self-contained directory with a SKILL.md file containing specialized instructions, helper scripts, and reference docs for a specific task. Pi loads them on-demand when your request matches a skill’s description. Pi discovers skills from these locations:

Location Scope
~/.pi/agent/skills/ Global skills (*.md files in root)
~/.agents/skills/ Global skills (directories with SKILL.md)
.pi/skills/ Project-local (trusted projects only)
.agents/skills/ Project-local, recursive discovery

Skills register as /skill:name commands in the interactive REPL:

/skill:brave-search              # Load the skill
/skill:pdf-tools extract         # Load with arguments

Without the slash command, Pi may still load skills automatically when a task matches a skill’s description — the agent reads the SKILL.md on demand and follows its instructions.

Extensions

Extensions are TypeScript modules that modify Pi’s runtime — they register custom tools, subscribe to lifecycle events, add commands, shortcuts, and more. They run directly via jiti11, so no compilation step is needed.

Location Scope
~/.pi/agent/extensions/*.ts Global (all projects)
.pi/extensions/*.ts Project-local (trusted only)

Additional paths can be specified in settings under extensions.

Plan Mode

Pi ships with a plan-mode12 extension in its examples directory. Copy it into your global extensions folder:

# for example
cp -r ~/opt/pi-0.80.7/examples/extensions/plan-mode ~/.pi/agent/extensions/

Pi auto-discovers subdirectories with index.ts, so no configuration is needed. Use /plan or Ctrl+Alt+P to toggle read-only exploration mode, then execute or refine the generated plan.

Packages

Manual

Use pi install13 to add packages from npm, git, or local paths. The command writes the package entry to your settings file so Pi loads it persistently on every startup.

pi install npm:pi-web-access
Installing npm:pi-web-access...

added 1 package, and audited 2 packages in 1s

found 0 vulnerabilities
Installed npm:pi-web-access

Interact with packages:

# show installed packages from settings
pi list

# delete a package
pi remove npm:<name>

Settings

Packages can appear in both global and project settings. When the same package exists in both, the project entry takes full precedence. Package identity is determined by name (npm), repository URL without ref (git), or resolved absolute path (local).

~/.pi/agent/settings.json
{
  "packages": ["npm:pi-web-access"]
}

Missing packages auto-installed when configured in the settings