README · Setup · Auth Methods · Troubleshooting
The plugin has four main responsibilities:
- Auth method registration — adds Claude Code session, browser sign-in, and API key methods to the Anthropic provider
- Credential loading and refresh — reads and refreshes tokens for both auth paths
- Config patching — adds Anthropic provider/model config to
opencode.jsonon demand - Request rewriting — transforms headers, body, and responses for Anthropic OAuth compatibility
| File | Purpose |
|---|---|
src/index.ts |
Plugin entrypoint. Registers auth methods, auth loader, config prompt. |
src/creds.ts |
Reads Claude credentials from macOS Keychain or ~/.claude/.credentials.json. |
src/refresh.ts |
Refreshes Claude Code session by invoking claude -p . --model claude-haiku-4-5. |
src/oauth.ts |
Browser OAuth: PKCE generation, code exchange, token refresh. |
src/headers.ts |
Rewrites request headers, body, URLs, and response streams. |
src/configure.ts |
configure and doctor CLI helpers for opencode.json patching. |
src/cli.ts |
CLI entrypoint for configure / doctor commands. |
src/state.ts |
Persists the last active auth source (claude-code-session or browser-oauth). |
User selects "Claude Code session"
→ hasClaude()? → readClaudeCreds() → ensureFresh()
→ isFresh? return creds
→ stale? → spawn claude CLI → re-read creds → return if fresh
→ sync to OpenCode auth storage
→ save source = "claude-code-session"
User selects "Browser sign-in"
→ authorize() → generate PKCE + state → return URL
→ user pastes code
→ exchange() → POST to Anthropic token endpoint → get access + refresh tokens
→ sync to OpenCode auth storage
→ save source = "browser-oauth"
Auth loader reads stored auth
→ source = "claude-code-session"? → readClaudeCreds() → ensureFresh()
→ source = "browser-oauth"? → check token expiry → refresh via OAuth if stale
→ build headers → rewrite body → fetch → rewrite response
→ on 401/403 → force refresh → retry once
Plugin loads → ready()? → if false, show config prompt
→ user selects "Update this project"
→ apply({ cwd, yes: true })
→ locate opencode.json
→ plan() → diff only missing keys
→ write patched config
CLI: npx opencode-claude-code-auth configure
→ same apply() logic with interactive confirmation
Keys added (only if missing):
| Key | Value |
|---|---|
provider.anthropic.npm |
@ai-sdk/anthropic |
provider.anthropic.name |
Anthropic |
provider.anthropic.models.* |
Default model entries |
model |
anthropic/claude-sonnet-4-5 |
small_model |
anthropic/claude-haiku-4-5 |
The auth loader wraps fetch to transform Anthropic requests:
| What | How |
|---|---|
| Auth header | Authorization: Bearer <access_token> |
| Beta header | anthropic-beta: oauth-2025-04-20,interleaved-thinking-2025-05-14 |
| User-Agent | claude-cli/2.1.2 (external, cli) |
x-api-key |
Removed (not used with OAuth) |
| System prompt | Prepends Claude Code identity prefix |
| Tool names | Prefixed with mcp_ on outgoing, stripped on incoming |
| URL | Adds ?beta=true to /v1/messages if missing |
| File | Purpose |
|---|---|
~/.config/opencode-claude-code-auth/state.json |
Last active auth source (claude-code-session or browser-oauth) |
~/.local/share/opencode/auth.json |
OpenCode's auth storage (managed by OpenCode, written by plugin via client.auth.set) |
- No silent config mutation — config is only patched with explicit user consent (CLI prompt or
configurecommand) - Claude Code dependency — session auth requires
claudeto be installed and logged in; the plugin cannot fix a broken local Claude session - Web/TUI limitations — plugin prompt metadata (install, config) is not available in all OpenCode surfaces; CLI gives the fullest experience
- OAuth behavior — browser auth depends on Anthropic's current OAuth endpoints and may need updates if they change