Connecting a proxy to a native client
CLIProxyAPI is the endpoint. What do you point at it?
CLIProxyAPI takes a subscription you already pay for and re-exposes it as an Anthropic-compatible API on localhost:8317. Every writeup walks you through installing it and pointing a terminal tool or an OpenAI-shaped client at the port. The question that nobody answers: if you want a real native Mac app on top of that endpoint, with chats that survive a restart and fork in one click, which one consumes it? This is that guide, written from the source of one app that does.
Direct answer (verified 2026-06-16)
Run CLIProxyAPI, note its base URL (default http://localhost:8317). In Fazm, open Settings, Advanced, AI Chat, Custom API Endpoint, toggle it on, paste that URL, and switch your model to any Claude model. From then on every Claude request from the Fazm GUI is routed through your proxy instead of Fazm’s built-in Claude, and it does not count against built-in credits. Do not append /v1/messages; the SDK adds it. Verified against the CLIProxyAPI repo at github.com/router-for-me/CLIProxyAPI.
What CLIProxyAPI actually is
CLIProxyAPI is an MIT-licensed Go gateway. It logs into the CLI agents you already have, Gemini CLI, ChatGPT Codex, Claude Code, and a couple of others, through their normal OAuth flows, then re-serves them behind a single local HTTP server that speaks the OpenAI, Gemini, Claude, and Codex API formats. The motivation is simple: a Claude Pro or Max plan, or a ChatGPT subscription, is a flat monthly fee, while raw API access is metered per token. The proxy lets any API client borrow the flat-fee subscription as if it were a metered endpoint.
That solves the supply side. It does nothing for the demand side. Once the proxy is running you still need a client, and the examples in the wild are almost all command-line: curl, a coding CLI configured with a custom base URL, or an OpenAI SDK script. If what you wanted was a desktop chat app with real session management, you are on your own. The Anthropic SDK that Claude Code is built on reads one environment variable, ANTHROPIC_BASE_URL, and any app that sets it correctly becomes a valid CLIProxyAPI client. Fazm exposes that variable as a single text field.
Where the request goes
With the endpoint set, a Claude request you type (or speak) into Fazm travels through the proxy before it ever reaches a model provider. Your subscription credentials live only in CLIProxyAPI; Fazm never holds them.
One Claude turn, from GUI to subscription
Fazm (native macOS UI)
You send a Claude-model message. The bridge launches with ANTHROPIC_BASE_URL set to your proxy.
ANTHROPIC_BASE_URL override
The Anthropic SDK appends the Messages path and sends the request to your URL instead of api.anthropic.com.
CLIProxyAPI on :8317
Receives the Anthropic-format request, translates it, and uses your OAuth-logged-in subscription upstream.
Provider subscription
Your Claude Pro/Max (or other) plan answers. Tokens count against that plan, not against Fazm credits.
Connecting Fazm to your proxy
Four steps. The only one people miss is the last one, and it is the reason an endpoint can look connected while receiving no traffic.
- 1
Run CLIProxyAPI
Install via Homebrew or build from source, complete its OAuth login, and confirm it is listening (default port 8317).
- 2
Open the endpoint setting
In Fazm: Settings, Advanced, AI Chat, then the Custom API Endpoint card. Toggle it on.
- 3
Paste the base URL
Enter http://localhost:8317 (no /v1/messages suffix). On submit, Fazm restarts its bridge to pick up the change.
- 4
Switch to a Claude model
The override only affects Claude-model traffic. If you stay on Gemini or Codex, the proxy gets nothing. Pick a Claude model.
What that single field actually does
This is the part you will not find on any CLIProxyAPI page, because it lives in Fazm’s source rather than the proxy’s. When you set a valid endpoint, Fazm rewrites the environment of the agent process it spawns. The relevant code is makeBridgeEnvironment in Desktop/Sources/Chat/ACPBridge.swift (around line 2425).
Three deliberate behaviors are worth calling out, because each one is a bug you would otherwise hit by hand:
- The value is validated, not trusted.
validCustomAPIEndpoint(ACPBridge.swift line 301) requires a realhttporhttpsURL with a host. A barelocalhost:8317with no scheme is rejected. This matters: a malformed value landing inANTHROPIC_BASE_URLwould make the Anthropic SDK throw “Invalid URL” on every turn and silently brick chat. On a bad value, Fazm logs it and falls back to the default endpoint instead. - The bundled key is removed and a placeholder is substituted. Fazm sets
ANTHROPIC_API_KEYtosk-fazm-custom-endpoint. The reason is subtle: with no key at all, the SDK would try a Claude OAuth handshake against your proxy; with a real key, you would be leaking Fazm’s credential to a third-party server. A harmless placeholder keeps an Anthropic-compatible gateway on the simple API-key path. If your CLIProxyAPI config enforces anapi-keysallowlist, add that exact string to it. - The override is Claude-only, by design. It rewrites
ANTHROPIC_BASE_URLand nothing else, so Gemini and Codex models route through their own backends untouched. The settings card watches your selected model and renders a warning the moment it is not a Claude model, with a button to switch (SettingsPage.swift around line 1086). That warning exists specifically because new installs default to Gemini, and without it the endpoint would look configured while receiving zero requests.
What the GUI adds that the endpoint cannot
A proxied endpoint answers “where do the tokens come from.” It says nothing about how you work day to day. That is the half Fazm fills, and it is the same agent loop (real Claude Code, wrapped via ACP) with the rough edges fixed:
- Sessions survive a restart. Quit, reboot, reopen, and every window comes back with its full conversation intact. The proxy is stateless; persistence is on the client side.
- Forking is one click. Any chat opens into a new window carrying the full prior context, and the original is left untouched, so you can branch an investigation without a session-id dance.
- No auto-compacting. The full chat history stays live in context for the lifetime of the window. Long sessions through your proxy do not quietly drop earlier decisions.
- Voice-first input. Hold a hotkey and talk; the same agent runs with no typing.
- Reach beyond the terminal. Through macOS accessibility APIs the agent can drive your real browser and native Mac apps, not just files in a working directory.
Fazm is open source and runs locally, which is the right pairing for a setup whose whole premise is keeping your credentials and traffic on your own machine.
Routing a subscription through a proxy and want a real client on top?
Bring your CLIProxyAPI or local-gateway setup to a call and we will get Fazm pointed at it, model selection and all.
Questions people actually ask
Frequently asked questions
What is CLIProxyAPI?
CLIProxyAPI is an open-source Go gateway (MIT licensed, github.com/router-for-me/CLIProxyAPI) that wraps the OAuth login of Gemini CLI, ChatGPT Codex, Claude Code, and a few others, then re-exposes them as OpenAI / Gemini / Claude / Codex compatible HTTP APIs. The point is to take a subscription you already pay for (Claude Pro/Max, ChatGPT) and make it reachable as a plain API endpoint, with no per-token API key billing, so any client that speaks one of those formats can talk to it. By default it listens on port 8317.
Can I use CLIProxyAPI with a graphical app instead of curl or a CLI?
Yes. CLIProxyAPI is just an HTTP server that speaks the Anthropic Messages format (among others), so any client that lets you override the Anthropic base URL can use it. Fazm is a native macOS app built exactly for this: Settings, Advanced, AI Chat, Custom API Endpoint. You paste the proxy URL, switch to a Claude model, and every request from the GUI is routed through your local proxy instead of Fazm's built-in Claude.
What URL do I paste into Fazm for a local CLIProxyAPI instance?
The base URL of the proxy, typically http://localhost:8317 (or http://127.0.0.1:8317). Do not append /v1/messages yourself. Fazm hands the URL to the Anthropic SDK as ANTHROPIC_BASE_URL, and the SDK appends the Messages path on its own. The field validates that you entered a real http(s) URL with a host; a bare host like localhost:8317 with no scheme is rejected and ignored, and Fazm falls back to its default endpoint rather than bricking chat.
Why does my custom endpoint receive zero requests after I set it?
Almost always because your selected model is not a Claude model. The custom endpoint only overrides ANTHROPIC_BASE_URL, which only routes Claude-model traffic. Gemini and Codex models in Fazm bypass it entirely. New installs default to a Gemini model, so the endpoint silently gets nothing until you switch to a Claude model. Fazm shows an inline warning in the same settings card when your current model will skip the endpoint, with a one-click Switch to a Claude model button.
Will Fazm send its own Anthropic API key to my proxy?
No. The moment a valid custom endpoint is set, Fazm removes its bundled Anthropic key from the request environment and substitutes a harmless placeholder, sk-fazm-custom-endpoint, so Anthropic-compatible local gateways that accept any key stay on the API-key path instead of triggering a Claude OAuth flow. Your CLIProxyAPI instance holds the real upstream credentials; Fazm never sees them, and this usage is not counted against Fazm's built-in credits.
Does CLIProxyAPI require an API key for incoming requests?
By default CLIProxyAPI expects an api-keys list in its config.yaml and will require one of those keys on inbound requests. If you set incoming keys, your client has to send one. Fazm sends the placeholder sk-fazm-custom-endpoint as the Anthropic key, so if your proxy enforces an allowlist you either add that exact string to the api-keys list or run the proxy with incoming auth disabled for trusted localhost use. Check help.router-for.me/configuration/basic for the current config shape.
What do I actually gain by using Fazm in front of CLIProxyAPI versus the raw CLI?
CLIProxyAPI gives you a reachable endpoint; it does not give you a UI. Fazm adds a native macOS chat surface on top of that endpoint: sessions that survive a Mac restart, one-click forking of any conversation into a new window with full prior context, no auto-compacting of context for the lifetime of a window, voice-first input on a hotkey, and an agent loop that reaches past the terminal into your browser and native Mac apps via accessibility APIs. The proxy handles the where-do-tokens-come-from question; Fazm handles the how-do-I-actually-work-with-it question.
Related reading
Claude Code compacting loses decisions
What auto-compacting silently drops from a long session, and why keeping the full transcript live in context avoids it.
Control Claude Code context compaction
Where the SDK decides to compact, what gets dropped, and how a wrapper keeps the full transcript live for the lifetime of the window.
AI agent context checkpoint: the two-layer pointer most guides skip
What a real resume-and-branch pointer looks like in a shipping ACP agent, with file paths you can read yourself.
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.