The thing that finally pushed me over the edge was a 401 at 1am.
Anthropic key rotated. Claude Code dead. Three terminals open, a half-finished refactor, and now I'm digging through a password manager looking for the right ANTHROPIC_API_KEY to paste into a shell config so my CLI tool can keep talking to a model.
Then it hit me: I was already logged into Google's Antigravity in another tab. And Antigravity hands out claude-sonnet-4-6 and claude-opus-4-6 like it's nothing.
So why was I paying Anthropic again?
What Antigravity Actually Is
If you haven't bumped into it yet — Antigravity is Google's enterprise developer platform, built on top of Google Cloud Code Assist. The interesting part isn't that it gives you Gemini. The interesting part is that it gives you Claude.
Sign in with a Google account, accept the Code Assist terms, and the model list that comes back includes:
claude-sonnet-4-6
claude-sonnet-4-6-thinking
claude-opus-4-6
claude-opus-4-6-thinking
gemini-2.5-pro
gemini-2.5-flash
That's Anthropic's flagship models, served through Google's infrastructure, authorized by a Google OAuth token. No Anthropic key, no Anthropic billing surface, no key rotation.
The catch — and this is the whole reason I'm writing this — is that the protocol Antigravity speaks is not the protocol Claude Code speaks. Antigravity expects requests at cloudcode-pa.googleapis.com/v1internal:generateContent with a Google bearer token. Claude Code wants to talk to api.anthropic.com/v1/messages with an Anthropic key.
You can't just point Claude Code at Antigravity. The shapes don't match.
The Bridge
CliGate is a local proxy I've been working on that already handles routing Claude Code, Codex CLI, and Gemini CLI to multiple backends. The Antigravity integration is the newest piece: it adds a Google-OAuth-backed account pool that exposes Antigravity's Claude and Gemini models as a routing target.
When Claude Code sends an Anthropic-formatted streaming request to the proxy, CliGate:
- Picks an Antigravity account from the pool
- Refreshes the Google access token if it's near expiry
- Translates the Anthropic Messages payload into Antigravity's
generateContentshape - Streams the response back as Anthropic SSE
Claude Code never knows it's talking to Google. It thinks it just got a normal response from Anthropic.
The 5-Minute Setup
Step 1 — Start CliGate
npx cligate@latest start
The dashboard opens at http://localhost:8081.
Step 2 — Add your Antigravity account
Go to Accounts → Antigravity. Click Sign in with Google.
✓ Browser opens to accounts.google.com
✓ You authorize Cloud Platform + Code Assist scopes
✓ Callback hits localhost:36545
✓ CliGate stores the refresh token
The OAuth flow hands back a refresh token that CliGate keeps in encrypted local storage. Tokens get auto-refreshed when they're under 5 minutes from expiry — you log in once.
Step 3 — Let CliGate discover your models
After the account is added, CliGate calls loadCodeAssist to fetch your project ID, then fetchAvailableModels to discover what your account can use. The model list populates automatically:
claude-sonnet-4-6 ✓ recommended
claude-sonnet-4-6-thinking ✓ thinking variant
claude-opus-4-6 ✓ recommended
claude-opus-4-6-thinking ✓ thinking variant
gemini-2.5-pro
gemini-2.5-flash
No manual entry. The list updates if your account's quotas change.
Step 4 — Route Claude Code to Antigravity
Open App Routing. For Claude Code, set the credential to your Antigravity account.
Claude Code → Antigravity (your-google-email)
Codex CLI → ChatGPT Plus account
Gemini CLI → cloud
That's it. Claude Code is already pointed at CliGate from the one-click setup, so this routing change takes effect on the next request.
Step 5 — Test it
claude "explain what this regex matches: ^(\d{4})-(\d{2})-(\d{2})$"
The request goes to CliGate. CliGate sees the routing rule, picks your Antigravity account, talks to cloudcode-pa.googleapis.com, streams the response back as Anthropic SSE. You see normal Claude Code output.
If you want to confirm it's actually hitting Antigravity, the Request Logs tab shows the upstream provider for every call:
14:23:01 POST /v1/messages → antigravity / claude-sonnet-4-6 ✓ 200
The Part That Surprised Me
The model name juggling.
Anthropic's public model IDs and Antigravity's internal model IDs don't quite line up. Claude Code might send claude-sonnet-4-5-20250929 (an old alias). Antigravity expects claude-sonnet-4-6. The proxy normalizes between them on the way out and on the way back.
// Sketch of the normalization
function normalizeForAntigravity(modelId) {
if (modelId.startsWith('claude-sonnet-4-5')) return 'claude-sonnet-4-6';
if (modelId === 'claude-opus-4-6') return 'claude-opus-4-6-thinking';
// ...
return modelId;
}
If you're routing your own tools through Antigravity, this is the gotcha you'll hit first. The actual Antigravity API doesn't return a friendly error for an unknown model — it 404s with no JSON body. Spent an hour on that one.
When This Is Actually Useful
I'm not pretending this is a trick that works for everyone. But there are three real cases where it matters:
- Your company already has Google Workspace. Adding an Antigravity account is zero new billing. Anthropic keys are a separate procurement conversation.
- You don't want Anthropic keys floating around in dev shells. OAuth tokens with refresh rotation are easier to revoke than keys.
- You want one tool (Claude Code) but two backends. Toggle between Antigravity and a direct Anthropic key from the dashboard, depending on quota or model availability.
The same proxy handles ChatGPT account pools, Anthropic OAuth, raw API keys, Azure OpenAI, and local Ollama. Antigravity is just one more lane.
What's Your Setup?
Are you on Antigravity yet? Or still on a direct Anthropic key? I'm curious whether the enterprise OAuth path is something people are actually using day-to-day, or whether the API-key-in-env-var workflow is too entrenched to displace.
GitHub: github.com/codeking-ai/cligate
npx cligate@latest start
Top comments (1)
Happy to answer questions about the OAuth flow or the Anthropic↔Antigravity
model ID mapping — what's your current Claude Code backend?