#23700: feat: Claude CLI personal-use auth (no API key required) + native Anthropic SDK streaming
commands
agents
size: L
Cluster:
AI Provider Enhancements
## Summary
- **Anthropic native streaming transport**: New `anthropic-native-stream` ModelApi that uses `@anthropic-ai/sdk` directly with full streaming support, designed for use with API keys.
- **Claude CLI auth choice**: New onboarding option (`claude-agent-sdk`) that spawns the `claude` CLI binary for inference — no credentials are read, copied, or exchanged. The CLI manages its own authentication session internally.
- **Policy disclosure**: The auth choice is labeled **personal use** with a hint noting "personal/local only", and links directly to Anthropic's policy during onboarding.
### How it works
1. During onboarding, the user selects "Claude CLI (personal use)"
2. OpenClaw verifies the `claude` binary exists on PATH
3. A CLI backend config is stored (just the binary path)
4. At inference time, OpenClaw spawns `claude` as a subprocess — the CLI handles its own OAuth internally
5. No OAuth tokens are read from `~/.claude/.credentials.json` or passed between processes
### What this is NOT
- NOT extracting or forwarding OAuth tokens — the Claude CLI auth path lets the CLI manage its own session internally
- NOT impersonating Claude Code via HTTP headers
- NOT for commercial, shared, or hosted deployments (API keys are the recommended path for those)
- NOT reading `~/.claude/.credentials.json`
- NOT a hosted service — runs entirely on the user's local machine
---
## Policy Context
> **Note:** The `anthropic-native` transport is a separate, API-key-only feature with no policy implications. This section applies only to the **Claude CLI spawning path**.
Anthropic's [authentication and credential use policy](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use) (Feb 19, 2026) states that consumer-plan OAuth is "intended exclusively for Claude Code and Claude.ai" and that using OAuth tokens "in any other product, tool, or service — including the Agent SDK — is not permitted."
### Key Policy Quotes
| Source | Key Quote | Link |
|--------|-----------|------|
| **OAuth Policy** (Feb 19, 2026) | "OAuth authentication (used with Free, Pro, and Max plans) is intended exclusively for Claude Code and Claude.ai." | [Authentication and credential use](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use) |
| **OAuth Policy** | "Using OAuth tokens obtained through Claude Free, Pro, or Max accounts in any other product, tool, or service — including the Agent SDK — is not permitted." | [Authentication and credential use](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use) |
| **Headless/CLI Docs** | Documents `--print` and `--output-format json` specifically for scripted and automated CLI usage | [code.claude.com/docs/en/headless](https://code.claude.com/docs/en/headless) |
### Why this works
- **OAuth tokens stay inside Claude Code.** OpenClaw spawns the `claude` binary; the CLI loads its own credentials, constructs its own HTTP request, and authenticates with Anthropic's API. Tokens never cross the process boundary. OpenClaw communicates with the CLI via stdin/stdout only.
- **The CLI was designed for subprocess invocation.** Anthropic's own [Agent SDK](https://github.com/anthropics/claude-agent-sdk-typescript) spawns `claude` via `child_process.spawn()` ([ref](https://github.com/anthropics/claude-agent-sdk-typescript/issues/142)). The [VS Code extension](https://github.com/anthropics/claude-code/issues/8510) does the same. Anthropic's [headless docs](https://code.claude.com/docs/en/headless) document `--print` and `--output-format json` for scripted usage.
- **No third party exists in personal use.** The developer, user, and Anthropic account holder are the same person. There is no "on behalf of" relationship.
Users should review Anthropic's [current policy](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use) and the [Consumer Terms](https://www.anthropic.com/legal/consumer-terms) before using this option. Terms may change.
### Safeguards
- API keys are the **default recommended path** — Claude CLI is a secondary option
- Labeled "personal use" with a direct link to [Anthropic's policy](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use) in the onboarding UI
- OAuth tokens never enter OpenClaw's process memory
- The `anthropic-native` transport is API-key-only and does not handle OAuth tokens
- The CLI enforces Anthropic's rate limits
---
## Files changed
| File | Change |
|------|--------|
| `src/agents/anthropic-native-stream.ts` | New streaming transport for API key users |
| `src/commands/auth-choice.apply.claude-agent-sdk.ts` | New auth handler — verifies CLI binary, stores config |
| `src/commands/auth-choice-options.ts` | Add choice to onboarding menu |
| `src/commands/auth-choice.apply.ts` | Register handler in chain |
| `src/commands/onboard-types.ts` | Add to AuthChoice union |
| `src/agents/cli-backends.ts` | Add CLI backend config |
| `src/agents/pi-embedded-runner/model.ts` | Support anthropic-native model type |
| `src/agents/pi-embedded-runner/run/attempt.ts` | Wire up anthropic-native stream |
| `src/config/types.models.ts` | Add anthropic-native to ModelApi type |
| `src/config/zod-schema.core.ts` | Add to zod schema |
| `package.json` | Add `@anthropic-ai/sdk` dependency |
## Test plan
- [x] `pnpm build` passes
- [x] `pnpm check` (format + typecheck + lint) passes with 0 errors
- [x] All 6150 tests pass across 742 test files
- [ ] Manual: `openclaw onboard` → select "Claude CLI (personal use)" with `claude` installed
- [ ] Manual: Configure anthropic-native model and verify streaming works with API key
## Related issues
Closes #12061
Addresses #19534 — `anthropic-native` transport adds `cache_control: { type: "ephemeral" }` on system blocks, fixing prompt cache misses for users on this transport.
Addresses #17537 — same root cause; the native transport sends proper `cache_control` headers that `streamSimple` was missing.
Related: #20107, #21716, #9422 (Anthropic 404 errors — `anthropic-native` transport bypasses the broken `anthropic-messages` path), #16952 (thinking + tool_use — native transport handles interleaved thinking correctly), #22128 (cache metrics — native transport captures `cacheRead`/`cacheWrite` in Usage)
🤖 AI-assisted (research, implementation, and legal analysis)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds two independent features: (1) native Anthropic SDK streaming transport for API key users with prompt caching support, and (2) Claude CLI spawning option for personal-use inference. The implementation is clean with proper separation - the `anthropic-native-stream` transport only handles API keys, while the CLI auth path spawns the `claude` binary as a subprocess without reading or forwarding OAuth tokens. The HEAD commit (9fe5294c) actually removed OAuth token detection code that was dead code. Architecture follows established patterns (similar to `ollama-stream.ts`).
- New `anthropic-native` ModelApi type uses `@anthropic-ai/sdk` directly, bypassing pi-ai's `streamSimple` to enable prompt caching and remove 300s timeout
- Provider-level API override allows switching built-in Anthropic models to native transport via config
- CLI auth handler verifies `claude` binary exists, stores path in config, displays policy notice
- No OAuth tokens are read, extracted, or forwarded - verified both files don't access `.claude/.credentials.json`
- Proper integration with existing model resolution and config systems
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with standard review - adds two well-separated features with no OAuth token extraction
- Clean architecture with proper separation of concerns, no security issues found (OAuth tokens are NOT read/extracted), follows existing patterns. Score is 4 instead of 5 due to: (1) no test coverage for new functionality, (2) manual testing not yet completed per test plan. The implementation is sound and the HEAD commit actually removed dead OAuth code for additional safety.
- No files require special attention - the implementation follows established patterns and is well-structured
<sub>Last reviewed commit: 9fe5294</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#10108: fix: override stale Anthropic OAuth stealth headers for Opus 4.6
by CivilBooks · 2026-02-06
79.9%
#10492: fix(auth): store Anthropic setup-token as type:oauth for auto-refresh
by sparck75 · 2026-02-06
78.8%
#20428: feat: capture Anthropic rate-limit response headers to disk
by AndrewArto · 2026-02-18
78.0%
#18670: feat: add first-class Claude Code CLI auth path + CLI model UX hard...
by SmithLabsLLC · 2026-02-16
78.0%
#22105: feat(auth): add refreshable Anthropic OAuth login flow
by sauerdaniel · 2026-02-20
76.6%
#2806: [AI-Assisted] Fix: Repair tool_use/tool_result pairing for Claude o...
by Arthur742Ramos · 2026-01-27
75.6%
#20747: feat(copilot): support Claude models with correct context windows (...
by yuf1011 · 2026-02-19
74.5%
#13484: feat(auth): restore Claude Code CLI OAuth credential sync
by joshpocock · 2026-02-10
74.3%
#9163: Fix: Save Anthropic setup token to config file
by vishaltandale00 · 2026-02-04
74.0%
#15397: feat: support Anthropic speed:"fast" parameter passthrough
by mode80 · 2026-02-13
73.8%