Skip to content

foxswat/opencode-qwen-auth

OpenCode Qwen Auth Plugin

npm version npm downloads CI License: Apache-2.0 Built with Bun

Qwen OAuth authentication plugin for OpenCode with multi-account rotation, proactive token refresh, and automatic API translation.

Features

  • Device Flow OAuth - PKCE-secured authentication, works in headless/CI environments
  • Multi-Account Support - Store and rotate between multiple Qwen accounts
  • Proactive Token Refresh - Automatically refresh tokens before expiry
  • Rate Limit Handling - Detects 429 responses, rotates accounts, respects retry-after
  • API Translation - Bridges OpenAI Responses API ↔ Chat Completions API
  • Streaming Support - Full SSE transformation for real-time responses

Installation

Let an LLM Do It

Paste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):

Install the opencode-qwen-auth plugin by following: https://raw.githubusercontent.com/foxswat/opencode-qwen-auth/main/README.md

Quick Install (Recommended)

Run one command to automatically configure OpenCode:

bunx opencode-qwen-auth install
# or
npx opencode-qwen-auth install

This adds the plugin and Qwen provider configuration to your opencode.json.

Manual Installation

If you prefer manual setup:

# Using Bun
bun add opencode-qwen-auth

# Using npm
npm install opencode-qwen-auth

Then add to your opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-qwen-auth"],
  "provider": {
    "qwen": {
      "npm": "@ai-sdk/openai",
      "options": {
        "baseURL": "https://portal.qwen.ai/v1",
        "compatibility": "strict"
      },
      "models": {
        "qwen3-coder-plus": { "contextWindow": 1048576 },
        "qwen3-vl-plus": { "contextWindow": 262144, "attachment": true }
      }
    }
  }
}

Quick Start

  1. Start OpenCode in your project directory:

    opencode
  2. Authenticate with Qwen:

    /auth
    

    Select Qwen OAuth and follow the device flow instructions.

  3. Start coding with Qwen models:

    /model qwen/qwen3-coder-plus
    

Configuration

No configuration required. The plugin works out of the box with sensible defaults.

To customize behavior, create .opencode/qwen.json (project) or ~/.config/opencode/qwen.json (user-level) with only the options you want to override:

{
  // API endpoint (default: https://portal.qwen.ai/v1)
  "base_url": "https://portal.qwen.ai/v1",

  // OAuth client ID (default: built-in)
  "client_id": "your-client-id",

  // OAuth server URL (default: https://chat.qwen.ai)
  "oauth_base_url": "https://chat.qwen.ai",

  // Account rotation: "round-robin" or "sequential" (default: round-robin)
  "rotation_strategy": "sequential",

  // Refresh tokens before expiry (default: true)
  "proactive_refresh": true,

  // Seconds before expiry to trigger refresh (default: 300)
  "refresh_window_seconds": 300,

  // Maximum wait time when rate limited (default: 300)
  "max_rate_limit_wait_seconds": 300,

  // Suppress informational messages (default: false)
  "quiet_mode": true
}

Configuration Options

Option Default Description
base_url https://portal.qwen.ai/v1 API endpoint for Qwen requests
client_id (built-in) OAuth client ID
oauth_base_url https://chat.qwen.ai OAuth server URL
rotation_strategy round-robin Account rotation: round-robin or sequential
proactive_refresh true Refresh tokens before expiry
refresh_window_seconds 300 Seconds before expiry to trigger refresh
max_rate_limit_wait_seconds 300 Maximum wait time when rate limited
quiet_mode false Suppress informational messages

Environment Variables

All options can be overridden via environment variables:

  • QWEN_API_BASE_URL
  • QWEN_OAUTH_CLIENT_ID
  • QWEN_OAUTH_BASE_URL
  • QWEN_ROTATION_STRATEGY
  • QWEN_PROACTIVE_REFRESH
  • QWEN_REFRESH_WINDOW_SECONDS
  • QWEN_MAX_RATE_LIMIT_WAIT_SECONDS
  • QWEN_QUIET_MODE

Models

Available via OAuth

Model Context Window Features
qwen3-coder-plus 1M tokens Optimized for coding tasks
qwen3-vl-plus 256K tokens Vision + language multimodal

Multi-Account Rotation

Add multiple accounts for higher throughput:

  1. Run /auth and complete the first login
  2. Run /auth again to add additional accounts
  3. The plugin automatically rotates between accounts

Rotation Strategies

  • round-robin: Cycles through accounts on each request
  • sequential: Uses one account until rate limited, then switches

How It Works

This plugin bridges OpenCode's Responses API format with Qwen's Chat Completions API:

OpenCode → [Responses API] → Plugin → [Chat Completions] → Qwen
                                ↓
OpenCode ← [Responses API] ← Plugin ← [Chat Completions] ← Qwen

Request Transformation

Responses API Chat Completions API
input messages
input_text text content type
input_image image_url content type
instructions System message
max_output_tokens max_tokens

Response Transformation (Streaming)

Converts SSE events from Chat Completions to Responses API format:

  • response.created
  • response.output_item.added
  • response.content_part.added
  • response.output_text.delta
  • response.completed

Storage Locations

Data Location
User config ~/.config/opencode/qwen.json
Project config .opencode/qwen.json
Account tokens ~/.config/opencode/qwen-auth-accounts.json

Security Note: Tokens are stored with restricted permissions (0600). Ensure appropriate filesystem security.

Troubleshooting

Authentication Issues

"invalid_grant" error

  • Your refresh token has expired. Run /auth to re-authenticate.

Device code expired

  • Complete the browser login within 5 minutes of starting /auth.

Rate Limiting

Frequent 429 errors

  • Add more accounts with /auth
  • Increase max_rate_limit_wait_seconds in config

Reset Plugin State

To start fresh, delete the accounts file:

rm ~/.config/opencode/qwen-auth-accounts.json

Development

This project uses Bun for development.

Prerequisites

  • Bun 1.0+ (recommended)
  • Node.js 20+ (for npm compatibility)

Getting Started

# Install dependencies
bun install

# Build
bun run build

# Run tests
bun test

# Run tests in watch mode
bun test --watch

# Run e2e test (requires authenticated Qwen account)
bun run test:e2e

# Link for local testing
bun link

Using npm

The project also works with npm:

npm install
npm run build
npm test

Known Limitations

  • Audio input (input_audio) is not supported by Qwen and is converted to placeholder text

License

Apache-2.0

About

Qwen OAuth authentication plugin for OpenCode with multi-account rotation and proactive token refresh

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published