@schuettc/pi-claude-bridge
Pi extension that uses Claude Code (via Agent SDK) as a model provider and adds an AskClaude tool.
Package details
Install @schuettc/pi-claude-bridge from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@schuettc/pi-claude-bridge- Package
@schuettc/pi-claude-bridge- Version
0.9.1-schuettc.2- Published
- Oct 1, 2026
- Downloads
- 3,679/mo · 1,276/wk
- Author
- schuettc
- License
- MIT
- Types
- extension
- Size
- 490.4 KB
- Dependencies
- 4 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-claude-bridge
Pi extension that integrates Claude Code via the Agent SDK. Originally based on claude-agent-sdk-pi by Prateek Sunal.
- Provider — Use Opus/Sonnet/Haiku as models in pi, with all tool calls flowing through pi's TUI
- AskClaude tool — Delegate tasks or questions to Claude Code when using another provider
FYI: Anthropic announced and then unannounced a change to how you would be billed for tools that use the Agent SDK like this one. It currently uses your regular subscription quota just like Claude Code.
Install
pi install npm:pi-claude-bridge
Requires pi 0.86.1 or newer.
Provider
Use /model to select any Claude model in pi-ai's catalog, e.g. claude-bridge/claude-fable-5-1, claude-bridge/claude-opus-5, or claude-bridge/claude-haiku-4-5.
Behind the scenes, pi's tools are bridged to Claude Code but everything works like normal in pi. Bash commands get Claude Code's 120-second default timeout since pi's bash has none. Skills are forwarded to Claude Code's system prompt, and steering mid-turn reaches Claude at the next tool boundary.
The model list comes from pi-ai's Anthropic catalog automatically — when pi-ai adds a new Claude model, it appears in /model after updating the package, no bridge update needed. Dated snapshot ids (e.g. claude-opus-4-5-20251101) are not shown.
1M Context: Fable 5/5.1, Opus 5.5/5/4.8/4.7, and Sonnet 5.5/5 get 1M context. Opus 4.6 gets 1M only on a Max plan or with Extra Usage, and Sonnet 4.6 only with Extra Usage — set provider.plan and/or provider.longContextExtraUsage as described in Configuration.
AskClaude Tool
Opt-in: set askClaude.enabled to true (see Configuration). Available when using any non-claude-bridge provider. Pi's LLM can delegate tasks to Claude Code and wait for it to answer a question or perform a task. Examples of how to use:
- "Ask Claude to plan a fix"
- "If you get stuck, ask claude for help"
- "Ask claude to review the plan in @foo.md, implement it, then ask an isolated=true claude to review the implementation"
- "Ask claude to poke holes in this theory"
Delegated calls don't read global CLAUDE.md files or Claude Code's skill listing, and always get Claude Code's own system prompt.
Parameters
prompt— the question or task for Claude Codemode—read(default, read files and search/fetch on web),none, orfull(read+write+bash, disable this mode withallowFullMode: falsein config)model—opus(default),sonnet,haiku, or a full model IDthinking— effort level:off,minimal,low,medium,high,xhighisolated— whentrue, Claude gets a clean session with no conversation history (default:false)
Configuration
Config: ~/.pi/agent/claude-bridge.json (global) or the project Pi config directory, usually .pi/claude-bridge.json (project; merged over global).
{
"askClaude": {
"enabled": true,
"allowFullMode": true,
"defaultIsolated": false,
"description": "Custom tool description override"
},
"provider": {
"plan": "max",
"longContextExtraUsage": false,
"strictMcpConfig": true,
"pathToClaudeCodeExecutable": "/home/you/.nix-profile/bin/claude"
}
}
askClaude:
enabled— register the AskClaude tool (defaultfalse). If it's unset, the startup notice below points this out once.name— override the tool's pi-side name (default"AskClaude")label— override the TUI label (default"Ask Claude Code")description— override the tool description. Default whenallowFullMode: true: "Delegate to Claude Code for a second opinion or analysis (code review, architecture questions, debugging theories), or to autonomously handle a task. Defaults to read-only mode — use full mode when the user wants to delegate a task that requires changes. Prefer to handle straightforward tasks yourself."defaultMode—"read"(default),"none", or"full"defaultIsolated— start each call in a fresh session (defaultfalse)allowFullMode— allowmode: "full"; setfalseto lock it outappendSkills— forward pi's skills block into the system prompt (defaulttrue)
provider:
plan(default"pro") — set to"max"if you have a Max (or Team Premium/Enterprise) Anthropic plan. This enables Opus with 1M context.longContextExtraUsage— set totrueto enable 1M context models even if they cost money through Extra Usage on your plan. It enables Sonnet 4.6 with 1M on every plan and Opus 4.6 with 1M on Pro. Not needed for Opus 4.7 or 4.8.forceTwoHundredK— array of model ids to pin to 200K context (bare id, no[1m]suffix). Use if pi-ai declares a model at 1M but Claude Code won't serve it on your plan.strictMcpConfig— block MCP servers from~/.claude.json/.mcp.json(defaulttrue). Cloud MCP (Gmail/Drive via claude.ai OAuth) is always blocked.autoMemoryEnabled— enable Claude Code's auto-memory system (defaultfalse)pathToClaudeCodeExecutable— path to theclaudebinary. Useful if your OS/filesystem has the SDK's bundled musl/glibc binaries in a place where they can't run. For example, with Nix you can set the binary to e.g."/home/you/.nix-profile/bin/claude".
Startup notice: the first session lists provider.plan and askClaude.enabled if unset, then records startupNoticeShown in the global config so it doesn't nag again.
Extension providers and models.json: pi's modelOverrides in ~/.pi/agent/models.json do not currently apply to extension-registered providers (like claude-bridge). Overriding contextWindow or other fields requires editing src/models.ts directly — to pin a model to 200K, use provider.forceTwoHundredK instead.
Multiple Claude accounts
Type /claude-account to open the accounts panel. Each session uses one account; two panes can use different ones at the same time, and a resumed session goes back to the account it last used.
- Add an account: choose
+ Add accountand type a name. Your browser opens Claude's sign-in page (it signs the browser out of claude.ai first, so you can pick any account). Enter the account's email, click the link in the email, then Authorize. - Switch this session: select an account and press Enter. It takes effect on the next turn; the first turn after a switch sends the full history once, because the prompt cache belongs to the account.
- Switch every open session: press
aon an account. Every running pi session on this machine switches to it from its next turn, and each one records the switch, so resuming it later keeps that account. It doesn't change the default for new sessions. - Other keys:
dmakes an account the default for new sessions,rrenames,xremoves (signs it out and deletes its folder). - Without the panel:
/claude-account <name>,/claude-account all <name>,/claude-account add <name>,/claude-account default <name>,/claude-account rename <old> <new>,/claude-account list,/claude-account remove <name>.
Your existing login appears as default and is used until you add another account. Each added account is a Claude Code config directory under ~/.pi/agent/claude-bridge/accounts/; the bridge never reads or stores credentials. Signing in is supported on macOS.
Tests
npm run test:unit for offline tests. npm test adds integration tests that hit APIs; set CLAUDE_BRIDGE_TESTING_ALT_MODEL in .env.test for the alt-provider smoke test.
Integration tests spawn real pi and Claude Code subprocesses and need write access to ~/.claude — a sandbox that blocks it makes --resume fail with No conversation found with session ID.
Debugging
Set CLAUDE_BRIDGE_DEBUG=1 to enable debug output:
- Bridge log at
claude-bridge.login pi's agent dir (PI_CODING_AGENT_DIR, default~/.pi/agent) — provider calls, session sync decisions, tool results, CC stderr. Override location withCLAUDE_BRIDGE_DEBUG_PATH. - Per-query CC CLI logs at
cc-cli-logs/<timestamp>-<tag>-<seq>.login the same directory — the subprocess's own debug stream; tag isprovideroraskclaude. Shows CC's view of session loading, API requests, and tool calls.
When filing a bug about a session-resume failure (e.g. "No conversation found"), the most useful attachments are the syncResult: lines from the bridge log plus the matching cc-cli-logs/ file for the failing query.
Compatibility with other extensions
Which injection routes reach Claude Code
The bridge forwards pi's structured parts — project context files, skills, custom prompt, appended instructions — and drops the rest. Measured against the request body (diag/capture-proxy.mjs):
| Route | Reaches Claude Code |
|---|---|
before_agent_start -> message |
Yes, as literal prompt text in the user turn |
context editing the last user message |
Yes, as literal prompt text |
--append-system-prompt |
Yes, with pi's appended instructions |
context_with_system editing the system message |
Yes when it wraps pi's prompt; the turn fails when it replaces one |
before_agent_start -> systemPrompt |
No, dropped |
Two traps. Returning systemPrompt from before_agent_start makes pi replace the whole system prompt, discarding any context_with_system edit in the same run — only one reaches the request. And system-prompt edits work by wrapping: replacing pi's prompt leaves the bridge with nothing to match, so it refuses the turn rather than send Claude Code a request missing your context files, skills and custom instructions. The error names the closest known prompt and where it diverged.
To add instructions, use message, context, or a system-message edit that keeps pi's prompt intact.
Hooks written for Claude Code
~/.claude/settings.json hooks fire inside bridge turns, so a hook injecting Claude-specific guidance duplicates what pi's extensions already provide. pi sets PI_CODING_AGENT=true for child processes, including the Claude Code child; a hook can skip itself on that:
[ -n "$PI_CODING_AGENT" ] && exit 0
Hooks do not fire on the compact-summary side query.
System prompt rejections
Other extensions can change the system prompt. When the result still contains pi's built-in system prompt text, or the two documentation paths that Anthropic looks for (docs/custom-provider.md in the same prompt with docs/packages.md), the bridge stops the turn instead of sending it, since Anthropic may otherwise bill these requests as Extra Usage. Fix the source extension before retrying; CLAUDE_BRIDGE_DEBUG=1 writes the full prompt to the bridge log when this happens.
Using claude bridge with @gotgenes/pi-subagents
Requires the following in ~/.pi/agent/subagents.json:
{"promptInheritance": {"claude-bridge": "portable"}}
Known issues
A session rebuild re-sends the whole conversation. The bridge rewrites Claude Code's session from pi's history whenever the two diverge — after an abort, /compact, tree navigation, an API error, or on returning to a session — and the next request usually misses the prompt cache for everything past the system prompt. Abort-heavy sessions cost noticeably more.
Files Claude Code edits are not carried across a rebuild. The edit itself survives in the history as a tool call and result — what's lost is the post-edit file snapshot. @file expansions are carried.
System prompt changes mid-session may not reach the model. The bridge keeps Claude Code's default prompt recording: project context (AGENTS.md/CLAUDE.md), skills, and extension-written instructions are captured on the first request and reused on resume. This keeps the cached prefix stable, but later changes may not take effect until a rebuild or compaction. Start a new session if updated instructions must take effect immediately.
Exported Anthropic environment variables override the Claude Code child (issue #107). An exported ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY, or ANTHROPIC_AUTH_TOKEN redirects Claude Code to that gateway and every turn fails with its auth error. Unset them for the pi process.