- AGENTS.md: step-by-step instructions for LLM agents to guide users through install, configure, and troubleshoot - README.md: SEO-optimized with keywords (Gemini 3.5 Flash, Claude Sonnet, OpenAI-compatible, free API, LLM proxy), collapsible config sections, badges, AI-assisted setup callout - Topics: 20 SEO tags added via GitHub API
13 KiB
Antigravity Proxy
Free Gemini 3.5 Flash, Claude Sonnet 4.6 & more — through a local OpenAI-compatible proxy
Features · Quick Start · Models · Configuration · Docs
What is this?
A lightweight OpenAI-compatible proxy that bridges any AI tool to Google Antigravity's internal Cloud Code Assist API. Authenticate once with the Antigravity CLI, then use Gemini and Claude models from any OpenAI-compatible client — no API key, no billing, no credit card.
Your Tool (OpenAI format) → Antigravity Proxy (localhost:8877) → Gemini / Claude models
Why use this?
- Free — uses the OAuth token from the Antigravity CLI, no paid API key
- Universal — works with any OpenAI-compatible tool (Aider, Continue, Hermes, Claude Code, OpenAI SDK, LangChain, etc.)
- No dependencies — pure Python stdlib, no
pip installneeded - Two endpoints — OpenAI chat completions + native Gemini passthrough (for images & structured output)
- Tool/function calling — full support, including round-trip through conversation history
- Streaming — SSE streaming support for real-time token generation
Features
- OpenAI-compatible
POST /v1/chat/completions— streaming + non-streaming - Native Gemini passthrough
POST /v1beta/models/{model}:generateContent— images, structured JSON output - Tool/function calling — OpenAI tools format → Gemini functionDeclarations, with round-trip encoding
- Model auto-mapping — use friendly names (
gemini-3.5-flash), the proxy translates to backend names automatically - OAuth token auto-refresh — token refreshed automatically when expired, no manual intervention
- Zero pip dependencies — Python 3.10+ standard library only
- systemd service included — run as a background service on Linux
Available Models
| Friendly Name | Backend Model | Thinking | Type |
|---|---|---|---|
gemini-3.1-pro |
gemini-3.1-pro-low |
Low | Gemini |
gemini-3.1-pro-high |
gemini-3.1-pro-low |
High | Gemini |
gemini-3-flash |
gemini-3-flash |
— | Gemini |
gemini-3.5-flash |
gemini-3.5-flash-low |
— | Gemini |
gemini-2.5-pro |
gemini-2.5-pro |
— | Gemini |
gemini-2.5-flash |
gemini-2.5-flash |
— | Gemini |
claude-sonnet-4.6 |
claude-sonnet-4-6 |
— | Claude |
claude-opus-4.6 |
claude-opus-4-6-thinking |
Enabled | Claude |
You always use the friendly name in your client. The proxy handles translation.
Quick Start
Prerequisites
- Python 3.10+ — check with
python3 --version - Antigravity CLI — install and authenticate (one-time):
# Install agy (macOS/Linux)
curl -fsSL https://storage.googleapis.com/antigravity-releases/install.sh | bash
# Authenticate (opens browser, sign in with Google)
agy
Windows: download from antigravity.google
Install & Run
git clone https://github.com/usamashehab/antigravity-proxy.git
cd antigravity-proxy
# Start the proxy
python3 antigravity_proxy.py
# Verify it's running
curl http://127.0.0.1:8877/health
# → {"status": "ok", "service": "antigravity-proxy"}
That's it. The proxy is now listening on http://127.0.0.1:8877.
Connect Your Tool
Any OpenAI-compatible client works. Set base URL to http://127.0.0.1:8877/v1 and use any model from the table above. The API key can be any string (the proxy doesn't check it).
OpenAI Python SDK
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8877/v1",
api_key="antigravity",
)
response = client.chat.completions.create(
model="gemini-3.5-flash",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
curl
curl http://127.0.0.1:8877/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.5-flash",
"messages": [{"role": "user", "content": "Hello!"}]
}'
Aider
export OPENAI_API_BASE=http://127.0.0.1:8877/v1
export OPENAI_API_KEY=antigravity
aider --model gemini-3.5-flash
Continue.dev (VS Code)
In ~/.continue/config.json:
{
"models": [{
"title": "Antigravity",
"provider": "openai",
"model": "gemini-3.5-flash",
"apiBase": "http://127.0.0.1:8877/v1",
"apiKey": "antigravity"
}]
}
Hermes Agent
hermes config set model.provider custom
hermes config set model.base_url http://127.0.0.1:8877/v1
hermes config set model.api_key antigravity
hermes config set model.default gemini-3.5-flash
Claude Code
export ANTHROPIC_BASE_URL=http://127.0.0.1:8877/v1
claude # uses claude-sonnet-4.6 through the proxy
LangChain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="http://127.0.0.1:8877/v1",
api_key="antigravity",
model="gemini-3.5-flash",
)
AI-Assisted Setup 🤖
Using an AI assistant (Claude, GPT, Gemini, etc.) to set this up?
This repo includes AGENTS.md — a complete instruction file for AI agents. Just tell your AI assistant:
"Help me install and configure the antigravity-proxy from https://github.com/usamashehab/antigravity-proxy"
The AI will read AGENTS.md and guide you through every step: prerequisites check, installation, tool configuration, and troubleshooting.
Configuration
CLI Arguments
python3 antigravity_proxy.py [--port PORT] [--host HOST]
--port PORT Port to listen on (default: 8877)
--host HOST Host to bind to (default: 127.0.0.1)
Run as a systemd Service (Linux)
# Clone to permanent location
git clone https://github.com/usamashehab/antigravity-proxy.git ~/antigravity-proxy
# Install service
mkdir -p ~/.config/systemd/user
cp ~/antigravity-proxy/antigravity-proxy.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable antigravity-proxy
systemctl --user start antigravity-proxy
# Check status
systemctl --user status antigravity-proxy
Environment Variables
| Variable | Default | Description |
|---|---|---|
ANTIGRAVITY_CLIENT_ID |
built-in | Override OAuth client ID |
ANTIGRAVITY_CLIENT_SECRET |
built-in | Override OAuth client secret |
The default client credentials are the same values embedded in every Antigravity CLI binary — you only need these env vars if you're using a custom build.
Two API Endpoints
1. OpenAI Chat Completions
POST /v1/chat/completions
Standard OpenAI format with messages, tools, and streaming. Use this for any OpenAI-compatible client.
2. Native Gemini Passthrough
POST /v1beta/models/{model}:generateContent
Accepts the exact same format as Google's Generative Language API. Use this for:
- Image inputs (
inline_datawith base64-encoded images) - Structured output (
responseSchemafor enforced JSON schema) - Thinking control (
thinkingConfig)
Structured output example
curl http://127.0.0.1:8877/v1beta/models/gemini-3.5-flash:generateContent \
-H "Content-Type: application/json" \
-d '{
"contents": [{"parts": [{"text": "Extract: Ahmed is 30 years old"}]}],
"generationConfig": {
"temperature": 0,
"responseMimeType": "application/json",
"responseSchema": {
"type": "OBJECT",
"properties": {
"name": {"type": "STRING"},
"age": {"type": "NUMBER"}
},
"required": ["name", "age"]
}
}
}'
Image input example
# Base64-encode an image and send it
B64=$(base64 -w0 photo.jpg)
curl http://127.0.0.1:8877/v1beta/models/gemini-3.5-flash:generateContent \
-H "Content-Type: application/json" \
-d "{
\"contents\": [{
\"parts\": [
{\"text\": \"What is in this image?\"},
{\"inline_data\": {\"mime_type\": \"image/jpeg\", \"data\": \"$B64\"}}
]
}]
}"
Management
# Health check
curl http://127.0.0.1:8877/health
# List models
curl http://127.0.0.1:8877/v1/models
# View logs (systemd)
journalctl --user -u antigravity-proxy -f
# Restart / stop
systemctl --user restart antigravity-proxy
systemctl --user stop antigravity-proxy
# Re-authenticate when token expires
agy && systemctl --user restart antigravity-proxy
How It Works
Your Client (OpenAI format)
│
▼
Antigravity Proxy (localhost:8877)
│ ┌─ Translates OpenAI messages → Gemini contents
│ ├─ Converts OpenAI tools → Gemini functionDeclarations
│ ├─ Manages OAuth token (auto-refresh)
│ ├─ Maps friendly model names → backend model names
│ └─ Wraps in Antigravity envelope {project, model, request}
│
▼
cloudcode-pa.googleapis.com
│
▼
Gemini / Claude models → Response unwrapped → OpenAI format → Your client
Technical details
- Reads OAuth token from
~/.gemini/antigravity-cli/antigravity-oauth-token - Refreshes expired access tokens via
oauth2.googleapis.com/token - Discovers Cloud Code Assist project ID via
v1internal:loadCodeAssist - Wraps each request in the Antigravity envelope:
{project, model, request, requestType, userAgent, requestId} - Forwards to
v1internal:generateContentorv1internal:streamGenerateContent?alt=sse - Unwraps the
{response: {...}}envelope - Converts Gemini response → OpenAI format (choices, message, usage)
- For tool calls, encodes Gemini's
functionCall.id+thoughtSignatureinto OpenAItool_call.idfor round-tripping
Adding or Updating Models
Edit MODEL_MAP at the top of antigravity_proxy.py:
MODEL_MAP = {
"gemini-3.5-flash": ("gemini-3.5-flash-low", None),
# "friendly-name": ("backend-name", thinking_level),
# thinking_level: "low", "high", or None
}
Restart the proxy after editing.
Requirements
- Python 3.10+
- Antigravity CLI (
agy) installed and authenticated - No pip dependencies
FAQ
Is this legal to use?
The proxy uses the same OAuth token and API endpoints that the Antigravity CLI itself uses. It does not bypass authentication — you need a valid Google account with Antigravity access. Multiple similar projects exist publicly on GitHub. However, Google's terms of service may restrict programmatic API access. Use at your own discretion.
Does it support streaming?
Yes. SSE streaming ("stream": true) on the OpenAI endpoint, and the native Gemini stream endpoint.
Can I send images?
Yes, through the native Gemini passthrough endpoint (/v1beta/models/{model}:generateContent). Send inline_data with base64-encoded images, exactly like Google's API.
Is there a rate limit?
Rate limits are determined by Google's Antigravity quota, not the proxy. The proxy itself is multithreaded with no concurrency limit.
Does the token expire?
The OAuth access token expires (~1 hour). The proxy auto-refreshes it. The refresh token can expire if unused for extended periods — re-run agy if that happens.
Can I bind to 0.0.0.0?
Yes, but the proxy has no authentication layer. Anyone who can reach it can use your Antigravity quota. Only bind to a non-localhost address if you understand the risk.