Bug Summary
The Pi extension (build/pi-extension.js) injects a routing block that instructs the LLM to use ctx_execute, ctx_search, ctx_batch_execute, ctx_fetch_and_index, etc. — but none of these tools are registered via pi.registerTool().
The LLM sees the routing directive but cannot find the tools, so it falls back to ignoring the block entirely. This makes context-mode a pure cost with zero benefit in Pi.
Evidence
What the Pi extension DOES register:
pi.on("session_start", ...) ✅ session tracking
pi.on("tool_call", ...) ✅ event capture
pi.on("tool_result", ...) ✅ event capture
pi.on("before_agent_start", ...) ✅ routing block injection
pi.registerCommand("ctx-stats") ✅ command
pi.registerCommand("ctx-doctor") ✅ command
What the Pi extension DOES NOT register:
pi.registerTool("ctx_execute") ❌ MISSING
pi.registerTool("ctx_execute_file") ❌ MISSING
pi.registerTool("ctx_search") ❌ MISSING
pi.registerTool("ctx_batch_execute") ❌ MISSING
pi.registerTool("ctx_fetch_and_index") ❌ MISSING
pi.registerTool("ctx_index") ❌ MISSING
pi.registerTool("ctx_doctor") ❌ MISSING (only a command, not a tool)
pi.registerTool("ctx_stats") ❌ MISSING (only a command, not a tool)
pi.registerTool("ctx_purge") ❌ MISSING
pi.registerTool("ctx_upgrade") ❌ MISSING
pi.registerTool("ctx_insight") ❌ MISSING
Impact measurements (18 sessions over 2 days):
| Metric |
Value |
| System prompt cost per window |
~2,500 tokens (routing block + 12 skill descriptions + MCP tool stubs) |
| Tool calls via ctx_* tools |
0 (never called) |
| Tokens saved by context-mode |
0 |
| Knowledge base events recorded |
447 (never retrieved) |
| Net ROI |
Negative |
Root cause
The server.bundle.mjs implements 13 MCP tools via the MCP protocol (stdio JSON-RPC), which works for Claude Code and other MCP hosts. But Pi extensions use pi.registerTool() API instead of MCP protocol. The Pi extension file (pi-extension.js) never bridges these two worlds.
Suggested fix
Add pi.registerTool() calls in pi-extension.js that wrap the server-side tool handlers. Example pattern from Pi docs:
pi.registerTool({
name: "ctx_execute",
label: "ctx_execute",
description: "Execute code and index output for later search",
parameters: Type.Object({
language: Type.String({ description: "Programming language" }),
code: Type.String({ description: "Code to execute" }),
}),
async execute(toolCallId, params, signal, onUpdate, ctx) {
// Bridge to the existing server-side handler
const result = await serverHandler.executeCode(params);
return {
content: [{ type: "text", text: result }],
details: {},
};
},
});
This needs to be done for all 13 tools defined in server.bundle.mjs.
Environment
- context-mode: 1.0.111
- pi: 0.73.0
- OS: macOS (Apple Silicon)
- Node: v22.20.0
Bug Summary
The Pi extension (
build/pi-extension.js) injects a routing block that instructs the LLM to usectx_execute,ctx_search,ctx_batch_execute,ctx_fetch_and_index, etc. — but none of these tools are registered viapi.registerTool().The LLM sees the routing directive but cannot find the tools, so it falls back to ignoring the block entirely. This makes context-mode a pure cost with zero benefit in Pi.
Evidence
What the Pi extension DOES register:
What the Pi extension DOES NOT register:
Impact measurements (18 sessions over 2 days):
Root cause
The server.bundle.mjs implements 13 MCP tools via the MCP protocol (stdio JSON-RPC), which works for Claude Code and other MCP hosts. But Pi extensions use
pi.registerTool()API instead of MCP protocol. The Pi extension file (pi-extension.js) never bridges these two worlds.Suggested fix
Add
pi.registerTool()calls inpi-extension.jsthat wrap the server-side tool handlers. Example pattern from Pi docs:This needs to be done for all 13 tools defined in server.bundle.mjs.
Environment