Pi with mittwald AI Hosting
Pi is a command-line coding agent with read, bash, edit and write tools, an extension system, and a terminal UI. Providers are declared in a JSON file, which makes an OpenAI-compatible endpoint like mittwald AI Hosting straightforward to add.
Installation
npm install -g @earendil-works/pi-coding-agent
Or with Homebrew:
brew install pi-coding-agent
Check the install:
pi --version
Choosing between Pi and opencode
Both are CLI coding agents that work with mittwald AI Hosting; the difference is how
much they load before your own work starts. Measured directly against the mittwald
gateway, Pi's first request sends a 2,640-character system prompt (as a
developer-role message) plus JSON schemas for its 4 built-in tools — read, bash,
edit, write — totaling 3,024 characters, for a full first request body of about
6 KB. That's a small, fixed toolset and a compact prompt, so less of the model's
context window is spent before you start working.
opencode ships more capability out of the box — a plugin array, an MCP config block, and agent packs with per-agent model overrides. On disk, Pi installs to about 142 MB and opencode to about 160 MB, a modest difference either way.
If you want a small, scriptable agent and prefer to add MCP servers and extensions only as you need them, start with Pi. If you'd rather have a fuller, batteries-included setup from the first run, see opencode.
Pointing Pi at mittwald AI Hosting
Pi reads providers from ~/.pi/agent/models.json. Add a provider block:
{
"providers": {
"mittwald": {
"name": "mittwald AI Hosting",
"baseUrl": "https://llm.aihosting.mittwald.de/v1",
"api": "openai-completions",
"apiKey": "sk-...",
"models": [
{
"id": "Qwen3.5-122B-A10B-FP8",
"name": "Qwen3.5-122B-A10B-FP8",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 245760,
"maxTokens": 32768
},
{
"id": "Qwen3.8-27B-NVFP4",
"name": "Qwen3.8-27B-NVFP4",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 256000,
"maxTokens": 32768,
"samplingParams": {
"temperature": 0.7,
"top_p": 0.8,
"top_k": 20
}
},
{
"id": "Qwen3.6-35B-A3B-FP8",
"name": "Qwen3.6-35B-A3B-FP8",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 256000,
"maxTokens": 32768
}
]
}
}
}
Replace sk-... with your AI Hosting API key. You create it in the AI-Hosting
section of your mStudio project — see
Gaining access. An mStudio API
token from your profile settings is a different credential and will not work here.
The api value must be openai-completions — that is what selects the
OpenAI-compatible request format.
Make it the default in ~/.pi/agent/settings.json:
{
"defaultProvider": "mittwald",
"defaultModel": "Qwen3.5-122B-A10B-FP8"
}
Per-model samplingParams are optional. The recommended values for each model are on
its page in the AI models documentation.
Verifying the connection
The models you declared should now be listed:
pi --list-models
Then force a tool call, since a plain chat reply would succeed even with tool calling broken:
pi --provider mittwald --model Qwen3.5-122B-A10B-FP8 --no-session \
-p "Create a file called hello.txt containing the word hello, then read it back."
Expected: Pi writes the file, reads it back, and reports the contents. Run this in a
scratch directory — the agent writes files where you start it. --no-session keeps
the run ephemeral, so it doesn't leave a saved conversation behind.
Recommended extensions and MCP servers
Extensions
Extensions install from npm and are recorded in settings.json under packages:
pi install npm:pi-mcp-adapter
pi list
| Extension | What it does |
|---|---|
pi-mcp-adapter | Required for MCP. Pi has no MCP support without it |
pi-safe-compact | Safer context compaction on long sessions |
@narumitw/pi-plan-mode | A plan-then-execute mode |
pi-background-tasks | Long-running commands without blocking the session |
@juicesharp/rpiv-todo | Task tracking inside a session |
Toggle what is enabled with pi config.
MCP servers
Install pi-mcp-adapter first, then declare servers in ~/.pi/agent/mcp.json:
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"lifecycle": "lazy"
},
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"],
"lifecycle": "lazy"
},
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp"],
"lifecycle": "lazy"
}
}
}
lifecycle: "lazy" starts a server on first use instead of at launch. Prefer it —
several eagerly started servers noticeably slow down startup.
For mittwald infrastructure access, see MCP Integration.
Skills
Pi discovers skills automatically, or you can load one explicitly:
pi --skill ./path/to/skill
Disable discovery for a run with --no-skills.
Troubleshooting
A declared model is missing from pi --list-models
The provider block has a JSON syntax error, or api is not openai-completions.
Validate the file: python3 -m json.tool ~/.pi/agent/models.json.
MCP servers are ignored
pi-mcp-adapter is not installed. Check with pi list.
A .pi/ directory appears even with --no-session
That's expected if the pi-background-tasks extension is installed — it writes
per-run task state under .pi/tasks/ regardless of the session flag, because
--no-session only disables the conversation transcript, not extension-local state.
Safe to delete; run agents in a scratch directory if you don't want it left behind.
Next steps
- Hermes Agent — another CLI agent
- opencode — a third
- MCP Integration — manage mittwald infrastructure from the agent
- AI models — the full model list
Disclaimer
Third-party tools, MCP servers and external links are provided for convenience without endorsement or warranty. Use them at your own risk, review licenses and privacy policies, and scope access conservatively (least privilege). Avoid sending sensitive data to external services unless required and permitted.