fix(claude-code): add oauthToken config for subscription SDK auth
`claude login` alone does not authorize SDK / non-interactive (`claude -p`) usage. Anthropic gates that behind a separate long-lived token minted by `claude setup-token`. Without it, subscription users hit `billing_error` from the SDK even though interactive Claude Code works fine. Changes: - ClaudeCodeConfig.oauthToken: new optional field. When set, the provider exports it as CLAUDE_CODE_OAUTH_TOKEN before invoking the SDK, which makes the SDK bill against the user's Pro/Max subscription instead of API credits. - apiKey continues to work for users with a console API key. If both are present, oauthToken takes precedence. - billing_error / authentication_failed messages now point users at `claude setup-token` so the fix is obvious from the error alone. - README: rewrite the Claude Code section to document both modes and the `claude setup-token` step explicitly. - examples/claude-code.ts: read CLAUDE_CODE_OAUTH_TOKEN from env so the smoke test actually works for subscribers.
This commit is contained in:
31
README.md
31
README.md
@@ -52,27 +52,46 @@ const claude = new ClaudeProvider({
|
||||
});
|
||||
```
|
||||
|
||||
### Claude Code (subscription via local CLI)
|
||||
### Claude Code (subscription or API key via local CLI)
|
||||
|
||||
`ClaudeCodeProvider` wraps `@anthropic-ai/claude-agent-sdk`, which authenticates through the local `claude` CLI. This is the supported path for **Claude Pro / Max subscribers** who don't have a console API key.
|
||||
`ClaudeCodeProvider` wraps `@anthropic-ai/claude-agent-sdk`, which spawns the local `claude` CLI under the hood. It supports two billing modes:
|
||||
|
||||
**Setup:** install the CLI and run `claude login` once. No API key required.
|
||||
**Mode A — Claude Pro/Max subscription** (billed against subscription credits):
|
||||
|
||||
```bash
|
||||
# One-time: install the CLI, then mint a long-lived OAuth token.
|
||||
# `claude login` alone is NOT enough — Anthropic gates SDK use behind setup-token.
|
||||
claude setup-token
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { ClaudeCodeProvider } from 'simple-ai-provider';
|
||||
|
||||
const claude = new ClaudeCodeProvider({}); // uses local credentials
|
||||
await claude.initialize();
|
||||
const claude = new ClaudeCodeProvider({
|
||||
oauthToken: process.env.CLAUDE_CODE_OAUTH_TOKEN // from `claude setup-token`
|
||||
});
|
||||
|
||||
await claude.initialize();
|
||||
const response = await claude.complete({
|
||||
messages: [{ role: 'user', content: 'Hello!' }]
|
||||
});
|
||||
```
|
||||
|
||||
You can still pass `apiKey` to override (it's set as `ANTHROPIC_API_KEY` for the SDK). Optional config:
|
||||
**Mode B — Console API key** (billed per-token):
|
||||
|
||||
```typescript
|
||||
const claude = new ClaudeCodeProvider({
|
||||
apiKey: process.env.ANTHROPIC_API_KEY
|
||||
});
|
||||
```
|
||||
|
||||
If both are present, `oauthToken` wins. Either field can also be picked up from the environment (`CLAUDE_CODE_OAUTH_TOKEN` / `ANTHROPIC_API_KEY`) without being passed explicitly.
|
||||
|
||||
Optional config:
|
||||
|
||||
```typescript
|
||||
new ClaudeCodeProvider({
|
||||
oauthToken: '...',
|
||||
defaultModel: 'sonnet', // 'sonnet' | 'opus' | 'haiku' | 'inherit' | full model ID
|
||||
maxTurns: 1, // 1 for plain completion; raise for agent/tool loops
|
||||
allowedTools: [], // tool names to enable (default: none)
|
||||
|
||||
Reference in New Issue
Block a user