Releases: okhsunrog/claude-proxy-rs
Release list
v2.0.1
Code-review cleanups and a full dependency refresh.
Changes
- Remove unused dependencies (
aegis,dirs, directtower) - Mirror the 401 force-refresh retry into the OpenAI
chat_completionspath - Deserialize OpenAI requests from a borrow to avoid cloning the request body
- Consolidate
useUsageHistoryonto the generated OpenAPI client, dropping duplicate hand-written types and rawfetchcalls - Upgrade Rust dependencies (
tower-http0.7, plus compatible bumps) - Upgrade frontend dependencies including majors: TypeScript 6,
@types/node26,@vue/tsconfig0.9,@hey-api/openapi-ts0.99; regenerate the API client
v2.0.0
Changelog
v2.0.0 - 2026-06-22
Breaking Changes
- Replaced Turso storage with PostgreSQL via
sqlx. - Removed all Turso runtime code and migration helpers.
- Deployment now requires
CLAUDE_PROXY_DATABASE_URLorDATABASE_URLpointing to PostgreSQL. - Database migrations are now managed by
sqlxmigrations inmigrations/.
Migration Notes
- Back up existing data before upgrading.
- Ensure PostgreSQL is available and configured before starting the service.
- Existing deployments should run the included migrations on startup.
client_keys.enabled,client_keys.allow_extra_usage, andmodels.enabledare now native PostgreSQLBOOLEANcolumns.
Added
- Compile-time checked
sqlxqueries with checked metadata in CI. - Online SQLx migration/cache validation in CI.
- Stricter Clippy guardrails for production safety.
- PostgreSQL-backed usage history, model limits, client key limits, auth storage, and admin sessions.
Changed
- Refactored database and usage-history code into smaller modules.
- Refactored admin session handling out of
main.rs. - Improved typed database error handling with
thiserror. - Shortened fully qualified paths and grouped imports consistently.
Removed
- Turso dependencies, database code, and migration compatibility paths.
v1.3.0
What's Changed
- Added opt-in request/response capture support for debugging proxy behavior.
- Improved embedded database concurrency with WAL/busy-timeout initialization fixes.
- Updated to stable
turso0.6.0. - Added Claude Code-compatible tool-name normalization for cloaked native Anthropic requests.
- Added tested native Anthropic support for ForgeCode and Roo Code custom tool names.
- Added local loud-fail behavior for unknown or colliding custom tool names.
- Documented third-party tool support and custom tool-name behavior in the README.
Tested
- ForgeCode via native Anthropic API.
- Roo Code via native Anthropic API.
v1.2.0
Major reliability rewrite for subscription usage fetching.
Highlights
claude.ai web session bypass for OAuth rate limit
Anthropic aggressively rate-limits the OAuth /api/oauth/usage endpoint for third-party clients (429 with a useless retry-after: 0, only recoverable by re-establishing the OAuth session). The admin UI now supports an optional claude.ai web session path: scrape a sessionKey cookie, org_uuid, anthropic-device-id, and anthropic-anonymous-id from DevTools, paste them into the new form in the Claude Subscription card, and the proxy will fetch usage through claude.ai/api/organizations/{uuid}/usage — the same endpoint the web UI uses, which isn't rate-limited. The session cookie is auto-rotated from Set-Cookie on every successful request, so the session stays alive indefinitely as long as the proxy polls at least once a month.
Unified UsageCache module
Replaced the split cached_usage/window_resets state and three scattered fetch helpers with a single src/usage/ module that owns all subscription usage state. Everything now goes through one well-defined API: snapshot / get_or_refresh / force_refresh / patch_from_headers / invalidate / is_over_subscription_limit.
Two freshness timestamps drive an adaptive refresh:
util_updated_at— 5h/7d utilization, refreshed on every `/v1/messages` response header (near-realtime under active inference). Throttle: 60s.full_fetched_at— full snapshot including extras (`extra_usage`, `seven_day_sonnet`, `seven_day_opus`). Throttle: 5 min.
Under active inference through the proxy, `patch_from_headers` keeps util fresh for free, so only the 5-min threshold fires. With no inference traffic (e.g. when using Claude through another client and only monitoring via the proxy), the 60s threshold fires and the cache falls into a 1/min refresh cadence automatically. No modes, no state machine.
Fixed bugs along the way
- Rate-limit check was silently broken: `routes/auth.rs` was calling `fetch_fresh_subscription_state` on every `/v1/messages` request for keys with `allow_extra_usage=false`, which hit the rate-limited OAuth endpoint and silently returned `SubscriptionState::default()` on 429 — turning the "subscription exhausted" guard into a no-op. Now it reads `usage_cache.is_over_subscription_limit()` with zero I/O.
- `delete_oauth` did not invalidate cached usage, so stale data could be served after logout.
- Error-matching via string comparison (`Err(e) if e == "no web session configured"`) replaced with a proper `FetchError::NotConfigured` variant.
Admin UI improvements
- Auto-polling: the subscription card now refreshes every 60 s while the page is open (backed by the throttled `UsageCache`, so most polls cost nothing upstream).
- Freshness metadata footer: under the limits grid, shows the fetch source (claude.ai web session / OAuth / none), utilization age, and extras age, all ticking live.
- Two refresh buttons: the normal one respects the cache throttle; a new ⚡ force button sends `?force=true` and bypasses the throttle.
- Error visibility: the silent `is_stale` fallback is now surfaced as a bright warning with the upstream status + body, so 429s etc. are no longer invisible.
- Live utilization updates from inference headers: the admin UI now sees 5h/7d percentages change in near-realtime during active Claude Code sessions, not just on the 5-min full-fetch cycle.
Breaking changes
None — the `SubscriptionUsageResponse` JSON gains a few optional fields (`is_stale`, `upstream_error`, `source`, `full_fetched_at`, `util_updated_at`) but is otherwise unchanged.
Full changelog: v1.1.0...v1.2.0
v1.1.0
What's Changed
OAuth & Claude Code mimicry
- Fix token refresh race condition — concurrent requests could trigger simultaneous refreshes, causing Anthropic's token rotation to invalidate the others and log the user out. Fixed with a per-process mutex and double-check pattern.
- Correct User-Agent headers — inference requests now send
claude-cli/2.1.92 (external, cli), admin/usage API calls sendclaude-code/2.1.92, matching Claude Code's two distinct functions. - Add
X-Claude-Code-Session-Idheader — stable UUID generated at startup, sent on every inference request. - Fix OAuth scopes — authorize now requests the full scope set including
user:mcp_serversanduser:file_upload; refresh explicitly sendsCLAUDE_AI_OAUTH_SCOPES(withoutorg:create_api_key), verified from the 2.1.92 binary. - Fix
anthropic-betaheader — addscontext-management-2025-06-27, removesfine-grained-tool-streamingandadaptive-thinking(not base betas per binary analysis). - Fix usage/profile API headers — send only
oauth-2025-04-20, not the full inference beta list. - Add 401 retry with force token refresh — on server-side token revocation, the proxy force-refreshes and retries once automatically.
Subscription usage caching & resilience
- Cache usage API responses —
/oauth/usagecaches for 5 minutes, invalidated when the 5-hour window resets. Prevents hitting Anthropic's rate-limited endpoint on every admin UI open. - Update window state from inference headers — every successful inference response updates 5h/7d utilization from
anthropic-ratelimit-unified-*headers, so the admin UI stays accurate without dedicated polling. - Graceful 429 fallback — returns stale cache on rate limit; reconstructs from window state if cache is empty.
User-facing usage dashboard
- New
/admin/usagepage — no admin session required, users authenticate with theirsk-proxy-*key to view their own usage. - Cost/token charts over time, per-model breakdown, current 5h/7d/total window counts, period selector (24h / 7d / 30d).
Admin UI improvements
- Replace vue-chrts with Chart.js — gzipped JS bundle reduced from ~772 KB to ~216 KB.
- Upgrade Vite v7 → v8 (Rolldown bundler) with interactive chart legend filtering.
- Migrate to Vite+ unified toolchain (
vpCLI) — replaces ESLint, Prettier, Oxlint. CI now usesvp check.
Other
- Extend admin session TTL to 30 days with sliding expiration (renewed per request, throttled to once/day).
- Replace Swagger UI with
--openapiCLI flag — dump spec without config or DB (cargo run -- --openapi). - Increase request body limit to 100 MB — supports file attachments.
- Split monolithic
admin.rsinto per-feature modules. - Fix rand 0.10 API changes (
Rng→RngExt), add 15 streaming transform tests. - Turso bump from
0.5.0-pre.14to0.6.0-pre.15.
v1.0.0
claude-proxy-rs v1.0.0
Unified API proxy that lets AI coding assistants use a Claude Pro/Max subscription via OpenAI-compatible or Anthropic native API formats.
Features
- Dual API format support — OpenAI-compatible (
/v1/chat/completions) and Anthropic native (/v1/messages) endpoints - Admin UI — Vue 3 SPA for managing API keys, models, and usage
- Per-key rate limiting — 5-hour, weekly, and total cost limits with subscription window sync
- Per-model usage tracking — configurable limits and pricing per model
- Usage history charts — cost and token time-series, breakdowns by model and key
- OAuth authentication — Anthropic OAuth 2.0 with PKCE and automatic token refresh
- Request cloaking — fake user IDs, system message injection, tool name prefixing
- Streaming support — SSE stream transformation with keep-alive pings
- Extended thinking — supports thinking/reasoning via model suffixes like
claude-sonnet-4-5(high) - Embedded database — Turso with versioned migrations, no external DB needed
- Single binary — admin UI assets embedded at compile time
Tech Stack
- Rust 2024 edition, Axum, Turso, reqwest, tokio
- Vue 3, TypeScript, Nuxt UI v4, Tailwind CSS v4, Vite