English | 中文
A lightweight bridge that turns the Gemini web app (gemini.google.com, using your own account cookies) into an OpenAI / Anthropic compatible API.
- Protocols: OpenAI
/v1/chat/completions(incl. streaming) + Anthropic/v1/messages - Tool calling: multi-turn
tool_callspassthrough (standard OpenAI protocol) - Account pool: reads
accounts.json, multi-account with hot-switch via web panel (short TTL re-read) - Session: one persistent
ChatSession; the prompt carries only the last N turns - Image input: OpenAI
image_url/ Anthropicimageblocks are passed through to Gemini
⚠️ This project works by reverse-engineering the Gemini web interface. For personal study and self-use only. Respect Google's Terms of Service; do not use commercially or for abuse. Your cookie is your login credential — keep it secret.
- The official Gemini API requires a credit card, paid plan, and specific regions — a high bar for individual developers.
- The official API has RPM/RPD quota limits; free quota is small.
- This project uses your own web account, consuming the web-side quota (usually enough for personal daily use).
| Feature | Description |
|---|---|
| Dual protocol | OpenAI /v1/chat/completions + Anthropic /v1/messages; works with RikkaHub / Cursor / Claude-style clients |
| Account pool + hot switch | Multiple accounts in accounts.json; switch with one click on the web panel, no service restart |
| Tool-calling bridge | The web endpoint doesn't understand the tools field; this project bridges via prompt + lenient parsing, supports multi-turn tool_calls |
| Recent-turn windowing | Only the last N turns (GEMINI_SEEKER_HISTORY_TURNS, default 3) are folded into the prompt; older context stays in the persistent server-side session — smaller prompts, more coherent context (supersedes the old 100k truncation) |
| Image input | Passes image blocks through to Gemini: OpenAI image_url / Anthropic image formats, incl. data URLs and http(s) links |
| JSON unwrapping | Automatically strips the model's {"content":...} wrapper so clients receive plain text |
| Single-file deploy | Flask + venv, one systemd unit; no database, no extra baggage |
- For study/research only: this project is for technical research and personal learning; commercial use is prohibited.
- Unofficial: no affiliation with Google LLC / Alphabet Inc.; not authorized or endorsed by them.
- May violate ToS: accessing the Gemini web endpoint with reverse-engineered cookies may violate Google's Terms of Service. Any consequences (account restriction, ban, data loss) are borne by the user.
- Use at your own risk: provided "as is"; the author is not liable for any direct or indirect loss.
- Recommendation: prefer the official Gemini API. This project is only a personal fallback when the official API is unavailable.
Client (OpenAI/Anthropic protocol)
│
▼
app.py (Flask) ← parse messages / tools, build prompt
│
▼
gemini_seeker/session.py ← gemini_webapi persistent ChatSession + thread lock
│
▼
gemini_seeker/pool.py ← read accounts.json for cookies
│
▼
gemini_webapi → gemini.google.com
The Gemini web endpoint doesn't accept a native tools field, so we use a prompt bridge: write the tool definitions into the system prompt and ask the model to output JSON only ({"tool_calls":[...]} or {"content":"..."}). parser.py then leniently parses the model output back into the standard format.
gemini-seeker/
├── app.py # Flask entry
├── requirements.txt
├── gemini_seeker/
│ ├── __init__.py
│ ├── pool.py # account pool reader
│ ├── session.py # client + persistent session + lock
│ ├── prompt.py # tool-bridge prompt
│ └── parser.py # lenient model-output parser
├── deploy/
│ ├── gemini-seeker.service
│ └── Caddyfile.example
└── config.example.json # accounts.json example
Prerequisite: a Linux server (or local machine) that can reach
gemini.google.com.
Step 1. Get your cookies (the crucial step)
Install the Cookie-Editor extension in your browser (Chrome / Edge / Firefox stores), then:
- Log in to https://gemini.google.com
- Click the Cookie-Editor icon → Export as JSON (do NOT use F12
document.cookie— it cannot readHttpOnlycookies) - From the exported JSON, find these two values:
__Secure-1PSID(starts withg.a000...)__Secure-1PSIDTS(starts withAKEyXz...orsidts-...)
Join them into one line: __Secure-1PSID=g.a000...; __Secure-1PSIDTS=AKEyXz...
Step 2. Install
git clone https://github.com/ymf2317-tech/gemini-seeker.git
cd gemini-seeker
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtStep 3. Write the account pool
mkdir -p /root/gemini-panel
cat > /root/gemini-panel/accounts.json <<'EOF'
{
"A": {
"name": "my account",
"cookies": "__Secure-1PSID=<paste Step 1 value>; __Secure-1PSIDTS=<paste Step 1 value>",
"auth_user": ""
}
}
EOFStep 4. Run
.venv/bin/python app.pyIf you see * Running on http://0.0.0.0:4983, it's up.
Step 5. Verify
curl -s localhost:4983/health
# {"ok":true,...} means OK
curl -s -X POST localhost:4983/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"gemini","messages":[{"role":"user","content":"hello"}]}'Step 6. Connect a client
Put http://<your-server-ip>:4983 into RikkaHub / any OpenAI client (see "Client setup" below).
For production, use systemd + Caddy reverse proxy (HTTPS). Templates are in
deploy/.
git clone https://github.com/ymf2317-tech/gemini-seeker.git /root/gemini-seeker
cd /root/gemini-seeker
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtrequirements.txt:
flask>=3.0
requests>=2.31
gemini-webapi>=2.1.1
Placed in the project root (default path /root/gemini-panel/accounts.json, changeable via env var GEMINI_POOL_PATH).
{
"A": {
"name": "account A",
"cookies": "__Secure-1PSID=g.a000...; __Secure-1PSIDTS=sidts...",
"auth_user": ""
},
"B": {
"name": "account B",
"cookies": "__Secure-1PSID=g.a000...; __Secure-1PSIDTS=sidts...",
"auth_user": ""
}
}How to get cookies: log in to gemini.google.com in a browser → F12 → Application → Cookies → copy the __Secure-1PSID and __Secure-1PSIDTS values, joined as key=value; key=value.
Cookies expire. Once the log shows
Account status: UNAUTHENTICATED, responses become extremely slow (the library falls back to a degraded path). Re-login and update the cookie.
| Variable | Default | Description |
|---|---|---|
GEMINI_SEEKER_API_KEY |
empty | Client auth key; empty means no auth |
GEMINI_SEEKER_HISTORY_TURNS |
3 | How many recent user-turns are folded into the prompt (older context stays in the server-side session) |
GEMINI_POOL_PATH |
/root/gemini-panel/accounts.json |
Account pool path |
GEMINI_POOL_DEFAULT |
A |
Which account to use by default |
GEMINI_POOL_TTL |
3 | Account pool cache TTL (seconds) |
GEMINI_EXTRA_COOKIES |
<project>/all_cookies.json |
Path to the full browser cookie set (JSON); injected automatically when present |
💡 Premium models (Pro / Flash / Argon) need the "full cookie set" (since 2026-10)
After Google reshuffled its subscription tiers in 2026-10, sending only
__Secure-1PSIDmakes premium models get silently dropped or degraded (replying with just "I am a language model..."). Fix:
- Install the Cookie-Editor extension, open
gemini.google.com, click Export → Export as JSON;- Save it as
all_cookies.jsonin the project root;- Restart the service (or point
GEMINI_EXTRA_COOKIESelsewhere).
⚠️ That file holds account credentials — never commit it (.gitignorealready blocks it). Cookies expire; just re-export when they do.
.venv/bin/python app.py # listens on 0.0.0.0:4983Or use systemd directly (see deploy/).
| Field | Value |
|---|---|
| Base URL | https://your-domain.example (replace with your own domain) |
| API path | /v1/chat/completions |
| API Key | the GEMINI_SEEKER_API_KEY you set |
| Model name | gemini-argon / gemini-pro / gemini-flash / gemini-flash-lite (real pass-through; short forms argon/pro/flash/lite also work) |
| Extended thinking | Append @think to the model name, e.g. gemini-pro@think, gemini-flash@think (maps to the web "Extended thinking" level; roughly doubles latency on reasoning tasks) |
Note the path must include
/v1. Some clients already include/v1in the Base URL; in that case the path is/chat/completions.
Anthropic protocol endpoint: /v1/messages.
GET /health— health check, returns current account/session state (includescurrent_model)GET /v1/models— live list of models available to the current accountPOST /v1/chat/completions— OpenAI protocol (supportsstream)POST /v1/messages— Anthropic protocol
⚠️ Since 2026-10 a full cookie set is required: with only__Secure-1PSID, premium models (Pro / Flash / Argon) get silently dropped or degraded by Google. Exportall_cookies.jsonas described in section 3 to fix it.- Cookie expiry → very slow: the library falls back to a degraded path, each request may take tens of seconds. Refreshing the cookie restores it.
- Typical latency:
gemini-flash≈ 5s,gemini-flash-lite≈ 7s,gemini-argon≈ 30s,gemini-pro≈ 40s (premium models "think" longer — expected). - Concurrency: only one request enters the session at a time (lock); extra concurrent client requests queue up.
- usage field: token counts are 0 (not implemented); does not affect functionality.
- Image input: supported (OpenAI
image_url/ Anthropicimage). Gemini may not recognize tiny or solid-color images (e.g. 1x1) — that is expected.
GNU Affero General Public License v3.0 (AGPL-3.0) — see LICENSE.
Why AGPL: this project depends on
gemini-webapi(AGPL-3.0). AGPL is viral, so the whole project is released under AGPL-3.0.Third-party sources:
gemini-webapi(AGPL-3.0)- Part of
parser.py's parsing approach is adapted fromAmanCode22/deeperseeker(MIT)