Pi OpenAI Bridge — Turn Your Pi Agent Into an OpenAI-Compatible API

Agent Daily · Tutorial · June 2026
📖 Tutorial 🏷 Pi Agent · OpenAI API · Extension · HTTP Bridge · Chat UI

Overview

Pi is a powerful coding agent — but it only has a TUI. What if you want to talk to it from a web chat interface like Open WebUI, ChatBox, or TypingMind? Or use it as a drop-in replacement for OpenAI's GPT API?

Pi OpenAI Bridge is a Pi extension that starts an HTTP server implementing the OpenAI Chat Completions API. Any application that can talk to OpenAI can now talk to your Pi agent — complete with your skills, extensions, context files, and custom brain.

1 What It Does

The extension adds an OpenAI-compatible HTTP API to your running Pi instance:

  • POST /v1/chat/completions — the standard OpenAI chat endpoint, with streaming support
  • GET /v1/models — lists the Pi agent as an available "model"
  • GET /health — health check for monitoring
  • /bridge — a Pi slash command to check the bridge status

This means you can point any OpenAI-compatible client at http://localhost:11434 and chat with your fully-configured Pi agent — with all its skills, AGENTS.md brain, extensions, and tools active.

💡 Key benefit: Your Pi agent becomes accessible from any chat UI, mobile app, or automation tool that supports the OpenAI API format — without changing anything about your Pi setup.

2 Architecture

💬
Chat UI
Open WebUI / ChatBox
🌉
Bridge
:11434/v1/chat
🥧
Pi Agent
pi -p "prompt"
🧠
LLM
GPT / Claude / etc

The bridge receives OpenAI-formatted requests, converts them into Pi print-mode invocations (pi -p), captures the output, and returns it in OpenAI response format. For streaming, it sends Server-Sent Events (SSE) as Pi generates output.

3 Installation

Step 1: Download the extension

# Download directly to Pi's global extensions directory curl -sL "https://raw.githubusercontent.com/example/pi-openai-bridge/main/pi-openai-bridge.ts" \ -o ~/.pi/agent/extensions/pi-openai-bridge.ts

Or manually copy the pi-openai-bridge.ts file to:

~/.pi/agent/extensions/pi-openai-bridge.ts

Step 2: Reload Pi

If Pi is already running, use:

/reload

Or restart Pi. You should see:

🌉 Pi OpenAI Bridge running at http://127.0.0.1:11434 POST /v1/chat/completions — OpenAI-compatible chat GET /v1/models — List models GET /health — Health check

Step 3: Verify

curl http://localhost:11434/health

Expected response:

{"status":"ok","service":"pi-openai-bridge","version":"1.0.0","model":"pi-agent"}
Tip: Use /bridge inside Pi to check the bridge status and see a quick reference of all endpoints.

4 Configuration

Configuration is done via environment variables. Set these before starting Pi:

VariableDefaultDescription
PI_BRIDGE_PORT11434HTTP port for the bridge server
PI_BRIDGE_HOST127.0.0.1Bind address. Use 0.0.0.0 to listen on all interfaces (for remote access)

Example: custom port

export PI_BRIDGE_PORT=8080 pi

Example: allow remote connections

export PI_BRIDGE_HOST=0.0.0.0 pi
⚠️ Warning: Setting PI_BRIDGE_HOST=0.0.0.0 exposes your Pi agent to the network. The bridge has no authentication — anyone who can reach the port can use your agent (and spend your LLM tokens). Use a reverse proxy with auth or Tailscale for remote access.

5 API Reference

POST /v1/chat/completions

The main endpoint. Accepts the standard OpenAI Chat Completions request format:

{ "model": "pi-agent", // optional, ignored (Pi uses its configured model) "messages": [ {"role": "system", "content": "You are a helpful assistant"}, {"role": "user", "content": "Hello!"} ], "stream": false, // true for SSE streaming "temperature": 0.7, // optional, passed to Pi's model "max_tokens": 2048 // optional }

GET /v1/models

Returns a list with a single model (pi-agent). Required by most chat UIs during setup.

GET /health

Simple health check. Returns {"status": "ok"}.

Response format

Standard OpenAI Chat Completion response:

{ "id": "chatcmpl-abc123...", "object": "chat.completion", "created": 1717689600, "model": "pi-agent", "choices": [{ "index": 0, "message": {"role": "assistant", "content": "Hello! How can I help?"}, "finish_reason": "stop" }], "usage": {"prompt_tokens": 12, "completion_tokens": 8, "total_tokens": 20} }

6 Testing with curl

Basic request

curl http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [ {"role": "user", "content": "What skills do you have?"} ] }'

