Integrations

pibox

Try it

Install, configure, or run pi-coding-agent through the pibox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.

What it does

pi-coding-agent inside an aicodebox container. One image, seven ways in: interactive shell, one-shot exec, HTTP REST API, OpenAI-compatible endpoint, MCP server, Telegram bot, cron scheduler.

The skill document

pibox

pi-coding-agent inside an aicodebox container. One image, seven ways in: interactive shell, one-shot exec, HTTP REST API, OpenAI-compatible endpoint, MCP server, Telegram bot, cron scheduler.

You talk to pibox, pibox talks to pi, pi talks to whatever Anthropic-compatible LLM you point it at (ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN).

For installation and configuration, see references/setup.md.

Security & safety

  • No auth when PIBOX_API_MODE_TOKEN is unset. With it empty the REST/OpenAI-compatible API surface is UNAUTHENTICATED — anyone who can reach it gets full agent-execution and workspace file-read/write/delete access. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy.
  • No auth when PIBOX_MCP_MODE_TOKEN is unset. Same story for the MCP surface (/mcp or the sidecar) — empty token means unauthenticated run_prompt/file-tool access, and it does not fall back to PIBOX_API_MODE_TOKEN. Set it explicitly.
  • Destructive & irreversible. DELETE /run/{id}, DELETE /files/{path}, and the MCP delete_file tool remove state with no undo (canceled runs can't be resumed; deleted files are gone). An agent must NEVER call these unless the user explicitly asked for that exact action; confirm the specific target first, scope it to the current task, and never enumerate-then-bulk-delete. On a shared/multi-tenant instance a deletion can destroy another caller's in-flight run or workspace file — treat these routes as admin-only.

When To Use

  • Drive pi-coding-agent from a script/service instead of an interactive terminal (/run, /openai/v1/chat/completions, or MCP tools).
  • Wire pi into an OpenAI-SDK-compatible client (LangChain, openai-python) via the /openai/v1/* surface.
  • Give an MCP-aware agent (Claude, Cursor, OpenClaw) remote tool access to a pi-driven workspace.
  • Chat with pi from Telegram, with per-chat model/effort overrides and file transfer.
  • Schedule recurring pi runs (standups, digests, periodic maintenance) via cron mode.
  • One-off container run for a single prompt (CI step, quick script) via one-shot exec.

When NOT To Use

  • Don't run two foreground modes together except Telegram+Cron (cron runs in-thread inside telegram) — API set alongside anything else wins and the others don't start.
  • Don't expect /openai/v1/chat/completions to stream token-by-token when tools or a JSON schema is in play — those modes compute the full answer first and replay it as a single-shot SSE stream (still a valid stream, just not incremental). Plain chat streams incrementally.
  • Don't rely on PIBOX_MCP_MODE_TOKEN falling back to PIBOX_API_MODE_TOKEN — MCP has its own bearer, no fallback.
  • Don't point multiple concurrent runs at the same workspace — the API/OAI layer returns 409 "workspace busy" while a run is in flight in that workspace.

Interactive shell mode

No mode env var set, no args passed to docker run. Falls through to pi's own CLI, invoked directly — a normal interactive pi session inside the container.

docker run -it --rm \
  -e ANTHROPIC_AUTH_TOKEN=your-token \
  -e ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
  -e ANTHROPIC_MODEL=glm-4.6 \
  -v "$PWD/workspace:/workspace" \
  psyb0t/pibox:latest

Auth: none at the container boundary — you're inside it. pi itself uses the ANTHROPIC_* env vars.

One-shot exec mode

No mode env var set, args passed after the image name are forwarded verbatim to the pi binary (passthrough). -p "" runs pi non-interactively and prints the result to stdout, then exits.

docker run --rm \
  -e ANTHROPIC_AUTH_TOKEN=your-token \
  -e ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
  -e ANTHROPIC_MODEL=glm-4.6 \
  -v "$PWD/workspace:/workspace" \
  psyb0t/pibox:latest \
  -p "list the files in /workspace"

Any pi CLI flag works here (--model, --thinking, --session, etc.) — the entrypoint just execs pi "$@". Auth: none at the container boundary; pi uses ANTHROPIC_*.

REST API mode

PIBOX_API_MODE=1. FastAPI server on :8080 (override PIBOX_API_MODE_PORT). Requires PIBOX_AVAILABLE_MODELS= — the server refuses to boot without it (no sensible default; pi can drive any provider's models).

docker run -d --network host \
  -e PIBOX_API_MODE=1 \
  -e PIBOX_API_MODE_TOKEN=your-secret \
  -e PIBOX_AVAILABLE_MODELS=glm-4.6,glm-4.5-air \
  -e ANTHROPIC_AUTH_TOKEN=your-token \
  -e ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
  -e ANTHROPIC_MODEL=glm-4.6 \
  -v "$PWD/workspace:/workspace" \
  psyb0t/pibox:latest
MethodPathWhat it does
GET/healthzliveness — {ok, adapter}, unauthenticated
GET/statusin-flight runs + busy workspaces
POST/runrun the agent — sync by default; body async or fireAndForget makes it fire-and-poll
GET/run/result?runId=poll a run started with async/fireAndForget
DELETE/run/{id}cancel an in-flight run (kills the subprocess)
GET/fileslist the workspace root — {entries: [{name, type, size?}, ...]}
GET/files/{path}list a sub-directory, or stream a file's bytes
PUT/files/{path}upload — raw request body becomes the file contents; parent dirs auto-created
DELETE/files/{path}delete a file (refuses directories — 400)
POST/openai/v1/chat/completionsOpenAI-compatible chat (see below)
GET/openai/v1/modelsmodel list, from PIBOX_AVAILABLE_MODELS
POST/mcpMCP server (streamable HTTP) — mounted only when PIBOX_MCP_MODE=1

All /files/* paths resolve against the workspace root with traversal checking — .. segments that escape the root return 400. Every route except /healthz is gated by Authorization: Bearer when that var is set; empty/unset token = no auth.

No auth when PIBOX_API_MODE_TOKEN is unset. With it empty the API is UNAUTHENTICATED — anyone who can reach it gets run-the-agent and workspace file-read/write/delete access. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy.

Destructive & irreversible. DELETE /run/{id} kills the in-flight subprocess with no undo, and DELETE /files/{path} deletes a workspace file with no undo. An agent must NEVER call either unless the user explicitly asked for that exact action; confirm the specific target first; scope it to the current task; never enumerate-then-bulk-delete. On a shared/multi-tenant instance this can disrupt or destroy another caller's run or data — treat these routes as admin-only.

# sync run
curl -s http://localhost:8080/run \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "say HELLO", "workspace": "/workspace"}'

# async run, then poll
RUN_ID=$(curl -s http://localhost:8080/run \
  -H "Authorization: Bearer your-secret" -H "Content-Type: application/json" \
  -d '{"prompt": "long task", "async": true}' | jq -r .runId)
curl -s "http://localhost:8080/run/result?runId=$RUN_ID" \
  -H "Authorization: Bearer your-secret"

# cancel it
curl -s -X DELETE "http://localhost:8080/run/$RUN_ID" \
  -H "Authorization: Bearer your-secret"

# upload / download / list / delete a workspace file
curl -sS -X PUT -H "Authorization: Bearer your-secret" \
  --data-binary @local.txt http://localhost:8080/files/notes/hello.txt
curl -sS -H "Authorization: Bearer your-secret" \
  http://localhost:8080/files/notes/hello.txt
curl -sS -H "Authorization: Bearer your-secret" \
  http://localhost:8080/files/notes | jq
curl -sS -X DELETE -H "Authorization: Bearer your-secret" \
  http://localhost:8080/files/notes/hello.txt

POST /run body fields: prompt (required), workspace, model, systemPrompt, appendSystemPrompt, jsonSchema, noContinue, resume, timeoutSeconds, thinking, noTools, toolsAllowlist, extraArgs, async, fireAndForget, includeRaw. With jsonSchema set the response is verbose: text, json (schema-validated), events, sessionId, usage, attempts (per-retry breakdown, up to 3 self-correction retries on parse/validation failure). Without jsonSchema the response is lean: {runId, workspace, exitCode, text}.

OpenAI-compatible endpoint mode

Same PIBOX_API_MODE=1 server, POST /openai/v1/chat/completions and GET /openai/v1/models. Drop-in for any OpenAI-SDK client — point the base URL at http://host:8080/openai/v1 and set the model to one of PIBOX_AVAILABLE_MODELS.

curl -s http://localhost:8080/openai/v1/chat/completions \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-4.6",
    "messages": [{"role": "user", "content": "say HELLO"}]
  }'

Streaming ("stream": true): plain chat streams incrementally, one SSE chunk per token delta. Requests carrying tools or a JSON-schema constraint can't stream token-by-token (the answer only exists once fully computed) — they're buffered: the whole response is computed, then replayed as a single-shot SSE stream (role chunk → one content/tool_calls delta → finish chunk → [DONE]). The client's streaming parser is satisfied either way.

Tools / tool_choice (OpenAI client-executed tool calling): send tools (OpenAI function-schema array) and optionally tool_choice (auto/none/required/{"type":"function","function":{"name":...}}). pibox's own internal tools (bash, file edits) default OFF while in tool mode so the model behaves as a pure function-calling LLM — override with header x-aicodebox-no-tools: 0 to re-enable the hybrid. The response comes back as tool_calls + finish_reason: "tool_calls", exactly like OpenAI; you execute the tool client-side and send the result back in the next message round.

response_format / JSON-schema: standard OpenAI response_format body field —{"type": "text"} (default), {"type": "json_object"} (force parseable JSON, no shape constraint), or {"type": "json_schema", "json_schema": {"name": ..., "schema": {...}}} (schema-validated, with up to 3 self-correction retries on failure → 422 if still invalid). tools and response_format compose in one request: a tool-call turn returns tool_calls (not schema-checked); the model's final answer (no more tool calls) is what gets schema-validated.

Extra x-aicodebox-* headers (workspace pinning, session continuation, extra args, timeout, tools allowlist) are documented in references/setup.md. Upstream provider errors (auth failure, rate limit, content-safety rejection) surface as HTTP 400, not a silent empty response.

MCP server mode

PIBOX_MCP_MODE=1. Exposes an MCP (streamable HTTP) surface with 5 tools: run_prompt, list_files, read_file, write_file, delete_file. Coexists with any foreground mode:

ForegroundMCP placement
API mode (PIBOX_API_MODE=1)mounted at /mcp on the API port — no extra process
Telegram / Cron / passthrough / nonesidecar uvicorn on its own port, PIBOX_MCP_MODE_PORT (default 8081), mounted at the port root
claude mcp add --transport http pibox http://localhost:8080/mcp \
  --header "Authorization: Bearer your-mcp-token"

Raw JSON-RPC (debugging, non-MCP-aware callers):

curl -s http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer your-mcp-token" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'

run_prompt(prompt, workspace?, model?, system_prompt?, append_system_prompt?, no_continue=true, resume?, thinking?, json_schema?) invokes the agent and returns its text. list_files/read_file/write_file/delete_file operate on workspace-relative paths with the same traversal guard as the REST /files endpoints.

Destructive & irreversible. delete_file removes a workspace file with no undo. An agent must NEVER call it unless the user explicitly asked for that exact action; confirm the specific target first; scope it to the current task; never enumerate-then-bulk-delete. On a shared/multi-tenant instance this can destroy another caller's workspace data — treat it as admin-only.

Auth: PIBOX_MCP_MODE_TOKEN= — bearer via Authorization: Bearer …, or ?apiToken=… query param for clients that can't set headers. Empty = no auth. No fallback to PIBOX_API_MODE_TOKEN.

No auth when PIBOX_MCP_MODE_TOKEN is unset. With it empty the MCP surface is UNAUTHENTICATED — anyone who can reach it gets run_prompt (arbitrary agent execution) and workspace file read/write/delete access. NEVER expose such an instance on a network or to untrusted agents; set the token and bind to loopback / behind an authenticating proxy.

Telegram bot mode

PIBOX_TELEGRAM_MODE=1 + PIBOX_TELEGRAM_MODE_TOKEN=.

  • Text in → pi runs → Markdown→HTML rendered response back.
  • File uploads land in the chat's workspace. [SEND_FILE: path] in pi's output delivers workspace files as Telegram attachments.
  • Per-chat overrides: /model, /effort (maps to pi's --thinking levels), /system_prompt, /append_system_prompt. Persisted across restarts.
  • /cancel kills the in-flight run. /reload re-reads config. /config dumps merged settings. /status shows in-flight state. /fetch downloads a file. /start, /help for basics.
  • Replies to cron messages inject the job's instruction + result so pi has full context for follow-ups.

Config at $HOME/.aicodebox/telegram.yml (override via PIBOX_TELEGRAM_MODE_CONFIG):

allowed_chats: [-100123, 42]
default:
  model: glm-4.6
  workspace: shared
chats:
  -100123:
    workspace: alpha
    allowed_users: [10, 20]

Auth: chat/user allowlisting via the config yaml (allowed_chats, per-chat allowed_users) — no separate bearer token, the bot token itself gates who can even message it.

Cron scheduler mode

PIBOX_CRON_MODE=1 + PIBOX_CRON_MODE_FILE=/path/to/cron.yaml. 6-field cron schedules via croniter. Each job fires pi with the given instruction on schedule.

jobs:
  - name: morning-standup
    schedule: "0 0 9 * * 1-5"
    instruction: |
      Summarize what changed in /workspace since yesterday.
      Be brief. One paragraph max.
    workspace: myproject
    telegram_chat_id: -100123
    model: glm-4.6
    thinking: low

Each run gets a history dir at $HOME/.aicodebox/cron/history//-/ (override root via PIBOX_CRON_MODE_HISTORY_DIR) with meta.json, stdout.log, stderr.log, result.txt. If telegram is also configured, telegram.json lands there too and the next run's prompt gets a "prior run" hint so pi can reference its own history without you wiring it up. Running alongside Telegram mode (PIBOX_TELEGRAM_MODE=1 + PIBOX_CRON_MODE=1) runs cron in-thread inside the telegram process — the only foreground-mode pairing allowed.

Auth: none — this is a scheduled background job, not a request-driven surface. telegram_chat_id on a job routes its result through the (already-authenticated) Telegram bot if set.

Auth (LLM upstream)

pi speaks the Anthropic wire protocol. Point it at any Anthropic-compatible endpoint via env vars, forwarded into every mode:

VarPurpose
ANTHROPIC_AUTH_TOKENBearer token (Z.AI, direct Anthropic, etc.)
ANTHROPIC_API_KEYSame thing — pi reads both
ANTHROPIC_BASE_URLEndpoint override (default https://api.anthropic.com)
ANTHROPIC_MODELDefault model when the caller doesn't specify one

Z.AI's GLM models are a fast/cheap default: ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic + ANTHROPIC_MODEL=glm-4.6.

pi's thinking levels (--thinking): off, minimal, low, medium, high, xhigh. Exposed as /effort in Telegram mode and thinking in API/OAI requests.

Surface-level auth (separate from the LLM upstream) is per-mode: PIBOX_API_MODE_TOKEN gates the REST + OAI routes, PIBOX_MCP_MODE_TOKEN gates MCP (no fallback between the two), Telegram gates by bot-token possession + chat/user allowlist, cron and interactive/exec modes have no surface auth (container-boundary trust). Both PIBOX_API_MODE_TOKEN and PIBOX_MCP_MODE_TOKEN default to empty, which means no auth — see Security & safety above before exposing either surface beyond localhost.

Typical Workflows

One-off task from a script, no server:

docker run --rm -e ANTHROPIC_AUTH_TOKEN=$TOKEN -e ANTHROPIC_BASE_URL=$BASE_URL \
  -e ANTHROPIC_MODEL=glm-4.6 -v "$PWD:/workspace" \
  psyb0t/pibox:latest -p "summarize the diff in /workspace"

Long-running server, drive it with curl:

docker run -d --network host -e PIBOX_API_MODE=1 -e PIBOX_API_MODE_TOKEN=$SECRET \
  -e PIBOX_AVAILABLE_MODELS=glm-4.6 -e ANTHROPIC_AUTH_TOKEN=$TOKEN \
  -e ANTHROPIC_BASE_URL=$BASE_URL -v "$PWD/workspace:/workspace" psyb0t/pibox:latest
curl -s http://localhost:8080/run -H "Authorization: Bearer $SECRET" \
  -H "Content-Type: application/json" -d '{"prompt": "run the tests and report failures"}'

Structured extraction via JSON schema:

curl -s http://localhost:8080/run -H "Authorization: Bearer $SECRET" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "extract TODOs from /workspace", "jsonSchema": {"type":"object","properties":{"todos":{"type":"array","items":{"type":"string"}}},"required":["todos"]}}'

Wire an MCP-aware agent (Claude Code, OpenClaw) to a running pibox:

claude mcp add --transport http pibox http://localhost:8080/mcp \
  --header "Authorization: Bearer $MCP_TOKEN"

Chat + Telegram + scheduled digest, all on one box:

docker run -d --network host \
  -e PIBOX_TELEGRAM_MODE=1 -e PIBOX_TELEGRAM_MODE_TOKEN=$BOT_TOKEN \
  -e PIBOX_CRON_MODE=1 -e PIBOX_CRON_MODE_FILE=/config/cron.yaml \
  -e ANTHROPIC_AUTH_TOKEN=$TOKEN -e ANTHROPIC_BASE_URL=$BASE_URL \
  -v "$PWD/workspace:/workspace" -v "$PWD/cron.yaml:/config/cron.yaml:ro" \
  psyb0t/pibox:latest

Related skills

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai21 installs8 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván1 installs

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván1 installs

More from psyb0t

Browse all skills

Drive a user-deployed mt5-httpapi MetaTrader 5 bridge over HTTP, with per-action confirmation on every real-money call.

by psyb0t107 installs4 stars

Docker-packaged browser automation for QA against anti-bot stacks and authorized detection testing.

by psyb0t137 installs2 stars

Self-hosted OpenAI-compatible speech service — transcription, translation, and synthesis from one container.

by psyb0t13 installs

Run ffmpeg, sox, and ImageMagick jobs against your files in a fixed-allowlist SSH sandbox.

by psyb0t71 installs

Generate speech audio via Qwen3-TTS over SSH with preset voices, voice cloning, and voice design.

by psyb0t55 installs

Drive one or more IMAP/SMTP mailboxes through a single REST + MCP endpoint — read, search, send, mark-seen, and delete across accounts in parallel.

by psyb0t15 installs