{"_id":"@8-/gemini-web-api","_rev":"3-fd901e5265c7b90b8adb9b92c4992d41","name":"@8-/gemini-web-api","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@8-/gemini-web-api","version":"1.0.0","keywords":["gemini","gemini-web-api","openai","openai-compatible","reverse-proxy","bun","node","llm","sse","streaming"],"license":"MIT","_id":"@8-/gemini-web-api@1.0.0","maintainers":[{"name":"i18n-now","email":"i18n.site@gmail.com"}],"homepage":"https://github.com/x-at-01/gemini-web-api#readme","bugs":{"url":"https://github.com/x-at-01/gemini-web-api/issues"},"bin":{"gemini-web-api":"index.js"},"dist":{"shasum":"676edd3c59dbaf07446b9968750854189569e1ea","tarball":"https://registry.npmjs.org/@8-/gemini-web-api/-/gemini-web-api-1.0.0.tgz","fileCount":5,"integrity":"sha512-aZxgdbQmg29oWwKiIW7Ly8XhnznkmNqIDBHeERZsRciwNCOzdJE2fbtfLNYh+mdwNpGD9fqUOvXCoAv4mWlsqw==","signatures":[{"sig":"MEUCIAItdhw9OjlcDIEuFqI/2C/0+jqLQmzcuS07Paz+TOU6AiEAxF9XwXP0JPKdOyONK/YU/LODuafCthnwcX3lB0npuSY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43612},"main":"index.js","type":"module","gitHead":"32d70f83720377d7c9735c02a3e5ecf02e27fdff","scripts":{"start":"bun index.js","start:node":"node index.js"},"_npmUser":{"name":"i18n-now","email":"i18n.site@gmail.com"},"repository":{"url":"git+https://github.com/x-at-01/gemini-web-api.git","type":"git"},"_npmVersion":"11.19.0","description":"OpenAI-compatible Gemini Web API reverse proxy running seamlessly on both Bun and Node.js with zero external dependencies.","directories":{},"_nodeVersion":"26.7.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/gemini-web-api_1.0.0_1789033855754_0.384855120010533","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@8-/gemini-web-api","version":"1.0.1","keywords":["gemini","gemini-web-api","openai","openai-compatible","reverse-proxy","bun","node","llm","sse","streaming"],"license":"MIT","_id":"@8-/gemini-web-api@1.0.1","maintainers":[{"name":"i18n-now","email":"i18n.site@gmail.com"}],"homepage":"https://github.com/x-at-01/gemini-web-api#readme","bugs":{"url":"https://github.com/x-at-01/gemini-web-api/issues"},"bin":{"gemini-web-api":"index.js"},"dist":{"shasum":"3917ba40dd78f790800afb9817673a5e20da6f03","tarball":"https://registry.npmjs.org/@8-/gemini-web-api/-/gemini-web-api-1.0.1.tgz","fileCount":17,"integrity":"sha512-sP4FAFF4v997kTPSo/0W9bNoaGAdMETGSys615Msi8xOaqLizcfCvsqnbxKNxdOhpUCQ4xhzPLMfpFi1fj6IRw==","signatures":[{"sig":"MEUCIGDt3xjfa8Odj378rmRuqS6Gid4wSUD4I9w9zolB28p8AiEApQSHZgiuWuPzr/UJ4zsma4t6gwtvoMRvLoG7EPS4gAg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82742},"main":"index.js","type":"module","gitHead":"90bef8375af0801be0cbb2b05f1d35ecb92baa96","scripts":{"test":"node --test","start":"bun index.js","test:bun":"bun test","start:node":"node index.js"},"_npmUser":{"name":"i18n-now","email":"i18n.site@gmail.com"},"repository":{"url":"git+https://github.com/x-at-01/gemini-web-api.git","type":"git"},"_npmVersion":"11.19.0","description":"OpenAI-compatible Gemini Web API reverse proxy running seamlessly on both Bun and Node.js with zero external dependencies.","directories":{},"_nodeVersion":"26.7.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/gemini-web-api_1.0.1_1789045843564_0.16801906870392225","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@8-/gemini-web-api","version":"1.0.2","description":"OpenAI-compatible Gemini Web API reverse proxy running on Bun & Node.js / 兼容 OpenAI 格式的 Gemini Web 反向代理服务","type":"module","main":"index.js","bin":{"gemini-web-api":"index.js"},"scripts":{"start":"bun index.js","start:node":"node index.js","test":"node --test","test:bun":"bun test"},"repository":{"type":"git","url":"git+https://github.com/x-at-01/gemini-web-api.git"},"bugs":{"url":"https://github.com/x-at-01/gemini-web-api/issues"},"homepage":"https://github.com/x-at-01/gemini-web-api#readme","keywords":["gemini","gemini-web-api","openai","openai-compatible","reverse-proxy","bun","node","llm","sse","streaming"],"license":"MIT","gitHead":"d78afcaf1c4079871c6859779eceabec5638f0cb","_id":"@8-/gemini-web-api@1.0.2","_nodeVersion":"26.7.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-iyC4ONLgmM+jK1YWWjVPupDe0lq5hbu4yNovFX7D5cOL3KbJUdXqCol21i/TzJRmT6iJQPNQm/bp7D/KHayCoA==","shasum":"1baf7fe400ed01418f9fb50c228ccf59ebe5cf17","tarball":"https://registry.npmjs.org/@8-/gemini-web-api/-/gemini-web-api-1.0.2.tgz","fileCount":17,"unpackedSize":80048,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCDHcCmo/DU2sbeHWeKa5MZGPpWLKak6SgsxpzeXF+9gAIhAPxduAlGG7O17WK6+ztDR2+3bhaPAWUV2zTIMwkkZU0Q"}]},"_npmUser":{"name":"i18n-now","email":"i18n.site@gmail.com"},"directories":{},"maintainers":[{"name":"i18n-now","email":"i18n.site@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/gemini-web-api_1.0.2_1789046590759_0.4185578508808716"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-10T09:50:55.432Z","modified":"2026-09-10T13:23:11.085Z","1.0.0":"2026-09-10T09:50:55.888Z","1.0.1":"2026-09-10T13:10:43.696Z","1.0.2":"2026-09-10T13:23:10.919Z"},"bugs":{"url":"https://github.com/x-at-01/gemini-web-api/issues"},"license":"MIT","homepage":"https://github.com/x-at-01/gemini-web-api#readme","keywords":["gemini","gemini-web-api","openai","openai-compatible","reverse-proxy","bun","node","llm","sse","streaming"],"repository":{"type":"git","url":"git+https://github.com/x-at-01/gemini-web-api.git"},"description":"OpenAI-compatible Gemini Web API reverse proxy running on Bun & Node.js / 兼容 OpenAI 格式的 Gemini Web 反向代理服务","maintainers":[{"name":"i18n-now","email":"i18n.site@gmail.com"}],"readme":"<div align=\"center\">\n\n# Gemini Web API\n\n**OpenAI-compatible Gemini Web API reverse proxy running on Bun & Node.js.**\n**Automatically detects Chrome session cookies. Zero configuration required.**\n\n**兼容 OpenAI 格式的 Gemini Web 反向代理服务，支持 Bun 与 Node.js 双运行时。**\n**全自动探测本地 Chrome 凭据，无需任何手动配置，开箱即用。**\n\n<p>\n  <a href=\"#english\">English</a> | <a href=\"#简体中文\">简体中文</a>\n</p>\n\n</div>\n\n---\n\n<a id=\"english\"></a>\n\n## English\n\n### Overview\n\n**`@8-/gemini-web-api`** is an ultra-lightweight reverse proxy that turns your Google Gemini Web session into a standard OpenAI-compatible API.\n\n**No configuration is needed**: It automatically discovers your existing Chrome / Brave / Edge browser session, retrieves the encryption key from the macOS Keychain, decrypts your Gemini session cookies, and starts serving OpenAI-compatible endpoints (`/v1/chat/completions`, `/v1/models`) instantly.\n\n### Key Highlights\n\n- **Zero Configuration**: As long as you are logged into [gemini.google.com](https://gemini.google.com) in Chrome (or Brave / Edge), the server automatically extracts and decrypts your tokens. No manual cookie copying or `.env` required!\n- **Dual Runtime Support**: Native ultra-high performance on **Bun** (`Bun.serve`) and seamless native support on **Node.js** (>= 22.5.0, via `node:sqlite` and Web Streams).\n- **Zero External Dependencies**: 100% built on standard Web APIs (`fetch`, `ReadableStream`, `crypto.subtle`) and built-in Node/Bun modules. Zero `node_modules` required!\n- **OpenAI Drop-in Replacement**: Fully compatible with `/v1/chat/completions` and `/v1/models`. Works seamlessly with ChatGPT-Next-Web, LobeChat, Cherry Studio, Cline, Roo Code, Cursor, Aider, and official OpenAI SDKs.\n- **Robust 4-Tier Tool / Function Calling Engine**:\n  1. **Tier 1 (Fenced Code Blocks)**: Parses ` ```tool_call `, ` ```tool_calls `, ` ```json `, or bare ` ``` ` blocks.\n  2. **Tier 2 (Tool Call Arrays)**: Extracts structured `\"tool_calls\": [...]` arrays embedded in output.\n  3. **Tier 3 (Unfenced / Broken Fences)**: Recovers missing opening backticks (e.g. `tool_call\\n{...}````).\n  4. **Tier 4 (Bare JSON Objects)**: Bracket-matched scanner for raw JSON objects with `name` and `arguments`/`args`/`input`.\n  - **Auto Syntax Healing**: Automatically cleans escaped markdown underscores (`subagent\\_type` → `subagent_type`), trailing commas, unquoted keys, and invalid escapes.\n  - **Framework Agnostic**: Natively normalizes tool call formats from Vercel AI SDK, ZCode, LangChain, and OpenAI SDKs (`toolCalls`, `input`, `toolName`, `toolCallId`).\n- **Reasoning & Thinking Models**: Full support for `<think>` thoughts and `reasoning_content` deltas in SSE streaming with an automatic tag closure state machine, as well as `reasoning_content` in non-streaming responses.\n- **Dynamic Model Discovery**: Automatically discovers available Gemini models (Flash, Pro, etc.) and capacity tiers directly from your web session.\n- **Image Proxy**: Built-in `/gemini-proxy/image` endpoint to safely render generated card images without CORS or anti-hotlinking issues.\n\n---\n\n### Installation\n\nInstall globally using **Bun** or **npm**:\n\n```bash\n# Using Bun\nbun i -g @8-/gemini-web-api\n\n# Using npm\nnpm i -g @8-/gemini-web-api\n```\n\nOr run instantly without installing:\n\n```bash\n# Using bunx\nbunx @8-/gemini-web-api\n\n# Using npx\nnpx @8-/gemini-web-api\n```\n\n---\n\n### Usage\n\n#### 1. Start the Server\n\nSimply run:\n\n```bash\ngemini-web-api\n```\n\nThe server will automatically:\n1. Detect your local Chrome / Brave / Edge cookies database.\n2. Read the encryption key from macOS Keychain.\n3. Decrypt your `__Secure-1PSID` and `__Secure-1PSIDTS` cookies.\n4. Discover available models from Gemini.\n5. Start listening on `http://127.0.0.1:7860`.\n\n#### 2. Optional Environment Variables\n\nIf you want to customize the port, add an authentication key, or enable thinking mode, set environment variables inline or in a `.env` file:\n\n```bash\n# Example: Custom port, API key, and thinking mode\nPORT=8000 API_KEY=sk-mysecret ENABLE_THINKING=true gemini-web-api\n```\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `PORT` | `7860` | Server listening port |\n| `HOST` | `127.0.0.1` | Server listening host |\n| `API_KEY` | *(empty)* | Optional Bearer API key for authorization |\n| `ENABLE_THINKING` | `false` | Enable reasoning thoughts (`<think>` blocks & `reasoning_content`) |\n| `SECURE_1PSID` | *(auto-detected)* | Manual override for `__Secure-1PSID` cookie (only needed if no browser is logged in) |\n| `SECURE_1PSIDTS` | *(auto-detected)* | Manual override for `__Secure-1PSIDTS` cookie |\n\n---\n\n### API Calling Examples\n\n#### 1. Streaming Chat (cURL)\n\n```bash\ncurl -N http://127.0.0.1:7860/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gemini-flash\",\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Explain quantum computing in one sentence.\"}\n    ],\n    \"stream\": true\n  }'\n```\n\n#### 2. Function Calling / Tool Calling (Python SDK)\n\n```python\nfrom openai import OpenAI\n\nclient = OpenAI(\n    base_url=\"http://127.0.0.1:7860/v1\",\n    api_key=\"none\"\n)\n\ntools = [\n    {\n        \"type\": \"function\",\n        \"function\": {\n            \"name\": \"get_weather\",\n            \"description\": \"Get current weather for a city.\",\n            \"parameters\": {\n                \"type\": \"object\",\n                \"properties\": {\n                    \"city\": {\"type\": \"string\"}\n                },\n                \"required\": [\"city\"]\n            }\n        }\n    }\n]\n\nresponse = client.chat.completions.create(\n    model=\"gemini-flash\",\n    messages=[{\"role\": \"user\", \"content\": \"What is the weather in Tokyo?\"}],\n    tools=tools,\n    tool_choice=\"auto\"\n)\n\nmessage = response.choices[0].message\nif message.tool_calls:\n    for tool_call in message.tool_calls:\n        print(f\"Tool: {tool_call.function.name}\")\n        print(f\"Arguments: {tool_call.function.arguments}\")\n```\n\n#### 3. Streaming Chat with Node.js SDK\n\n```javascript\nimport OpenAI from \"openai\";\n\nconst openai = new OpenAI({\n  baseURL: \"http://127.0.0.1:7860/v1\",\n  apiKey: \"none\",\n});\n\nconst stream = await openai.chat.completions.create({\n  model: \"gemini-flash\",\n  messages: [{ role: \"user\", content: \"Tell me a short joke.\" }],\n  stream: true,\n});\n\nfor await (const chunk of stream) {\n  process.stdout.write(chunk.choices[0]?.delta?.content || \"\");\n}\n```\n\n---\n\n<a id=\"简体中文\"></a>\n\n## 简体中文\n\n### 项目简介\n\n**`@8-/gemini-web-api`** 是一个极简的 Google Gemini Web 转 OpenAI 标准接口反向代理服务。\n\n**无需繁琐配置**：只需在日常使用的 Chrome（或 Brave、Edge）浏览器中登录过 [gemini.google.com](https://gemini.google.com)，程序启动时即可全自动探测浏览器 Cookie 数据库，通过 macOS Keychain 提取密钥并自动解密登录凭据，立即开始提供兼容 OpenAI 的 `/v1/chat/completions` 与 `/v1/models` 接口！\n\n### 核心亮点\n\n- **开箱即用，零手动配置**：自动探测 Chrome / Brave / Edge 浏览器会话，全自动解密并获取登录令牌，彻底告别手动抓包复制 Cookie 的烦恼！\n- **Bun 与 Node.js 双运行时支持**：在 **Bun** 下使用原生 `Bun.serve` 极速响应；在 **Node.js** (>= 22.5.0) 下利用内置 `node:sqlite` 与原生 Web Streams 同样流畅运行。\n- **零第三方外部依赖**：纯基于 Web 标准接口（`fetch`、`ReadableStream`、`crypto.subtle`）与运行时内置标准模块构建，零 `node_modules` 外部依赖！\n- **无缝替代 OpenAI 接口**：标准 `/v1/chat/completions` 与 `/v1/models` 路由，直接兼容 ChatGPT-Next-Web、LobeChat、Cherry Studio、Cline、Roo Code、Cursor、Aider 以及官方 OpenAI SDK。\n- **四级高鲁棒性 Function Calling / 工具调用引擎**：\n  1. **第一级（围栏代码块）**：精确解析 ` ```tool_call `、` ```tool_calls `、` ```json ` 或裸反引号代码块。\n  2. **第二级（数组提取）**：自动提取内嵌于回复中的 `\"tool_calls\": [...]` 结构体。\n  3. **第三级（缺失开头围栏容错）**：支持缺失开头反引号等残缺输出自愈（如 `tool_call\\n{...}````）。\n  4. **第四级（无围栏裸 JSON 深度探测）**：括号平衡算法精确提取包含 `name` 与 `arguments`/`args`/`input` 的独立 JSON 对象，游标防跳步确保多个紧邻调用不遗漏。\n  - **语法自动修复**：自动反转义 Markdown 下划线（`subagent\\_type` → `subagent_type`），智能修复未加引号的键名与尾随逗号。\n  - **框架协议泛化**：原生兼容 Vercel AI SDK、ZCode、LangChain 及各类 Agent 框架自定义字段（`toolCalls`、`input`、`toolName`、`toolCallId`）。\n- **深度思考与推理模式**：完整支持 `<think>` 思考标签与 SSE `reasoning_content` 流式字段传输，内置状态机保证思考标签严格闭合，且在非流式调用中完整保留思考链。\n- **动态模型列表发现**：启动时自动从 Gemini 网页端动态拉取已解锁的可用模型及配额层级。\n- **图片安全代理**：内置 `/gemini-proxy/image` 接口，解决 Google 生成图片防盗链和跨域展示问题。\n\n---\n\n### 安装方式\n\n通过 **Bun** 或 **npm** 全局安装：\n\n```bash\n# 使用 Bun 全局安装\nbun i -g @8-/gemini-web-api\n\n# 使用 npm 全局安装\nnpm i -g @8-/gemini-web-api\n```\n\n或者无需安装，直接使用 `bunx` / `npx` 即开即用：\n\n```bash\n# 使用 bunx\nbunx @8-/gemini-web-api\n\n# 使用 npx\nnpx @8-/gemini-web-api\n```\n\n---\n\n### 使用指南\n\n#### 1. 启动服务\n\n安装后直接在终端运行：\n\n```bash\ngemini-web-api\n```\n\n程序将全自动执行：\n1. 自动探测本地 Chrome、Brave、Edge 浏览器的 Cookie 存储路径；\n2. 自动从 macOS Keychain 安全读取加密密码并推导密钥；\n3. 解密 `__Secure-1PSID` 与 `__Secure-1PSIDTS` 凭据；\n4. 动态同步 Gemini 网页端模型配置；\n5. 在 `http://127.0.0.1:7860` 启动 OpenAI 兼容接口。\n\n#### 2. 可选环境变量配置\n\n如需自定义端口、设置访问密码或启用思考模式，可在命令行直接传入或在当前目录下创建 `.env` 文件：\n\n```bash\n# 示例：自定义端口 8000、密码及开启思考模式\nPORT=8000 API_KEY=sk-mysecret ENABLE_THINKING=true gemini-web-api\n```\n\n| 环境变量 | 默认值 | 说明 |\n| :--- | :--- | :--- |\n| `PORT` | `7860` | 服务的监听端口 |\n| `HOST` | `127.0.0.1` | 监听的主机地址 |\n| `API_KEY` | *(留空)* | 可选的 Bearer 访问密码鉴权 |\n| `ENABLE_THINKING` | `false` | 是否开启思考模式（输出 `<think>` 与 `reasoning_content`） |\n| `SECURE_1PSID` | *(自动探测)* | 手动指定 `__Secure-1PSID`（仅在未登录浏览器时需要） |\n| `SECURE_1PSIDTS` | *(自动探测)* | 手动指定 `__Secure-1PSIDTS` |\n\n---\n\n### 接口调用示例\n\n#### 1. cURL 流式对话调用\n\n```bash\ncurl -N http://127.0.0.1:7860/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gemini-flash\",\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"用一句话解释相对论\"}\n    ],\n    \"stream\": true\n  }'\n```\n\n#### 2. 工具调用 / Function Calling (Python SDK)\n\n```python\nfrom openai import OpenAI\n\nclient = OpenAI(\n    base_url=\"http://127.0.0.1:7860/v1\",\n    api_key=\"none\"  # 未设置 API_KEY 时可填任意字符串\n)\n\ntools = [\n    {\n        \"type\": \"function\",\n        \"function\": {\n            \"name\": \"get_weather\",\n            \"description\": \"查询指定城市的天气温度\",\n            \"parameters\": {\n                \"type\": \"object\",\n                \"properties\": {\n                    \"city\": {\"type\": \"string\"}\n                },\n                \"required\": [\"city\"]\n            }\n        }\n    }\n]\n\nresponse = client.chat.completions.create(\n    model=\"gemini-flash\",\n    messages=[{\"role\": \"user\", \"content\": \"查询东京的天气\"}],\n    tools=tools,\n    tool_choice=\"auto\"\n)\n\nmessage = response.choices[0].message\nif message.tool_calls:\n    for tool_call in message.tool_calls:\n        print(f\"触发工具: {tool_call.function.name}, 参数: {tool_call.function.arguments}\")\n```\n\n#### 3. Node.js 流式对话 (OpenAI SDK)\n\n```javascript\nimport OpenAI from \"openai\";\n\nconst openai = new OpenAI({\n  baseURL: \"http://127.0.0.1:7860/v1\",\n  apiKey: \"none\",\n});\n\nconst stream = await openai.chat.completions.create({\n  model: \"gemini-flash\",\n  messages: [{ role: \"user\", content: \"讲个笑话吧\" }],\n  stream: true,\n});\n\nfor await (const chunk of stream) {\n  process.stdout.write(chunk.choices[0]?.delta?.content || \"\");\n}\n```\n\n---\n\n### 开源协议\n\n本项目采用 [MIT License](LICENSE) 授权。\n","readmeFilename":"README.md"}