Model or dataset
pulseaiclub/phi avatar
pulseaiclub/phi

phi: a Go terminal coding agent with sub-agents, hashline edits and MCP

a coding agent, rpc plugin, sub-agents, hashline edits, and mcp

397 stars16 forksGoMIT

At a glance

What is it?
phi is a Go coding agent harness that runs in the terminal, ships as a roughly 15 MB binary, and keeps MCP tool schemas out of the model prompt. It is a good fit if you want a small agent you can extend in Go or Rust; it is the wrong tool if you need a graphical IDE integration.
Who is it for?
Adopt phi if you want a small Go binary that runs a coding agent in the terminal, you are comfortable editing ~/.phi/config.yaml, and you want MCP servers available without their schemas occupying the prompt. Do not adopt it if you need a GUI, a hosted service, or an agent framework in a language other than Go or Rust.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What phi is and which developers it targets

phi is a terminal coding agent harness written in Go, described in its README as "a lean, high-performance terminal coding agent harness in Go, a sibling to Pi." The repository is pulseaiclub/phi, licensed MIT, with a homepage at pulseaiclub.github.io and a documentation set under doc/.

The audience is narrow and specific. You are expected to live in a terminal, to be willing to edit a YAML file, and to care about process footprint. The README's own framing is about size and startup cost: a release binary of roughly 15 MB, idle RSS of about 21 MB for one session, and about 31 ms to first frame. Those numbers come from a stripped release build (CGO_ENABLED=0, -ldflags="-s -w") on macOS arm64, and the README notes that comparisons against other harnesses use their published Linux PSS and interactive PTY figures, so the comparison is not apples to apples. Treat the absolute numbers as the useful part.

The project also expects you to bring your own model. There is no bundled inference and no hosted backend described. You configure an OpenAI-compatible endpoint, Anthropic, or Gemini, and phi connects to it.

Who is this not for? Anyone who wants a graphical editor, a browser UI for the agent loop, or a managed service. The config editor opens in a browser, but the agent itself is a TUI.

Sub-agents, hashline edits and the permission gate

Three mechanisms distinguish phi from a plain chat loop wrapped around shell access.

Sub-agents. The README says phi can "spawn isolated jobs and watch the full run unfold in the TUI / job logs, without stuffing every turn into the parent context." The design intent is context hygiene: a long exploratory job runs as its own unit, and the parent conversation is not inflated by every intermediate step. The README does not specify a sub-agent count limit or a scheduling policy, so how parallelism behaves under load is not documented.

Hashline edits. Instead of asking the model to rewrite whole files, phi uses anchors. The README describes editing "by whole-file @file path#TAG plus line LINE#HASH anchors," and credits the same idea to oh-my-pi. The important property is rejection: "stale tags/hashes are rejected so over-edits and silent corruption stop here." This is a real trade-off. You gain a check against the model editing a file that changed underneath it. You pay in extra tokens for anchor lines and in a stricter edit format the model has to follow. A model that is weak at structured output will fail here more often than it would with free-form patching.

Permission gate. Destructive tools can be gated. The README describes "Gate / Ask before destructive tools fire" and states that safety is not optional when an agent can touch your tree. The README does not document a rollback mechanism, so the gate is a prevention control, not an undo.

One more design choice worth noting: the TUI gives the model four core tools (read, write, edit, bash) plus grep, find and ls. External HTTP fetch is available only through MCP when configured. That is a deliberately small built-in surface.

Installing phi and running a first session

The README gives a one-line installer for macOS and Linux. It fetches scripts/install.sh from the main branch and pipes it to bash.

bash
curl -fsSL https://raw.githubusercontent.com/pulseaiclub/phi/main/scripts/install.sh | bash

Windows users get a PowerShell equivalent, which the README says requires PowerShell 5.1 or later.

powershell
irm https://raw.githubusercontent.com/pulseaiclub/phi/main/scripts/install.ps1 | iex

If you would rather build it yourself, the repository has a Makefile and go.mod declares go 1.26.3. The README says to use Go 1.26.3 or later.

bash
make build          # produces ./phi
make install        # build and install into $GOBIN

The first launch needs a model. Running phi config opens an HTML editor in your browser and, per the README, creates the ~/.phi layout and writes ~/.phi/config.yaml. If you only want a one-off run, environment variables work instead.

bash
export PHI_MODEL=gpt-4o
export PHI_API_KEY=sk-...

