pi-cli-mcp
This server lets your MCP client delegate coding tasks to your locally installed pi CLI — starting, resuming, steering, and inspecting pi sessions while inheriting your pi configuration.
pi — start a new pi session with a self-contained prompt, optional cwd, model, thinking level, timeout, tool allowlist, or no-tools mode; get back a session id, the final answer, and stats.
pi_reply — continue an existing session that is not running, including one that timed out or was cancelled; sessions survive server restarts.
pi_models — list currently reachable models with provider, id, context, max output, thinking, and image support.
pi_send — deliver a steer, follow-up, or abort into a turn that is running right now (rpc transport only).
pi_running — list in-flight pi turns that pi_send can reach.
pi_sessions — list known sessions, newest first, with their working directories, for recovery after failures.
Preserves pi's own session files and settings (provider, models, AGENTS.md/CLAUDE.md), returns only pi's final answer plus diagnostics, and makes killed runs resumable rather than lost.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pi-cli-mcpMap how retries are wired in src/http.rs, report call sites only"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pi-cli-mcp
MCP server that delegates coding tasks to your locally installed pi CLI.
It wraps the real pi binary instead of bundling its own copy of the agent, so every call inherits
your ~/.pi/agent/settings.json — provider, models, thinking level, extensions, AGENTS.md /
CLAUDE.md discovery. Nothing about your model stack is duplicated here, and the server does not
drift when you upgrade pi.
Use it when your primary agent (Claude Code, Cursor, any MCP client) should hand work to pi: a second opinion from a different model, an investigation you want kept out of the main context window, or parallel work.
Install
npx -y pi-cli-mcp # no install
npm install -g pi-cli-mcp # or globalRequires Node ≥ 22 and a working pi on PATH (npm i -g @earendil-works/pi-coding-agent).
Claude Code
claude mcp add-json pi -s user '{
"type": "stdio",
"command": "npx",
"args": ["-y", "pi-cli-mcp"],
"timeout": 3600000
}'
claude mcp list | grep '^pi:' # expect: ✔ ConnectedThe generous timeout matters: the server applies no run deadline by default, and a real
delegated task can run for minutes.
Any other MCP client
{
"mcpServers": {
"pi": { "command": "npx", "args": ["-y", "pi-cli-mcp"] }
}
}Keep the server name short (pi): it becomes part of the tool names your model sees.
Related MCP server: cursor-agent-bridge
Tools
Tool | Purpose |
| Start a pi session. Returns |
| Continue a session that is not executing — including one killed by a timeout. |
| List reachable models (provider, id, context, max output, thinking, images). |
| Send a message into a turn that is running right now ( |
| List turns executing right now and reachable by |
| List known sessions, newest first, with their working directory. |
pi
Argument | Notes |
| Required. Must be self-contained — pi cannot see your conversation. |
| Absolute path. pi reads |
| e.g. |
|
|
| Wall clock for this run. Off unless you set it — the task decides whether it needs a deadline. |
| Allowlist, e.g. |
| Pure reasoning over the prompt text. |
| Extra text appended to pi's system prompt. |
pi({
prompt: "Map how retries are wired in src/http.rs. Report call sites only.",
cwd: "/abs/path/to/repo",
tools: "read,grep,find,ls"
})pi has no permission system. With its default tools it edits files and runs shell commands as your user inside
cwd. Passtoolsorno_toolswhenever the task is analysis. UsePI_MCP_WRAPif you want a sandbox.
What comes back
Only pi's final answer plus aggregate stats — never the transcript, tool arguments or tool output:
[session: 0927adc5-a840-4b68-93ca-5ca344c9fafb]
Created note.md containing "hello" and updated target.txt to read "new content".
---
pi: bifrost/minimax/MiniMax-M3 · 5 turns · 4 tool calls: bash, read, write, edit · 11k in / 276 out · 9.8s
pi wrote: note.md, target.txt"Final answer" is defined by
stopReason, not by position: the last assistant message that settled — the last one whosestopReasonis nottoolUse, which is how pi marks tool-call steps. Mid-run narration is dropped even when a preamble shares a message with a tool call. If the settled message has no text, that is reported as a broken run rather than silently reaching back for an earlier preamble. If nothing settled at all, the last text produced is returned, labelled as such.The answer is never truncated. Set
PI_MCP_MAX_OUTPUTif you want a cap. Only diagnostics are bounded.pi wrote:appears only when pi actually wrote files, so it doubles as a side-effect check.Bad
stopReasonfails the call, fail-closed.stop/lengthare success;error,aborted, a missingstopReason, and anything outside the known vocabulary are reported as errors with the answer still attached. ThestopReasonthat is validated belongs to the message being returned, not to whichever event arrived last. pi can exit 0 on a turn that did not settle cleanly, so the exit code alone is not trusted.Raw stdout is never returned as an answer. If the event stream does not match the expected contract, the response says so and describes the shape of what arrived (message count,
stopReasonvalues, tool-call count, byte count) — never the transcript itself, which would leak narration, tool arguments and tool results.
Sessions
pi returns a session id; pi_reply continues it. The conversation lives in pi's own session
files, so follow-ups keep working across restarts of this server — the session → directory map is
persisted in ~/.local/state/pi-mcp/sessions.json.
Concurrent replies to one session are serialized: two pi processes writing one session file would
corrupt it. If an id is unknown, pi starts a fresh conversation and the answer carries an explicit
[warning: no existing session …] rather than pretending to continue.
Cross-process caveat. The session mutex is process-local. If you run two MCP clients against two server processes and both reply to the same session id at the same time, nothing serializes them. The state file is written with re-read-then-merge, so sessions learned by one process are not erased by the other, but the underlying pi session file has no such protection. In practice one client owns a session; if you need a hard guarantee, keep one server process.
Transports
Two ways to drive pi, behind one interface. Everything downstream — the event accumulator, answer selection, the stats line, failure reporting — is shared, so the choice changes only how pi is launched and what is possible during a run.
|
| |
command |
|
|
process | stays up, reads JSONL commands on stdin | one per turn, exits when done |
mid-run message |
| impossible: pi reads nothing while working |
interrupted by deadline or cancel | pi's own | SIGTERM, then SIGKILL |
prompt delivery | inside the command, no argv limit | argv, with a temp file for long or dash-leading prompts |
rpc is the default because it is a superset: the same event stream and the same answer, plus a
running turn stays reachable and an interrupted one is ended in-protocol. Pick per call with
transport, or set the default with PI_MCP_TRANSPORT=print.
Reaching a running turn
pi --mode rpc accepts commands while it works. That is the whole reason the
transport exists, and it is exposed as pi's commands, unchanged:
A call blocks until the turn settles, so reaching it needs a second caller — or a client that stops waiting. Claude Code, for one, moves a tool call to the background after about two minutes, and from that point the turn is reachable from the same conversation:
pi({ prompt: "long task…", cwd: "/repo" }) // moved to the background by the client
pi_running()
// 1 running:
// 5aef3387-… 8.0s /repo
pi_send({ session: "5aef3387-…", message: "stop and report what you have" })
// Sent steer to session 5aef3387-… (running for 8.1s).The answer appears in the call that is still waiting on that turn:
[session: 5aef3387-…]
STEERED_LIVE
---
pi: bifrost/agnes/agnes-2.5-flash · 3 turns · 3 tool calls: bash×3 · 23k in / 207 out · 46.6scommand selects which pi command to pass: steer (default, interrupts the
current turn), follow_up (queues for after it), abort (stops it).
Ending a turn early
A deadline or a cancellation ends an rpc turn with pi's own abort first, and
only signals if that does not take within PI_MCP_ABORT_GRACE_MS. The reason is
in pi's own shutdown path: on SIGTERM it deliberately skips flushRawStdout(),
so signalling straight away can cost the tail of the event stream — including the
answer pi was in the middle of writing. After abort the turn closes through the
normal path and its report arrives. Print mode has no stdin to talk to, so there
it is SIGTERM then SIGKILL as before.
The report says which happened: the turn was aborted means it closed itself and
the events are complete, the process was killed means it was cut off.
Nothing is ever sent on this server's initiative: pi_send fires only when you call it.
When a run dies
A run killed by its deadline, by cancellation, or by a non-zero exit is not a dead end — pi keeps the conversation in its own session file, so the work is parked rather than lost. The failure carries what is needed to pick it back up:
[session: 0927adc5-…]
[error: pi timed out after 1800000 ms and was killed]
last thing pi said:
43 tests pass, now showing the failure
progress before it died:
pi: bifrost/zai/glm-5.3 · 9 turns · 14 tool calls: bash×6, read×5, edit×3 · 61k in / 4.2k out · 1800.0s
pi wrote: tests/test_upstream.py, conftest.py
The session is intact and resumable — pi still has every turn above.
To continue where it stopped:
pi_reply({ session: "0927adc5-…", prompt: "..." })
Raise the limit for the next leg with timeout_ms if the task needs longer.The session is recorded before the run starts, not after it succeeds, so a
killed run is still listed by pi_sessions and still resumable. The files line
comes from pi's own tool calls — this server does not inspect the filesystem.
timeout_ms exists because the right deadline belongs to the task. By default
the server sets no deadline at all — pi runs until it finishes. Give the task a
wall clock when it needs one, or install a server-wide default with
PI_MCP_TIMEOUT_MS; a global limit would otherwise kill long work at an
arbitrary point, while per-call it is a decision, and the report above makes
the decision recoverable either way.
stderr
stderr is diagnostics, and only the tail is forwarded (PI_MCP_STDERR_LIMIT).
By the protocol, events belong on stdout, so a stderr line that parses as an
event is a channel violation: those lines are counted by type and reported as
[6 protocol event line(s) on stderr, suppressed: message_start×3, message_end×3]
rather than pasted in. The classification comes from parsing the line once and
reusing that parse for the tally — the payloads, prompts included, are never
forwarded. PI_MCP_STDERR_KEEP_EVENTS=1 turns the guard off and forwards stderr
verbatim.
Cancellation
MCP notifications/cancelled kills pi with SIGTERM, escalating to SIGKILL after a grace period.
Children go with it: pi runs in its own process group and the whole tree is signalled, so an
interrupted sleep 120 does not survive even if pi fails to forward the signal.
Cancellation registers before the call queues for a concurrency slot or a session lock, so a call that is cancelled while still waiting never starts pi at all.
Shutdown — stdin EOF, SIGTERM, SIGINT, SIGHUP, or a closed stdout — reaps every running pi
tree before exiting. Detached children have no other parent to clean them up.
Environment
Variable | Default | Meaning |
|
| Path to the pi binary. |
| pi's setting | Default model for every call. |
| pi's setting | Default thinking level. |
| unset | Server-wide default wall clock; unset means no deadline. |
|
| Ceiling on what |
|
| Concurrent pi processes. |
| unset | Cap on the answer. Unset means no truncation. |
|
| stderr tail included in the response. |
| unset |
|
|
| Read-buffer guard against a runaway stream. |
|
| Longest single event line from pi before it is dropped. |
|
| Longest single JSON-RPC frame from the client. |
|
| Remembered sessions before the oldest is dropped. |
|
| SIGTERM → SIGKILL grace period. |
|
| How long |
|
| Session → cwd map. |
| unset | Command prefix, e.g. |
|
| Default transport: |
Design
Process per call. pi's own session files are the source of truth, which is what makes follow-ups survive a restart of this server.
pi -p --mode json. The json event stream is what yields turns, tool calls, token usage and cost — no scraping of human-readable output.No dependencies. Newline-delimited JSON-RPC 2.0 is spoken directly; installing this package pulls nothing else in.
Long or dash-leading prompts are passed as an
@fileattachment, since pi has no--separator and argv has an OS size limit.
Why not the alternatives
pandysp/pi-mcp-server depends on @mariozechner/pi-coding-agent@^0.52.9 — the old fork under
pi's previous package name — so it runs a bundled copy of a much older agent instead of your CLI,
and knows only a fixed provider list. Everything else in the ecosystem (pi-mcp-adapter,
pi-mcp-extension and forks) runs the opposite direction: MCP servers into pi. pi itself has
no native mcp-server subcommand.
Development
TypeScript, mirroring pi's own toolchain — one version newer where there is a newer one.
pi 0.84 | here | |
compiler |
| typescript 7 ( |
lint / format | Biome 2.3.5, | Biome 2.5.9, |
tests | Vitest 4.1.9 | Vitest 4.1.11, with |
module |
|
|
strictness |
| plus |
npm run hooks # once per clone: git hooks from .githooks/
npm run build # tsc -> dist/
npm test # unit + type tests, no API access, no tokens
npm run check # format + types + tests
npm run fix # biome --write
PI_CLI_MCP_LIVE=1 npm test # also exercise the real pi binaryWhat changed between versions is in CHANGELOG.md. House rules are in
AGENTS.md; procedures — releasing, validation, pi's contract, testing — in
.agents/skills/.
License
MIT
Available Tools
6 toolspiA
Start a NEW task in the local pi agent — a separate CLI coding agent with its own read/bash/edit/write tools and its own context window. Blocks until pi settles, then returns only its final answer plus stats, prefixed [session: ]; continue that session later with pi_reply.
Good for: a second opinion from a different model, work kept out of this context, or parallel investigation.
Caution: pi has no permission system. With its default tools it edits files and runs shell commands as your user inside cwd. For analysis-only work pass tools or no_tools.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Usually omit to use this server's cwd. If set, must be an absolute path (relative is rejected). pi works and edits here, and reads AGENTS.md / CLAUDE.md from here. | |
| model | No | Model pattern or id, e.g. 'sonnet', 'bifrost/minimax/MiniMax-M3', 'provider/id:thinking'. Defaults to pi's own settings; pi_models lists valid values. | |
| tools | No | Usually omit to keep pi's default set (includes bash/edit/write). Set a comma-separated allowlist of pi tool names only to restrict, e.g. 'read,grep,ls' for a read-only run. | |
| prompt | Yes | The complete task. pi cannot see this conversation, so include everything it needs: file paths, goal, constraints, expected output format. | |
| no_tools | No | Disable all pi tools: pure reasoning over the prompt, no file or shell access. | |
| thinking | No | Thinking level. No-op on models without thinking support (check pi_models). Defaults to pi's own settings. | |
| transport | No | Usually omit. The default 'rpc' keeps pi up, so a running turn can be steered or aborted with pi_send. 'print' runs one process per turn that cannot be reached while it works. | |
| timeout_ms | No | Usually omit — the server default is generous. Override only when the task's real size demands it. A run killed at the deadline is not lost: it still returns its session id and is resumable with pi_reply. | |
| system_prompt_append | No | Extra text appended to pi's system prompt for this run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden, and it does substantial work: it discloses that pi blocks until completion, returns only final answer plus stats, has no permission system, edits files and runs shell commands as the user inside cwd, and that a timeout-killed run is resumable. A small gap is not describing the exact stats format or failure behavior, but the most important behavioral traits are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet dense: an opening behavioral summary, a clear 'Good for' section, and a Caution section. Every sentence earns its place. It front-loads the core behavior (starts a new task, blocks, returns session id) before routing and caution details, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 9-parameter tool with no output schema and no annotations, the description provides a complete operating picture: session lifecycle (via pi_reply), model discovery (pi_models), steering/aborting (pi_send), timeout recovery, safety caveats, and parameter defaults. The combination of description and 100% schema coverage leaves little ambiguity about how to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 9 parameters well. The description adds value beyond the schema by explaining which parameters to 'usually omit' (cwd, tools, transport, timeout_ms) and why, and by explaining the consequences of transport choices and timeout deadlines. This is helpful guidance an agent could not get from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Start a NEW task') and resource ('local pi agent'), and clearly distinguishes this tool from its siblings by explaining pi_reply continues sessions, pi_models lists models, and pi_send steers running turns. The scope is explicit: it blocks until pi settles and returns only the final answer plus stats prefixed with [session: <id>].
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use pi ('Good for: a second opinion from a different model, work kept out of this context, or parallel investigation') and offers clear caution about its lack of a permission system, advising to pass tools or no_tools for analysis-only work. It also references sibling tools for continued sessions and model listings, giving an agent actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pi_modelsA
List the models pi can actually reach right now — provider, model id, context window, max output, thinking and image support — read from the live catalog. Use it to pick model and thinking values for pi / pi_reply. Starts no session, runs no task.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Optional fuzzy filter, e.g. 'glm', 'deepseek', 'minimax'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does so well: it states this is a read from the live catalog ('actually reach right now') and explicitly denies side effects. It could add error/availability behavior or auth expectations, but the core read-only, no-task traits are clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the main action and output fields before the usage directive. Every sentence contributes either scope, use case, or a side-effect exclusion; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-optional-parameter input and no output schema, the description is complete: it describes the returned model attributes, the purpose, and the non-mutating behavior. An agent can call it correctly without additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the only parameter with 100% coverage, so the description need not compensate; it stays at the baseline. The description does not add extra semantic detail beyond the schema's 'Optional fuzzy filter' with examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('List the models pi can actually reach right now') and enumerates the return fields, making the tool's function unmistakable. It also ties itself to pi and pi_reply, which separates it from the session/task siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when to use it: to pick `model` and `thinking` values for `pi` / `pi_reply`. The closing phrase 'Starts no session, runs no task' also signals when-not to use it, distinguishing it from pi_send, pi_running, and pi_sessions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pi_replyA
Send a new turn to an existing pi session that is not executing right now — including one that timed out or was cancelled: the session survives, so resume it here instead of restarting with pi. pi still has its prior turns (but never this conversation), so the follow-up can be short. Survives restarts of this server. For a turn still running under 'rpc', use pi_send instead.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Absolute path override. Defaults to the directory where the session started. | |
| model | No | Model pattern or id, e.g. 'sonnet', 'bifrost/minimax/MiniMax-M3', 'provider/id:thinking'. Defaults to pi's own settings; pi_models lists valid values. | |
| prompt | Yes | Follow-up message for this session. | |
| session | Yes | Session id from a [session: <id>] prefix, or from pi_sessions. | |
| thinking | No | Thinking level. No-op on models without thinking support (check pi_models). Defaults to pi's own settings. | |
| transport | No | Usually omit. The default 'rpc' keeps pi up, so a running turn can be steered or aborted with pi_send. 'print' runs one process per turn that cannot be reached while it works. | |
| timeout_ms | No | Usually omit — the server default is generous. Override only when the task's real size demands it. A run killed at the deadline is not lost: it still returns its session id and is resumable with pi_reply. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and meets it well: it discloses session survival across timeout/cancellation, that pi retains prior turns but 'never this conversation', and that sessions survive server restarts. The schema's transport and timeout_ms descriptions add durability semantics (killed runs still return a session id and are resumable). Minor deduction for not covering what happens when a session id is invalid or expired, though the schema's reference to pi_sessions partially mitigates this.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, zero filler, and the core purpose plus most critical edge case are front-loaded in the first sentence. Each subsequent sentence earns its place: context retention, persistence, and sibling routing. Nothing is redundant with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a stateful tool with 7 parameters, no annotations, and no output schema, the definition is complete. It covers how to obtain a session id (via schema references to pi_sessions and the [session: <id>] prefix), what the timeout behavior is (resumable, returns session id), when the call returns before the turn completes (transport semantics), and how to distinguish siblings. The essential return-value behavior is disclosed through the timeout_ms description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds genuine parameter-level value on top. It clarifies the session parameter's semantics (timed-out/cancelled sessions are still valid targets) and the prompt parameter's expected style ('so the follow-up can be short'). The schema parameter descriptions themselves are unusually rich, cross-referencing pi_models, pi_sessions, and pi_send, which justifies above-baseline scoring.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'Send a new turn to an existing pi session' — with a precise scope condition ('that is not executing right now'). It actively distinguishes itself from siblings by naming both alternatives: 'resume it here instead of restarting with `pi`' and 'use pi_send instead.' An agent can tell exactly what this tool does without opening any sibling schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use and when-not-to-use guidance is present. It covers valid edge cases ('including one that timed out or was cancelled'), gives the exclusion condition ('For a turn still running under "rpc", use pi_send instead'), and names the restart alternative (`pi`). The persistence guarantee ('Survives restarts of this server') further informs whether resuming is safe.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pi_runningA
List pi turns executing at this moment — the ones pi_send can reach — with session id, working directory, elapsed time, and messages already sent in. Only rpc-transport runs appear; 'print' runs are unreachable mid-run. For past sessions use pi_sessions.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses the live-only nature of the data, the rpc-transport limitation, the unavailability of 'print' runs during execution, and the fields returned. It does not spell out that the call is read-only, but 'List' strongly implies it, and the caveats add meaningful behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no filler. The main action and scope are front-loaded, and each subsequent sentence adds a necessary caveat or alternative. The description is compact but information-dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list tool with no output schema, the description is complete: it names the resource, the live scope, the transport restriction, the return fields, and the alternative for historical data. An agent has everything needed to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so there is nothing for the description to explain. The description adds value by itemizing the returned fields (session id, working directory, elapsed time, messages sent in), which helps the agent understand the tool's output even in the absence of an output schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and a precise resource ('pi turns executing at this moment'), and clarifies the scope by saying 'the ones pi_send can reach.' It also distinguishes itself from pi_sessions explicitly, so an agent can tell them apart without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states exactly when to use this tool: for currently executing pi turns over rpc-transport. It explicitly excludes 'print' runs as unreachable mid-run and directs the agent to pi_sessions for past sessions, giving clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pi_sendA
Deliver a message into a pi turn that is executing right now. Works only on runs started with transport 'rpc' — 'print' runs cannot be reached, and a session that already finished takes pi_reply, not pi_send. Returns immediately; pi's reaction appears in the answer of the pi/pi_reply call still waiting on that turn. pi_running lists reachable sessions.
| Name | Required | Description | Default |
|---|---|---|---|
| command | No | 'steer' (default) interrupts the current turn with the message; 'follow_up' queues it for after the turn finishes; 'abort' stops the turn. Passed to pi unchanged. | |
| message | No | Text to deliver. Required for 'steer' and 'follow_up', ignored by 'abort'. | |
| session | Yes | Session id of the running turn (see pi_running). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it delivers. It discloses the async behavior ('Returns immediately'), where the effect surfaces ('pi's reaction appears in the answer of the pi/pi_reply call still waiting on that turn'), and the transport/reachability constraint. This is exactly the kind of non-obvious behavioral context an agent needs beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences with zero waste. The core action is front-loaded, followed by constraints, behavioral timing, and a helpful pointer to pi_running. Every sentence earns its place and no information is duplicated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no annotations and no output schema, the description covers the essential context: transport constraint, timing semantics, where the result appears, sibling differentiation, and session discovery. The only minor gap is the exact return value of pi_send itself (an ack?) and behavior on an invalid or unknown session id, but these are small omissions for an otherwise complete definition.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3: the schema already documents each parameter's meaning, including the command enum behavior and message requirements. The description adds marginal value by framing session as a currently executing turn and pointing to pi_running, but it does not meaningfully augment the parameter docs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Deliver a message into a pi turn that is executing right now.' It explicitly distinguishes the tool from pi_reply ('a session that already finished takes pi_reply, not pi_send'), so an agent can tell them apart instantly. The scope is precise — only live turns on 'rpc' transport.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
This is exemplary routing guidance. It states the exact precondition ('Works only on runs started with transport 'rpc''), a negative exclusion ('print' runs cannot be reached), and names the alternative tool for the finished-session case (pi_reply). It also points to pi_running for discovering reachable sessions. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pi_sessionsA
List all pi sessions started through this server, newest first, with their working directory — running or finished, including runs that timed out. Use it to recover an id for pi_reply. For turns still executing (pi_send targets), use pi_running.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It clearly discloses listing order, the working directory field, and the inclusion of running, finished, and timed-out sessions. The only minor gap is that it doesn't state return format or error behavior, but for a listing tool the disclosed scope and status coverage are strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. The first sentence delivers the core behavior and result fields, the second gives the primary use case, and the third handles sibling differentiation. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless list tool with no output schema, the description is complete enough: it states scope, ordering, covered statuses, a concrete usage purpose, and the related alternative for in-progress sessions. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, which is the baseline case for a 4. The description correctly focuses on what the return value contains (all sessions, working directory, ordering) rather than parameter details, which are not applicable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a clear resource ('pi sessions'), and adds distinguishing details: 'started through this server, newest first, with their working directory'. It also covers inclusion criteria (running, finished, timed out) and explicitly differentiates from the sibling pi_running, so an agent can select it correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states exactly when to use the tool: 'Use it to recover an id for pi_reply.' It also gives an explicit exclusion: 'For turns still executing (pi_send targets), use pi_running.' This directs the agent to the right sibling without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
v0.5.1- First observed
pi - First observed
pi_models - First observed
pi_reply - First observed
pi_running - First observed
pi_send - First observed
pi_sessions
TDQS
Each tool maps to a distinct lifecycle stage: starting a session, messaging a running session, messaging an idle/finished one, listing running sessions, listing all sessions, and listing models. pi_reply and pi_send both send messages, but their descriptions clearly separate them by execution state and transport, so an agent should not confuse them.
Tool names are consistently lowercase snake_case with a pi_ prefix, which makes the namespace predictable. The slight inconsistency is that pi is a bare root command, and pi_running/pi_sessions/pi_models are noun-style list commands rather than verb-style names, but the pattern is still easy to follow.
Six tools is well-scoped for a server that manages an external CLI agent. Each tool handles a necessary interaction point—start, continue, interrupt, list live sessions, list historical sessions, and inspect available models—without redundancy or bloat.
The core session lifecycle is covered: create, resume, message mid-run, list running, list all, and check models. There is no explicit cancel/stop tool or read-only session history viewer, but pi_reply can resume any non-running session, so agents are not blocked by the omissions.
Maintenance
Related MCP Connectors
Develop, manage, and debug Railway projects, services, and deployments from within agents.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
- OolkinOAuthcom.oolkin
AI colleagues that keep your standards, your project and their reasoning between sessions
Related MCP Servers
- AlicenseCqualityCmaintenanceEnables MCP hosts to delegate coding tasks to Pi CLI as a programmable sub-agent with session tracking and process management.72MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients like Claude Code to delegate coding tasks to the local Cursor Agent CLI, with persistent per-workspace sessions that resume across calls.12MIT
- AlicenseNot gradedqualityBmaintenanceDelegates bounded coding tasks from MCP clients to the Pi Coding Agent over stdio. Supports review, verification, implementation, and batch operations with long-running task polling.MIT
- FlicenseNot gradedqualityBmaintenanceEnables MCP hosts like Claude Code and Codex to spawn, manage, and interact with persistent, reusable Pi coding-agent sessions, supporting task dispatch, status checks, and session lifecycle control.2-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/minmax/pi-cli-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server