pi-lean-ctx
Pi Coding Agent extension — routes bash/read/grep/find/ls through lean-ctx for strong token savings. The embedded MCP bridge (on by default) adds a persistent session cache so unchanged re-reads cost ~13 tokens.
Package details
Install pi-lean-ctx from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-lean-ctx- Package
pi-lean-ctx- Version
3.10.2- Published
- Sep 16, 2026
- Downloads
- 3,617/mo · 834/wk
- Author
- pounce_ch
- License
- Apache-2.0
- Types
- extension
- Size
- 692.1 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./extensions/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-lean-ctx
Status: Research / experimental integration. LeanCTX makes its Rust core available to Pi through a local CLI and a small TypeScript client. It exposes selected local Runtime tools in Pi; it does not provide a generic agent platform, hosted service, shared team context, or a performance guarantee. Measure a comparable workload with a declared quality threshold before making a gain claim. Product scope and status are governed by
docs/internal/README.md.
Pi Coding Agent extension that provides
ctx_-prefixed tools backed by a local lean-ctx Runtime.
- Default: embedded MCP bridge enabled; additive mode preserves Pi builtins
- Opt out:
LEAN_CTX_PI_ENABLE_MCP=0(or"enableMcp": false) forces the one-shot CLI path, which cannot cache across calls - Optional: replace mode (
LEAN_CTX_PI_MODE=replace) disables Pi builtins
Tool Mode
By default, pi-lean-ctx runs in additive mode: Pi's built-in tools (read, bash, ls, find, grep) remain available alongside the ctx_* tools. Agents can use either set.
To switch to replace mode (disables Pi builtins, only ctx_* tools available):
export LEAN_CTX_PI_MODE=replace
Tool surface (lean / standard / power)
The embedded bridge advertises whatever tool surface it requests from lean-ctx —
by default the lean core (including ctx_patch) plus the ctx_call gateway,
exactly like a normal lean-ctx install. Other tools, including ctx_edit, stay
reachable through ctx_call, and Pi's own native edit / write builtins are
available in every mode regardless of this setting.
To promote the whole lean-ctx registry (ctx_edit, architecture, and
quality tools, …) to first-class Pi tools, set toolProfile:
export LEAN_CTX_PI_TOOL_PROFILE=power # or "standard" for the balanced 15-tool set
or in config.json: "toolProfile": "power". Values: lean (default) ·
standard · power (full/all alias power). It maps to the engine's
LEAN_CTX_TOOL_PROFILE, so it mirrors lean-ctx profile <name> on a normal
install. power costs more prompt tokens (more tool schemas) — opt in when you
want the full surface in Pi. Check the active profile any time with /lean-ctx.
Config file
If you only use lean-ctx through Pi, keep every setting in one file instead of
env vars — ~/.pi/agent/extensions/pi-lean-ctx/config.json:
{
"mode": "replace",
"enableMcp": true,
"toolProfile": "power",
"binary": "/opt/lean-ctx/bin/lean-ctx",
"env": { "LEAN_CTX_COMPRESSION": "aggressive" }
}
mode → LEAN_CTX_PI_MODE, enableMcp → LEAN_CTX_PI_ENABLE_MCP,
toolProfile → LEAN_CTX_PI_TOOL_PROFILE, binary → LEAN_CTX_BIN,
disableTools → LEAN_CTX_PI_DISABLE_TOOLS,
toolPrefix → LEAN_CTX_PI_TOOL_PREFIX (see
Coexisting with AFT and magic-context).
The env map is forwarded to every lean-ctx subprocess, so it can override
~/.lean-ctx/config.toml engine settings. Explicit env vars still win over the
file; the file wins over defaults. The deny-list is the one exception — the env
and file lists are merged, since a deny-list is additive by intent.
What it does
ctx_ Tools (CLI-backed)
Adds ctx_-prefixed tools alongside Pi's builtins (or replaces them in replace mode):
| Tool | Replaces | Compression |
|---|---|---|
ctx_read |
read |
Smart mode selection (full/map/signatures) based on file type and size |
ctx_shell |
bash |
All shell commands compressed via lean-ctx's 95+ patterns |
ctx_grep |
grep |
Results grouped and compressed via ripgrep + lean-ctx |
ctx_find |
find |
File listings compressed and .gitignore-aware |
ctx_ls |
ls |
Directory output compressed |
Pi's edit and write builtins remain unchanged.
Direct lean-ctx CLI tool
The lean_ctx tool runs lean-ctx directly (no nested compression).
Use it for commands like:
lean_ctx overviewlean_ctx session …lean_ctx knowledge …lean_ctx gain/lean_ctx statslean_ctx index …
Embedded MCP Tools (enabled by default)
By default, pi-lean-ctx starts its embedded MCP bridge. It spawns lean-ctx as
an MCP server and registers its available advanced tools directly in Pi:
| Tool | Purpose |
|---|---|
ctx_session |
Session state management and persistence |
ctx_knowledge |
Project knowledge graph with temporal validity |
ctx_semantic_search |
Find code by meaning, not exact text |
ctx_overview |
Codebase overview and architecture analysis |
ctx_compress |
Manual compression control |
ctx_metrics |
Local usage diagnostics |
ctx_multi_read |
Batch file reads |
ctx_search |
MCP-native search |
ctx_tree |
File tree listing |
To opt out, set LEAN_CTX_PI_ENABLE_MCP=0 (or "enableMcp": false) and use
the one-shot ctx_ CLI tools plus lean_ctx instead.
Install
# 1. Install lean-ctx (if not already installed)
cargo install lean-ctx
# or: brew tap yvgude/lean-ctx && brew install lean-ctx
# 2. Install the Pi package
pi install npm:pi-lean-ctx
# 3. Restart Pi
Or use the automated setup:
lean-ctx init --agent pi
The published package has zero runtime npm dependencies: the MCP SDK
(incl. zod) is shipped as a self-contained vendor bundle
(extensions/vendor/mcp-sdk.cjs). This makes the extension immune to pi's
shared npm prefix rewriting node_modules on every pi install/pi remove
(which previously corrupted zod's locale files — GH #670).
How it works
ctx_ tools (CLI-backed)
These tools invoke the lean-ctx binary via CLI with LEAN_CTX_COMPRESS=1.
In the default additive mode, Pi’s native tools remain available alongside the
ctx_ tools. Replace mode hides the replaceable Pi builtins; additive mode with
shell routing enabled hides only bash.
Embedded MCP bridge (session cache + advanced tools)
On by default, pi-lean-ctx uses the lean-ctx binary as an MCP server (JSON-RPC over stdio).
This persistent process holds the session cache: ctx_read (every mode, including line
ranges) is routed through the bridge, allowing unchanged re-reads to use the Runtime's cached
representation. Token use depends on the file, mode, cache policy, and host. The bridge
also discovers the server's advertised tools (ctx_overview, ctx_graph, ctx_session, …),
filters out those already exposed as ctx_ CLI tools, and registers the rest as native Pi tools.
By default that surface is the lean core + ctx_call; set toolProfile: power (see the
Tool surface section) to also surface ctx_edit
and the rest of the registry as first-class Pi tools. After the first discovery, validated
versioned schemas are cached beside the Pi extension config. Warm starts register that direct
surface from the cache and defer the MCP process connection until the first bridge-backed call;
concurrent first calls share one connection attempt. That deferred connection is bounded by the
same 10s startup limit as eager discovery and is cancelled by the host's abort signal; if it
fails, the CLI-backed tools keep serving and a short cooldown stops every following call from
paying the bound again. Cache invalidation covers the extension and engine contract, binary
identity, tool profile, disabled tools, prefix, local tool surface, and forwarded engine
configuration. A missing, corrupt, or incompatible cache keeps the eager discovery path for that
startup and refreshes the cache atomically after success.
The bridge wins over ~/.pi/agent/mcp.json: a lean-ctx entry there (written by
lean-ctx init --agent pi) does not disable the embedded bridge, because Pi has no native
MCP support and that entry only does anything if you separately run
pi-mcp-adapter. /lean-ctx warns about possible
duplicates only when the adapter is genuinely running. If the bridge can't start, the CLI path
keeps working — only the cache and advanced tools are unavailable.
Automatic reconnection
If the MCP server process crashes, the bridge automatically reconnects (up to 3 attempts with exponential backoff). If reconnection fails, CLI-based tools continue working normally — only the advanced MCP tools become unavailable.
Disabling the bridge (optional)
The bridge is on by default. To force the one-shot CLI path (no cross-call cache), set an environment variable and restart Pi:
export LEAN_CTX_PI_ENABLE_MCP=0
pi
…or set "enableMcp": false in ~/.pi/agent/extensions/pi-lean-ctx/config.json.
Verifying local cache behavior
Use this self-test to establish whether an unchanged re-read collapses to the Runtime's cache stub for a chosen file and policy. It verifies cache behavior; it does not establish a workload-level performance or savings claim.
lean-ctx verify-cache
It reads a file twice through the real session cache and checks whether the
second read collapses to a [unchanged …] stub. The following is illustrative
diagnostic output, not a general result:
lean-ctx verify-cache
Target: src/main.rs
Cache policy: aggressive
Read #1: response observed locally
Read #2: unchanged stub emitted
Cache comparison: stub emitted
Cache scope: this file and active local policy
PASS — session cache engaged: the unchanged re-read returned a cache stub.
- Exit code
0= cache proven,1= no stub (cache not engaging),2= stubbing disabled by config (e.g.cache_policy = safe). Add--jsonfor CI. - Pass an explicit path to probe a real file:
lean-ctx verify-cache src/app.ts. lean-ctx doctoralso prints a Session cache line (CEP sessions + cross-call hit ratio) so you can answer "is the cache engaging?" at a glance.
On Pi specifically, the embedded MCP bridge (on by default) is what holds the cache across calls. If
verify-cachefails, confirm the bridge is connected via/lean-ctx; the one-shot CLI path cannot cache across calls.
Use a comparable baseline, treatment, quality threshold, and visible methodology before turning any local measurement into a performance claim.
pi-mcp-adapter compatibility
If you prefer using pi-mcp-adapter to manage your MCP servers, configure it explicitly:
# Option A: lean-ctx writes the config for you
lean-ctx init --agent pi
# Option B: Manual configuration in ~/.pi/agent/mcp.json
{
"mcpServers": {
"lean-ctx": {
"command": "/path/to/lean-ctx",
"lifecycle": "lazy",
"directTools": true
}
}
}
A lean-ctx entry in mcp.json does not disable the embedded bridge. If you
choose pi-mcp-adapter to own the MCP server, explicitly set
"enableMcp": false (or LEAN_CTX_PI_ENABLE_MCP=0) to avoid duplicate MCP
tools; pi-lean-ctx then keeps only its CLI-backed tools.
Binary Resolution
The extension locates the lean-ctx binary in this order:
LEAN_CTX_BINenvironment variablebinaryin~/.pi/agent/extensions/pi-lean-ctx/config.json~/.cargo/bin/lean-ctx~/.local/bin/lean-ctx(Linux) or%APPDATA%\Local\lean-ctx\lean-ctx.exe(Windows)/usr/local/bin/lean-ctx(macOS/Linux)lean-ctxon PATH
Smart Read Modes
The ctx_read tool automatically selects the optimal lean-ctx mode:
| File Type | Size | Mode |
|---|---|---|
.md, .json, .toml, .yaml, etc. |
Any | full |
| Code files (55+ extensions) | < 8 KB | full |
| Code files | 8–96 KB | map (deps + API signatures) |
| Code files | > 96 KB | signatures (AST extraction) |
| Other files | < 48 KB | full |
| Other files | > 48 KB | map |
Slash Command
Use /lean-ctx in Pi to check:
- Which binary is being used
- MCP bridge status (disabled / embedded / adapter)
- Active
ctx_tool names - Coexistence info (#359): active tool prefix, tools handed to other extensions
(
Disabled), and tools skipped due to a name already taken (Skipped)
Disabling specific tools
To disable specific MCP tools, configure disabled_tools in ~/.lean-ctx/config.toml:
disabled_tools = ["ctx_graph", "ctx_benchmark"]
Or via environment variable:
LEAN_CTX_DISABLED_TOOLS=ctx_graph,ctx_benchmark pi
Coexisting with AFT and magic-context
pi-lean-ctx is built to stack with other Pi extensions such as AFT and magic-context (issue #359).
No more load crashes. If another extension already registered a tool name
(e.g. magic-context's ctx_expand), pi-lean-ctx now skips that tool with a
warning instead of crashing the whole agent. The rest of lean-ctx keeps
working. Run /lean-ctx to see exactly which tools were skipped.
Hand tool names to another extension
Use a deny-list so the other extension owns shared names while lean-ctx keeps
its compression + session-cache core (ctx_read, ctx_shell, …):
# env: comma/space separated, case-insensitive
export LEAN_CTX_PI_DISABLE_TOOLS="ctx_memory,ctx_expand,ctx_search"
…or in ~/.pi/agent/extensions/pi-lean-ctx/config.json (merged with the env list):
{
"disableTools": ["ctx_memory", "ctx_expand", "ctx_search"]
}
This is the Pi-extension deny-list — it controls which tools lean-ctx registers in Pi (including its own
ctx_*tools likectx_grep). It is separate from the engine-leveldisabled_tools/LEAN_CTX_DISABLED_TOOLS, which hides tools from the MCP server itself.
Or namespace them with a prefix
Keep every tool but expose the bridge tools under your own prefix, so nothing collides and small models see no duplicate names:
export LEAN_CTX_PI_TOOL_PREFIX="lc_" # ctx_expand → lc_ctx_expand
The signature tools (ctx_read, ctx_shell, ctx_ls, ctx_find, ctx_grep)
keep their stable names; only the bridge-discovered MCP tools are prefixed.
Curated profile (recommended division of labor)
| Concern | Owner | Why |
|---|---|---|
| File reads, shell, grep/find/ls — compression + session cache | lean-ctx | Local behavior; measure a comparable workload with a quality gate before making a gain claim |
Long-horizon memory (ctx_memory, ctx_expand) |
magic-context | purpose-built long-term memory |
Symbol-aware file ops (aft_*) |
AFT | precise AST edits |
Copy-paste config for the profile above
(~/.pi/agent/extensions/pi-lean-ctx/config.json):
{
"mode": "additive",
"enableMcp": true,
"disableTools": ["ctx_memory", "ctx_expand", "ctx_search"]
}
Result: no duplicate search/memory tools in the tool list, no load crash, and
each extension does what it is best at. Verify with /lean-ctx, which now lists
the active prefix plus any handed-off (Disabled) and skipped tools.