Then start the TUI by running phi with no arguments. On first start, the README states that phi automatically creates ~/.phi/{bin,skills,hooks,session}, and that the search tools fd and rg download into ~/.phi/bin in the background when missing. Expect the first session to be slower than later ones for that reason, and expect writes to your home directory rather than a project-local state folder.

A minimal config file, following the shape shown in the README, looks like this. The api field is explicit, and the README is direct that Anthropic requires it: "no name/URL guessing."

yaml
# ~/.phi/config.yaml
models:
  - name: gpt-4o
    api: OpenAI
    api_key: sk-...
    base_url: https://api.openai.com/v1
    context_window: 128000
    default: true
  - name: deepseek-flash
    api_key: sk-...

Built-in presets exist for DeepSeek and Gemini, which fill in base_url, context and thinking settings so you only supply the key.

Why MCP servers do not bloat the prompt

Most agent harnesses that support MCP inline every server's tool schemas into the system prompt. With a handful of servers that is manageable; with a dozen it is a fixed tax on every request. phi takes the opposite route. The README states that MCP tool schemas "never enter the model prompt," and that the system prompt lists server names only, in the same way a Skills catalog would.

The agent then discovers and calls tools through three meta-tools: mcp_list, mcp_inspect and mcp_call. The cost model changes shape. Instead of paying schema tokens on every turn, you pay a round trip when the agent needs a tool it has not inspected yet. For an agent that touches one MCP server occasionally, that is clearly cheaper. For an agent whose whole job is hammering a single MCP server on every turn, the extra discovery step is pure overhead, and a harness that inlines the schema would be faster.

The README also says MCP calls go through the same Gate / Ask / Hooks path as built-in tools. That matters if you are relying on the permission gate as your main control: adding an MCP server does not create a side channel that bypasses it. The README does not describe how mcp_inspect output is truncated for large schemas, so if you have a server with unusually wide tool definitions, that is worth checking in practice.

Extending phi in Go or Rust, and the PXB protocol

Extensions are native binaries, not scripts. They speak the PXB binary protocol over stdin/stdout, and the repository ships official author SDKs under ext/go and ext/rust. The README lists what an extension can provide: LLM tools, slash commands, event intercepts and confirm dialogs. It also notes that the SDKs use JSON at their edges via serde_json on the Rust side, and that there is "no reflection."

That last detail is a design statement. The host does not discover your extension's capabilities by inspecting types at runtime; the protocol is explicit. It also means the extension boundary is a process boundary, so a crashing extension should not take the TUI with it, though the README does not document crash containment or restart behaviour.

The practical consequence is that extension authors need a working Go or Rust toolchain. The Makefile reflects this: make test runs go test ./... and then go test -C ext/go ./..., while make test-rust runs cargo test --all-targets inside ext/rust. There is a separate make check-rust target that runs cargo fmt --check and cargo clippy --all-targets -- -D warnings. If you were hoping to write an extension in Python or JavaScript, the README does not describe a path for that.

Note also that go.mod carries a replace directive pointing github.com/pulseaiclub/phi/ext/go at the local ./ext/go directory. Building from a clone therefore uses the in-tree SDK, which is convenient for development but means the tagged SDK version and the working copy can diverge.

Limitations, failure modes and where phi is the wrong choice

The README is a feature document, and several operational questions go unanswered. There is no documented rollback for a destructive tool that already fired. The permission gate prevents; it does not undo. If your workflow depends on being able to revert an agent action after the fact, you are relying on git, not on phi.

Hashline edits are a constraint as much as a safeguard. A model that produces malformed anchors will have its edits rejected, and the README does not describe a fallback path or a retry loop for that case. The failure mode is a stalled edit rather than a corrupted file, which is the better of the two, but it is still a stall.

Model configuration is explicit by design. The README says the api field is required for Anthropic and that there is "no name/URL guessing." That is honest, and it also means a typo in the api field is a configuration error you have to debug yourself rather than something phi infers. Accepted values per the README are OpenAI, OpenAIResponses, Anthropic and Gemini, with an empty value falling back to OpenAI-compatible.

State lives in ~/.phi. That is a global layout, not a per-project one, so two projects share the same config, skills and session directory unless you do something the README does not describe.

Finally, the footprint numbers are macOS arm64 release-build figures, and the README itself notes that comparisons against other harnesses use their published Linux PSS and PTY numbers. Do not read the comparison charts as a controlled benchmark. The absolute figures for phi are the reproducible part, and only if you build with the same flags the Makefile uses.

