All notes

#202 Pi: The minimal agent harness

August 8, 2026·10 min read

#202 — Pi: The minimal agent harness

Pi is a deliberately minimalist, four-tool coding agent and toolkit that gives you full control over what enters the context window, across many LLM providers and runtimes.

Why Pi exists

Mario Zechner built Pi after Claude Codes system prompt, tools, and behavior kept changing under him, breaking workflows without warning. He wanted a small, layered coreunder 1,000 tokens of promptthat could run as a terminal coding CLI or sit underneath products you build, without hidden context injection or undocumented session formats.

Pi targets a specific problem: most harnesses and unified LLM SDKs quietly inject instructions, mishandle tool calling on non-frontier models, and obscure what actually enters the context window. Pi reverses that: controlling context is the design goal, not a side-effect.

The four core packages

Pi ships as a small toolkit of packages you can use together or embed separately.

  • pi-ai unified API for Anthropic, OpenAI, Google, xAI, Groq, Cerebras, OpenRouter, and other OpenAI-compatible endpoints, handling streaming, TypeBox/AJV-validated tool calls, reasoning traces, cross-provider context handoff, and cost tracking.
  • pi-agent-core the agent loop: tool execution, validation, event streaming, state management, message queuing, attachments, and a transport layer that runs directly or behind a proxy.
  • pi-tui a terminal UI framework Zechner wrote from scratch, with differential rendering that only redraws changed lines instead of repainting the entire screen.
  • pi-coding-agent the CLI harness that wires sessions, tools, themes, and project context files onto the three layers below.

Zechners rule is explicit: if he doesnt need a feature, Pi wont ship it.

What pi-ai normalizes

Under the hood, pi-ai collapses different provider APIs into four shapes: OpenAI Completions, OpenAI Responses, Anthropic Messages, and Google Generative AI. It patches over inconsistenciesfields like store being rejected by some providers, max_tokens vs max_completion_tokens, and differing reasoning-trace fieldsso you can switch models mid-session without rewriting payloads.

Anthropic thinking traces become tagged text blocks when you move to OpenAI, and full contexts can serialize to JSON for later resume on a different model. Tool results can split into a text portion for the model and a structured portion for UI rendering, including images as native attachments, with arguments checked via TypeBox and AJV. AbortController propagates through the pipeline, so canceling mid-stream still leaves a usable partial result, and pi-ai works around limitations like Googles lack of streaming tool calls.

CLI capabilities

The Pi CLI runs on Windows, Linux, and macOS. It supports multiple providers with mid-session switching, session resume and branching, and automatic loading of an AGENTS.md file from parent directories upward.

You get slash commands with arguments, OAuth for Claude Pro/Max, JSON-configured custom providers, live-reloading themes, fuzzy file search and drag-and-drop in the editor, message queuing while the agent runs, vision support, HTML export, and headless operation via JSON streaming or RPC.

System prompt and tools

Pis system prompt is intentionally small: a few short paragraphs describing four tools, plus your AGENTS.md appended at the bottomand nothing else. Prompt plus tool definitions stay under 1,000 tokens, vs 10,000+ in many other harnesses.

The built-in tools:

  • read reads text and images with a default 2,000-line limit and offset/limit controls.
  • write creates or overwrites files, creating parent directories as needed.
  • edit performs exact-match text replacement.
  • bash runs commands synchronously with optional timeouts.

Read-only helpers like grep, find, and ls exist but are off by default, keeping the tool surface small.

Full access, security posture, and isolation

Pi runs with full filesystem and command access by default and does not prompt for confirmation. Zechners argument is that once an agent can write and execute code, permission popups dont meaningfully mitigate the risk; the only strong mitigation is cutting network access, which neuters most useful workflows.

He points to Simon Willisons dual LLM pattern as evidence that a trifecta of read access, code execution, and network access remains exploitable even with elaborate safeguards. Pi doesnt ship a default web-search tool, but tools like curl and file reads already let a malicious file inject instructions.

If that trade-off is uncomfortable, the docs outline three containerized patterns:

