Expose GitHub Copilot as an OpenAI, Anthropic, and Gemini compatible API Built with Go + Vue 3, single binary with embedded WebUI, zero external runtime dependencies
- OpenAI-compatible proxy endpoint at
http://localhost:15432/v1/chat/completions - Anthropic Messages API compatibility at
http://localhost:15432/v1/messages - Gemini API compatibility at
http://localhost:15432/v1beta/models/{model}:generateContent - Single binary — Go backend with embedded Vue 3 + Naive UI frontend via
go:embed - AES-GCM encrypted token storage using machine-specific key derivation, no system keyring required
- Multi-account support — add and switch between multiple GitHub accounts via WebUI
- Request statistics and real-time quota display
- Streaming support with proper SSE handling
- Cross-platform: Windows, macOS, Linux (including headless servers)
git clone https://github.com/Open-Copilot-Proxy/Copilot_Proxy.git
cd Copilot_Proxy
# Build frontend
cd web && npm install && npm run build && cd ..
# Build Go binary
go build -o copilot-proxy ./cmd/copilot-proxy
# Run
./copilot-proxy
Or use the Makefile:
make build # builds frontend + Go binary in one step
On macOS / Linux:
go build -o copilot-proxy ./cmd/copilot-proxy
chmod +x ./copilot-proxy
./copilot-proxy
On Windows:
go build -o copilot-proxy.exe ./cmd/copilot-proxy
.\copilot-proxy.exe
Then open http://localhost:15432/ui/ in your browser
./copilot-proxy serve
# Or just run without arguments
./copilot-proxyThe server starts immediately without blocking on authorization If a saved token exists, it refreshes automatically If no token, the WebUI shows a login page — complete GitHub authorization from the browser
copilot-proxy # Alias for `serve`
copilot-proxy serve # Start proxy server
copilot-proxy login # Run GitHub device authorization in terminal
copilot-proxy logout # Remove current account
copilot-proxy config show # Print effective configuration
copilot-proxy config path # Print config file location
copilot-proxy --config <path> # Use custom config file- Start the server:
./copilot-proxy - Open the WebUI at
http://localhost:15432/ui/ - In the WebUI, click 添加 GitHub 账号 to start device authorization
- Copy the verification code and open the provided GitHub URL
- After authorization, the account appears and is ready to use
- Optionally set an 管理密码 (admin password) in config to protect the WebUI
macOS and Linux users: If you downloaded a pre-built binary from Releases, you may need to grant execute permission first:
chmod +x ./copilot-proxyIf macOS displays "copilot-proxy cannot be opened because the developer cannot be verified", go to System Settings > Privacy & Security and click Open Anyway.
No desktop environment required Start the server, check the logs for the WebUI URL, and access it from another machine on the same network All authorization can be done through the WebUI — no terminal interaction needed
- Go 1.23+
- Node.js 20+
# 1. Install frontend dependencies and build
cd web
npm install
npm run build
cd ..
# 2. Copy frontend to embed directory
rm -rf internal/web/dist
mkdir -p internal/web/dist
cp -r web/dist/. internal/web/dist/
# 3. Build Go binary (embeds frontend automatically)
go build -ldflags="-s -w" -o copilot-proxy ./cmd/copilot-proxymake build-allThis produces binaries for Windows (amd64), Linux (amd64 + arm64), and macOS (amd64 + arm64)
make docker
# or
docker build -t copilot-proxy .The default config is auto-created at <exe_dir>/config/config.json on first run
You can override with --config <path> or the COPILOT_PROXY_CONFIG environment variable
A template is available at config.example.json
server.host/server.port— bind address and port (default:0.0.0.0:15432)security.admin_password— password to protect the WebUI. If empty, WebUI has no loginsecurity.api_key— optional API key for compatible API requestscopilot.api_base— GitHub Copilot API base URLauth.accounts— list of GitHub accounts (token is stored encrypted, not in plain text)auth.active_account_id— currently active accountruntime.proxy_disabled— toggle to pause compatible API requestsui.language—zhorenui.theme—system,light, ordark
By default, the WebUI is protected with password admin (set in security.admin_password)
Change it to a secure password in config.json or via the WebUI settings page
The password is stored in plaintext in the config file
If no password is set, the WebUI is open to anyone on the local network — set this for production use
Security note: The default password
adminis provided for convenience. Change it immediately if the proxy is exposed to untrusted networks.
curl http://localhost:15432/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer dummy" \
-d '{"model":"gpt-4.1","messages":[{"role":"user","content":"hello"}]}'curl http://localhost:15432/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: dummy" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"claude-sonnet-4.6","max_tokens":1024,"messages":[{"role":"user","content":"hello"}]}'curl "http://localhost:15432/v1beta/models/gemini-pro:generateContent?key=dummy" \
-H "Content-Type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"hello"}]}]}'GET /— health checkGET /v1/models— list available modelsPOST /v1/chat/completions— OpenAI chat completionsPOST /v1/messages— Anthropic Messages APIPOST /v1beta/models/{model}:generateContent— Gemini generateContentPOST /v1beta/models/{model}:streamGenerateContent— Gemini streamingGET /api/status— service and token statusGET /api/config— read current configPUT /api/config— save config (applied without restart)GET /api/models— list models visible to active Copilot accountGET /api/stats— request statistics (counts, tokens, recent records)POST /api/service— enable or pause proxy serviceGET /api/accounts— list GitHub accountsPOST /api/accounts— add a GitHub accountPOST /api/accounts/switch— switch active accountDELETE /api/accounts/:id— remove an accountGET /api/quota— probe GitHub Copilot quotaPOST /api/auth/login— WebUI admin loginPOST /api/auth/device/start— start device authorization flowPOST /api/auth/device/poll— poll device authorization statusPOST /api/auth/logout— remove current account (legacy)
GitHub tokens are encrypted at rest using AES-256-GCM before being written to config.json
The encryption key is derived from the machine's hardware fingerprint:
- Windows:
MachineGuidfrom registry - Linux:
/etc/machine-id - macOS:
IOPlatformUUIDfrom I/O Kit
This means the config file is tied to a specific machine and cannot be decrypted on another device No system keyring, no third-party credential managers, no plaintext token files
cmd/copilot-proxy/ # Entry point (CLI subcommands, signal handling, server start)
internal/
├── config/
│ ├── config.go # Config load/save/validation (defaults, hot-reload)
│ ├── config_test.go # Config tests
│ └── crypto.go # AES-GCM encrypt/decrypt (machine-fingerprint key)
├── auth/
│ ├── auth.go # Account manager (multi-account CRUD + token lifecycle)
│ └── oauth.go # GitHub Device Code Flow client
├── proxy/
│ ├── proxy.go # OpenAI-compatible forwarding + main handler
│ ├── anthropic.go # Anthropic Messages API protocol conversion
│ ├── gemini.go # Gemini API protocol conversion
│ ├── compat.go # Protocol compatibility utilities
│ └── stats.go # Request statistics (ring buffer)
├── server/ # HTTP server, routing, SSE, admin auth, WebUI API
└── web/
├── assets.go # go:embed embedded frontend dist
├── favicon.go # Favicon data (go:embed)
├── favicon.png # Favicon image
└── fs.go # Frontend static file serving (disk/embed dual mode)
web/ # Vue 3 + TypeScript + Naive UI frontend
MIT