Server data from the Official MCP Registry
Self-hosted MCP server: pi-coding-agent tools (run_prompt, file ops) over streamable HTTP.
Self-hosted MCP server: pi-coding-agent tools (run_prompt, file ops) over streamable HTTP.
This is a well-structured MCP bridge plugin that connects AI agents to a self-hosted pibox server. The code demonstrates good security practices with proper input validation, safe token handling, and no malicious patterns. Minor code quality observations exist around error handling and type safety, but they do not constitute security vulnerabilities. Permissions are appropriate for the stated purpose of bridging MCP protocols.
8 files analyzed · 5 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-psyb0t-pibox": {
"args": [
"-y",
"@psyb0t/pibox"
],
"command": "npx"
}
}
}From the project's GitHub README.
pi-coding-agent inside an aicodebox container. One image, five ways in: interactive shell, one-shot API, OpenAI-compatible endpoint, MCP server, Telegram bot, and a cron scheduler that fires pi on whatever schedule you want.
You talk to pibox. pibox talks to pi. pi talks to whatever LLM you point it at. Nobody cares about the middle.
# one-shot prompt
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 \
psyb0t/pibox:latest \
-p "list the files in /workspace"
# API server
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
Foreground modes (API / Telegram / Cron) are mutually exclusive — except PIBOX_TELEGRAM_MODE=1 + PIBOX_CRON_MODE=1, which run together (cron in-thread inside telegram). API wins if set alongside anything else.
MCP mode (PIBOX_MCP_MODE=1) is independent — it coexists with whatever foreground mode is running. In API mode it's mounted at /mcp on the API port; in other modes it runs as a sidecar uvicorn on its own port.
PIBOX_API_MODE=1. FastAPI server on :8080 (override with PIBOX_API_MODE_PORT).
Required:
PIBOX_AVAILABLE_MODELS=<csv>(e.g.glm-4.6,claude-sonnet-4-6). API mode refuses to boot without it —/openai/v1/modelsneeds a real list and there's no sensible default (pi can drive any provider's models). Pick the ones your configuredANTHROPIC_BASE_URL/ provider actually serves.
| Method | Path | What it does |
|---|---|---|
GET | /healthz | liveness |
GET | /status | in-flight runs |
POST | /run | agent run → {text, exit_code, ...}; body async/fireAndForget fires and returns a job id instead of blocking |
GET | /run/result?runId=<id> | poll async job |
DELETE | /run/{id} | kill in-flight run |
GET | /files | list 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/completions | OpenAI-compatible (streaming + non-streaming; supports tools / tool_choice client-executed tool calling, composable with response_format) |
GET | /openai/v1/models | model list |
POST | /mcp | MCP server (streamable HTTP) — mounted only when PIBOX_MCP_MODE=1 |
All /files/* paths are resolved against the workspace root with traversal checking — .. segments that escape the root return 400. Same Authorization: Bearer ... token gates them as the rest of the API.
# upload a file
curl -sS -X PUT \
-H "Authorization: Bearer your-secret" \
--data-binary @local.txt \
http://localhost:8080/files/notes/hello.txt
# download it back
curl -sS -H "Authorization: Bearer your-secret" \
http://localhost:8080/files/notes/hello.txt
# list the dir
curl -sS -H "Authorization: Bearer your-secret" \
http://localhost:8080/files/notes | jq
# delete it
curl -sS -X DELETE -H "Authorization: Bearer your-secret" \
http://localhost:8080/files/notes/hello.txt
POST /run body: prompt (required), workspace, model, systemPrompt, appendSystemPrompt, jsonSchema, noContinue, resume, timeoutSeconds, thinking, noTools, toolsAllowlist, includeRaw, async, fireAndForget. With jsonSchema set the response includes text, json, events, sessionId, usage, attempts; without it the response is {runId, workspace, exitCode, text}.
curl -s http://localhost:8080/run \
-H "Authorization: Bearer your-secret" \
-H "Content-Type: application/json" \
-d '{"prompt": "say HELLO", "workspace": "/workspace"}'
PIBOX_TELEGRAM_MODE=1 + PIBOX_TELEGRAM_MODE_TOKEN=<token>.
[SEND_FILE: path] in pi's output delivers workspace files as Telegram attachments./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. /fetch <path> downloads a file.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]
PIBOX_CRON_MODE=1 + PIBOX_CRON_MODE_FILE=/path/to/cron.yaml. 6-field schedules via croniter. Each job fires pi with the given instruction.
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/<workspace>/<timestamp>-<job>/ with meta.json, stdout.log, stderr.log, result.txt. If telegram is 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.
PIBOX_MCP_MODE=1. Exposes the MCP (Model Context Protocol) surface — run_prompt, list_files, read_file, write_file, delete_file as tools. Coexists with any foreground mode:
| Foreground | MCP placement |
|---|---|
API mode (PIBOX_API_MODE=1) | mounted at /mcp on the API port — no extra process |
| Telegram / Cron / passthrough | sidecar uvicorn on PIBOX_MCP_MODE_PORT (default 8081) |
Auth: PIBOX_MCP_MODE_TOKEN=<token> — bearer in the Authorization: Bearer … header, or ?apiToken=… for clients that can't set headers. Empty = no auth. No fallback to API_MODE_TOKEN — MCP has its own bearer.
Naming convention: PIBOX_<MODE>_MODE=1 is the on/off flag, PIBOX_<MODE>_MODE_<KNOB>=... is its config. Non-mode-scoped vars (workspace, container name, available models) are bare.
The image is built on top of aicodebox, so the equivalent AICODEBOX_* names also work — the entrypoint translates PIBOX_X to AICODEBOX_X when only the pibox-prefixed one is set. If you set both, AICODEBOX_* wins.
| Var | Default | What it does |
|---|---|---|
PIBOX_API_MODE | 0 | Boot the HTTP API server (foreground) |
PIBOX_TELEGRAM_MODE | 0 | Boot the Telegram bot (foreground) |
PIBOX_CRON_MODE | 0 | Boot the cron scheduler (foreground; in-thread when telegram is also on) |
PIBOX_MCP_MODE | 0 | Expose MCP — mounted at /mcp in API mode, or as a sidecar elsewhere |
| Var | Default | What it does |
|---|---|---|
PIBOX_API_MODE_PORT | 8080 | Port the API server binds to |
PIBOX_API_MODE_TOKEN | empty | Bearer token for the API surface. Empty = no auth |
| Var | Default | What it does |
|---|---|---|
PIBOX_TELEGRAM_MODE_TOKEN | — | Bot token from @BotFather |
PIBOX_TELEGRAM_MODE_CONFIG | ~/.aicodebox/telegram.yml | Path to the telegram config yaml |
PIBOX_TELEGRAM_MODE_OVERRIDES | ~/.aicodebox/telegram_overrides.json | Per-chat override store (model/effort/system prompts) |
| Var | Default | What it does |
|---|---|---|
PIBOX_CRON_MODE_FILE | — | Path to the cron yaml |
PIBOX_CRON_MODE_HISTORY_DIR | ~/.aicodebox/cron/history | Where cron writes per-run history dirs (meta.json, stdout.log, stderr.log, result.txt, telegram.json) |
| Var | Default | What it does |
|---|---|---|
PIBOX_MCP_MODE_PORT | 8081 | Port the sidecar MCP server binds to (ignored when mounted inside API) |
PIBOX_MCP_MODE_TOKEN | empty | Bearer token for MCP. Empty = no auth. No fallback to API_MODE_TOKEN |
| Var | Default | What it does |
|---|---|---|
PIBOX_WORKSPACE | /workspace | Root workspace dir inside the container |
PIBOX_CONTAINER_NAME | aicodebox | Used to scope per-container state files (auth, etc.) |
PIBOX_AVAILABLE_MODELS | — | Required for API mode. CSV list returned by /openai/v1/models and shown in the telegram /model picker. API mode refuses to boot without it; telegram /model picker degrades to a "set this env var" reply. |
PIBOX_AVAILABLE_EFFORTS | adapter list | Override the effort/--thinking list shown by the telegram /effort picker (comma-separated) |
pi speaks the Anthropic wire protocol. Point it at any Anthropic-compatible endpoint:
| Var | Purpose |
|---|---|
ANTHROPIC_AUTH_TOKEN | Bearer token (Z.AI, direct Anthropic, etc.) |
ANTHROPIC_API_KEY | Same thing — pi reads both |
ANTHROPIC_BASE_URL | Endpoint override (default: https://api.anthropic.com) |
ANTHROPIC_MODEL | Default model when the caller doesn't specify one |
Z.AI's GLM models are fast and cheap for most tasks — ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic + ANTHROPIC_MODEL=glm-4.6 is the recommended default.
pi's thinking levels (--thinking): off, minimal, low, medium, high, xhigh. Exposed as the /effort command in telegram mode and as thinking in API requests.
make help # list targets
make build # pull the published aicodebox base, build + tag psyb0t/pibox:v<VERSION> and :latest
make test # run the full e2e suite (needs .env.test)
make clean # remove built images
VERSION is read from pibox/pyproject.toml. make build pulls the published psyb0t/aicodebox base pinned in the Dockerfile; set SKIP_BASE_PULL=1 to use a locally-built base instead (e.g. from a sibling ../docker-aicodebox checkout), or override with make build BASE_IMAGE=....
End-to-end tests build the image and run it against a real LLM endpoint. Telegram tests use psyb0t/telethon-plus as a real MTProto userbot.
cp .env.test.example .env.test
$EDITOR .env.test # fill in ANTHROPIC_* and optionally Telegram creds
make test
Telegram tests auto-skip if AICODEBOX_TELEGRAM_MODE_TOKEN is empty. Everything else only needs ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL.
WTFPL — see LICENSE. Do what the fuck you want.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Modelcontextprotocol · Developer Tools
Web content fetching and conversion for efficient LLM usage
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.