How I Got Claude Code Running on My Gemini Subscription (Without Any API Keys)
TL;DR: I built a lightweight local proxy called CodeWeaver that translates Claude Code's Anthropic API calls into Google Cloud Code Assist requests — using your existing Gemini CLI OAuth session. Zero dependencies, one file, ~500 lines.
The Problem
If you're a developer working with AI coding agents, you've probably noticed a split in the ecosystem:
- Claude Code has arguably the best UX among AI coding CLIs — great streaming, tool use, multi-turn conversations, and a polished workflow.
- Gemini CLI comes bundled with your Google account and doesn't require managing API keys, but the CLI experience is different.
I found myself wanting the Claude Code interface with my Gemini subscription. Paying for two AI subscriptions felt wasteful, and setting up API keys for every tool was a pain.
So I built a bridge.
The Architecture
CodeWeaver is a local HTTP proxy that sits between Claude Code and Google's APIs:
Claude Code ──> Anthropic API request ──> CodeWeaver ──> Gemini Request ──> Google
│
Claude Code <── Anthropic response <── CodeWeaver <── Gemini Response <────────┘
It's a single Node.js file using only native modules (http, fs, path, crypto) — zero npm dependencies. It runs on localhost:8099 and speaks the Anthropic Messages API on one side and the Google Cloud Code Assist streaming API on the other.
How Protocol Translation Works
This was the most interesting part. Claude Code and Gemini have different API shapes, and bridging them required handling several translation layers:
1. Message Role Mapping
Anthropic uses "user" / "assistant" roles, while Gemini uses "user" / "model". Simple enough. The tricky part was handling tool interactions.
2. Tool Use ↔ Function Calling
When Claude Code calls a tool, it sends a tool_use content block. CodeWeaver translates this into Gemini's functionCall format:
Anthropic: Gemini:
tool_use block ──> functionCall { name, args }
tool_result ──> functionResponse { name, response }
The trickiest bit was preserving the thought signature — Gemini 3 models include a cryptographic signature in tool responses for security. CodeWeaver encodes this inside the tool_use ID with a custom encoding scheme (toolu_{name}_{random}_sig_{sig}) and decodes it on the way back.
3. Schema Sanitization
This was the biggest gotcha. Claude Code sends OpenAPI 3.1-style tool schemas with keywords like $schema, anyOf, oneOf, const, and exclusiveMinimum. Google's API strictly rejects these.
CodeWeaver's sanitizeSchema() function strips unsupported keywords, flattens anyOf/oneOf into their typed variant, and converts const to enum arrays — all while preserving the actual type structure.
4. Streaming Response Translation
Claude Code expects Server-Sent Events (SSE) with a specific event structure:
event: message_start
event: content_block_start
event: content_block_delta (text_delta / input_json_delta)
event: content_block_stop
event: message_delta
event: message_stop
Google sends a different SSE format. CodeWeaver maintains state about the current active content block (text vs. tool_use) and translates Google's stream chunks into the Anthropic event sequence on the fly.
Authentication: The Best Part
No API keys. No .env files. No vertex AI setup.
CodeWeaver reuses the OAuth credentials from your existing Gemini CLI session. When you run codeweaver --login, it:
- Spins up a local callback server on port 8085
- Opens a Google OAuth consent screen (PKCE flow)
- Exchanges the authorization code for access + refresh tokens
- Optionally provisions a free-tier Cloud Code Assist project
- Stores credentials locally
After that, it handles token refresh transparently — keeping your session alive without any manual intervention.
Rate Limiting and Fallbacks
Google's Cloud Code Assist has strict per-minute quotas on Pro models. CodeWeaver handles this with a self-healing fallback:
- If a Pro model (
gemini-2.5-pro) hits a 429, the proxy transparently retries withgemini-2.5-flash - If the Flash model also hits limits, it parses the retry-after duration and waits
- Up to 3 retry attempts before giving up
This means your Claude Code session rarely fails — it just gracefully degrades to a faster (but still capable) model when traffic is high.
Model Mapping
Claude Code has a hard-coded model selector. CodeWeaver maps those to their Gemini equivalents:
| Claude Code Model | Gemini Model |
|---|---|
| Sonnet (default) | gemini-2.5-pro |
| Haiku | gemini-2.5-flash |
| Opus | gemini-3.1-pro-preview |
| Fable | gemini-3.1-flash-lite |
You can also pass raw Gemini model IDs directly: claude --model gemini-3.1-pro-preview.
The Result: 500 Lines, Zero Dependencies
The entire proxy is a single proxy.js file. Here's the breakdown:
- ~80 lines — OAuth login flow with PKCE
- ~60 lines — Schema sanitization
- ~120 lines — Request translation (Anthropic → Gemini)
- ~200 lines — HTTP server + streaming response handling
- ~40 lines — Token management and config
Total: ~500 lines of vanilla Node.js. No TypeScript, no frameworks, no npm packages.
What's Next
CodeWeaver is intentionally focused on the Gemini → Claude bridge right now. But the roadmap aims for something bigger:
- Plugin architecture — provider-agnostic backend swapping
- Ollama support — run Claude Code against local models
- OpenAI / DeepSeek / OpenRouter — any API-compatible provider
- Auto failover — cascade through providers on rate limits or outages
- Docker image — containerized deployment
- Web dashboard — visual provider configuration
The vision is to make Claude Code a universal frontend for any AI model backend.
Try It
curl -fsSL https://raw.githubusercontent.com/whysooraj/CodeWeaver/main/claude-gemini-proxy/install.sh | bash
codeweaver --login
codeweaver
claude
Or clone and run manually:
git clone https://github.com/whysooraj/CodeWeaver.git
cd CodeWeaver/claude-gemini-proxy
node proxy.js --login
node proxy.js
claude
Requirements: Node.js 18+, a Google account, and the Gemini CLI.
CodeWeaver is open source under MIT. Contributions, issues, and feature requests are welcome!
Links:
- GitHub: github.com/whysooraj/CodeWeaver
- Install: One-liner above or clone the repo
Have questions? Found a bug? Want another provider supported? Let me know in the comments or open an issue on GitHub.