Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Pi.nix

FreeNot checked

Pi Coding Agent for Nix Users

GitHubEmbed

About

Pi Coding Agent for Nix Users

README

A Nix flake that packages pi (the minimal terminal coding harness, currently v0.85.1) together with a small set of pre-built extensions — web search, local SQLite memory, GitHub MCP + CLI tools, and RTK command rewriting. Everything ships in a single pi binary; you opt extensions in at runtime via an env var.

Quick start

# Pi with NO extensions (the default).
nix run github:cyprx/pi.nix

# Pi with everything.
PI_EXTENSIONS=all nix run github:cyprx/pi.nix

# Pi with a hand-picked set.
PI_EXTENSIONS=localmemory,web-search nix run github:cyprx/pi.nix

# Everything except RTK.
PI_EXTENSIONS=all PI_DISABLE_EXTENSIONS=rtk nix run github:cyprx/pi.nix

Extensions are opt-in — running pi with no env vars gives you the vanilla agent.

Available extensions

Name What it adds External dep
web-search web_search tool backed by public SearXNG instances. (none)
localmemory Cross-session memory in a single SQLite file (FTS5, per-project). (none — uses Node's built-in node:sqlite)
github-mcp The full github-mcp-server toolset over MCP/stdio. GITHUB_PERSONAL_ACCESS_TOKEN
github-cli Project-aware PR/issue/review helpers via the gh CLI. gh (bundled) + GitHub auth
rtk RTK command rewriting — filters noisy build/test output to save tokens. rtk binary (bundled)

Selecting PI_EXTENSIONS=all means all of the above. Telemetry for RTK is disabled by default (RTK_TELEMETRY_DISABLED=1 is baked into the wrapper).

Composition for your own flake

If you want a different default set, build your own pi with lib.mkPi:

{
  inputs.pi-nix.url = "github:cyprx/pi.nix";

  outputs = { self, nixpkgs, pi-nix, ... }: {
    packages.x86_64-linux.my-pi =
      let l = pi-nix.lib.x86_64-linux;
      in l.mkPi {
        name = "minimal";
        extensions = {
          inherit (l.extensions) localmemory web-search;
          # rtk and github-* omitted
        };
      };
  };
}

The resulting my-pi/bin/pi only knows about the extensions you pass in; PI_EXTENSIONS=all will resolve to just those.

GitHub auth (for github-mcp / github-cli)

export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_...
PI_EXTENSIONS=github-mcp,github-cli nix run .

Or use the NixOS / Home Manager githubTokenFile option (below).

Web Search (web-search)

Adds a web_search tool. No API key. Set SEARXNG_URL=https://your.instance to override the default public pool.

Local Memory (localmemory)

Single SQLite file at $XDG_DATA_HOME/pi/memory.db. No second process, no native binary — it uses Node's built-in node:sqlite and FTS5.

Tools

  • memory_search, memory_save, memory_forget, memory_health
  • /localmemory-status command
  • before_agent_start recall — top-5 matches for your prompt injected into the system prompt
  • agent_end capture — opt-in only: assistant text is saved only when it contains a <remember>…</remember> block

<remember> capture syntax

<remember kind="decision" tags="auth,oauth">
Use PKCE for native clients
---
Native apps cannot keep a client secret safe, so use PKCE for the OAuth flow.
</remember>

<remember scope="global">
Prefer ripgrep over grep
</remember>

First line (or text before ---) is the title; the rest is the body. Attributes: kind (decision/convention/bug/pref/note), tags (comma-separated), scope (project default or global).

Scoping

Project root is detected via git rev-parse --show-toplevel, falling back to $PWD. Searches return current-project rows plus anything saved with scope="global". Pass scope: "global" or scope: "all" to broaden. Set PI_MEMORY_GLOBAL=1 to make global the default for new saves.

Env vars

Variable Default Description
PI_MEMORY_DB $XDG_DATA_HOME/pi/memory.db SQLite file path
PI_MEMORY_PROJECT (auto) Override detected project root
PI_MEMORY_GLOBAL (off) When 1, new saves default to global

Inspect

sqlite3 ~/.local/share/pi/memory.db \
  "SELECT id, datetime(ts/1000,'unixepoch'), kind, title FROM memories ORDER BY ts DESC LIMIT 20"

RTK (rtk)

RTK is a Rust CLI that filters the output of common commands (cargo, npm, git, docker, …) so your LLM sees only the failures, not 500 lines of passing tests. The rtk extension hooks pi's tool_call event and delegates rewriting to the rtk rewrite binary.

The flake packages both the binary and the (vendored, verbatim) extension. Telemetry is off by default.

PI_EXTENSIONS=rtk nix run github:cyprx/pi.nix
# or use the binary directly:
nix run github:cyprx/pi.nix#rtk -- gain        # token-savings dashboard

Disable for a single command at runtime: RTK_DISABLED=1 (handled by the extension).

NixOS module

{
  inputs.pi-nix.url = "github:cyprx/pi.nix";

  outputs = { self, nixpkgs, pi-nix }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        pi-nix.nixosModules.default
        ({ pkgs, ... }: {
          nixpkgs.overlays = [ (_: _: { pi = pi-nix.packages.x86_64-linux.pi; }) ];
          programs.pi-coding-agent = {
            enable = true;
            extensions = [ "localmemory" "web-search" "rtk" ];
            # or:  extensions = [ "all" ]; disabledExtensions = [ "rtk" ];
            githubTokenFile = "/run/secrets/github-token";
          };
        })
      ];
    };
  };
}

