Skip to content
Tool Review

pi — hands-on review full setup and audit, July 2026

Sébastien Giband · Terminal-first setup with per-preset model layering, 14 in-house extensions, skills shared with Claude Code. The daily driver remains Claude Code. ·
PHP/Symfony 7 TypeScript/React Neovim + herdr chezmoi
The most extensible CLI agent I've configured — and the most demanding

pi dictates nothing: no MCP, no sub-agents, no guardrails by default. Everything others ship turnkey, you build in TypeScript. In exchange you get native multi-provider and total control, including one-model-per-preset layering. It's the cleanest terminal-first setup I've built — but it doesn't replace Claude Code day to day yet, and I say why.

Strengths

  • + Real native multi-provider: Ctrl+P cycles between Claude, GPT, Gemini, opencode Go models and local ones without leaving the session — per-preset layering (one model per role: plan, implement, review) becomes trivial
  • + End-to-end TypeScript extensibility: my 15 Claude Code bash hooks collapse into a single typed, testable extension, with access to the UI (confirm/notify) and the session manager
  • + Standard Agent Skills: the 37 skills in ~/.claude/skills are read as-is (progressive disclosure, only ~1,600 tokens of descriptions) — zero duplication between pi and the rest of the setup
  • + JSONL sessions with native tree branching (/tree, /fork, /clone) — history branches instead of being overwritten
  • + Open-source MIT, BYOK, zero vendor lock-in: the exact opposite of the Claude Code model
  • + Terminal-first by design: pipe-friendly (pi -p), integrates natively into an agent multiplexer like herdr and over SSH, no IDE dependency