PatternWhats isolatedBest for
Gondolin extensionBuilt-in tools and ! commands routed into a local micro-VMLocal isolation with host-side authentication
Plain DockerEntire pi process inside a containerSimple local boundary; credentials enter container
OpenShellPi inside a policy-controlled sandbox (filesystem, network, credential rules)Managed local or remote isolation via a gateway

Project trust only gates whether project-local settings and extensions load before you review them; it does not restrict what the model can do once running.

What Pi leaves out

Pi deliberately omits several common agent features and explains why.

Instead ofPi suggestsReasoning
MCP serversWrite a CLI tool with a README, or ship/install a Pi extensionLarge MCP bundles consume thousands of prompt tokens before any useful work, shrinking the context window.
Sub-agentsSpawn another Pi instance via tmux, or orchestrate via extensionsSub-agents hide checks and failures inside another black box, reducing visibility.
Permission popupsRun Pi in a container, or build your own confirmation flow in an extensionConfirmation dialogs dont help once shell access exists.
Plan modeWrite plans to PLAN.mdSame output, but readable, editable, and versioned like normal code, instead of opaque in-model state.
Built-in to-dosUse a TODO.md file with checkboxesFiles are easier to inspect and diff than to-do state embedded in a models memory.
Background bashUse tmuxtmux already handles background processes reliably.

Anything missing from Pis core can be built as an extension, or pulled from the example extensions and third-party packages.

pi-tui: terminal UI from scratch

Zechner evaluated two terminal UI patterns: full-screen pixel buffer UIs that take over the terminal and lose native scrollback/search, and UIs that write into normal scrollback and redraw only changed lines. Pis TUI uses the second approach.

Components cache rendered output and only re-render when something changes. On first render or width changes, Pi redraws everything; otherwise it finds the first changed line and redraws from there, using synchronized-output sequences to avoid flicker.

Providers and auth

Pi supports many providers via API key or subscription login.

  • Direct APIs: Anthropic, OpenAI, Google, xAI, Groq, Cerebras, OpenRouter, Mistral, and more via custom endpoints.
  • Subscriptions: Claude Pro/Max, ChatGPT Plus/Pro, GitHub Copilot, xAI, OpenRouter, Radius.
  • Enterprise: Azure OpenAI, Amazon Bedrock, Cloudflare AI Gateway and Workers AI, Google Vertex AI.

Credentials resolve in a fixed order: CLI flags, then auth.json, then environment variables, then models.json. In auth.json, a key can be a literal string, an environment variable reference, or a shell command, which lets you pull from system credential stores.

Sessions, compaction, and branching

Pi stores sessions as JSONL trees under ~/.pi/agent/sessions/, with each entry carrying id and parentId to model branches.

  • /tree jumps to any earlier point within a session file.
  • /fork starts a new file from a past message.
  • /clone copies the current branch into a new file.

Auto-compaction kicks in when context size passes contextWindow minus a 16,384-token reserve. It summarizes everything older than a ~20k-token recent window into a structured summaryGoal, Constraints & Preferences, Progress, Key Decisions, Next Steps, Critical Contextwithout ever cutting through the middle of a tool call.

When /tree navigates away from a branch, Pi finds the common ancestor and offers to summarize the abandoned path before you leave it; extensions can intercept both compaction and summarization to hand them to different models.

Settings

Global settings live under ~/.pi/agent/settings.json; project overrides live under .pi/settings.json, and they merge instead of replacing each other.

Settings cover model and thinking defaults, custom thinking budgets, UI behavior, retry tuning, message transport mode, and glob-based resource paths for extensions, skills, prompts, and themes. The docs explicitly warn that raising provider-level retries can hide usage-limit errors.

Extensions

Extensions are TypeScript modules with access to tools, commands, keybindings, events, and the TUI. Hooks include:

  • project_trust, session_start, before_agent_start to inject messages or rewrite the system prompt.
  • tool_call to modify arguments or block execution.
  • context to edit the message list before each LLM call.
  • before_provider_request and after_provider_response to rewrite raw API payloads.
  • model_select to control model choice.

Features like permission gates, git checkpointing, and path protection are all built as extensions; none of them are hard-coded into Pi itself.

Skills

