Add Pi coding agent as a supported MCP client
Summary
Please add Pi, an open-source terminal coding agent, as a supported client for thv client register / thv client setup and the desktop app's Manage Clients dialog.
Since Pi 0.99.0, MCP support is built in. Pi reads servers from a standard mcpServers JSON file, so it fits ToolHive's existing client model with no new config logic. It would be configured much like Cursor, Claude Code and Kimi CLI are today.
Pi's MCP configuration
Docs: https://pi.dev/docs/latest/mcp
- User config:
~/.pi/agent/mcp.json. The directory can be overridden with PI_CODING_AGENT_DIR.
- Project config:
.pi/mcp.json. Pi only reads it after the user trusts the project.
- Format: a top-level
mcpServers object, the same shape Claude Desktop, Claude Code and Cursor use:
{
"mcpServers": {
"fetch": {
"type": "http",
"url": "http://127.0.0.1:12345/mcp"
}
}
}
- Transports:
- stdio (
command/args) and streamable HTTP (url).
type is optional. When present, it must be stdio, http, or streamable-http.
- Legacy SSE is not supported.
"type": "sse" is rejected and the entry is skipped.
- Reloading: servers are loaded at session start and on
/reload. pi mcp list validates the file and connects to every enabled server, which makes it a handy way to verify a registration.
- Skills:
- Pi's own locations:
~/.pi/agent/skills/ (user) and .pi/skills/ (project).
- Pi also reads the shared Agent Skills locations:
~/.agents/skills/ and .agents/skills/.
- Binary:
pi (npm package @earendil-works/pi-coding-agent).
Proposed clientAppConfig entry
// Pi represents the Pi coding agent.
Pi ClientApp = "pi"
{
ClientType: Pi,
Description: "Pi coding agent",
SettingsFile: "mcp.json",
MCPServersPathPrefix: "/mcpServers",
RelPath: []string{".pi", "agent"},
Extension: JSON,
SupportedTransportTypesMap: map[types.TransportType]string{
types.TransportTypeStdio: "http",
types.TransportTypeStreamableHTTP: "http",
// SSE intentionally omitted: Pi rejects "type": "sse"
},
IsTransportTypeFieldSupported: true,
MCPServersUrlLabelMap: map[types.TransportType]string{
types.TransportTypeStdio: defaultURLFieldName,
types.TransportTypeSSE: defaultURLFieldName,
types.TransportTypeStreamableHTTP: defaultURLFieldName,
},
SupportsSkills: true,
SkillsGlobalPath: []string{".pi", "agent", skillsDirName},
SkillsProjectPath: []string{".pi", skillsDirName},
},
Installation detection would work through the existing IsClientInstalled check, since ~/.pi/agent exists once Pi has been run.
Open questions / notes
- SSE workloads: with SSE left out of the transport map, an SSE workload would be written without a
type field. Pi would then treat it as streamable HTTP and fail to connect. Should ToolHive skip SSE workloads for this client, or is it acceptable to document that Pi only supports stdio and streamable-HTTP workloads?
- Missing config file:
~/.pi/agent/mcp.json doesn't exist until the user adds a server. Is creating it on registration (as {}) the expected behavior, or should users create it first?
PI_CODING_AGENT_DIR: ToolHive could respect this override if set. Other clients don't seem to handle env overrides, so it's probably fine to leave out at first.
- MCP-replacing extensions: a Pi extension that registers its own
/mcp command (for example the older pi-mcp-adapter) replaces the built-in MCP support, and Pi then ignores mcp.json. This is worth a note in the client compatibility docs.
Scope
This would follow the pattern of #4788 (Kimi CLI) and #2489 (OpenCode):
pkg/client/config.go: the new ClientApp constant and config entry.
pkg/client/config_test.go and skills_test.go.
- Regenerated CLI docs (
thv_client_register.md, thv_client_remove.md), swagger/OpenAPI, and the Go SDK.
- A row in the client compatibility page (docs-website).
I'm happy to open the PR if this approach looks good.
Add Pi coding agent as a supported MCP client
Summary
Please add Pi, an open-source terminal coding agent, as a supported client for
thv client register/thv client setupand the desktop app's Manage Clients dialog.Since Pi 0.99.0, MCP support is built in. Pi reads servers from a standard
mcpServersJSON file, so it fits ToolHive's existing client model with no new config logic. It would be configured much like Cursor, Claude Code and Kimi CLI are today.Pi's MCP configuration
Docs: https://pi.dev/docs/latest/mcp
~/.pi/agent/mcp.json. The directory can be overridden withPI_CODING_AGENT_DIR..pi/mcp.json. Pi only reads it after the user trusts the project.mcpServersobject, the same shape Claude Desktop, Claude Code and Cursor use:{ "mcpServers": { "fetch": { "type": "http", "url": "http://127.0.0.1:12345/mcp" } } }command/args) and streamable HTTP (url).typeis optional. When present, it must bestdio,http, orstreamable-http."type": "sse"is rejected and the entry is skipped./reload.pi mcp listvalidates the file and connects to every enabled server, which makes it a handy way to verify a registration.~/.pi/agent/skills/(user) and.pi/skills/(project).~/.agents/skills/and.agents/skills/.pi(npm package@earendil-works/pi-coding-agent).Proposed
clientAppConfigentryInstallation detection would work through the existing
IsClientInstalledcheck, since~/.pi/agentexists once Pi has been run.Open questions / notes
typefield. Pi would then treat it as streamable HTTP and fail to connect. Should ToolHive skip SSE workloads for this client, or is it acceptable to document that Pi only supports stdio and streamable-HTTP workloads?~/.pi/agent/mcp.jsondoesn't exist until the user adds a server. Is creating it on registration (as{}) the expected behavior, or should users create it first?PI_CODING_AGENT_DIR: ToolHive could respect this override if set. Other clients don't seem to handle env overrides, so it's probably fine to leave out at first./mcpcommand (for example the olderpi-mcp-adapter) replaces the built-in MCP support, and Pi then ignoresmcp.json. This is worth a note in the client compatibility docs.Scope
This would follow the pattern of #4788 (Kimi CLI) and #2489 (OpenCode):
pkg/client/config.go: the newClientAppconstant and config entry.pkg/client/config_test.goandskills_test.go.thv_client_register.md,thv_client_remove.md), swagger/OpenAPI, and the Go SDK.I'm happy to open the PR if this approach looks good.