Limitations

  • No sandbox: pi runs with your user permissions. The only guardrails are the extensions you write — if you don't code the rm -rf block or the secret-guard, it doesn't exist
  • Per-preset layering isn't a native feature: it's an in-house extension (preset.ts), with no safety net upstream — zero occurrences of 'presets' in pi's own code
  • Non-interactive-mode trap: in -p / --mode json, defaultProjectTrust is 'ask', so no trust prompt appears and project resources are silently ignored — you need --approve, otherwise pi ignores your context without a word
  • Announced debt: extensions import @mariozechner/* (old scope), and CHANGELOG 0.80.0 announces the future removal of the alias to @earendil-works/* — inaction = scheduled breakage
  • No MCP by philosophical choice: everything the MCP ecosystem gives for free elsewhere (context7, connectors), you reimplement as an extension or go without
  • No IDE, no sub-agents, no LSP plugins — the entry cost is real for anyone not already living in the terminal

Test context

pi 0.82.1, package @earendil-works/pi-coding-agent, full setup and audit done in July 2026 on my primary machine (Mac, Neovim + herdr, config versioned via chezmoi). Certainty level up front: this is not my primary daily agent — that’s still Claude Code. I built a complete pi setup (14 extensions, one-model-per-preset layering, shared skills), audited it line by line, but haven’t yet run it under weeks of production load. This review covers what the setup does, verified against real code — not a daily-driver gut feeling.

What it actually does

pi connects the terminal to 30+ providers with a deliberately bare core. Its author’s line sums it up: “pi is aggressively extensible so it doesn’t have to dictate your workflow.” Concretely, it hands you seven tools (read, bash, edit, write, grep, find, ls), a TUI, JSONL sessions that branch — and nothing else. No MCP servers, no sub-agents, no plan mode, no permission popups. Everything missing is a choice, not an oversight: it’s on you to build it as a TypeScript extension.

What makes it interesting for a serious agentic workflow is native multi-provider combined with extensibility. That’s what makes one-model-per-preset layering not just possible, but clean.

What works

Multi-provider as a foundation, not an option. Ctrl+P cycles between Claude, GPT, Gemini, opencode Go models and local, without leaving the session. On that base, assigning a model to each role — the fastest for mechanical volume, the most capable for plan — becomes one line of config. That’s the model routing that Claude Code, single-provider, structurally cannot offer.

A nuance learned in use: calling Claude from pi goes through claude -p, which breaks interactive prompts (no AskUserQuestion) and blinds any supervision. So in my layering, open models hold every preset, and the frontier — when a task deserves the best model with all the gates — goes to Claude Code directly, outside pi. pi’s multi-provider is real, but it stops where a provider’s interactivity matters.

Extensibility that absorbs what you already have. My fifteen Claude Code bash hooks — rm -rf blocking, secret-guard, pre-push-gate, review-gate — collapse into a single typed extension. Instead of fifteen scripts maintained separately, one file with isToolCallEventType("bash", event) handing you a typed event.input.command, access to ctx.ui.confirm() and the session manager. Testable, importable, versionable. The code for these guardrails is public, with their test benches.

Zero duplication with the rest of the setup. pi reads standard skills straight from ~/.claude/skills — 37 skills exposed, only their descriptions in context (progressive disclosure, ~1,600 tokens). Knowledge doesn’t fork across tools: it lives in one place.

What doesn’t work

No sandbox, and it’s structural. pi runs with your user permissions. The only guardrails are the extensions you write. If you don’t code destructive-command blocking, there is none — and auditing my own setup proved it: my rm -rf block regex let the most common forms through (rm -rf ~, rm -rf $HOME) because it required a character after the path. The net you think you have is only real once you test it.

Layering isn’t a native feature. The presets carrying my whole workflow are an in-house extension (preset.ts) — zero occurrences of “presets” in pi’s own code. It works, but with no net upstream: it’s my code, with my bugs.

Non-interactive mode lies by omission. In pi -p or --mode json, defaultProjectTrust is “ask” — so no trust prompt shows, and project resources are silently ignored. You think pi reads your AGENTS.md; it doesn’t, and it won’t tell you. You need --approve. A trap only an audit reveals.

A pre-scheduled alias debt. Extensions still import the old @mariozechner/* scope; CHANGELOG 0.80.0 announces the future removal of the alias to @earendil-works/*. Today it passes thanks to loader aliasing — the day it drops, everything breaks at once.

Who is it for?

pi is the right pick if you already live in the terminal and anti-lock-in is a requirement, not a preference: BYOK, MIT, multi-provider, everything portable. It’s also the best ground I know for clean model layering — a topic I cover in a dedicated piece on opencode Go.

But be clear-eyed about the contract: pi’s minimalism hands the work back to you. No MCP, no sub-agents, no default guardrails — you build, or you go without. If you want plug-and-play, Claude Code ships the ecosystem turnkey; if you want multi-provider without reimplementing everything yourself, OpenCode is a notch less bare. pi rewards those who want to control everything, and punishes those who hoped to maintain nothing.

Recommended for

  • Terminal-first devs (Neovim/herdr/SSH) who want native multi-provider and one-model-per-task layering
  • Those for whom anti-lock-in is a requirement, not a preference — BYOK, MIT, everything portable
  • Those who'd rather write their own guardrails in TypeScript than suffer permission popups

Not recommended for

  • IDE-first users (VS Code, JetBrains) without CLI comfort — pi has zero IDE integration
  • Those who want plug-and-play: MCP, sub-agents and ready-made guardrails are elsewhere
  • A usage where you don't want to maintain your own extensions — pi's minimalism hands the work back to you

Frequently Asked Questions

What is pi (pi coding agent)?
An open-source (MIT) CLI agent written by Mario Zechner, terminal-first and aggressively extensible in TypeScript. The official package is @earendil-works/pi-coding-agent (version 0.82.1 as of July 2026; the old @mariozechner/pi-coding-agent is deprecated). Its philosophy: a minimal core that doesn't dictate your workflow — no MCP, no sub-agents, everything done via extensions.
How does pi differ from Claude Code?
pi is open-source, multi-provider (BYOK, 30+ providers) and terminal only; Claude Code is proprietary, single-provider Anthropic, but ships MCP, sub-agents, LSP plugins and IDE integrations turnkey. pi gives you total control at the cost of integration work. Skills are the same standard, so ~/.claude/skills is shared between the two.
How do you do model layering with pi?
Via an in-house presets extension: each role (plan, implement, review, bulk, fast) gets a dedicated model and tool set. Native multi-provider makes the assignment trivial — a fast model for volume, a more capable one for plan and review. Note: this isn't a native pi feature, it's your own code.
Is pi safe to use without a sandbox?
It runs with your user permissions, no sandbox. Security rests entirely on the extensions you write (dangerous-command blocking, secret-guard, commit gates). Without them, no net. It's a deliberate pi choice, but it shifts the responsibility onto you.
Do you need a subscription to use pi?
No: pi is free and works BYOK with any API key. A login subscription (the opencode Go plan, ~$10-25/month) gives access to a model pool without managing keys one by one — useful for layering, but optional.

Go further