Module options

Option Type Description
enable bool Install pi and set the env vars below.
package pkg The pi package. Default: pkgs.pi if overlaid, else built from this flake.
extensions [str] Sets PI_EXTENSIONS. Default: []. Use ["all"] for everything.
disabledExtensions [str] Sets PI_DISABLE_EXTENSIONS.
githubTokenFile path Read at boot into /etc/pi-coding-agent/env as GITHUB_PERSONAL_ACCESS_TOKEN.

Home Manager module

{
  imports = [ inputs.pi-nix.homeManagerModules.default ];

  programs.pi-coding-agent = {
    enable = true;
    extensions = [ "all" ];
    disabledExtensions = [ "rtk" ];
    githubTokenFile = "${config.home.homeDirectory}/.config/github/token";
  };
}

Outputs

packages.<system>.pi              # default: dispatcher with all extensions baked in
packages.<system>.pi-bare         # vanilla pi, no extensions, no wrapper
packages.<system>.rtk             # just the rtk binary
apps.<system>.{pi, pi-bare, rtk}  # nix run targets
lib.<system>.mkPi                 # composition function for your own flake
lib.<system>.extensions.{web-search, localmemory, github-mcp, github-cli, rtk}
nixosModules.default              # NixOS module
homeManagerModules.default        # Home Manager module
checks.<system>.pi-localmemory-tests

How it works

  1. Extensions are buildNpmPackage derivations that install their entry point at $out/share/pi-extensions/extension.ts and declare their PATH dependencies via passthru.runtimeInputs (e.g. the rtk extension carries the rtk binary).
  2. lib.mkPi takes an attrset extensions = { <name> = pkg; ... } and:
    • symlinks each ${pkg}/share/pi-extensions into $out/share/pi-extensions/<name>/,
    • writes a small dispatcher script at $out/libexec/pi-dispatch that builds -e <path> flags from $PI_EXTENSIONS / $PI_DISABLE_EXTENSIONS at launch,
    • wraps the dispatcher with makeWrapper to merge all extensions' runtime PATHs and default env vars,
    • exposes the result as $out/bin/pi.
  3. packages.pi is mkPi applied to the full extension set. Default selection is empty (opt-in).

The whole story is ~80 lines of Nix in nix/lib/mk-pi.nix.

Development / tests

The pure-logic helpers of the localmemory extension (FTS5 query sanitization, <remember> parser, schema/triggers) are covered by a small test suite using Node 24's built-in test runner. Zero extra npm deps.

# locally
cd nix/pi-localmemory
npm install
node --test --disable-warning=ExperimentalWarning extension.test.ts

# in the Nix sandbox (also runs as part of `nix flake check`)
nix build .#checks.<system>.pi-localmemory-tests

Migrating from previous versions

The package names pi-web-search, pi-localmemory, pi-lite, pi-github-mcp, pi-agentmemory, pi-full have all been replaced by a single pi package gated at runtime by PI_EXTENSIONS. The mapping is:

Old New
nix run .#pi-coding-agent nix run .#pi-bare
nix run .#pi-web-search PI_EXTENSIONS=web-search nix run .
nix run .#pi-localmemory PI_EXTENSIONS=localmemory nix run .
nix run .#pi-lite PI_EXTENSIONS=web-search,localmemory nix run .
nix run .#pi-github-mcp PI_EXTENSIONS=web-search,github-mcp,github-cli nix run .
nix run .#pi-full PI_EXTENSIONS=all nix run .
Module enableLocalMemory = true Module extensions = [ "localmemory" ];
Module enableGitHubMCP = true Module extensions = [ "github-mcp" "github-cli" ];

The agentmemory server, the iii-engine binary, and the pi-agentmemory extension have been removed.

License

MIT

from github.com/cyprx/pi.nix

Installing Pi.nix

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/cyprx/pi.nix

FAQ

Is Pi.nix MCP free?

Yes, Pi.nix MCP is free — one-click install via Unyly at no cost.

Does Pi.nix need an API key?

No, Pi.nix runs without API keys or environment variables.

Is Pi.nix hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Pi.nix in Claude Desktop, Claude Code or Cursor?

Open Pi.nix on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Pi.nix with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All ai MCPs