Model or dataset
GewoonJaap/gemini-cli-openai avatar
GewoonJaap/gemini-cli-openai

gemini-cli-openai: an OpenAI-compatible proxy for Gemini CLI, deployed on Cloudflare Workers

Expose Gemini CLI endpoints as OpenAI API with Cloudflare Workers

897 stars204 forksTypeScriptLicense varies

At a glance

What is it?
The project exposes Gemini models behind OpenAI-shaped endpoints using OAuth2 credentials from the official Gemini CLI, with the worker handling streaming, tool calls and thinking budgets. It is a self-hosted bridge for people who already have a Google account with Gemini access and want OpenAI SDK compatibility without an API key.
Who is it for?
Adopt gemini-cli-openai if you already use the official Gemini CLI, are comfortable with Wrangler and Cloudflare KV, and need OpenAI-shaped endpoints for clients like Open WebUI. Do not adopt it if you want a supported product with a documented licence, or if you cannot refresh OAuth2 credentials from a Google account yourself.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap gemini-cli-openai fills for Gemini CLI users

The official Gemini CLI authenticates through a Google account with OAuth2 and stores credentials in a local JSON file. That works for a terminal session, but it does not give you an HTTP endpoint that speaks the OpenAI chat completions format, so any tool built around the OpenAI SDK cannot talk to Gemini through it. gemini-cli-openai is a Cloudflare Worker that reads those same OAuth2 credentials and re-exposes Gemini behind OpenAI-compatible routes. The audience is narrow and specific: developers who already have Gemini access through their Google account, are willing to run their own worker, and want existing OpenAI client code to keep working. The README frames it as a drop-in replacement for OpenAI endpoints and lists Open WebUI and ChatGPT clients among the intended consumers. It is not a hosted service and there is no public endpoint to point at.

How the worker turns OAuth2 credentials into OpenAI responses

The architecture is a single TypeScript worker built on Hono, with Cloudflare KV as the token store. Credentials arrive as a JSON string in the GCP_SERVICE_ACCOUNT environment variable, containing access_token, refresh_token, scope, token_type, id_token and expiry_date, exactly the shape the Gemini CLI writes to ~/.gemini/oauth_creds.json. The worker caches and refreshes tokens in the GEMINI_CLI_KV namespace, which the README describes as smart token caching. Requests are translated to the Code Assist API, the same backend the official CLI uses, which is how the project claims free tier access without an API key.

Model handling is where the design gets opinionated. Three models are listed: gemini-2.5-pro, gemini-2.5-flash and gemini-2.5-flash-lite, each with a 1M context window and 65K max output tokens. Thinking behaviour is split into two independent switches. ENABLE_FAKE_THINKING produces synthetic reasoning text and the README says it is good for testing. ENABLE_REAL_THINKING uses Gemini's native reasoning. A per-request thinking_budget can override the default, with -1 for dynamic allocation and 0 to disable thinking. The reasoning_effort parameter maps to fixed budgets: none sets 0, low sets 1024, medium sets 12288 for flash models and 16384 for others, high sets 24576 for flash and 32768 for others. STREAM_THINKING_AS_CONTENT moves reasoning into the content stream wrapped in <thinking> tags, which the README compares to DeepSeek R1 style.

There is also ENABLE_AUTO_MODEL_SWITCHING, which falls back from pro to flash models on rate limits. That is a sensible default to leave on if you care about availability more than model quality, because a silent downgrade is easy to miss in logs.

Installing gemini-cli-openai and making a first request

Prerequisites are a Google account with Gemini access, a Cloudflare account with Workers enabled, and Wrangler. The README installs Wrangler globally with npm.

bash
npm install -g wrangler

You then need OAuth2 credentials. The documented path is to install and run the official Gemini CLI, choose Login with Google, and copy the resulting file. On macOS and Linux it lives at ~/.gemini/oauth_creds.json, on Windows at C:\Users\USERNAME\.gemini\oauth_creds.json. That file is the input to the worker, so the two projects are coupled at setup time.

Next create the KV namespace that backs token caching, and note the ID it returns.

bash
wrangler kv namespace create "GEMINI_CLI_KV"

Put that ID into wrangler.toml under the binding name the worker expects.

toml
kv_namespaces = [
  { binding = "GEMINI_CLI_KV", id = "your-kv-namespace-id" }
]

For local development, create a .dev.vars file. GCP_SERVICE_ACCOUNT holds the credential JSON as a single string. OPENAI_API_KEY is optional, and the README is explicit that if it is not set, the API is public.

bash
GCP_SERVICE_ACCOUNT={"access_token":"ya29...","refresh_token":"1//...","scope":"...","token_type":"Bearer","id_token":"eyJ...","expiry_date":1750927763467}
OPENAI_API_KEY=sk-your-secret-api-key-here

For production the same values go in as secrets rather than a file.

bash
wrangler secret put GCP_SERVICE_ACCOUNT
wrangler secret put OPENAI_API_KEY

Finally install dependencies and deploy.

bash
npm install
npm run deploy

