Asia/Shanghai
February 10, 2026

OpenCode Provider Setup: Every Pitfall I Hit

OpenCode Provider 配置:我踩过的每一个坑

Mingjian Shao
OpenCode Provider Setup: Every Pitfall I Hit
How I configured OpenCode with 5 AI providers — getting Claude Opus 4.6, Gemini 3 Pro, and 6 Chinese models all for $0/month.
I use OpenCode as my primary AI coding tool — a terminal-based, extensible LLM coding agent. One thing I love about it is the provider system: you can configure multiple AI backends and switch between them on the fly.My target setup: Claude Opus 4.6, Gemini 3 Pro, Gemini Flash, a bunch of Chinese models (DeepSeek, Kimi, GLM), and local models via LM Studio — all without paying API fees.Here's how I got there, and every pitfall I hit along the way.
ProviderSDKAuthModelsCost
Antigravity (OAuth)@ai-sdk/googleGoogle OAuthGemini Pro/Flash + ClaudeFree (Google Cloud quota)
Gemini (API Key)@ai-sdk/googleAPI KeyFlash onlyFree tier
Ark Coding Plan@ai-sdk/openai-compatibleAPI Key6 Chinese modelsFree (Volcengine plan)
Claude (Relay)@ai-sdk/anthropicAPI KeyOpus/Sonnet/HaikuRelay credits
LM StudioOpenAI-compatibleNoneLocal modelsFree (local)
Antigravity is an OpenCode plugin that routes requests through Google Cloud's Code Assist API using OAuth tokens. This means you get access to Claude and Gemini Pro models for free — they're covered under Google Cloud's code assistance quota.The setup is just an OAuth flow:
Bash
opencode auth login google
# Opens browser → Google account → authorize → done
The plugin supports multi-account rotation, so if one account hits rate limits, it automatically switches to the next.In opencode.json:
Json
"google": {
  "id": "google",
  "name": "🪐 Antigravity",
  "api": "@ai-sdk/google",
  "models": {
    "antigravity-gemini-3-pro": {
      "name": "💎 Gemini 3 Pro (AG)"
    },
    "antigravity-gemini-3-flash": {
      "name": "⚡ Gemini 3 Flash (AG)"
    },
    "antigravity-claude-opus-4-6-thinking": {
      "name": "🟣 Claude Opus 4.6 (AG)"
    }
  },
  "whitelist": [
    "antigravity-gemini-3-pro",
    "antigravity-gemini-3-flash",
    "antigravity-claude-opus-4-6-thinking"
  ]
}
Key gotcha: model IDs must be prefixed with antigravity- to avoid conflicts with direct API access.
Google gives a free tier for Gemini API keys — but only for Flash models. Pro models return 429 errors on the free tier, even if you have a Google One AI Premium subscription.
Trap: Google Student Pro / Google One AI Premium gives you unlimited Gemini access in the web app — but provides zero free API quota for Pro models. Only Flash has free API access.
Since Antigravity already handles Pro, I set up a separate gemini provider just for Flash as a fallback:
Json
"gemini": {
  "id": "gemini",
  "name": "💎 Gemini",
  "api": "@ai-sdk/google",
  "apiKey": "AIzaSy...",
  "models": {
    "gemini-2.5-flash": { "name": "⚡ Gemini 2.5 Flash" },
    "gemini-3-flash-preview": { "name": "⚡ Gemini 3 Flash Preview" }
  }
}
Key gotcha: Antigravity hijacks all @ai-sdk/google requests by default. Having a separate provider with its own apiKey field bypasses this — the API key takes precedence over OAuth routing.
Volcengine (ByteDance's cloud) offers a Coding Plan with free access to multiple Chinese LLMs. But it has a completely separate API from regular Volcengine Ark.
Regular ArkCoding Plan
SDK@ai-sdk/openai@ai-sdk/openai-compatible
Endpoint/api/v3/api/coding/v3
API KeyRegular keyCoding Plan key
These are not interchangeable. Wrong SDK + wrong endpoint = silent failures.
Json
"ark-coding": {
  "id": "ark-coding",
  "name": "🌋 Ark Coding Plan",
  "api": "@ai-sdk/openai-compatible",
  "baseURL": "https://ark.cn-beijing.volces.com/api/coding/v3",
  "apiKey": "your-coding-plan-key",
  "models": {
    "ark-code-latest": { "name": "🤖 Auto Router" },
    "doubao-seed-code": { "name": "🫘 Doubao Seed Code" },
    "kimi-k2.5": { "name": "🌙 Kimi K2.5" },
    "deepseek-v3.2": { "name": "🐋 DeepSeek V3.2" },
    "kimi-k2-thinking": { "name": "🌙 Kimi K2 Thinking" }
  }
}
After adding all these providers, my model picker showed 26 models instead of the 5 I configured. Why?OpenCode merges your config with data from models.dev — a remote model registry. Your custom models are appended to the registry data, not replaced. So every Google model, every Anthropic model from the registry gets added too.The fix: whitelist.
Json
"google": {
  "whitelist": [
    "antigravity-gemini-3-pro",
    "antigravity-gemini-3-flash",
    "antigravity-claude-opus-4-6-thinking"
  ],
  "models": { ... }
}
Only whitelisted model IDs survive the merge. Every custom provider needs this, otherwise models.dev data floods your picker.There's also a blacklist option (exclude specific models). They're mutually exclusive — pick one.Pro tip: Set OPENCODE_DISABLE_MODELS_FETCH=1 in your shell env to skip the remote fetch entirely. Then clear the cache:
Bash
rm ~/.cache/opencode/models.json
This one bit me hard. Gemini's API doesn't support several JSON Schema keywords that MCP tool schemas commonly use:
  • anyOf / oneOf
  • $ref / $defs
  • const
OpenCode has a sanitizeGemini() function that's supposed to flatten schemas, but it missed these cases. The result: Gemini crashes when calling tools from Notion MCP (66 violations), Memory MCP, and Lark MCP.I submitted PR #12911 to fix this by:
  • Resolving $ref → inline definitions
  • Flattening anyOf/oneOf → first non-null option
  • Converting constenum: [value]
Workaround until merged: use Antigravity or Claude providers when calling complex MCP tools. The Gemini API key provider works fine for tools with simple schemas (Obsidian, Filesystem, etc).
OpenCode runs as a persistent server (opencode serve --port 4096). I manage it via macOS LaunchAgent + shell aliases.One subtle bug I hit: after migrating OpenCode from a self-managed binary (~/.opencode/bin/opencode) to Homebrew (/opt/homebrew/bin/opencode), the LaunchAgent plist still pointed to the old path. The server silently failed to start, and my o alias fell back to starting a fresh process every time — making restarts lose all sessions.Shell aliases that use port probing instead of process detection:
Bash
# Attach to server (start if needed)
alias o='...'  # polls curl -sf http://127.0.0.1:4096

# Restart via LaunchAgent
function orestart() {
    ostop
    launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.opencode.server.plist
    # Wait for port ready (up to 10s)
    for i in $(seq 1 20); do
        curl -sf http://127.0.0.1:4096 >/dev/null 2>&1 && break
        sleep 0.5
    done
}
Why port probing > pgrep? Because a process existing doesn't mean the port is ready. The 0.5s×20 loop ensures you only attach after the server is actually accepting connections.
5 providers, 20+ models, $0/month:
Text
🔮 Antigravity   → Claude Opus 4.6, Gemini 3 Pro/Flash (free via OAuth)
💎 Gemini API     → Gemini Flash (free tier)
🌋 Ark Coding     → DeepSeek, Kimi, Doubao, GLM (free plan)
🟣 Claude Relay   → Full Claude lineup (relay credits)
🖥️ LM Studio     → Qwen, Codestral, etc. (local)
The model picker is clean (whitelist), MCP tools work (schema fix pending), and server restarts are reliable (port-based health checks).If you're using OpenCode and want a similar setup, the full config is on my experience doc — or just ask in the OpenCode Discord.
我把 OpenCode 配了 5 个 AI Provider——Claude Opus 4.6、Gemini 3 Pro、6 个国产模型,月费 $0。
我日常用 OpenCode 写代码——终端下的 AI coding agent,最大的优势就是 provider 系统:可以配多个 AI 后端,随时切换。我的目标:Claude Opus 4.6Gemini 3 ProGemini Flash、一堆国产模型(DeepSeek、Kimi、GLM),再加上 LM Studio 本地模型——全白嫖。以下是完整配置过程,以及一路踩过的每个坑。
ProviderSDK认证方式模型费用
Antigravity (OAuth)@ai-sdk/googleGoogle OAuthGemini Pro/Flash + Claude免费
Gemini (API Key)@ai-sdk/googleAPI Key仅 Flash免费额度
Ark Coding Plan@ai-sdk/openai-compatibleAPI Key6 个国产模型免费计划
Claude (Relay)@ai-sdk/anthropicAPI KeyOpus/Sonnet/HaikuRelay 积分
LM StudioOpenAI 兼容无需认证本地模型免费
Antigravity 是 OpenCode 的一个插件,通过 Google Cloud 的 Code Assist API 做 OAuth 路由。等于说 Claude 和 Gemini Pro 模型都走的 Google Cloud 代码辅助额度——免费设置就一个 OAuth 流程:
Bash
opencode auth login google
# 弹浏览器 → 选 Google 账号 → 授权 → 完事
还支持多账号轮转,一个账号到额度了自动切到下一个。:model ID 必须加 antigravity- 前缀,不然会跟 API key 直接访问冲突。
Google 的 Gemini API key 有免费额度,但只给 Flash 模型用。Pro 模型在免费额度下直接返回 429。
大坑:就算你开了 Google One AI Premium 或 Google Student Pro 订阅,那也只是 网页版 无限用——API 的 Pro 模型没有免费额度。只有 Flash 有。
既然 Antigravity 已经搞定了 Pro,我就单独建了一个 gemini provider 只跑 Flash 做备用:
Json
"gemini": {
  "id": "gemini",
  "name": "💎 Gemini (API Key Free)",
  "api": "@ai-sdk/google",
  "apiKey": "AIzaSy...",
  "models": {
    "gemini-2.5-flash": { "name": "⚡ Gemini 2.5 Flash" },
    "gemini-3-flash-preview": { "name": "⚡ Gemini 3 Flash Preview" }
  }
}
:Antigravity 默认会劫持所有 @ai-sdk/google 的请求。带了 apiKey 字段的 provider 会绕过这个劫持——API key 优先级高于 OAuth 路由。
火山引擎有个 Coding Plan,可以免费用多个国产大模型。但它跟普通 Ark API 是完全独立的两套体系
普通 ArkCoding Plan
SDK@ai-sdk/openai@ai-sdk/openai-compatible
Endpoint/api/v3/api/coding/v3
API Key普通 keyCoding Plan key
三样东西全不通用。SDK 用错了、endpoint 用错了,不报错,就是不返回结果。
Json
"ark-coding": {
  "id": "ark-coding",
  "name": "🌋 Ark Coding Plan",
  "api": "@ai-sdk/openai-compatible",
  "baseURL": "https://ark.cn-beijing.volces.com/api/coding/v3",
  "apiKey": "your-coding-plan-key",
  "models": {
    "ark-code-latest": { "name": "🤖 Auto Router" },
    "doubao-seed-code": { "name": "🫘 Doubao Seed Code" },
    "kimi-k2.5": { "name": "🌙 Kimi K2.5" },
    "deepseek-v3.2": { "name": "🐋 DeepSeek V3.2" }
  }
}
配完所有 provider 后,模型选择器里冒出来 26 个模型,但我只配了 5 个。为啥?OpenCode 会把你的配置跟 models.dev 的远程模型注册表深度合并。你自定义的模型是追加上去的,不是替换。所以 Google 的所有模型、Anthropic 的所有模型全灌进来了。解决方法:whitelist
Json
"google": {
  "whitelist": [
    "antigravity-gemini-3-pro",
    "antigravity-gemini-3-flash",
    "antigravity-claude-opus-4-6-thinking"
  ]
}
只有 whitelist 里的 model ID 才会保留。每个自定义 provider 都建议加,不然 models.dev 有这个 provider 的数据就会全量灌入。小技巧:在 shell 环境变量里设 OPENCODE_DISABLE_MODELS_FETCH=1 可以直接跳过远程拉取。再清一下缓存:
Bash
rm ~/.cache/opencode/models.json
这个坑比较深。Gemini 的 API 不支持 JSON Schema 里的好几个常用关键字:
  • anyOf / oneOf
  • $ref / $defs
  • const
OpenCode 有个 sanitizeGemini() 函数负责拍平 schema,但漏掉了这些。结果就是 Gemini 调 Notion MCP(66 处违规)、Memory MCP、飞书 MCP 的工具时直接崩。我提了 PR #12911 来修这个:
  • 解析 $ref → 内联展开
  • anyOf/oneOf → 取第一个非 null 选项
  • const → 转成 enum: [value]
临时方案:用 Antigravity 或 Claude provider 来调用复杂 MCP 工具。Gemini API key provider 只用来调简单工具(Obsidian、Filesystem 等)。
OpenCode 以持久 server 模式运行(opencode serve --port 4096),我用 macOS LaunchAgent + shell alias 来管理。一个隐蔽 bug:我把 OpenCode 从自管理 binary(~/.opencode/bin/opencode)迁到了 Homebrew(/opt/homebrew/bin/opencode),但 LaunchAgent plist 还指着旧路径。server 启动静默失败,我的 o alias 每次都回退到启一个新进程——导致重启后丢失所有 session。Shell alias 用端口探测而不是进程检测:
Bash
# 等端口就绪(最多 10 秒)
for i in $(seq 1 20); do
    curl -sf http://127.0.0.1:4096 >/dev/null 2>&1 && break
    sleep 0.5
done
为什么端口探测 > pgrep?因为进程在不代表端口就绪。0.5 秒 ×20 的循环确保 attach 时 server 真的已经能接请求了。
5 个 provider,20+ 个模型,月费 $0:
Text
🔮 Antigravity   → Claude Opus 4.6, Gemini 3 Pro/Flash (OAuth 白嫖)
💎 Gemini API     → Gemini Flash (免费额度)
🌋 Ark Coding     → DeepSeek, Kimi, Doubao, GLM (免费计划)
🟣 Claude Relay   → 全系列 Claude (relay 积分)
🖥️ LM Studio     → Qwen, Codestral 等 (本地)
模型选择器干净了(whitelist),MCP 工具能用了(schema 修复待合并),server 重启也靠谱了(基于端口的健康检查)。如果你也在用 OpenCode 想搞类似的配置,完整 config 在我的 GitHub 上——或者直接去 OpenCode Discord 问。
Share this post:
Enjoy this post? Subscribe via RSS: English | 中文