A lightweight Go gateway/proxy that exposes GitHub Copilot as OpenAI-compatible and Anthropic-compatible API endpoints, with an optional web dashboard.
Originally forked from whtsky/copilot2api, now maintained independently.
- OpenAI API Compatible:
/v1/chat/completions,/v1/responses,/v1/models - Anthropic API Compatible:
/v1/messages - Models Cache: 5-minute cache for
/v1/modelsand Anthropic model capability lookups - API Key Auth: Required key for all requests — safe to deploy beyond localhost
- Auto Authentication: GitHub Device Flow OAuth with automatic token refresh
- Streaming Support: Full SSE streaming for both OpenAI and Anthropic formats
- Direct Passthrough: Requests are forwarded as-is to the matching endpoint, with no cross-format translation
- Web Dashboard: Showing the live model catalog, enabled only when
COPILOTGW_WEB_*are configured
- Authenticates with GitHub via Device Flow OAuth
- Exchanges GitHub token for Copilot API token (auto-refreshes)
- Passthrough each request straight to the matching endpoint, OpenAI to
/chat/completionsor/responses; Anthropic to/v1/messages - Automatically detects API endpoint from token (Individual/Business/Enterprise)
- The gateway refuses to start without
COPILOTGW_API_KEYor cli flag-api-key. - Every request must present a matching key, so it is safe to expose beyond localhost.
- Both of these are accepted in headers:
Authorization: Bearer <key>orx-api-key: <key>. - The
/healthendpoint is unauthenticated for load balancer probes. - Credentials are stored in
~/.config/copilotgateway/credentials.json.
| Endpoint | Method | Description |
|---|---|---|
/v1/chat/completions |
POST | OpenAI Chat Completions (streaming & non-streaming) |
/v1/responses |
POST | OpenAI Responses API |
/v1/messages |
POST | Anthropic Messages API (streaming & non-streaming) |
/v1/models |
GET | List available models (5min cache) |
/health |
GET | Health check (unauthenticated) |
A login-protected page at / that shows the live model catalog: the latest generation of each model series with expandable per-model details (limits, capabilities, pricing), plus one-click copy of the endpoint URL and gateway API keys.
Disabled by default. It only exists when both COPILOTGW_WEB_USERNAME and COPILOTGW_WEB_PASSWORD are set, otherwise all web paths return 404 and the gateway behaves as a pure API gateway, exactly as before.
An API key is required for both ways — the gateway refuses to start without one. Any opaque string works; generate a strong one:
echo "sk-cgw-$(openssl rand -hex 32)"On first run, the gateway asks for GitHub Device Flow authorization — visit the URL, enter the code, and you are done; credentials persist afterwards:
🔐 GitHub Authentication Required
Please visit: https://github.com/login/device
Enter code: XXXX-XXXX
Waiting for authorization...
✅ Authentication successful!
Set the key via COPILOTGW_API_KEY. Since the container runs detached, the first-run device-flow prompt appears in docker logs -f copilotgateway.
1)Minimal — API-only gateway:
docker run -d --name copilotgateway --restart unless-stopped \
-p 127.0.0.1:7777:7777 \
-e COPILOTGW_API_KEY=<key1,key2,...> \
-v ~/.config/copilotgateway:/root/.config/copilotgateway \
ghcr.io/heyjiqingcode/copilotgateway:latest2)Full — with the web dashboard enabled:
docker run -d --name copilotgateway --restart unless-stopped \
-p 127.0.0.1:7777:7777 \
-e COPILOTGW_API_KEY=<key1,key2,...> \
-e COPILOTGW_WEB_USERNAME=admin \
-e COPILOTGW_WEB_PASSWORD=<your_web_password> \
-v ~/.config/copilotgateway:/root/.config/copilotgateway \
ghcr.io/heyjiqingcode/copilotgateway:latestSee Configuration for every available variable.
Download the archive for your OS/arch from Releases, extract, and run — same behavior as Docker. Web credentials are env-only by design (no CLI flags), so secrets never show up in ps output.
Pass the key via COPILOTGW_API_KEY or the -api-key flag. The first-run device-flow prompt appears right in your terminal — credentials are saved to ~/.config/copilotgateway (configurable via -token-dir), so later runs start without re-authenticating.
# example: macOS on Apple silicon
tar -xzf copilotgateway_*_darwin_arm64.tar.gz
# 1)API-only gateway
COPILOTGW_API_KEY=<your-secret-key> ./copilotgateway
# 2)with the web dashboard
COPILOTGW_API_KEY=<your-secret-key> \
COPILOTGW_WEB_USERNAME=admin \
COPILOTGW_WEB_PASSWORD=<your_web_password> \
./copilotgatewayThe CLI listens on
127.0.0.1:7777by default; pass-host 0.0.0.0to expose it beyond localhost.
All flags are listed in Configuration.
./copilotgateway [options]
-host string Server host (default "127.0.0.1")
-port int Server port (default 7777)
-token-dir string Token storage directory (default ~/.config/copilotgateway)
-api-key string Required API key(s), comma-separated (env: COPILOTGW_API_KEY)
-debug Enable debug logging
-version Show version and exit
CLI flags take precedence over environment variables.
| Variable | Description | Default |
|---|---|---|
COPILOTGW_API_KEY |
Required API key(s) for clients, comma-separated | none — required |
COPILOTGW_HOST |
Server host | 127.0.0.1 |
COPILOTGW_PORT |
Server port | 7777 |
COPILOTGW_TOKEN_DIR |
Token storage directory | ~/.config/copilotgateway |
COPILOTGW_DEBUG |
Enable debug logging (true/false, 1/0) |
false |
COPILOTGW_EDITOR_VERSION |
Spoofed editor version header | vscode/1.127.0 |
COPILOTGW_PLUGIN_VERSION |
Spoofed plugin version header | copilot-chat/0.55.0 |
COPILOTGW_CHAT_USER_AGENT |
Spoofed Copilot Chat User-Agent | GitHubCopilotChat/0.55.0 |
COPILOTGW_API_VERSION |
GitHub Copilot API version header | 2026-06-01 |
COPILOTGW_WEB_USERNAME |
Web dashboard login username (dashboard enabled only when username & password are both set) | unset — dashboard disabled |
COPILOTGW_WEB_PASSWORD |
Web dashboard login password | unset — dashboard disabled |
COPILOTGW_WEB_SESSION_HOURS |
Web dashboard session lifetime (hours) | 24 |
Environment variables are used as defaults when flags are not provided
Newer models on Copilot (e.g. Opus 4.6/4.7/4.8, Sonnet 4.6/5, gpt-5.5/5.6) expose their context limits through the Copilot /models catalog on the base model ID. There are no -1m model variants to append; send the model ID as-is.
The /v1/models gateway uses VS Code-style model metadata headers (model-access) and Copilot API version 2026-06-01, matching the model catalog shape VS Code currently uses for long-context metadata. If VS Code shows a larger context window than this gateway, check that COPILOTGW_API_VERSION is not overridden to an older value.
Add to ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:7777",
"ANTHROPIC_AUTH_TOKEN": "your-secret-key",
"ANTHROPIC_MODEL": "claude-opus-4.8",
"ANTHROPIC_DEFAULT_FABLE_MODEL": "claude-fable-5",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4.8",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-5",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4.5",
"CLAUDE_CODE_SUBAGENT_MODEL": "claude-opus-4.8",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
},
"permissions": {
"deny": [
"WebSearch"
]
}
}Add to ~/.codex/config.toml. With env_key, Codex reads the gateway key from an environment variable instead of storing it in the config file — export it before launching: export COPILOTGATEWAY_API_KEY=<your-secret-key>.
model = "gpt-5.6-sol"
model_provider = "copilotgateway"
model_reasoning_effort = "xhigh"
model_context_window = 1050000
web_search = "disabled"
[model_providers.copilotgateway]
name = "copilotgateway"
base_url = "http://127.0.0.1:7777/v1"
wire_api = "responses"
env_key = "COPILOTGATEWAY_API_KEY"