Pi extension package for Anthropic OAuth compatibility
TypeScript
279
348 commits
updated Sep 23, 2026
A Pi extension that improves compatibility with Anthropic Claude Pro/Max OAuth (i.e., your Claude subscription) while preserving Pi's normal Anthropic behavior.
Pi works great with Anthropic API keys out of the box. This extension fills in the gaps for users who want to use their Claude Pro or Max subscription via OAuth instead.
It keeps everything you'd expect — the built-in anthropic provider, the full model list, API-key behavior, and the native /login anthropic flow — and layers on the compatibility fixes needed to make OAuth subscriptions work reliably.
Requests to non-Anthropic providers and plain API-key Anthropic requests pass through completely untouched — the extension only activates when it detects an Anthropic OAuth access token (sk-ant-oat).
Shaping runs in a thin transport wrapper around Pi's own Anthropic transport, so it applies to interactive turns and to compaction — not just the main turn. Background agents that run their own agent loop are a known exception on Pi 0.80.8 and later. See docs/architecture.md for how this works, and for the workaround if you write such an extension.
Pi's own extra-usage warning still appears on every Anthropic OAuth session and is not suppressed by this extension — see Pi warns about extra usage on every OAuth session.
Requires Pi 0.86.0 or newer.
Pi 0.86.0 restructured its system prompt into XML-tagged sections, and this extension shapes that structure directly; the 2.x line supports Pi 0.80.8 through 0.85.x.
pi install npm:@gotgenes/pi-anthropic-auth
To try it without permanently installing:
pi -e npm:@gotgenes/pi-anthropic-auth
/login anthropic as usual — Pi's native Anthropic login flow is preserved.Run /anthropic-auth:status in Pi to print a diagnostics report:
pi-anthropic-auth diagnostics
version: 0.6.5
module: /root/.pi/agent/.../src/index.ts
built-in Anthropic transport: resolved
The module line shows which copy of the extension loaded.
If the command is not found, the extension is not loaded at all.
Pi prints this warning once per interactive session whenever an Anthropic model is selected and your stored Anthropic credentials are OAuth:
Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in
/settings.
Installing this extension does not silence it, and that is not a sign the extension is broken. Pi's check looks only at which provider the selected model belongs to and whether the stored credential is an OAuth token. It has no way to see that a provider registration is in place, so no extension can suppress it.
The warning is also not entirely wrong. Interactive turns and compaction go through this extension's request shaping; requests from background agents that run their own agent loop do not, and for those the warning describes exactly what happens. See docs/architecture.md for the full call-path table.
This is a startup notice, not a failure.
A request that actually fails with an HTTP 400 saying You're out of extra usage. is a different problem — start with Verify the extension is loaded.
Pi owns the switch for this warning, so the extension leaves it alone.
Turn it off yourself with /settings → Warnings → "Anthropic extra usage", or set it in ~/.pi/agent/settings.json:
{
"warnings": {
"anthropicExtraUsage": false
}
}
Because the warning concerns real billing on paths this extension does not cover, that call is yours to make; the extension will never write the setting for you.
ANTHROPIC_API_KEY is ignored when OAuth credentials existPi's auth resolver gives stored credentials priority over environment variables.
If you have previously run /login anthropic and credentials are stored in ~/.pi/agent/auth.json, Pi uses the stored OAuth token on every request — even when ANTHROPIC_API_KEY is also set.
To use the API key instead, run /logout anthropic inside Pi to remove the stored credentials, or delete auth.json before starting the session.
claude_code_version_too_oldAnthropic gates newly released models on a minimum Claude Code version:
400 invalid_request_error: Claude Code 2.1.260 does not support this model;
version 2.1.280 or newer is required.
details.error_code: claude_code_version_too_old
This package reports a bundled Claude Code version in the OAuth billing header, and Anthropic gates on that value.
The bundled version is a floor, not a fixed value: when the Pi you are running reports a newer Claude Code version in its own user-agent, this extension adopts it automatically for the billing header.
So upgrading Pi is usually enough to reach a newly gated model.
When Anthropic raises the floor faster than either Pi or this package ships, the extension recovers on its own. The rejection names the required version, so the extension rebuilds the billing header at that version and retries the request once. It remembers that version for the rest of the session, so only the first request after a floor rise pays for the rejected attempt.
If the error still reaches you, it ends with a [pi-anthropic-auth] hint saying what to do: raise or unset an override, set one, or upgrade Pi.
To pin the version yourself:
export PI_ANTHROPIC_AUTH_CLAUDE_CODE_VERSION=2.1.280
The value must be a bare X.Y.Z version; anything else fails fast with an explicit error.
An override is absolute: it is taken verbatim, never raised from Pi's version, and turns off automatic recovery, so a stale override can itself cause this error.
Check the current release with npm view @anthropic-ai/claude-code dist-tags.
Do not derive the value from a local claude --version.
Claude Code's stable release channel lags latest, so an installed copy is often below the floor a new model requires.
/compact fails with a Terms of Service messageCompaction failed: Turn prefix summarization failed: This request was blocked as it seems to
violate Anthropic's Terms of Service restrictions on reverse engineering or duplicating model
outputs.
Fixed in pi 0.87.1. If you see this, upgrade pi.
This was Anthropic's reasoning_extraction classifier responding to pi's turn-prefix summarization prompt, which asserted "This is the PREFIX of a turn that was too large to keep" while sending a transcript of only a few hundred characters, mostly model output.
On claude-fable-5-1 that combination was refused.
Nothing in this extension caused it or fixed it: the fix is entirely upstream, in earendil-works/pi#9908.
If you install the extension at image build time with RUN pi install npm:@gotgenes/pi-anthropic-auth and then mount a persistent volume over ~/.pi/agent at runtime, Docker may mask the build-time install.
Docker seeds a named volume with the image directory only on its first creation.
If the volume already exists from a previous image, the extension directory inside it may be empty or out of date.
To fix this, either:
docker volume rm <volume-name>.pnpmpi installation, version 0.86.0 or newerpnpm install # install dependencies
pnpm run check # typecheck
pnpm test # run tests
pnpm run build # compile
pi -e /absolute/path/to/pi-anthropic-auth/dist/index.js
Set PI_ANTHROPIC_AUTH_DEBUG to enable structured debug logs from the OAuth shaping layer.
Modes:
PI_ANTHROPIC_AUTH_DEBUG=all — log all Anthropic OAuth shaping eventsPI_ANTHROPIC_AUTH_DEBUG=tool-use — log only requests that include tool_useExample:
PI_ANTHROPIC_AUTH_DEBUG=tool-use \
pi \
--model anthropic/claude-haiku-4-5 \
--no-session \
--tools read,grep,find,ls \
-e /absolute/path/to/pi-anthropic-auth/src/index.ts \
-p "How many lines are in @AGENTS.md ?"
For notes on how this project compares to similar work, see docs/comparison-to-similar-projects.md.
This project was inspired by opencode-anthropic-auth, which solved the same Anthropic OAuth compatibility problem for OpenCode.
MIT
TypeScript
92.4%
Shell
5.9%
JavaScript
1.7%
Pi extension package for Anthropic OAuth compatibility
TypeScript
279
348 commits
updated Sep 23, 2026
A Pi extension that improves compatibility with Anthropic Claude Pro/Max OAuth (i.e., your Claude subscription) while preserving Pi's normal Anthropic behavior.
Pi works great with Anthropic API keys out of the box. This extension fills in the gaps for users who want to use their Claude Pro or Max subscription via OAuth instead.
It keeps everything you'd expect — the built-in anthropic provider, the full model list, API-key behavior, and the native /login anthropic flow — and layers on the compatibility fixes needed to make OAuth subscriptions work reliably.
Requests to non-Anthropic providers and plain API-key Anthropic requests pass through completely untouched — the extension only activates when it detects an Anthropic OAuth access token (sk-ant-oat).
Shaping runs in a thin transport wrapper around Pi's own Anthropic transport, so it applies to interactive turns and to compaction — not just the main turn. Background agents that run their own agent loop are a known exception on Pi 0.80.8 and later. See docs/architecture.md for how this works, and for the workaround if you write such an extension.
Pi's own extra-usage warning still appears on every Anthropic OAuth session and is not suppressed by this extension — see Pi warns about extra usage on every OAuth session.
Requires Pi 0.86.0 or newer.
Pi 0.86.0 restructured its system prompt into XML-tagged sections, and this extension shapes that structure directly; the 2.x line supports Pi 0.80.8 through 0.85.x.
pi install npm:@gotgenes/pi-anthropic-auth
To try it without permanently installing:
pi -e npm:@gotgenes/pi-anthropic-auth
/login anthropic as usual — Pi's native Anthropic login flow is preserved.Run /anthropic-auth:status in Pi to print a diagnostics report:
pi-anthropic-auth diagnostics
version: 0.6.5
module: /root/.pi/agent/.../src/index.ts
built-in Anthropic transport: resolved
The module line shows which copy of the extension loaded.
If the command is not found, the extension is not loaded at all.
Pi prints this warning once per interactive session whenever an Anthropic model is selected and your stored Anthropic credentials are OAuth:
Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in
/settings.
Installing this extension does not silence it, and that is not a sign the extension is broken. Pi's check looks only at which provider the selected model belongs to and whether the stored credential is an OAuth token. It has no way to see that a provider registration is in place, so no extension can suppress it.
The warning is also not entirely wrong. Interactive turns and compaction go through this extension's request shaping; requests from background agents that run their own agent loop do not, and for those the warning describes exactly what happens. See docs/architecture.md for the full call-path table.
This is a startup notice, not a failure.
A request that actually fails with an HTTP 400 saying You're out of extra usage. is a different problem — start with Verify the extension is loaded.
Pi owns the switch for this warning, so the extension leaves it alone.
Turn it off yourself with /settings → Warnings → "Anthropic extra usage", or set it in ~/.pi/agent/settings.json:
{
"warnings": {
"anthropicExtraUsage": false
}
}
Because the warning concerns real billing on paths this extension does not cover, that call is yours to make; the extension will never write the setting for you.
ANTHROPIC_API_KEY is ignored when OAuth credentials existPi's auth resolver gives stored credentials priority over environment variables.
If you have previously run /login anthropic and credentials are stored in ~/.pi/agent/auth.json, Pi uses the stored OAuth token on every request — even when ANTHROPIC_API_KEY is also set.
To use the API key instead, run /logout anthropic inside Pi to remove the stored credentials, or delete auth.json before starting the session.
claude_code_version_too_oldAnthropic gates newly released models on a minimum Claude Code version:
400 invalid_request_error: Claude Code 2.1.260 does not support this model;
version 2.1.280 or newer is required.
details.error_code: claude_code_version_too_old
This package reports a bundled Claude Code version in the OAuth billing header, and Anthropic gates on that value.
The bundled version is a floor, not a fixed value: when the Pi you are running reports a newer Claude Code version in its own user-agent, this extension adopts it automatically for the billing header.
So upgrading Pi is usually enough to reach a newly gated model.
When Anthropic raises the floor faster than either Pi or this package ships, the extension recovers on its own. The rejection names the required version, so the extension rebuilds the billing header at that version and retries the request once. It remembers that version for the rest of the session, so only the first request after a floor rise pays for the rejected attempt.
If the error still reaches you, it ends with a [pi-anthropic-auth] hint saying what to do: raise or unset an override, set one, or upgrade Pi.
To pin the version yourself:
export PI_ANTHROPIC_AUTH_CLAUDE_CODE_VERSION=2.1.280
The value must be a bare X.Y.Z version; anything else fails fast with an explicit error.
An override is absolute: it is taken verbatim, never raised from Pi's version, and turns off automatic recovery, so a stale override can itself cause this error.
Check the current release with npm view @anthropic-ai/claude-code dist-tags.
Do not derive the value from a local claude --version.
Claude Code's stable release channel lags latest, so an installed copy is often below the floor a new model requires.
/compact fails with a Terms of Service messageCompaction failed: Turn prefix summarization failed: This request was blocked as it seems to
violate Anthropic's Terms of Service restrictions on reverse engineering or duplicating model
outputs.
Fixed in pi 0.87.1. If you see this, upgrade pi.
This was Anthropic's reasoning_extraction classifier responding to pi's turn-prefix summarization prompt, which asserted "This is the PREFIX of a turn that was too large to keep" while sending a transcript of only a few hundred characters, mostly model output.
On claude-fable-5-1 that combination was refused.
Nothing in this extension caused it or fixed it: the fix is entirely upstream, in earendil-works/pi#9908.
If you install the extension at image build time with RUN pi install npm:@gotgenes/pi-anthropic-auth and then mount a persistent volume over ~/.pi/agent at runtime, Docker may mask the build-time install.
Docker seeds a named volume with the image directory only on its first creation.
If the volume already exists from a previous image, the extension directory inside it may be empty or out of date.
To fix this, either:
docker volume rm <volume-name>.pnpmpi installation, version 0.86.0 or newerpnpm install # install dependencies
pnpm run check # typecheck
pnpm test # run tests
pnpm run build # compile
pi -e /absolute/path/to/pi-anthropic-auth/dist/index.js
Set PI_ANTHROPIC_AUTH_DEBUG to enable structured debug logs from the OAuth shaping layer.
Modes:
PI_ANTHROPIC_AUTH_DEBUG=all — log all Anthropic OAuth shaping eventsPI_ANTHROPIC_AUTH_DEBUG=tool-use — log only requests that include tool_useExample:
PI_ANTHROPIC_AUTH_DEBUG=tool-use \
pi \
--model anthropic/claude-haiku-4-5 \
--no-session \
--tools read,grep,find,ls \
-e /absolute/path/to/pi-anthropic-auth/src/index.ts \
-p "How many lines are in @AGENTS.md ?"
For notes on how this project compares to similar work, see docs/comparison-to-similar-projects.md.
This project was inspired by opencode-anthropic-auth, which solved the same Anthropic OAuth compatibility problem for OpenCode.
MIT
TypeScript
92.4%
Shell
5.9%
JavaScript
1.7%