April 2026 / one env var deep
The Anthropic announcement train ran for 26 days. Inside Fazm, every stop arrived through three lines of Swift.
Opus 4.7 GA on April 22. Mythos Preview and Project Glasswing on April 7. Claude Design on April 17. The Agent Client Protocol jump from 0.25.0 to 0.29.2. Managed Agents. Five threads, one month. Every other recap repeats the announcements. This one watches them land. The surface is a Node.js subprocess that reads exactly one environment variable, set by exactly one if-statement in ACPBridge.swift.
The shape of the month, before the code
April was the heaviest Anthropic news cycle of the year so far. Five threads ran in parallel. The model thread shipped Opus 4.7 generally available on April 22 at $5 per million input tokens and $25 per million output tokens, matching Opus 4.6 pricing, with stronger long-horizon coding scores and higher-resolution vision. The research thread shipped Claude Mythos Preview on April 7 alongside Project Glasswing, a gated cybersecurity initiative. The product thread shipped Claude Design on April 17, a research-preview visual canvas. The protocol thread shipped Agent Client Protocol 0.25.0 on April 7, then 0.29.2 on April 20. The platform thread shipped Managed Agents plus 3.5 gigawatts of next-generation Broadcom TPU capacity and a multi-year CoreWeave NVIDIA GPU agreement.
That list is the press-release view. It tells you nothing about how any of it arrives on a real machine. The rest of this page is the opposite view, written from inside one specific Mac app whose entire relationship with all of those announcements is mediated by one environment variable on one subprocess.
The path the announcement takes, from press release to your chat bubble
Fazm runs on macOS. The chat surface is native Swift. The model conversation runs through a Node.js subprocess called the ACP bridge, spawned by a Process started in Desktop/Sources/Chat/ACPBridge.swift. The bridge speaks the Agent Client Protocol over stdio, the Swift side talks to it over pipes, and the bridge in turn talks to whatever host is on the other end of an Anthropic SDK client. That last hop is where the news lands.
Five actors. One direction of arrows on the way out, the same actors in reverse on the way back. The interesting part is which host the arrow points at, and that decision is made before the bridge process ever starts.
how an April 2026 anthropic announcement reaches a fazm user
The three lines of Swift the whole month rests on
Open Desktop/Sources/Chat/ACPBridge.swift, scroll to line 383, and the entire conditional is right there. The comment is verbatim from the source, and the logic is unforgiving in how plain it is. If the toggle is off, the conditional never enters, ANTHROPIC_BASE_URL is never set on the spawned process, and the Anthropic SDK inside the bridge falls back to its built-in default host. If the toggle is on and the field has anything in it, that string becomes the env value, and from that moment forward the bridge subprocess sends every Anthropic-shaped request to that host.
the conditional, with toggle off vs on
// Default route, Custom API Endpoint toggle off
// /Users/matthewdi/fazm/Desktop/Sources/Chat/ACPBridge.swift
var env = ProcessInfo.processInfo.environment
env["NODE_NO_WARNINGS"] = "1"
switch mode {
case .personalOAuth:
env.removeValue(forKey: "ANTHROPIC_API_KEY")
case .bundledKey(let apiKey):
env["ANTHROPIC_API_KEY"] = apiKey
}
// ANTHROPIC_BASE_URL is never set.
// The Anthropic SDK inside the bridge falls back
// to its hardcoded default: https://api.anthropic.com
// Opus 4.7, Sonnet 4.6, Haiku 4.5, every model the
// April announcements introduced, all arrive here.
proc.environment = env
The diff is one if-let and one assignment. There is no second code path, no SDK swap, no separate transport. The Anthropic SDK inside the Node bridge does the rest: it reads ANTHROPIC_BASE_URL when it constructs its HTTP client, it joins the base with the request path, and it sends the same body it would have sent to api.anthropic.com. The proxy, gateway, or local bridge on the receiving end is responsible for whatever it does with the request before forwarding it upstream.
“Custom API endpoint (allows proxying through Copilot, corporate gateways, etc.)”
ACPBridge.swift line 383, verbatim comment in the public Fazm repo
The toggle that flips it
The user-facing surface lives at Desktop/Sources/MainWindow/Pages/SettingsPage.swift inside a settingsCard with the internal id aichat.endpoint. The card runs from line 906 to line 952. It has a header row with a server-rack glyph and a Switch toggle, a TextField with placeholder https://your-proxy:8766, and one help line that reads, verbatim:
Route API calls through a custom endpoint (e.g. local LLM bridge, corporate proxy, or GitHub Copilot bridge). Leave empty to use the default Anthropic API.
The bindings are the interesting part. The toggle is a derived binding: its getter returns true if either an internal showCustomEndpoint flag is on, or the stored customApiEndpoint string is non-empty. The setter only takes action when flipping off: it clears the field and awaits chatProvider?.restartBridgeForEndpointChange(), which kills the running ACP subprocess and respawns it with the new env. The TextField has the same restart bound to onSubmit. The next chat message after either action goes through a fresh process, either with ANTHROPIC_BASE_URL set to the new value, or with it unset.
The shape of that restart matters because none of the four big April announcements changed it. Opus 4.7 GA on April 22 was a model id rename and a pricing confirmation. Claude Design on April 17 was a new product surface, not a new transport. ACP 0.29.2 on April 20 reshaped the model picker payload but kept the env contract. Mythos Preview on April 7 was a research-grade preview, gated, not a public host change. The toggle did not need to know about any of them. It only needs to know what host string to set, and the rest of the app handles the announcement-shaped contents.
What changes when you flip it
Two parallel realities, depending on a single boolean. Read each column knowing the entire body of the request is identical. Same model id, same ACP frames, same tools, same accessibility-tree-shaped inputs that the Mac side feeds into Claude. Only the host changes.
default endpoint vs custom endpoint, observed externally
ANTHROPIC_BASE_URL is unset on the bridge subprocess. The Anthropic SDK falls back to api.anthropic.com. Authentication uses the bundled or personal OAuth token. April announcements arrive directly: Opus 4.7 GA shows up in the model picker, ACP 0.29.2 frames flow through, Claude Design and Mythos Preview metadata, if surfaced by the SDK, would appear here first. Latency is one network hop. Audit logs sit on Anthropic's side only.
- Direct connection to api.anthropic.com
- First to see new model ids the moment they go live
- Single network hop, lowest end-to-end latency
- No proxy logs on the user's side, only Anthropic's
The same env var, four April announcements
Here is what the month looked like at the boundary of that one env var. None of these events changed the conditional. Some of them changed the body of what flowed through it. Almost all of the companion Fazm releases ride the same pipe.
april 2026 timeline at the bridge boundary
- April 3, Sonnet 4.6 holds the everyday default. Fazm 2.0.1 lands the same day and the bridge keeps running on the old endpoint.
- April 5, personal-plan model errors get a tighter shape. Fazm 2.0.7 ships an auto-fallback to the built-in account on the same env var path.
- April 7, Agent Client Protocol 0.25.0 ships with reshaped credit and rate-limit error frames. Fazm 2.1.2 picks it up the same day. Mythos Preview and Project Glasswing announced.
- April 11, the edge starts returning a new phrasing for usage limits. Fazm 2.2.0 ships a two-substring guard and adds the Custom API Endpoint setting to the bridge.
- April 16, privacy language tightens to local-first. Fazm 2.3.2 rewrites onboarding copy without touching the env var.
- April 17, Claude Design launches as a research-preview visual canvas. The bridge pipe is unchanged.
- April 20, ACP 0.29.2 lands. Fazm 2.4.0 picks it up and rewires the model picker to populate dynamically from the agent response.
- April 22, Claude Opus 4.7 GA at $5 input and $25 output per million tokens. Fazm shows it in the Smart slot the first time the app opens a new session that morning.
- April 26, Fazm 2.4.2 fixes the stored Smart preference not mapping to the renamed Opus model id, and updates the Custom API Endpoint help text to mention local LLM bridges.
- April 27, Fazm 2.5.0 hardens credit-exhausted error recovery and restores the browser-control overlay. The env var is still the same line.
Notice the rhythm. New protocol version, same env var. New model id, same env var. New product surface from Anthropic, same env var. The shape that does not move is the contract between Fazm and whatever host responds. That stability is why a corporate proxy or a local LLM bridge written before April still works after Opus 4.7 GA on April 22, as long as the host on the other end serves the Anthropic-shaped responses the SDK expects.
Why this is the unusual shape, not the obvious one
The obvious shape, and the one most desktop AI apps ship, is to bake a vendor SDK directly into the native binary, hardcode the host, and pin the model list to whatever shipped at app build time. New Anthropic announcement, new app build. Custom endpoint, no. Air-gapped local LLM, hard. Corporate compliance proxy, contact support.
Fazm took the unusual shape because the bridge process is the only process that talks to the model. Its environment is the only thing that decides which host that conversation hits. That is why one env var carries the load. The Swift side stays declarative: a Settings card, a TextField, a toggle. The Node side stays vendor-agnostic in terms of host: it speaks Anthropic protocol, but it does not require api.anthropic.com on the other end. The result is that an Anthropic announcement can change what tokens are available to the user without changing the app, and a user can redirect those tokens through any Anthropic-compatible host without changing the app.
Two independent vectors, one shared boundary. That is the actual design choice the April news cycle stress-tested.
The bridge is one input among many
The endpoint is the most consequential env var, but not the only one. The bridge picks up its environment from a small handful of settings the Swift side writes. Each one steers a different part of how the bridge runs. None of them, except ANTHROPIC_BASE_URL, change which host the April announcements arrive from.
the bridge subprocess and the env vars feeding it
The diagram exaggerates the symmetry, the source code does not. Of the env vars feeding the bridge, only ANTHROPIC_BASE_URL is the one users wire themselves. The others are wired by the app. That asymmetry is intentional. Auth mode, browser-control path, voice path, and tool timeouts are local concerns. The host the bridge talks to is a deployment decision, sometimes a regulatory decision, sometimes a pricing decision, and the one that benefits most from being a one-line setting rather than a code change.
What you can verify yourself in 90 seconds
The Fazm desktop repo is open source. None of the claims on this page require trusting the writer. To confirm the env var lives in exactly one place:
- Clone the public repo from github.com/m13v/fazm.
- Run
grep -nR "ANTHROPIC_BASE_URL" Desktop/Sources. - One match. ACPBridge.swift line 385. Same env value, same source of truth.
- Run
grep -nR "customApiEndpoint" Desktop/Sources. - Three matches. ACPBridge.swift line 384 (the read), SettingsPage.swift line 840 (the AppStorage declaration), SettingsPage.swift line 921 and 925 (the toggle binding).
- Open the app, hit Cmd+, to open Settings, scroll to the AI Chat group, find Custom API Endpoint, type any URL, then watch the ACP bridge process restart in Activity Monitor.
That is the whole audit. The April announcements are interesting regardless of where you read about them. Where they actually arrive on a real machine is, in this case, this one line.
Want to wire Fazm through your own Claude proxy or local LLM bridge?
15 minutes, walk through the Custom API Endpoint toggle and the kinds of upstream hosts it works with.
Frequently asked questions
What did Anthropic actually announce in April 2026, briefly?
Five threads ran through the month. Claude Opus 4.7 went generally available on April 22 at $5 per million input tokens and $25 per million output tokens, matching Opus 4.6 pricing, with stronger software-engineering and long-horizon coding scores and higher-resolution vision. Claude Mythos Preview was announced on April 7 alongside Project Glasswing, a gated cybersecurity program. Claude Design, a research-preview visual canvas for prototypes and one-pagers, launched on April 17. The Agent Client Protocol moved from 0.25.0 on April 7 to 0.29.2 on April 20, the version Fazm 2.4.0 picked up the same day. Anthropic also introduced Managed Agents, a hosted Claude Platform service for long-horizon agent work, and announced 3.5 gigawatts of next-generation Broadcom TPU capacity plus a multi-year CoreWeave NVIDIA GPU agreement.
What does this page mean by `one env var deep`?
Every interaction Fazm has with Claude, including every announcement Anthropic shipped in April, runs through a Node.js subprocess Fazm spawns called the ACP bridge. That subprocess reads exactly one environment variable to decide which host to talk to: ANTHROPIC_BASE_URL. The Swift code that sets that variable lives at /Users/matthewdi/fazm/Desktop/Sources/Chat/ACPBridge.swift lines 383 through 386. If the user has not flipped the Custom API Endpoint toggle in Settings, the variable is never set, the subprocess inherits the SDK default, and traffic goes to api.anthropic.com. If the user has set it, that string becomes ANTHROPIC_BASE_URL on the spawned process and the same announcements arrive through whatever host the user pointed at: a corporate proxy, a GitHub Copilot bridge, or a local LLM gateway.
Where is the Custom API Endpoint setting in the app?
Settings under the AI Chat group, in the card with internal id aichat.endpoint. The card is at SettingsPage.swift lines 906 to 952. It renders a toggle, a TextField with placeholder https://your-proxy:8766, and a help line that reads `Route API calls through a custom endpoint (e.g. local LLM bridge, corporate proxy, or GitHub Copilot bridge). Leave empty to use the default Anthropic API.` The toggle is bound to a UserDefaults boolean called showCustomEndpoint and the field is bound to UserDefaults key customApiEndpoint. The toggle off path explicitly clears the field, then awaits chatProvider?.restartBridgeForEndpointChange() so the next message goes through a fresh subprocess on the default endpoint.
Did Opus 4.7 GA on April 22 require an app update to use in Fazm?
No. Fazm 2.4.0, released on April 20, two days before the GA announcement, rewired the model picker to populate dynamically from the live agent response rather than from a hardcoded list. When Opus 4.7 went GA on April 22 with the new ACP model identifier, it appeared in the Smart slot of the model picker the first time the app opened a new session that morning. The very next release, 2.4.1 on April 22, fixed two adjacent bugs the new model surfaced: a paywall blocking users mid-onboarding, and a Smart label that read incorrectly for Sonnet users when Anthropic returned a partial models_available list. Then 2.4.2 on April 26 fixed the stored Smart preference not migrating to the renamed Opus model id. The pipeline absorbed the announcement; the surface where it absorbed it is the same one env var.
What does a Custom API Endpoint that proxies Claude actually look like over the wire?
Whatever the user sets in the field becomes the value of ANTHROPIC_BASE_URL on the spawned Node process. The Anthropic SDK rewrites every outbound request URL by joining that base with /v1/messages and the rest of the path. Concretely, with the field empty, requests go to https://api.anthropic.com/v1/messages. With the field set to https://copilot-proxy.example.internal, the bridge opens TCP to that host, sends the same Anthropic-shaped JSON body, and expects an Anthropic-shaped streaming response. The proxy is responsible for translating, authenticating, or rate-limiting between the bridge and whichever upstream Claude it points at. Fazm does not transform the body; the bridge runs the same Anthropic SDK either way.
Does the toggle restart anything immediately, or only on the next message?
It restarts immediately. Both onSubmit on the TextField and the toggle off branch await chatProvider?.restartBridgeForEndpointChange(). That call tears down the running ACP subprocess and spawns a fresh one with the new env, so the very next chat turn goes through the new host. There is no app relaunch, no settings save dialog, and no manual `apply` button. This matters because the four April announcements landed in real time: Opus 4.7 on April 22, Claude Design on April 17, ACP 0.29.2 on April 20. A user who wanted to compare a corporate proxy against the default Anthropic endpoint during one of those windows could flip the toggle and have a different topology a second later.
What other env vars does the bridge read, and why do they matter?
The ACP bridge launch builds its environment from ProcessInfo.processInfo.environment plus a handful of additions in ACPBridge.swift around lines 350 to 400. NODE_NO_WARNINGS suppresses Node deprecation noise. ANTHROPIC_API_KEY is set from the bundled key when the user is on the built-in account, and removed when the user is on personal OAuth. PATH is augmented to ensure the directory of the resolved Node binary is included. FAZM_VOICE_RESPONSE flips the TTS path. PLAYWRIGHT_USE_EXTENSION and PLAYWRIGHT_MCP_EXTENSION_TOKEN wire the browser-control side. FAZM_TOOL_TIMEOUT_SECONDS overrides per-tool timeouts. FAZM_RESOURCES_PATH points at the app bundle so the bridge can find packaged assets. Of those, only ANTHROPIC_BASE_URL changes which host the announcements arrive from; everything else governs how the bridge runs locally.
How does this differ from a screenshot-based computer use agent?
A screenshot-based agent grabs a CGImage of the screen, base64-encodes it, sends it as a vision message, and lets Claude reason about pixels. Fazm goes the other direction. Claude reads structured AX trees pulled from the macOS accessibility API, which is what other Mac apps already expose to VoiceOver and to assistive tooling. The April 2026 announcements still flow through the same env var either way, but the data Claude sees is different. The accessibility-tree path costs less, runs faster, and survives high-DPI scaling, focus changes, and animation, because there is nothing to render and nothing to OCR. Screenshots are a reasonable fallback for apps that do not expose AX, and Fazm uses a small set of vision shortcuts for those, but the default surface is the AX tree.
Where does Fazm's open source repo show this?
The full ACPBridge.swift file lives in the public Fazm desktop repo under Desktop/Sources/Chat/ACPBridge.swift. The Custom API Endpoint card lives in Desktop/Sources/MainWindow/Pages/SettingsPage.swift. Both files are licensed under the project license at github.com/m13v/fazm and ship with every release. You can clone the repo, grep for ANTHROPIC_BASE_URL, and confirm the env var is set in exactly one place. There is no second branch, no flag wrapping, no opaque indirection layer.
What happens if the user enters a host that does not exist or rejects the connection?
The bridge subprocess will fail to reach the upstream and surface an error through the same path any Anthropic API failure does: a streaming error frame on the chat turn, a credit-exhausted style banner, or a stuck-loading recovery. Fazm 2.5.0 on April 27 explicitly hardened that path: it drops the ACP session on credit_exhausted-shaped errors, detects zero-output empty turns, and recreates the session so follow-up messages reach the host on the next try. Combined with the dynamic model picker, the failure mode for a misconfigured Custom API Endpoint is `next message fails, error visible, fix the URL or toggle off, no relaunch needed`.
Other April 2026 angles on Anthropic, Claude, and the Fazm bridge
More from this thread
Anthropic announcements, April 2026
The split inside Fazm: ACP bridge for Claude on chat and tool use, GeminiAnalysisService.swift line 67 on the 60-minute video summarizer. Why Opus 4.7 GA did not move the boundary.
Anthropic Claude latest news, April 2026
Reads the April news cycle from inside a Mac app that feeds Claude accessibility trees instead of screenshots, with the three-layer macOS permission probe that survives the Tahoe TCC cache.
Claude Code update, April 2026
ACP 0.25.0 to 0.29.2 over two weeks, plus the dynamic models_available list. What changed for any agent that talks to Claude Code over the protocol.