If you need a GUI, a hosted agent service, or an agent you can script in Python, phi is the wrong tool. The extension surface is Go and Rust only.

Maintenance, licensing and what an upgrade actually costs

The repository is not archived. The last push was on 2026-09-14, and the most recent releases listed are v0.26.0 on 2026-09-10, v0.25.1 on 2026-09-10 and v0.25.0 on 2026-09-09. That is a rapid release cadence, with two releases on the same day. Rapid cadence cuts both ways: fixes arrive quickly, and the surface you integrate against moves.

The version numbers tell you something about upgrade risk. The project is at v0.26.x, still pre-1.0. The README does not state a compatibility policy for the PXB extension protocol, and go.mod pins the Go SDK at github.com/pulseaiclub/phi/ext/go v0.24.0 while also replacing it with the local ./ext/go path. An extension built against v0.24.0 of the SDK is therefore not guaranteed to work against a v0.26.0 host, and the README does not say whether it will.

Upgrade cost for a normal user is low. The install script pulls the latest release, and configuration lives in ~/.phi/config.yaml, which is plain YAML. There is no database migration described. The CHANGELOG.md file is present at the repository root, and there is a verify_released_changelog.sh script under scripts/, which suggests changelog accuracy is checked in CI rather than left to release-time memory.

Licensing is MIT, per the LICENSE file at the repository root and the license badge in the README. MIT is permissive: it allows commercial use and modification, and it requires preserving the copyright notice and licence text. That is a description of the licence, not legal advice. If you plan to redistribute phi inside a product, have your own counsel review the LICENSE file and the licences of the six direct module dependencies listed in go.mod, which include chroma for syntax highlighting, goldmark for markdown and yaml.v3 for config parsing.

Editorial conclusion

Adopt phi if you want a small Go binary that runs a coding agent in the terminal, you are comfortable editing ~/.phi/config.yaml, and you want MCP servers available without their schemas occupying the prompt. Do not adopt it if you need a GUI, a hosted service, or an agent framework in a language other than Go or Rust. Before committing, verify three things: that your model's api field value is one of OpenAI, OpenAIResponses, Anthropic or Gemini, that the permission gate's Gate or Ask setting matches how much autonomy you want to hand over, and that the extension protocol you plan to target (PXB over stdin/stdout) has an SDK in ext/go or ext/rust that covers the hooks you need.

Frequently asked questions

What models does the phi coding agent support?

The README lists OpenAI, OpenAIResponses, Anthropic and Gemini via an explicit api field in ~/.phi/config.yaml, with an empty value falling back to OpenAI-compatible. Built-in presets exist for DeepSeek and Gemini, which fill in base_url, context window and thinking settings so you only supply an API key.

How do I install the phi coding agent on macOS or Linux?

The README gives a one-line installer that fetches scripts/install.sh from the main branch and pipes it to bash. Windows has a PowerShell equivalent requiring PowerShell 5.1 or later. You can also clone the repository and run make build followed by make install, which needs Go 1.26.3 or later.

Do MCP server tool schemas go into the phi prompt?

No. The README states that MCP tool schemas never enter the model prompt and that the system prompt lists server names only. The agent discovers and calls tools on demand through three meta-tools: mcp_list, mcp_inspect and mcp_call, which follow the same Gate, Ask and Hooks path as built-in tools.

What are hashline edits in the phi coding agent?

Hashline edits let the model point at anchors instead of rewriting whole files, using a whole-file @file path#TAG marker plus line LINE#HASH anchors. The README says stale tags or hashes are rejected so over-edits and silent corruption stop. The same idea is credited to oh-my-pi.

Can I write phi extensions in Python or JavaScript?

The README does not describe a path for that. Extensions are native binaries speaking the PXB binary protocol over stdin/stdout, and the repository ships official author SDKs under ext/go and ext/rust. The Makefile's test targets cover Go and Rust only.

Is the phi coding agent free and what licence does it use?

The repository is licensed MIT, according to the LICENSE file and the licence badge in the README. MIT permits commercial use and modification and requires preserving the copyright notice and licence text. Note that phi does not include a model; you supply your own API key.

Official sources

  1. License: MIT
  2. Project website
  3. pulseaiclub/phi on GitHub
  4. README
  5. Releases
Community notes

Community notes