FreeClaudeDesktop is a cross-platform command-line launcher and local API proxy for Claude Desktop. It lets Claude Desktop talk to any OpenAI-compatible or Anthropic-compatible gateway while keeping the proxy bound to 127.0.0.1.
Click a section to expand — 4 Console pages are collapsed by default to save space.
- Screenshots
- About
- Features
- Memory and Performance
- Quick Start
- Installation
- Configuration
- CLI Reference
- Proxy API
- Architecture & Project Structure
- Extensions & Local Optimizations
- Development
- Security
- Limitations
- Uninstall
- Project Links
- License
Claude Desktop speaks the Anthropic Messages API. FreeClaudeDesktop sits between Claude Desktop and your chosen gateway:
- Accepts Anthropic requests from Claude Desktop (
/v1/messages,/v1/models). - Translates them to OpenAI Chat Completions, forwards to the configured gateway, and streams the response back as Anthropic SSE/JSON.
- Applies local optimizations (quota probe mock, title/suggestion skips, prefix detection) so common UI probes never hit the gateway.
The proxy is the protocol boundary. Settings and secrets stay on your machine: non-secret config in the local settings store, API keys in the OS keyring (never returned by the Dashboard API).
For a deeper walk-through, see docs/ARCHITECTURE.md.
- Local proxy on
127.0.0.1:3000— Claude Desktop-compatible endpoint, loopback-only by default. - Gateway agnostic — works with OpenAI-compatible and Anthropic-compatible upstreams (
auto/bearer/x-api-key/ssoauth schemes). - Full model discovery — fetches
/v1/modelsfrom the gateway, normalizes metadata, and publishes every model in the Claude Desktop picker with per-model visibility toggles. - Model routing & reasoning — maps
claude-opus-5[0]/claude-sonnet-4[0]/claude-haiku-4[0]-style aliases to real gateway models; translatesthinking.budget_tokens→reasoning_effortand replays reasoning as native thinking blocks or<antThinking>text. - Isolated Claude Desktop profile — keeps a dedicated profile for the proxied setup and can re-sync selected data from the official profile.
- Cross-platform — Windows (Task Scheduler + Registry Run key), macOS (LaunchAgent), Linux (systemd user service); x64 and ARM64 binaries via npm optional dependencies.
- Single runtime process — one
freeclaudedaemon hosts the local Proxy and/companionWebSocket for Dashboard ↔ host RPC.
FreeClaudeDesktop routes and streams requests; model inference remains on the configured gateway. Streaming responses are forwarded as they arrive instead of being buffered in full. Common Dashboard probes are handled locally.
Memory use varies with the operating system, build profile, and concurrent requests. The Proxy limits each request body to 16 MiB; this is a per-request limit, not a process-wide RAM cap. The non-blocking logging queue is bounded to 2,048 lines. Each Tokio runtime uses at most 2 async worker threads by default, configurable with TOKIO_WORKER_THREADS. Upstream HTTP requests time out after 60 s. These settings limit specific work queues and requests; they do not imply a fixed memory footprint or latency.
Prerequisites: Claude Desktop and Bun 1.4.3 or newer. Bun automatically selects the binary package matching your OS and CPU architecture.
bun add -g @mushroomtw/freeclaudedesktop
freecd install
freecd dashboardfreecd installsets up the isolated profile, writes the proxied Claude Desktop config, starts the native proxy, and enables autostart at login (use--no-autostartto opt out).freecd dashboardopens the same-origin Web Dashboard athttp://127.0.0.1:3000/dashboard— configure Gateway URL, Auth Scheme, and API Key there.freecd startalone only starts the proxy.
Verify the proxy is up:
curl http://127.0.0.1:3000/healthz
# {"status":"ok"} (or similar JSON)Then launch Claude Desktop — the model picker will list the gateway's models (e.g. claude-opus-5[0]).
Tip
For the best Claude Desktop experience, use upstream models with multimodal input and ≥ 200K context. Text-only or small-context models still work, but images, long conversations, file handling, and tool-heavy flows may be limited.
bun add -g @mushroomtw/freeclaudedesktop
freecd install # autostart enabled by default
freecd install --no-autostart # without autostartPackage: @mushroomtw/freeclaudedesktop@2.0.1 — ships freecd / freeclaude bins and six platform optional dependencies (darwin-arm64/x64, linux-arm64/x64, win32-arm64/x64).
Requires the Rust 1.99.0 toolchain (Cargo.toml → workspace.package.rust-version).
git clone https://github.com/mushroomTW/FreeClaudeDesktop.git
cd FreeClaudeDesktop
cargo build --release
# macOS / Linux
./target/release/freeclaude install
# Windows (PowerShell)
.\target\release\freeclaude.exe installCargo builds one native executable, freeclaude, with the Proxy server embedded; the Bun wrapper exposes both freeclaude and freecd:
cargo build --release # builds the single freeclaude executableAll settings are edited through the Web Dashboard (/dashboard → /settings API). API keys are stored in the OS keyring and never returned by GET /settings.
| Variable | Purpose | Default | Where read |
|---|---|---|---|
FREECLAUDE_PROXY_PORT |
Proxy listen port | 3000 (core/src/core/constants.rs:DEFAULT_PORT) |
cli/src/main.rs:proxy_port(), cli/src/runtime_daemon.rs |
FREECLAUDE_PROXY_URL |
Override URL used by freecd status health check |
http://127.0.0.1:{PORT} |
cli/src/main.rs:print_proxy_status() |
TOKIO_WORKER_THREADS |
Async worker threads per Tokio runtime | min(logical CPUs, 2) |
core/src/runtime.rs |
- Gateway: Base URL, auth scheme (
auto/bearer/x-api-key/sso), transport type, proxy auth token. - Models: per-alias route table (
real_model_routes), reasoning effort routes, discovered models,supports1m/prefer1m/ visibility overrides,reasoning_replay_mode. - Optimizations: toggles for quota mock, prefix detection, title/suggestion skip, filepath extraction, web tools, API call logging.
- Desktop: custom Claude path, active port.
- UI: theme (
light/dark), language.
Run freecd --help or freecd <command> --help for full help. Summary (cli/src/cli_args.rs):
freecd install [--no-autostart]
freecd start
freecd stop
freecd status
freecd configure # opens http://127.0.0.1:{port}/dashboard
freecd dashboard # alias for configure
freecd launch-claude
freecd restore # restore official Claude config
freecd purge --yes # remove app data (requires --yes)
freecd update [--check]
freecd uninstall
freecd autostart enable|disable|status
Common flows:
freecd start
freecd status
freecd stop
freecd autostart enable
freecd autostart status
freecd autostart disable
# Check for a newer GitHub Release without changing local install
freecd update --checkstart waits for GET /healthz to succeed (up to ~5 s) before reporting success. When upgrading from a release that used separate Proxy and Companion processes, run freeclaude stop once before freeclaude start. Autostart backends: Windows Task Scheduler / Registry Run key, macOS LaunchAgent, Linux systemd user service (cli/src/runtime/autostart.rs).
All routes are served from http://127.0.0.1:{port} (proxy/src/server/router.rs). CORS allows same-origin dashboard requests only.
| Method | Path | Description |
|---|---|---|
GET |
/ |
Root / landing |
GET |
/healthz |
Health check — used by freecd start |
GET |
/dashboard |
Web Dashboard HTML |
GET |
/dashboard.css |
Dashboard stylesheet |
GET |
/dashboard.js |
Dashboard script |
GET |
/assets/icon.png |
App icon |
GET |
/settings |
Non-secret settings (API key omitted) |
POST |
/settings |
Update settings |
GET |
/status |
Runtime status |
POST |
/rpc |
Dashboard RPC → Companion Daemon (GetStatus, DetectClaude, ApplySettings, FetchModels, …) |
GET |
/companion |
WebSocket — first message must include requestId |
POST |
/v1/messages |
Anthropic Messages API (proxied to gateway) |
GET |
/v1/models |
Normalized model list (Claude-facing aliases) |
Body limit: 16 MiB (core/src/core/constants.rs:MAX_PROXY_BODY_BYTES). Gateway timeout: 60 s.
Logs are written to {local_app_data}/FreeClaudeDesktop/logs/ — launcher.log (daily rolling) and api-calls.log (10 MiB + 4 archives, proxy/src/server/api_log.rs). Enable API call logging from the Dashboard.
FreeClaudeDesktop/
├── core/ # free-claude-core — schemas, settings store, keyring, model routing, conversion
├── proxy/ # freeclaude-proxy library — Axum routes, gateway forwarding, SSE conversion, dashboard
├── cli/ # freeclaude — one runtime process for CLI, Proxy, and companion orchestration
├── packages/freeclaudedesktop/ # Bun wrapper (freeclaude/freecd) + platform optionalDependencies
└── docs/ # project documentation (ARCHITECTURE.md, EXTENSIONS_AND_SKILLS.md)
Crate dependency direction: proxy → core, cli → core + proxy. The native package contains one executable; its runtime daemon hosts the Proxy server and Companion WebSocket in one process. See docs/ARCHITECTURE.md for runtime topology, message execution flow, model discovery/routing, and state ownership diagrams.
Key design notes:
- Alias stability:
claude-opus-5[0]-style aliases are stable per model-list position;supports1m/prefer1mcontrol the 1M-context variant without changing the ID. - Single runtime process: one long-running
freeclaudeprocess hosts both the Axum Proxy and the Companion WebSocket.
Detailed in docs/EXTENSIONS_AND_SKILLS.md. Summary of toggles in Dashboard → Optimizations:
| Optimization | What it does |
|---|---|
| Quota Mock | Intercepts max_tokens=1 quota probes and answers locally |
| Prefix Detection | Resolves common shell prefixes (git, cargo, docker, …) without an LLM call |
| Title Generation Skip | Returns fixed "Conversation" instead of calling the LLM for a chat title |
| Suggestion Skip | Returns empty follow-up suggestions locally |
| Filepath Extraction | Extracts file paths from command output via local regex |
| Web Tools | Executes web_search / web_fetch locally (configurable allowed schemes + private-network guard) |
| API Call Logging | When enabled, appends JSON Lines to api-calls.log |
Toolchains pinned to Rust 1.99.0 (rust-version in Cargo.toml) and Bun 1.4.3 (packageManager in package.json), enforced in CI.
bun install --frozen-lockfile
bun test
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
cargo checkCI runs on ubuntu-latest, macos-15, windows-latest.
Release builds for six targets (x86_64/aarch64 × Linux/macOS/Windows) via bun run pack:platform <target> → dist/npm/; archives are checked before publishing to the npm registry with bun publish.
SonarQube local analysis uses sonar-project.properties at the repo root (see sonar-project.properties).
- The proxy binds to loopback by default. Do not expose it to a LAN or the public internet without adding authentication and network controls.
- API keys are stored in the OS keyring (
keyringcrate) and never returned byGET /settingsor the Dashboard API. - Review the generated Claude Desktop configuration before distributing it.
web_fetchcan be restricted tohttp/httpsschemes and blocked from private networks (Dashboard → Web Fetch settings) to mitigate SSRF.- Report security issues via the issue tracker — do not post credentials.
Disclaimer: This project is not affiliated with, endorsed by, or supported by Anthropic. “Claude” and “Claude Desktop” are trademarks of their respective owners. This program coordinates third-party models; you are responsible for API costs, credentials, and data-sharing choices.
- Upstream models without multimodal input or with small context windows still work, but image, long-conversation, file, and tool-heavy workflows may be degraded (see Quick Start tip above).
reasoning_replay_modeandsupports1m/prefer1mdepend on the gateway exposing the relevant capabilities via/v1/modelsand chat completions.- Linux 1M-context runtime patch attempts are documented separately in
docs/linux/claude-desktop-1m-runtime-patch-attempts.md. - The proxy enforces a
16 MiBrequest body limit and a60 sgateway timeout — configurable only via code (core/src/core/constants.rs).
For a Bun global installation, one command cleans up local state and removes the package:
freecd uninstalluninstall stops the runtime process, disables autostart, restores the official Claude config, and purges app data (cli/src/main.rs:uninstall).
The Bun wrapper waits for cleanup to finish before removing its global package. Cleanup failure preserves the package; if package removal fails, retry bun remove -g @mushroomtw/freeclaudedesktop --ignore-scripts. Source builds and local installations only clean up app state. If global ownership cannot be confirmed, the wrapper prints the manual removal command. purge also retains the package.
Clean up the existing installation first. Remove any legacy npm command alias using the package manager that installed it, then install with Bun:
freecd uninstall
bun add -g @mushroomtw/freeclaudedesktop
freecd installCleanup removes app data and restores Claude settings, so configure your gateway again after reinstalling.
FreeClaudeDesktop is released under the MIT License.