npm run dev runs the worker locally instead. There is also a Docker path: docker-compose.yml maps port 8787, loads .dev.vars through env_file, and defines a healthcheck against http://localhost:8787/health, so the container is expected to answer on that path. A first real use is pointing an OpenAI SDK client at your worker URL with the model set to gemini-2.5-flash and, if you set OPENAI_API_KEY, an Authorization: Bearer header. The repository ships api-test.http and stream-test.http plus examples/image-example.js, which are the practical starting points for verifying that streaming and image input behave as described.

Where gemini-cli-openai breaks down

The dependency on Gemini CLI credentials is the sharpest limitation. The README gives no documented way to obtain OAuth2 tokens other than running the official CLI and copying the file, and it does not describe what happens when the refresh token is revoked, expires, or the Google account loses Gemini access. A worker that silently fails to refresh will return errors to every client behind it, and the README does not document a rollback or credential rotation procedure.

The licence is the second problem. The repository metadata carries no licence identifier and the README does not state one, so anyone evaluating this for company use has to resolve that before shipping it. The README also does not describe rate limit behaviour in detail beyond the existence of ENABLE_AUTO_MODEL_SWITCHING, so the failure mode when Google throttles the account is only partly specified.

Finally, the security default deserves scrutiny. OPENAI_API_KEY is optional, and without it the deployed endpoint is public. Anyone who finds the worker URL can spend your Google account's quota. The README says this plainly, but it is the kind of default that is easy to leave alone in a quick deploy. If you need guaranteed capacity, per-token billing, or a vendor SLA, this is the wrong tool; it rides on a free tier through the Code Assist API.

gemini-cli-openai compared with LiteLLM

The obvious alternative for OpenAI-compatible access to Gemini is LiteLLM, which is a Python proxy that routes across many providers and authenticates with API keys rather than OAuth2. The difference in approach matters. LiteLLM is a general router: you configure providers, keys and fallbacks, and it runs as a long-lived Python service you host yourself. gemini-cli-openai does one provider, one auth path, and runs as a worker at the edge with KV-backed token caching. If you need to switch between Gemini, OpenAI and Anthropic in one process, LiteLLM is the fit. If you specifically want to reuse the Gemini CLI's free-tier OAuth2 session and do not want to manage API keys or a Python deployment, the worker is the smaller thing to run. The trade-off is that the worker inherits every constraint of that OAuth2 session, including whatever limits Google applies to it.

Maintenance, upgrades and licence status

The last push to the default branch was on 2026-09-03, and the repository is not archived. There are no retrieved releases, so there is no tagged version history to pin against; deployment is from the main branch through wrangler deploy. The dependency surface is small: hono is the only runtime dependency, with TypeScript, Wrangler, ESLint and Prettier as dev dependencies, and package.json pins wrangler at ^4.30.0 while the Dockerfile installs wrangler@4.23.0 globally, a version skew worth noticing if you build the container. Because there are no releases, upgrading means pulling main and redeploying, and the README does not describe a migration or compatibility policy between commits. The licence field is empty in the repository metadata and the README does not name a licence, so the terms under which you may use or redistribute the code are not stated anywhere in the repository. That is a question for whoever owns compliance on your side, not something this article can resolve.

Editorial conclusion

Adopt gemini-cli-openai if you already use the official Gemini CLI, are comfortable with Wrangler and Cloudflare KV, and need OpenAI-shaped endpoints for clients like Open WebUI. Do not adopt it if you want a supported product with a documented licence, or if you cannot refresh OAuth2 credentials from a Google account yourself. Before deploying, verify the licence situation in the repository, confirm that the KV namespace binding in wrangler.toml matches the ID returned by the create command, and decide whether OPENAI_API_KEY should be set, because leaving it unset makes the endpoint public.

Frequently asked questions

What is gemini-cli-openai and what problem does it solve?

It is a Cloudflare Worker that exposes Gemini models through OpenAI-compatible endpoints, so OpenAI SDKs and clients can talk to Gemini. It authenticates with OAuth2 credentials taken from the official Gemini CLI rather than an API key.

Do I need a Gemini API key to use gemini-cli-openai?

No. The README states that OAuth2 authentication requires no API keys and uses your Google account. You do need to run the official Gemini CLI once to produce the oauth_creds.json file the worker consumes.

Which models does gemini-cli-openai support?

The README lists gemini-2.5-pro, gemini-2.5-flash and gemini-2.5-flash-lite, each with a 1M context window and 65K max output tokens. All three are described as supporting thinking.

How do I install and deploy gemini-cli-openai?

Install Wrangler, create a GEMINI_CLI_KV namespace and put its ID in wrangler.toml, set GCP_SERVICE_ACCOUNT (and optionally OPENAI_API_KEY) in .dev.vars or as secrets, then run npm install followed by npm run deploy. npm run dev runs it locally, and docker-compose.yml serves it on port 8787.

Is the gemini-cli-openai endpoint public by default?

Yes, if OPENAI_API_KEY is not set. The README says that when the variable is unset the API is public, and that when it is set clients must send an Authorization: Bearer header.

Does gemini-cli-openai support streaming and tool calling?

The README lists real-time streaming over server-sent events with token usage, and tool calling with function calling support integrated into the Gemini API. The repository includes stream-test.http and api-test.http for exercising those paths.

Official sources

  1. GewoonJaap/gemini-cli-openai on GitHub
  2. Issues
  3. README
Community notes

Community notes