Tools and skills¶
The base tools are Pi's four: read, write, edit, and bash. Those exist
when the session has a computer (openai_hosted or a connected
self_hosted runner). They do not exist when environment.type is
none. Everything else is attached per agent: function tools, MCP
servers, and skills.
/v1/chat sessions have no computer, so bash and file tools stay off.
Chat allows function tools and HTTP MCP only. Stdio MCP, Playwright
auto-inject, and workspace skills are rejected with code chat_tool.
See Chat.
Copy-paste configs live in examples/ at the repo root (Tavily,
Playwright).
Function tools¶
Caller-defined functions. The agent emits a function_call item. The
session goes requires_action with a function_call action. The
client posts agent.session.input.tool_result with turn_id,
call_id, success, and output or error. That is the same idea as
OpenAI's Agents API. The gateway does not execute the function.
MCP¶
HTTP and stdio MCP use OpenAI's nested transport shape:
{
"type": "mcp",
"server_label": "tavily",
"transport": {
"type": "http",
"server_url": "https://mcp.tavily.com/mcp"
},
"headers": {
"Authorization": "Bearer ${TAVILY_API_KEY}"
}
}
{
"type": "mcp",
"server_label": "playwright",
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@playwright/mcp@latest", "--headless"]
}
}
Top-level server_url, command, or args on the tool are unknown
fields. Unknown transport.type values return 400. The gateway
connects HTTP servers when the session is created, then hands them to
Pi through a host credential broker. The guest does not receive MCP
bearers. Prefer a vault (static_bearer bound to
mcp_server_url, attach vault_ids on the session). Tool headers
with ${ENV} still expand on the host. Stdio servers start next to
Pi: on the host in none mode, and inside the same guest in
microvm mode. Pi does not speak MCP by itself. ApiPi loads a Pi
extension that starts each stdio server, lists its tools, and
registers them on Pi as mcp_<server_label>_<tool>. If a listed
stdio server cannot start, Pi exits instead of running without those
tools. Optional transport.cwd is the process working
directory. Stdio credentials stay in environment variables, not in
git. Bash that tries to install Playwright or browser binaries is
blocked. A bash call with no timeout is capped at 120 seconds so a
stuck install cannot hold the turn until APIPI_TURN_TIMEOUT.
Search goes through MCP.
Search — Tavily example¶
Tavily's hosted MCP is one search option. Set TAVILY_API_KEY. See
examples/tavily.yaml. You can swap that for Brave, Exa, or any other
server that speaks MCP.
Browser — Playwright example¶
Playwright MCP is one
browser option. --headless is the usual server flag. See
examples/playwright.yaml.
Sandbox size L on isolation microvm attaches that server for you
(system Chromium in the browser rootfs). You do not need to list it on
the agent. A caller-supplied Playwright MCP tool is not duplicated.
Turn auto-inject off with APIPI_SANDBOX_AUTO_PLAYWRIGHT=false if you
want L RAM and rootfs but manual MCP only. The platform prompt names
the sandbox size and, on L, tells the model to use MCP tools and
not to install browsers. Save screenshots under outputs/.
The browser follows Pi (none or microvm). Inside a microvm,
Chromium can use its own sandbox in the guest. A small client is
examples/sessions/browser_screenshot.py.
Skills¶
Agent Skills are a directory with
SKILL.md (name and description in front matter, then instructions).
Optional scripts/, references/, and assets/ sit next to that
file.
On the OpenAI Agents API you put those directories on the computer and
list the parent paths in environment.capability_directories on
session create. The harness discovers SKILL.md, puts name and
description in context, and reads the rest when the skill is used.
ApiPi does the same. Pi already loads this format. On
openai_hosted, listed directories that sit outside the workspace are
copied into it when the session is created. In microvm, skill
directories from that workspace are packed into the guest and
--skill paths are rewritten to /workspace.
Also discovered, if present on the workspace:
.agents/skills/.pi/skills/
Upload a skill zip with POST /v1/skills (multipart field files,
same 50 MiB cap as Files API). Attach it on session create with
environment.skills: { "type": "skill_reference", "skill_id": "…" }.
ApiPi unpacks the zip under .agents/skills/ so discovery works as
above. The zip must contain exactly one SKILL.md. Path traversal is
rejected. capability_directories still work for trees already on the
computer.
Per agent¶
MCP and function tools live on the saved agent (or the inline session
agent). Skills live on the computer, pointed at by
capability_directories or unpacked from environment.skills.
Changing tools later means updating the
saved agent; it does not rewrite history on existing sessions.