A skill is a directory with a SKILL.md file following the open Agent Skills standard: name, description, and optional allowed-tools. Only the name and description sit in context until you actually call the skill.

Pi relaxes the rule that the folder name must match the declared skill name so the same skill directory can work across Pi, Claude Code, and Codex without duplicates.

Embedding Pi via the SDK

The SDKs createAgentSession() returns a session object with methods like prompt(), steer(), followUp(), subscribe(), setModel() and cycleModel(), navigateTree(), and compact(). Starting, resuming, forking, or cloning sessions happens on a separate AgentSessionRuntime object.

Events emit granular lifecycle updatestool_execution_start, tool_execution_update, tool_execution_end, turn_start, turn_end, queue_update, compaction_start, compaction_endso you can show live tool status instead of a single filling chat bubble. You can disable all built-in tools with noTools: "all" and provide your own with defineTool() when youre not building a coding agent.

Model resolution follows the same credential order as the CLI, and scopedModels lets you present a curated model list instead of one fixed option. System prompts, skills, and slash commands go through a swappable ResourceLoader, and SettingsManager.inMemory() plus SessionManager.inMemory() bypass disk for multi-tenant products or tests.

Three main run modes sit on top:

  • InteractiveMode full terminal UI.
  • runPrintMode single prompt-in, answer-out from scripts or APIs.
  • runRpcMode JSON over stdin/stdout for integrating from other languages.

System prompt size and benchmarks

Zechner benchmarked Pis small prompt against heavier harnesses and found that frontier models dont need 10,000+ tokens of instruction to perform standard coding-agent tasks. He cites Amp as an example: it reuses parts of Claude Codes prompt but runs fine on a much smaller one, which he takes as evidence that prompt size and agent capability are less tightly coupled than most harnesses assume.

The recurring design pattern

Across Pi, the same pattern repeats: sessions are files, plans are files, to-dos are files, skills are portable folders, and extensions run through typed hooks instead of hidden logic. Thats deliberate: it keeps Pi transparent and composable enough to serve both as a personal terminal coding tool and as the engine inside products you build.

Would you like this adapted into a more launch blog voice or kept as a factual, docs-style overview?

Frequently asked questions

Is pi-agent-core free to use commercially in a product I'm selling?

Yes. Pi and its underlying packages ship under the MIT License, which permits commercial use, modification, and redistribution without royalties. You can embed pi-agent-core in a paid SaaS product with no licensing fee, though you're still responsible for whatever LLM API costs the agent generates at runtime.

How much does it cost to run an agent built on pi-agent-core?

Cost comes entirely from your model provider, not from Pi itself, since the framework adds no licensing fee on top. Because pi-ai supports over 25 providers behind one interface, you can route a product to a cheaper model like Ollama-hosted open weights or a discounted OpenRouter model instead of a frontier API, which is where most of the real savings show up at volume.

Can I use Pi with a self-hosted or local LLM instead of Claude or GPT?

Yes. Pi's pi-ai layer connects to Ollama, vLLM, LM Studio, and any OpenAI-compatible endpoint through custom model and provider configuration in models.json, so a fully local model can replace a hosted API with no changes to your tools or agent logic.

What's the difference between pi-agent-core and LangChain or LlamaIndex for building an agent?

LangChain and LlamaIndex are broader orchestration frameworks with heavier abstractions and larger dependency trees, while pi-agent-core is a narrower, lower-level agent loop: tool execution, state management, and provider abstraction, with no built-in chains, retrievers, or memory stores layered on top. Teams choose Pi's core when they want to define their own tool set and control exactly what enters the model's context, rather than working through a framework's opinions about how an agent should be structured.

Does Pi support Model Context Protocol (MCP) servers?

Not by default. Pi's core ships without MCP support because a single MCP server like Playwright's can consume 7-9% of the context window in tool descriptions before any work starts. MCP support is available as an optional extension you install or build, so you only pay that context cost if you actually need it.

Is it safe to run Pi on a client's codebase or an untrusted repository?

