copilot2api
A lightweight Go proxy that exposes GitHub Copilot as both OpenAI-compatible and Anthropic-compatible API endpoints.
Features
- OpenAI API Compatible:
/v1/chat/completions, /v1/models, /v1/embeddings, /v1/responses
- Anthropic API Compatible:
/v1/messages
- Streaming Support: Full SSE streaming for both OpenAI and Anthropic formats
- Anthropic Routing: Uses native
/v1/messages when the model supports it, otherwise routes via /responses or /chat/completions
- Auto Authentication: GitHub Device Flow OAuth with automatic token refresh
- Usage Monitoring: Built-in
/usage endpoint for quota tracking
- Models Cache: 5-minute cache for
/v1/models and Anthropic model capability lookups
Quick Start
# Build from source (requires Go 1.26+)
go build -o copilot2api .
# Start the proxy
./copilot2api
First run will prompt GitHub Device Flow authentication:
🔐 GitHub Authentication Required
Please visit: https://github.com/login/device
Enter code: XXXX-XXXX
Waiting for authorization...
✅ Authentication successful!
Server starts on http://127.0.0.1:7777 by default.
Security
⚠️ This proxy is designed for local development only.
- Does not implement API key validation — any request is accepted
- Do not expose publicly — it becomes an open proxy consuming your Copilot quota
- Credentials are stored in
~/.config/copilot2api/credentials.json
Usage with Claude Code
Add to ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:7777",
"ANTHROPIC_API_KEY": "dummy",
"ANTHROPIC_MODEL": "claude-opus-4.6",
"ANTHROPIC_SMALL_FAST_MODEL": "claude-haiku-4.5",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
},
"permissions": {
"deny": [
"WebSearch"
]
}
}
Usage with Codex
Add to ~/.codex/config.toml:
model = "gpt-5.3-codex"
model_provider = "copilot2api"
model_reasoning_effort = "high"
web_search = "disabled"
[model_providers.copilot2api]
name = "copilot2api"
base_url = "http://127.0.0.1:7777/v1"
wire_api = "responses"
api_key = "dummy"
Usage with curl
# OpenAI chat completion
curl http://localhost:7777/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.3-codex","messages":[{"role":"user","content":"Hello!"}]}'
# Anthropic message
curl http://localhost:7777/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: dummy" \
-d '{"model":"claude-sonnet-4.6","messages":[{"role":"user","content":"Hello!"}],"max_tokens":100}'
# List models
curl http://localhost:7777/v1/models
# Check usage/quota
curl http://localhost:7777/usage
Usage with SDKs
OpenAI Python SDK
import openai
client = openai.OpenAI(
api_key="dummy",
base_url="http://127.0.0.1:7777/v1"
)
response = client.chat.completions.create(
model="gpt-5.3-codex",
messages=[{"role": "user", "content": "Hello!"}]
)
Anthropic Python SDK
import anthropic
client = anthropic.Anthropic(
api_key="dummy",
base_url="http://127.0.0.1:7777"
)
message = client.messages.create(
model="claude-sonnet-4.6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
API Endpoints
| Endpoint |
Method |
Description |
/v1/chat/completions |
POST |
OpenAI Chat Completions (streaming & non-streaming) |
/v1/responses |
POST |
OpenAI Responses API |
/v1/models |
GET |
List available models (5min cache) |
/v1/embeddings |
POST |
Generate embeddings (string or array input) |
/v1/messages |
POST |
Anthropic Messages API (streaming & non-streaming) |
/usage |
GET |
Copilot usage and quota info |
Configuration
CLI Flags
./copilot2api [options]
-host string Server host (default "127.0.0.1")
-port int Server port (default 7777)
-token-dir string Token storage directory (default ~/.config/copilot2api)
-debug Enable debug logging
-version Show version and exit
Environment Variables
Environment variables are used as defaults when flags are not provided:
| Variable |
Description |
Default |
COPILOT2API_HOST |
Server host |
127.0.0.1 |
COPILOT2API_PORT |
Server port |
7777 |
COPILOT2API_TOKEN_DIR |
Token storage directory |
~/.config/copilot2api |
COPILOT2API_DEBUG |
Enable debug logging (true/false, 1/0) |
false |
CLI flags take precedence over environment variables.
Docker
docker run -it -p 7777:7777 \
-v ~/.config/copilot2api:/root/.config/copilot2api \
ghcr.io/whtsky/copilot2api
The Docker image defaults to COPILOT2API_HOST=0.0.0.0 so port forwarding works out of the box. The volume mount persists your GitHub credentials across container restarts. First run will prompt Device Flow authentication.
To use a custom port:
docker run -it -p 8080:8080 \
-v ~/.config/copilot2api:/root/.config/copilot2api \
-e COPILOT2API_PORT=8080 \
ghcr.io/whtsky/copilot2api
⚠️ The Docker image listens on all interfaces by default. Only publish the port to 127.0.0.1 (e.g. -p 127.0.0.1:7777:7777) unless you know what you're doing.
How It Works
- Authenticates with GitHub via Device Flow OAuth
- Exchanges GitHub token for Copilot API token (auto-refreshes)
- Proxies OpenAI-format requests directly to Copilot API
- Routes Anthropic Messages requests by model capabilities (native
/v1/messages, translated /responses, or translated /chat/completions)
- Automatically detects API endpoint from token (Individual/Business/Enterprise)
Development
go test ./... # Run tests
go build -o copilot2api . # Build
License
MIT