Deploy Gateway with your MDM
This is the path where your MDM writes each AI client’s own configuration directly. Nothing from Merge runs on the machine. It reaches more clients than the desktop client does, and it works today.
Read Roll out Gateway to your fleet first if you have not chosen a path yet. Come here once you have.
This page is about model traffic. To make the Merge MCP server the only tool source at the same time, see the Agent Handler tab under Devices → Deployment in the dashboard: Claude Code and Codex both accept a managed MCP allowlist your employees cannot override.
1. Decide the key before anything else
Every mechanism below carries the same payload: a base URL, an API key, and a model name. The key is the only one with consequences.
Use a project API key per team, created from the project’s API keys tab. Every request made with it attributes to that project, and the project’s routing policy and budget apply automatically with nothing else to configure. An organization key works everywhere and gives you one undifferentiated bill.
Set the model name to default_routing rather than a pinned model. Model choice then lives in the routing policy, where you can change it once, instead of in a config file on every laptop.
A key pushed to a laptop can be read by the person using that laptop. That is unavoidable on every path here, which is why per-team keys matter: a leaked key is scoped to one project’s budget and policy, and can be rotated without touching the rest of the fleet. Never push an organization key that also has access to the Management API.
2. Match the client to a mechanism
What you can do is decided entirely by where each client keeps its settings.
Work down that list in order. The first two are enforced by the operating system and survive a reboot untouched. The third is a file in the employee’s home directory that they can edit, so it needs re-assertion.
3. Managed preferences: Claude Desktop
The best case, and worth doing first because it covers Chat, Cowork, and the built-in Claude Code surface in one payload.
Configure one machine by hand
On any Mac, open Developer → Configure Third-Party Inference, set the provider to Gateway, and fill in the base URL https://api-gateway.merge.dev/v1/anthropic and your project key. Run Test connection and confirm both checks pass. See the Claude Desktop guide for the full field reference.
Export the profile
Use the app’s Export button. It produces a .mobileconfig for macOS or a .reg for Windows carrying exactly what you configured, so there is no hand-authored plist to get wrong.
Deploy it unchanged
Upload the .mobileconfig as a configuration profile, or apply the .reg through your Windows policy channel. The keys it contains are:
Leave modelDiscoveryEnabled on so the model picker populates itself from Gateway at launch and new models appear without a config change. To pin a curated list instead, set inferenceModels.
Claude Desktop’s connection test sends a real inference request. If your vendor or region restrictions leave no callable route for the model it picks, the test fails with vendor_restrictions_unavailable even though the connection is fine. Either relax the restriction or pin a Model list entry your organization can call, and put it first so it becomes the default.
4. Environment variables: Claude Code
Claude Code takes no config file for routing. It reads the environment, so your MDM sets variables rather than writing a file.
Three things decide whether this works:
ANTHROPIC_API_KEYmust be empty. Claude Code prefers it overANTHROPIC_AUTH_TOKEN, so any value inherited from a developer’s old setup silently bypasses Gateway. This is the most common reason a fleet looks configured and reports no traffic.default_routingon the opus and sonnet tiers hands model choice to your routing policy. Leave the haiku tier pinned to a cheap model: Claude Code runs frequent background tasks on it, and routing those adds latency for no benefit.- The employee must not be signed in to Anthropic. If they authenticated Claude Code before you deployed this, they run
/logoutonce and relaunch
The same MERGE_GATEWAY_API_KEY variable delivers the credential for Zed, OpenCode, Pi, and Factory Droid, so set it in the same payload even though those clients need a file too.
On macOS, an app launched from the Dock never sees a variable exported in ~/.zshrc. Terminal agents inherit it normally; anything with an icon does not. Deliver launchctl setenv through a LaunchAgent that runs at login, or the desktop apps will resolve an empty key and fail to authenticate.
5. Config file drops: everything else
Codex, Zed, Continue.dev, Pi, Factory Droid, and OpenCode each read a file in the employee’s home directory. The exact contents are in each client’s setup guide; this section is about delivering them.
Because these files are user-owned and user-writable, a one-time push is not a control. Deploy them the way your MDM deploys any drifting file: a script that runs on the recurring check-in, checks the current state, and rewrites it if it has changed.
Treat that as the shape rather than a finished script. It writes one file for one client; a real deployment writes several, and on a multi-user Mac it needs to loop rather than assume the console user.
Between two runs, an employee can edit the file and route around Gateway. Most MDMs check in every 15 minutes at best, so that is the window. It is a compliance control, not a security boundary. The only enforcement that does not have this gap is blocking the provider endpoints at the network layer.
6. Cursor
Cursor cannot be configured this way at all. Its base URL override and API key are entered in the GUI and held in encrypted local application state, so there is no file to write and no preference domain to set.
Your options:
- Cursor Business or Enterprise team admin settings, which can restrict models and disable bring-your-own-key
- Network policy, blocking the provider endpoints Cursor would otherwise reach
- Point the team at Claude Code or Codex for work that has to be governed
Separately, Cursor’s Agent mode does not accept custom API keys at all, so even a hand-configured Cursor only routes Ask and Plan traffic through Gateway. Tab autocomplete never routes.
7. Per-MDM delivery
The payloads above are the same everywhere; only the delivery differs, and it is the same delivery your MDM already uses for the Workforce desktop client. Follow the mechanics in the matching guide and substitute the payload from this page.
8. Verify
Pushed is not routed. Check in this order, because each one rules out a different failure.
- Did the payload land? On a test Mac,
defaults read /Library/Managed\ Preferences/<domain>.plistfor a profile, or read the file for a script drop - Does the client see it? Claude Code’s
/statusshould showAuth token: ANTHROPIC_AUTH_TOKENand the Gateway base URL. Claude Desktop’s Test connection runs discovery and a real inference request. - Is traffic arriving? The Gateway dashboard shows requests within a few seconds. This is the only check that proves the whole path, and it needs nothing on the endpoint.
- From how many people? Compare distinct users in the dashboard against the size of the group you scoped. Configuration that landed everywhere and reports traffic from four people means it landed and is being bypassed.
Roll out to a canary group and complete all four before widening. A misconfigured ANTHROPIC_API_KEY looks identical to a successful deployment until step 3.