With system prompt

curl http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [ {"role": "system", "content": "Respond in Greek only."}, {"role": "user", "content": "What is Pi Agent?"} ] }'

Streaming

curl -N http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"messages":[{"role":"user","content":"Hello!"}],"stream":true}'

7 Connect a Chat UI

Open WebUI

  1. Go to Settings → Connections
  2. Add a new OpenAI-compatible connection
  3. Set the URL to http://localhost:11434/v1
  4. API key: any string (e.g., not-needed) — the bridge doesn't check it
  5. The model pi-agent should appear in the model list

ChatBox

  1. Open Settings → AI Provider
  2. Select "OpenAI API Compatible"
  3. API Host: http://localhost:11434
  4. API Key: any string
  5. Model: pi-agent

TypingMind

  1. Go to Custom Model
  2. API Endpoint: http://localhost:11434/v1/chat/completions
  3. Model ID: pi-agent

Python (openai SDK)

from openai import OpenAI client = OpenAI( base_url="http://localhost:11434/v1", api_key="not-needed", ) response = client.chat.completions.create( model="pi-agent", messages=[{"role": "user", "content": "Hello Pi!"}], ) print(response.choices[0].message.content)
Tip: The bridge ignores the API key field — any non-empty string works. This is by design since the bridge runs locally. Add authentication via a reverse proxy if exposing to the network.

8 Streaming

When "stream": true is set in the request, the bridge returns Server-Sent Events (SSE) following the OpenAI streaming protocol:

  1. Initial chunk with role: "assistant"
  2. Content chunks as Pi generates output — each containing a fragment of the response
  3. Final chunk with finish_reason: "stop"
  4. Terminator: data: [DONE]

Most chat UIs use streaming by default for a responsive typing effect. The bridge handles this transparently — you don't need to configure anything special.

9 How It Works Under the Hood

The bridge uses Pi's print mode (pi -p "prompt") to process each request:

  1. Request arrives — the bridge parses the OpenAI-formatted JSON body
  2. System prompt extraction — messages with role: "system" are concatenated and passed via --append-system-prompt
  3. Conversation assembly — multi-turn conversations are formatted into a structured prompt. Single-turn messages are passed directly.
  4. Pi invocation — the bridge spawns pi -p "prompt" as a subprocess. Pi loads all your AGENTS.md, brain, skills, and extensions normally.
  5. Response formatting — Pi's output is wrapped in the OpenAI response JSON format with usage estimates
💡 Key design choice: Using pi -p (print mode) means every request goes through the full Pi pipeline — your AGENTS.md, brain.md, skills, and context files all apply. The API response IS your Pi agent, not a raw model.

10 Limitations & Considerations

FeatureStatusNotes
Chat completions✅ FullStreaming + non-streaming
System prompts✅ FullPassed via --append-system-prompt
Multi-turn conversations⚠️ PartialHistory formatted as structured prompt, not true session continuity
Tool use / function calling❌ Not yetPi tools (read/write/edit/bash) are available but tool-call API format is not mapped
Image/vision inputs❌ Not yetWould require mapping multimodal message format
Authentication❌ NoneAdd via reverse proxy (nginx/Caddy) or Tailscale
Embeddings❌ N/APi doesn't provide embedding models
Token counting⚠️ EstimatedUsage counts are approximated (chars/4), not real token counts
⚠️ Multi-turn limitation: Each API request spawns a fresh pi -p process. Conversation history from the chat UI is included in the prompt, but Pi doesn't maintain a persistent session across API calls. This means Pi's session features (tree navigation, fork, compact) are not available through the API.

11 Troubleshooting

Bridge doesn't start

  • Check that the file is at ~/.pi/agent/extensions/pi-openai-bridge.ts
  • Run /reload in Pi
  • Check Pi's console output for errors

Port already in use

export PI_BRIDGE_PORT=8080 # Use a different port

"pi" command not found in subprocess

  • Make sure Pi is installed globally: npm install -g --ignore-scripts @earendil-works/pi-coding-agent
  • Or that the pi binary is in your PATH

Slow responses

Each request spawns a new pi -p process, which includes loading AGENTS.md, brain, and skills. If your agent has many skills or a large brain, there will be startup overhead. Consider:

  • Using a fast model (e.g., GPT 5.5 low reasoning)
  • Keeping your AGENTS.md lean
  • Using streaming mode for a better UX

CORS errors from a web UI

The bridge includes CORS headers by default (Access-Control-Allow-Origin: *). If you're still getting CORS errors, check that your reverse proxy isn't stripping them.