antigravity-gateway
v2.1.0
Published
Universal AI gateway - access Claude & Gemini models via OpenAI or Anthropic-compatible API through Antigravity Cloud Code
Maintainers
Readme
Antigravity Gateway
Universal AI Gateway - Access Claude and Gemini models through any OpenAI or Anthropic-compatible client, powered by Antigravity's Cloud Code.
┌─────────────────────────────────────────────────────────────────────────┐
│ YOUR AI TOOLS │
│ Cursor • Cline • Continue • Aider • Claude Code • Gemini CLI • etc. │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────┐
│ Antigravity Gateway │
│ OpenAI + Anthropic API │
└───────────────────────────────┘
│
▼
┌───────────────────────────────┐
│ Antigravity Cloud Code │
│ Claude • Gemini models │
└───────────────────────────────┘Features
- Triple API Support: OpenAI Chat Completions (
/v1/chat/completions), OpenAI Responses (/v1/responses), and Anthropic (/v1/messages) endpoints - Multiple Models: Access Claude Sonnet 4.5, Opus 4.5, and Gemini 3 Flash/Pro models
- Extended Thinking: Full support for reasoning/thinking models
- Multi-Account Load Balancing: Add multiple Google accounts for higher throughput
- Universal Compatibility: Works with any OpenAI or Anthropic-compatible client
Quick Start
Docker (Recommended)
docker pull ghcr.io/johnneerdael/antigravity-gateway:latest
docker run -it -p 8080:8080 \
-v $(pwd)/data:/root/.config/antigravity-gateway \
ghcr.io/johnneerdael/antigravity-gateway:latestDocker Compose
services:
antigravity-gateway:
image: ghcr.io/johnneerdael/antigravity-gateway:latest
container_name: antigravity-gateway
ports:
- "8080:8080"
volumes:
- ./data:/root/.config/antigravity-gateway
environment:
- FALLBACK=true
restart: unless-stoppedNPM
npx antigravity-gateway start
# Or install globally
npm install -g antigravity-gateway
agw startAdding Google Accounts
The gateway requires Google accounts with Antigravity access. Add accounts via OAuth:
# Interactive (opens browser)
agw accounts add
# Headless servers (manual code entry)
agw accounts add --no-browser
# List configured accounts
agw accounts listClient Configuration
The gateway exposes three API endpoints:
- OpenAI Chat Completions:
http://localhost:8080/v1/chat/completions - OpenAI Responses API:
http://localhost:8080/v1/responses - Anthropic-compatible:
http://localhost:8080/v1/messages
Available Models
| Model ID | Type | Context | Output | Thinking |
|----------|------|---------|--------|----------|
| claude-sonnet-4-5-thinking | Claude | 200K | 16K | ✓ |
| claude-opus-4-5-thinking | Claude | 200K | 16K | ✓ |
| claude-sonnet-4-5 | Claude | 200K | 8K | ✗ |
| gemini-3-flash | Gemini | 1M | 16K | ✓ |
| gemini-3-pro-high | Gemini | 1M | 16K | ✓ |
| gemini-3-pro-low | Gemini | 1M | 16K | ✓ |
| gemini-3-pro-image | Gemini | 1M | 16K | ✓ |
| gemini-2.5-pro | Gemini | 1M | 16K | ✓ |
| gemini-2.5-flash | Gemini | 1M | 16K | ✓ |
| gemini-2.5-flash-thinking | Gemini | 1M | 16K | ✓ |
| gemini-2.5-flash-lite | Gemini | 1M | 8K | ✗ |
Note: Model availability depends on your Antigravity account. Run
curl http://localhost:8080/v1/modelsto see your available models.
AI Coding Tools Configuration
Cursor
Settings → Models → Add Model:
Provider: OpenAI Compatible
Base URL: http://localhost:8080/v1
API Key: any-value
Model: gemini-3-flashContinue.dev
Edit ~/.continue/config.json:
{
"models": [{
"title": "Antigravity Gateway",
"provider": "openai",
"model": "gemini-3-flash",
"apiBase": "http://localhost:8080/v1",
"apiKey": "any-value"
}]
}Cline (VS Code)
Settings → Cline → API Provider:
Provider: OpenAI Compatible
Base URL: http://localhost:8080/v1
API Key: any-value
Model ID: claude-sonnet-4-5-thinkingRoo Code
Settings → Custom API:
API Endpoint: http://localhost:8080/v1/chat/completions
API Key: any-value
Model: gemini-3-flashKilo Code
Settings → Provider → OpenAI Compatible:
Base URL: http://localhost:8080/v1
API Key: any-value
Model: claude-sonnet-4-5-thinkingTRAE
Configure in settings:
Provider: OpenAI
Base URL: http://localhost:8080/v1
API Key: any-valueOpenCode
Edit ~/.opencode/config.json:
{
"provider": {
"type": "openai",
"baseUrl": "http://localhost:8080/v1",
"apiKey": "any-value",
"model": "gemini-3-flash"
}
}Goose
Edit ~/.config/goose/config.yaml:
provider: openai
model: gemini-3-flash
api_base: http://localhost:8080/v1
api_key: any-valueAider
aider --openai-api-base http://localhost:8080/v1 \
--openai-api-key any-value \
--model openai/gemini-3-flashOr set environment variables:
export OPENAI_API_BASE=http://localhost:8080/v1
export OPENAI_API_KEY=any-value
aider --model openai/gemini-3-flashCody (Sourcegraph)
Settings → Cody → Enterprise:
Server Endpoint: http://localhost:8080
Access Token: any-valueClaude Code CLI
Create ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://localhost:8080",
"ANTHROPIC_API_KEY": "any-value"
}
}Then run: claude
Gemini CLI
export GEMINI_API_BASE=http://localhost:8080/v1
export GEMINI_API_KEY=any-value
gemini chatCherry Studio
Settings → API Configuration:
Provider: OpenAI Compatible
API URL: http://localhost:8080/v1
API Key: any-value
Model: gemini-3-flashFactory Droid
Configure provider:
Type: OpenAI
Base URL: http://localhost:8080/v1
API Key: any-valueCrush
Settings → AI Provider:
Provider: OpenAI Compatible
Endpoint: http://localhost:8080/v1
Key: any-valueSDK Integration
OpenAI Python SDK
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8080/v1",
api_key="any-value"
)
# Chat Completions API
response = client.chat.completions.create(
model="gemini-3-flash",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
# Responses API
response = client.responses.create(
model="gemini-3-flash",
input="Tell me a joke about programming."
)
print(response.output[0].content[0].text)OpenAI JavaScript SDK
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://localhost:8080/v1',
apiKey: 'any-value'
});
const response = await client.chat.completions.create({
model: 'gemini-3-flash',
messages: [{ role: 'user', content: 'Hello!' }]
});
console.log(response.choices[0].message.content);Anthropic Python SDK
import anthropic
client = anthropic.Anthropic(
base_url="http://localhost:8080",
api_key="any-value"
)
message = client.messages.create(
model="claude-sonnet-4-5-thinking",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
print(message.content[0].text)cURL
# OpenAI Chat Completions format
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer any-value" \
-d '{
"model": "gemini-3-flash",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# OpenAI Responses API format
curl http://localhost:8080/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer any-value" \
-d '{
"model": "gemini-3-flash",
"input": "Tell me a three sentence bedtime story about a unicorn."
}'
# OpenAI Responses API with streaming
curl http://localhost:8080/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer any-value" \
-d '{
"model": "gemini-3-flash",
"input": "Write a haiku about coding.",
"stream": true
}'
# Anthropic format
curl http://localhost:8080/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: any-value" \
-d '{
"model": "claude-sonnet-4-5-thinking",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}]
}'LiteLLM Integration
Create litellm-config.yaml:
model_list:
- model_name: claude-sonnet-4-5-thinking
model_info:
mode: chat
supports_vision: true
supports_function_calling: true
max_input_tokens: 200000
max_output_tokens: 16000
litellm_params:
model: openai/claude-sonnet-4-5-thinking
api_base: http://antigravity-gateway:8080/v1
api_key: "not-needed"
stream: true
- model_name: gemini-3-flash
model_info:
mode: chat
supports_vision: true
supports_function_calling: true
max_input_tokens: 1048576
max_output_tokens: 16384
litellm_params:
model: openai/gemini-3-flash
api_base: http://antigravity-gateway:8080/v1
api_key: "not-needed"
stream: trueAPI Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| /v1/chat/completions | POST | OpenAI Chat Completions API |
| /v1/responses | POST | OpenAI Responses API |
| /v1/messages | POST | Anthropic Messages API |
| /v1/models | GET | List available models |
| /health | GET | Health check |
| /account-limits | GET | Account quotas (add ?format=table) |
| /refresh-token | POST | Force token refresh |
Multi-Account Load Balancing
Add multiple Google accounts for higher throughput and automatic failover:
agw accounts add # Add first account
agw accounts add # Add second account
agw accounts add # Add third accountThe gateway automatically:
- Uses sticky account selection for prompt cache efficiency
- Switches accounts when rate limited
- Waits for short rate limits (≤2 min)
- Falls back to alternate models when all accounts exhausted
Check account status:
curl "http://localhost:8080/account-limits?format=table"Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| PORT | 8080 | Server port |
| DEBUG | false | Enable debug logging |
| FALLBACK | false | Enable model fallback on quota exhaustion |
Migration from v1.x
If upgrading from antigravity-claude-proxy:
- Config path changed:
~/.config/antigravity-proxy→~/.config/antigravity-gateway - Package name changed:
antigravity-claude-proxy→antigravity-gateway - Docker image changed:
ghcr.io/johnneerdael/antigravity-claude-proxy→ghcr.io/johnneerdael/antigravity-gateway - New CLI alias:
agw(short forantigravity-gateway)
Copy your existing accounts:
cp -r ~/.config/antigravity-proxy/* ~/.config/antigravity-gateway/Troubleshooting
"No accounts available"
Add Google accounts: agw accounts add
Rate limited
- Add more accounts for load balancing
- Enable fallback mode:
agw start --fallback - Wait for quota reset (shown in error message)
Connection refused
Ensure the gateway is running: agw start
Model not found
Use exact model IDs from /v1/models endpoint. Common models:
gemini-3-flash(recommended for speed)claude-sonnet-4-5-thinking(recommended for quality)
License
MIT License - see LICENSE
Credits
Based on work from:
