OpenCode v2 plugin that automatically rotates provider API keys on rate limits and quota errors.
Automatically swaps to the next saved key when OpenCode encounters rate limits (429), quota exhaustion, or resource errors during sessions.
- Automatic rotation — detects rate-limit and quota errors and swaps to the next available key on retry
- OpenCode v2 plugin — subscribes to public session events with one native v2 entrypoint
- Persistent storage — keys and rotation logs stored in the XDG data directory
- Configurable — customize rotation patterns via a sidecar config
- Secure — transactional SQLite writes, restrictive permissions, and credential log sanitization
npx -y @dmmop/opencode-key-rotator initOr install it globally:
npm install -g @dmmop/opencode-key-rotator
opencode-key-rotator initOpenCode runs the plugin with Bun and does not need additional flags. Node.js 22.5 or newer is also supported. In Node.js 22.5 through 22.12, node:sqlite is experimental: the installed opencode-key-rotator CLI enables --experimental-sqlite through its shebang, while direct package imports require:
NODE_OPTIONS=--experimental-sqlite node your-script.mjsNode.js 22.13 and newer do not require this option.
Run the init command to register both OpenCode V2 entrypoints and create a default sidecar config:
npx -y @dmmop/opencode-key-rotator initThe server plugin and local TUI plugin use separate OpenCode V2 configuration files. Add both entries, then restart OpenCode:
opencode.json:
cli.json:
{
"plugins": ["opencode-key-rotator/tui"],
}init creates or updates ~/.config/opencode/opencode.json, ~/.config/opencode/cli.json, and ~/.config/opencode/opencode-key-rotator.json idempotently. Use --config-dir to target another OpenCode config directory. A direct path such as ./dist/tui.js is only needed when developing the plugin locally.
npx -y @dmmop/opencode-key-rotator uninstallSaved keys and rotation logs are preserved on removal.
opencode-key-rotator init [--config-dir <dir>]
opencode-key-rotator uninstall [--config-dir <dir>]
opencode-key-rotator switch [--provider <id>] [--alias <alias>] [--data-dir <dir>]
opencode-key-rotator manage [--provider <id>] [--data-dir <dir>]
opencode-key-rotator status [--provider <id>] [--data-dir <dir>]
Use opencode-key-rotator switch for an interactive provider and alias selector. Pass --provider and --alias to use it non-interactively.
Use opencode-key-rotator manage for an interactive local workflow that saves the current credential, switches aliases, renames aliases, and deletes inactive aliases. It does not use the agent.
Use opencode-key-rotator status to list aliases, synchronization health, and the latest automatic rotation recorded in rotation.log.jsonl.
The server only translates OpenCode events. Rotation policy, cooldowns, switching, and automatic rotation logs live in rotation.ts, while SQLite CRUD lives in key-store.ts; the CLI and TUI adapter call the same core operations.
The ./tui adapter registers /key-save, /key-switch, and /key-status. It contains only TUI registration and rendering, and calls the same core operations.
Create a sidecar config file at ~/.config/opencode/opencode-key-rotator.json:
{
"rotation": {
"enabled": true,
"patterns": ["\\b429\\b", "rate\\s*limit", "quota", "resource exhausted", "usage limit", "insufficient quota"]
}
}The config file supports JSONC (comments and trailing commas). Resolution order:
${configDir}/opencode-key-rotator.json- Built-in defaults
- The plugin handles
session.retry.scheduledevents and evaluates every retry whose status is 429 or whose message matches the configured patterns. session.erroris a fallback and rotates on HTTP 429 or matching messages.- The provider comes from the event payload or the session model.
- If at least two keys are saved for the provider, the plugin switches to the next alias in a round-robin cycle.
- If a rotated key fails on the next attempt, that alias enters a 2-minute cooldown and is skipped during subsequent rotations.
- Before switching, the current credentials are saved under the previous alias.
- Every decision is recorded in
~/.local/share/opencode/keys/rotation.log.jsonl.
~/.local/share/opencode/
opencode-next.db # OpenCode credentials plus plugin alias metadata
keys/
rotation.log.jsonl # Rotation decisions (JSON Lines)
| Symptom | Cause | Fix |
|---|---|---|
Provider unknown |
The v2 event did not expose a provider ID | Check the provider event data |
No fallback key |
Only one key is saved for the provider | Save another alias |
All keys cooling down |
All saved aliases are in cooldown after failed attempts | Wait 2 minutes or save additional aliases |
npm install
npm run typecheck
npm run build
npm test
npm run formatA maintainer can trigger a fully automated release from GitHub Actions:
- Go to Actions → Release → Run workflow
- Choose
patch,minor, ormajor - The workflow will:
- Run the full test suite
- Bump the version in
package.json - Create and push a Git tag
- Create a GitHub Release with auto-generated notes
- Publish the package to npm
MIT
{ "plugins": ["opencode-key-rotator"], }