AI/pi-coding-agent.md

Pi Coding Agent

Design philosophy: no built-in MCP

Pi doesn't have built-in MCP support โ€” this is an intentional design choice. From the docs:

No MCP. Build CLI tools with READMEs (see Skills), or build an extension that adds MCP support. Why? https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/

Two paths instead:


Option 1: Use Skills (the pi-native approach)

Skills are markdown-based capability packages that follow the Agent Skills standard. They're simpler than MCP โ€” a skill is just a folder with a SKILL.md that tells the LLM how to use a CLI tool.

# My Skill
Use this skill when the user asks about X.
## Steps
1. Do this
2. Then that

Place skills in:

  • ~/.pi/agent/skills/ (global)
  • .pi/skills/ (project-local)

Then invoke with /skill:name or let the agent auto-detect them.


Option 2: Build an MCP extension

Since pi supports TypeScript extensions, you can build one that speaks the MCP protocol. An MCP extension would typically:

  1. Register tools via pi.registerTool() for each MCP server tool
  2. Use @modelcontextprotocol/sdk (npm package) to connect to MCP servers via stdio or SSE
  3. Proxy tool calls from the LLM to the appropriate MCP server

The pattern is similar to how the ssh.ts example delegates tools to a remote machine, or how the subagent example delegates tasks. Here's the basic shape:

// ~/.pi/agent/extensions/mcp.ts
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";

export default async function (pi: ExtensionAPI) {
  // Connect to MCP servers on startup
  // Register their tools with pi
  // Proxy tool calls through to the MCP server

  pi.on("session_start", async (_event, ctx) => {
    // Initialize MCP client connections
    ctx.ui.notify("MCP servers connected", "info");
  });
}

There's currently no official MCP extension in pi's examples or packages, but you can ask pi itself to help you build one.


Recommendation

If your use case is fairly straightforward (e.g., the MCP server wraps a CLI tool), use Skills โ€” they're simpler, first-class in pi, and avoid the complexity of the MCP protocol. If you need the full MCP protocol (like connecting to a remote resource server), building an extension is the way to go.


Pi Web UI + MCP Adapter Setup

A web-based Pi with full MCP server support, proxied through nginx.

Architecture

Browser โ”€โ”€HTTPSโ”€โ”€> pi.dph.am โ”€โ”€nginxโ”€โ”€> pi-webui (port 49998) โ”€โ”€> Pi CLI (via /resume)
                                                    โ”‚
                                            pi-mcp-adapter
                                                    โ”‚
                                            ~/.config/mcp/mcp.json
                                                    โ”‚
                                              (symlink to ~/.mcp.json)

Components

Component Repo Purpose
pi-webui github.com/khimaros/pi-webui Web-based UI for Pi โ€” browser access instead of terminal
pi-mcp-adapter github.com/nicobailon/pi-mcp-adapter MCP server adapter so Pi can use all configured MCP servers

Installation & Config

npm install -g @khimaros/pi-webui

Symlink trick โ€” Pi-mcp-adapter reads MCP config from ~/.config/mcp/mcp.json. Link it to the global Claude MCP config:

ln -s ~/.mcp.json ~/.config/mcp/mcp.json

This way every MCP server configured for Claude Code (Asana, Granola, notes, LSP, etc.) is also available in the Pi web UI.

Environment & Startup

export PI_WEBUI_HOST=0.0.0.0
export PI_WEBUI_PORT=49998
pi-webui

Note: pi --webui-listen 0.0.0.0:49998 currently doesn't work โ€” always use the pi-webui CLI directly.

Session Navigation: /resume trick

Pi's pi-webui start directory determines where new sessions are rooted. To switch between projects without restarting the web UI:

  1. In Terminal (direct Pi CLI): start Pi sessions in different project directories:

    # Terminal 1: Qwestly
    cd ~/Work/qwestly-workspace && pi
    
    # Terminal 2: Personal
    cd ~/Work/notes && pi
    
    # etc.
    
  2. In pi-webui: use /resume to see and hop between existing sessions. Once resumed into a session that lives in a different directory, use /new to start a fresh Pi session in that project's context.

This effectively gives you "cd between folders" โ€” each session retains its original working directory, and /resume + /new lets you spawn new sessions within any of those directories.

Nginx Proxy

  • Domain: https://pi.dph.am
  • Backend: localhost:49998
  • Auth service: lives in ~/Work/services/nginx-auth-service
    • Provides an authentication layer in front of the Pi web UI
    • Keeps access restricted

The proxy config and auth setup live in the nginx-auth-service project.