Not without adding isolation yourself. Pi runs with the full permissions of whatever account starts it and has no built-in sandbox, so a malicious or compromised repo can trigger prompt injection through its own files. For work on unaudited code, run Pi inside Docker, the Gondolin extension (a local micro-VM), or OpenShell (policy-based sandboxing), rather than on your host machine directly.

Can non-developers or a small team without engineers use Pi to build an internal tool?

Pi's CLI is built for people comfortable in a terminal, but the SDK layer (pi-agent-core plus pi-ai) requires basic Node.js and TypeScript to wire up custom tools, so it's not a no-code builder. A non-technical founder would typically need to pair with a contractor or technical co-founder for the initial setup, after which prompt templates and skills can be reused without touching code again.

What happened to Claude Code that made developers look for alternatives like Pi?

Mario Zechner, Pi's creator, built it after Claude Code's system prompt and toolset kept changing across releases, breaking established workflows without warning. Several public writeups frame Pi's minimalism as a direct response to that instability, prioritizing a fixed, auditable core over a harness whose behavior shifts on every update.

How do I migrate an existing agent built on LangChain to Pi's SDK?

There's no automated migration path since the two frameworks structure tool definitions and state differently. The practical approach is rebuilding your existing tools using Pi's defineTool() function and re-registering them on a new AgentSession, which is usually a smaller lift than it sounds since most custom LangChain tools are just wrapped API calls or database queries that map directly onto Pi's tool schema.

Can I run multiple Pi-based agents in parallel for different products or clients?

Yes, and this is a common pattern for founders managing several codebases. Each project keeps its own session directory, settings, and AGENTS.md file, and packages let you bundle a shared toolkit (extensions, skills, prompt templates) via pi install git:org/repo so every project pulls from the same base configuration instead of duplicating setup work.

Is Pi better than Claude Code?

Neither wins outright; they optimize for different things. Pi gives you a roughly 1,000-token system prompt, four built-in tools, and full control over what's added, while Claude Code ships a ~14,000-token prompt with 10+ built-in tools including sub-agents and native MCP support. Pi tends to win for developers who want low context overhead and multi-provider flexibility, and Claude Code tends to win for teams who want a finished product across terminal, VS Code, and desktop without configuring anything themselves.

Who created Pi and is it backed by a company?

Pi was created by Mario Zechner, an independent developer previously known for the libGDX game framework, and is maintained under Earendil Inc. It's community-driven and open source rather than backed by a major AI lab, which is part of why it has no built-in vendor lock-in to any single model provider.

Can I still use my Claude Pro or Max subscription with Pi instead of an API key?

This became a contested point in early 2026 after Anthropic restricted Claude subscription logins to its own Claude Code client, which affected Pi and other third-party harnesses like OpenCode that previously supported OAuth login with a Claude subscription. Check Pi's current provider documentation before assuming subscription-based login still works, since this is an area that has changed and could change again; API-key billing through the Anthropic API remains unaffected.

How does Pi perform on coding benchmarks compared to Claude Code and Codex?

Pi has been shown ranking competitively on Terminal-Bench 2.0 against tools like Cursor, Codex, and Windsurf despite its much smaller system prompt, which is the evidence its creator points to for the claim that prompt size and agent capability aren't as tightly linked as most harnesses assume. Independent benchmarks vary by model choice since Pi's score depends heavily on which underlying LLM you route it to, unlike Claude Code, which is fixed to the Claude model family.

Does Pi work on Windows, and does it support tmux and terminal customization?

Yes to both. Pi runs natively on Windows, Linux, and macOS, with dedicated setup docs for Windows and Termux on Android, and it documents specific tmux integration patterns for background process management and terminal customization for optimal rendering.

What is OpenClaw and how does it relate to Pi?

OpenClaw is a separate agent product reported to run on Pi's underlying agent core, cited as an example of Pi being used as embedded infrastructure inside another company's product rather than as a standalone CLI tool. This is the same pattern a founder would follow to build a custom agentic product on pi-agent-core rather than shipping Pi's coding-specific CLI directly.

more than just words|

We're here to help you grow better at every stage of the climb.

let's go to market

Whether you're finding problem-market fit, refining your positioning, shipping product, or scaling go-to-market we're built for every stage of the journey.