Pi
Pi is a terminal-based coding agent by earendil-works. With Lemonade, you can run Pi against local models through Lemonade's OpenAI-compatible API.
This guide focuses on the most common launch flows.
Prerequisites
-
Install Pi:
npm install -g @earendil-works/pi-coding-agent--mcpneeds Pi 1.0 or newer, and--codemodeneeds Pi 1.1 or newer. Launch checks this when you pass either flag: it stops with an older Pi for--codemodeand warns for--mcp. Check withpi --version, and update with the same install command. -
Make sure Lemonade Server is running (
lemond).
Launch Pi with Lemonade
Use:
lemonade launch pi [options]
Lemonade automatically configures Pi to use your local server by writing these files in ~/.pi/agent/ (or $PI_CODING_AGENT_DIR):
- models.json — Registers the Lemonade provider with your local server's base URL, every downloaded chat model, and the launched model
- settings.json — Sets the default provider to Lemonade, if Pi has none yet, so Pi launches straight into your local model
- mcp.json — With --mcp, adds Lemonade's MCP server (see Lemonade tools in Pi)
See How it works for what each file contains.
Use Case 1: First-time user (discover + import + launch)
If you are not sure which model to use yet, start with:
lemonade launch pi
You will get an interactive menu where you can:
- Select a recipe to import and launch.
- Browse downloaded models.
- Browse recommended llama.cpp models (download may be required), then launch.
All remote recipes in this flow are sourced from:
https://github.com/lemonade-sdk/recipes
Use Case 2: You already know the model
If you already downloaded a model or already imported the recipe, skip the interactive flow:
lemonade launch pi -m Qwen3.5-35B-A3B-GGUF
Equivalent long form:
lemonade launch pi --model Qwen3.5-35B-A3B-GGUF
When --model is provided, launch skips the model prompt. If the model's context size is automatic, it waits for the model to load before starting the agent; otherwise it starts the agent while the model loads.
Passing Pi arguments with --agent-args
You can pass any extra Pi CLI flags through Lemonade:
lemonade launch pi --model Qwen3.5-35B-A3B-GGUF --agent-args "-e npm:@foo/my-extension"
If Pi supports a flag, you can pass it through --agent-args.
Lemonade tools in Pi (MCP)
Add --mcp to give Pi Lemonade's MCP tools: list models, chat with another local model, generate images, transcribe audio, and search the Lemonade docs. This needs Pi 1.0 or newer; older versions ignore mcp.json.
lemonade launch pi --model Qwen3.5-35B-A3B-GGUF --mcp
This adds a lemonade server to ~/.pi/agent/mcp.json. It stays there for later launches, and each launch updates its URL and API key reference. Run pi mcp list to check the connection. To remove it again:
lemonade launch pi --model Qwen3.5-35B-A3B-GGUF --no-mcp
--no-mcp removes only the lemonade server; your other MCP servers are left alone. If the server can't be removed, for example because mcp.json is read-only, launch stops instead of starting Pi.
Pi shows generated images inline only in terminals that support the kitty or iTerm2 image protocol, such as Ghostty, kitty, WezTerm and iTerm2, because it draws images with those protocols' escape sequences. Other terminals, and terminal multiplexers like tmux that don't pass those sequences through, show a placeholder such as [Image: [image/png] 512x512] instead. The model still receives the image if it accepts image input. To keep a copy on disk, ask Pi to save it, for example "generate an image of a red dog and save it to disk". The tool then writes the PNG to Lemonade's MCP image folder (mcp-images in the Lemonade cache directory, or LEMONADE_MCP_IMAGE_DIR if set) and returns its path instead of the inline image.
Codemode
Add --codemode to turn on Pi's codemode tool for that launch. This needs Pi 1.1 or newer. The model can then write scripts that call Pi's tools. With --mcp as well, scripts can call Lemonade's tools, for example to generate an image and show it:
lemonade launch pi --model Qwen3.5-35B-A3B-GGUF --mcp --codemode
const result = await tools.mcp__lemonade__lemonade_generate_image({ prompt: "a red apple", model: "SD-Turbo-GGUF" });
image(result.content.find((block) => block.type === "image"));
Download an image model first, for example lemonade pull SD-Turbo-GGUF. --codemode does not change Pi's settings.
Images and tool calling
- Models labeled
visionaccept images: paste one, or reference it with@image.png. Other models get a note that the image was left out. - Launch warns when the model is not labeled
tool-calling. Pi needs tool calls to read and edit files. - Launch also warns when the model name is not on the Lemonade server, for example a typo.
How it works
lemonade launch pi writes these files in Pi's agent directory, ~/.pi/agent/ (or $PI_CODING_AGENT_DIR):
models.json registers the Lemonade provider with every downloaded chat model, plus the launched model if it is not downloaded yet:
{
"providers": {
"Lemonade": {
"baseUrl": "http://localhost:13305/v1",
"api": "openai-completions",
"apiKey": "lemonade",
"compat": {
"supportsStore": false,
"maxTokensField": "max_tokens"
},
"models": [
{
"id": "Qwen3.5-35B-A3B-GGUF",
"contextWindow": 32768,
"maxTokens": 32768,
"input": ["text", "image"]
}
]
}
}
}
contextWindowandmaxTokenscome from the model's savedctx_size, or 40960 when none is saved or it is set to automatic (-1). For the launched model,--ctx-sizeonlemonade launchtakes precedence, and when its size is automatic, launch waits for the model to load and uses the size Lemonade picked. If that load fails, launch shows the error and doesn't start Pi. If a model runs with a different context size, save it withlemonade load <model> --ctx-size N --save-optionsso Pi compacts the conversation before it overflows.apiKeyis the placeholderlemonadewhen Lemonade has no API key. When it has one (--api-key,LEMONADE_API_KEYorLEMONADE_ADMIN_API_KEY), the value is${LEMONADE_API_KEY}: launch passes the key to Pi in that environment variable, and it is never written to disk. Runningpidirectly then needsLEMONADE_API_KEYset. If launch can't read or update Pi's config while a key is set, it stops instead of starting Pi, so the key is never sent to the server in Pi's old config.
settings.json makes Lemonade Pi's default provider, only if Pi has no default yet:
{
"defaultProvider": "Lemonade",
"defaultModel": "Qwen3.5-35B-A3B-GGUF"
}
mcp.json (with --mcp) adds the lemonade server:
{
"mcpServers": {
"lemonade": {
"url": "http://localhost:13305/mcp",
"headers": { "Authorization": "Bearer ${LEMONADE_API_KEY}" },
"exposure": "direct",
"description": "Lemonade local AI server: ..."
}
}
}
The headers entry is only written when Lemonade has an API key.
If these files already exist, Lemonade updates only its own entries and keeps your other providers, servers and settings.
Switching models
You can switch models inside Pi with /model or Ctrl+P, or launch with a different model:
lemonade launch pi --model Gemma-4-E2B-it-GGUF
Related CLI Docs
For more launch examples and full option details, see: docs/guide/cli.md
For Pi product details, see the official docs: https://pi.dev/docs/latest/