Skip to content

Releases: okhsunrog/claude-proxy-rs

v2.0.1

Choose a tag to compare

@okhsunrog okhsunrog released this 22 Jun 15:37

Code-review cleanups and a full dependency refresh.

Changes

  • Remove unused dependencies (aegis, dirs, direct tower)
  • Mirror the 401 force-refresh retry into the OpenAI chat_completions path
  • Deserialize OpenAI requests from a borrow to avoid cloning the request body
  • Consolidate useUsageHistory onto the generated OpenAPI client, dropping duplicate hand-written types and raw fetch calls
  • Upgrade Rust dependencies (tower-http 0.7, plus compatible bumps)
  • Upgrade frontend dependencies including majors: TypeScript 6, @types/node 26, @vue/tsconfig 0.9, @hey-api/openapi-ts 0.99; regenerate the API client

v2.0.0

Choose a tag to compare

@okhsunrog okhsunrog released this 22 Jun 15:03

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_URL or DATABASE_URL pointing to PostgreSQL.
  • Database migrations are now managed by sqlx migrations in migrations/.

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, and models.enabled are now native PostgreSQL BOOLEAN columns.

Added

  • Compile-time checked sqlx queries 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

Choose a tag to compare

@okhsunrog okhsunrog released this 20 May 18:48

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 turso 0.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

Choose a tag to compare

@okhsunrog okhsunrog released this 08 Apr 16:54

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

Choose a tag to compare

@okhsunrog okhsunrog released this 08 Apr 10:55

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 send claude-code/2.1.92, matching Claude Code's two distinct functions.
  • Add X-Claude-Code-Session-Id header — stable UUID generated at startup, sent on every inference request.
  • Fix OAuth scopes — authorize now requests the full scope set including user:mcp_servers and user:file_upload; refresh explicitly sends CLAUDE_AI_OAUTH_SCOPES (without org:create_api_key), verified from the 2.1.92 binary.
  • Fix anthropic-beta header — adds context-management-2025-06-27, removes fine-grained-tool-streaming and adaptive-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/usage caches 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/usage page — no admin session required, users authenticate with their sk-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 (vp CLI) — replaces ESLint, Prettier, Oxlint. CI now uses vp check.

Other

  • Extend admin session TTL to 30 days with sliding expiration (renewed per request, throttled to once/day).
  • Replace Swagger UI with --openapi CLI flag — dump spec without config or DB (cargo run -- --openapi).
  • Increase request body limit to 100 MB — supports file attachments.
  • Split monolithic admin.rs into per-feature modules.
  • Fix rand 0.10 API changes (RngRngExt), add 15 streaming transform tests.
  • Turso bump from 0.5.0-pre.14 to 0.6.0-pre.15.

v1.0.0

Choose a tag to compare

@okhsunrog okhsunrog released this 24 Feb 20:26

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