A Rust proxy server that exposes GitHub Copilot models through a streaming OpenAI-compatible API.
Only streaming responses are supported. All requests must include "stream": true.
passenger-rs is primarily designed to let web UIs such as Open WebUI talk to models available through your GitHub Copilot subscription.
Open WebUI (and similar tools) expect an OpenAI-compatible API endpoint. GitHub Copilot does not expose one natively. passenger-rs sits between the two: it accepts standard OpenAI streaming requests from the web UI, forwards them to the Copilot API using your personal token, and translates the response back into the format the UI expects.
Open WebUI ──► passenger-rs (127.0.0.1:8081) ──► api.githubcopilot.com
OpenAI API Copilot API
Point your web UI at http://127.0.0.1:8081/v1 with any API key (the value is ignored) and all Copilot models that are enabled in your account will appear in the model picker.
In Open WebUI, go to Settings → Connections and add http://127.0.0.1:8081/v1 as an OpenAI API connection:
Click the gear icon next to the connection to confirm the settings. No authentication is required:
# From source
git clone https://github.com/grumlimited/passenger-rs.git
cd passenger-rs
cargo build --releaseOr download a pre-built binary from the releases page.
./passenger-rs --loginThis will:
- Display a GitHub device code and URL
- Open your browser to https://github.com/login/device
- After authorization, save tokens to
~/.config/passenger-rs/
./passenger-rsThe server starts on http://127.0.0.1:8081 by default.
curl http://127.0.0.1:8081/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'OpenAI-compatible streaming chat completions. Requires "stream": true.
Routes to Copilot /responses for gpt-5+ models (excluding gpt-5-mini), and to Copilot /chat/completions for all other models.
Example request:
{
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"stream": true
}Response is a text/event-stream of ChatCompletionChunk SSE events.
OpenAI Responses API streaming endpoint. Requires "stream": true.
The Copilot Responses SSE format is identical to the OpenAI Responses SSE format — the stream is passed through byte-for-byte.
Lists available models from the GitHub Copilot model catalog in OpenAI format.
Returns 200 OK with body OK.
- Rust 1.70 or later
- Active GitHub Copilot subscription
Pre-built packages for Ubuntu and Arch Linux are available on the releases page.
# Arch Linux
yay -U passenger-rs-0.0.1-1-x86_64.pkg.tar.zst
# Ubuntu/Debian
sudo dpkg -i passenger-rs-0.0.1-x86_64.debManage with systemd:
systemctl --user start passenger-rs.service
systemctl --user enable passenger-rs.service
systemctl --user status passenger-rs.serviceNote: Before starting the service, authenticate with --login.
Edit config.toml:
[github]
device_code_url = "https://github.com/login/device/code"
oauth_token_url = "https://github.com/login/oauth/access_token"
copilot_token_url = "https://api.github.com/copilot_internal/v2/token"
copilot_models_url = "https://models.github.ai/catalog/models"
client_id = "Iv1.b507a08c87ecfe98"
[copilot]
api_base_url = "https://api.githubcopilot.com"
[server]
port = 8081
host = "127.0.0.1"passenger-rs - GitHub Copilot streaming proxy (OpenAI-compatible)
Usage: passenger-rs [OPTIONS]
Options:
-c, --config <CONFIG>
Path to the configuration file [default: config.toml]
--login
Perform GitHub OAuth device flow login
--refresh-token
Refresh Copilot token using existing access token
--access-token-path <ACCESS_TOKEN_PATH>
Path to the access token file
[default: ~/.config/passenger-rs/access_token.json]
--copilot-token-path <COPILOT_TOKEN_PATH>
Path to the Copilot token file
[default: ~/.config/passenger-rs/token.json]
-h, --help
Print help information
-V, --version
Print version information
Tokens are stored in ~/.config/passenger-rs/:
- Access Token (
access_token.json): Long-lived, used to obtain Copilot tokens - Copilot Token (
token.json): Short-lived (~25 minutes), auto-refreshed 60 seconds before expiry
Custom paths:
./passenger-rs --login \
--access-token-path /custom/path/access_token.json \
--copilot-token-path /custom/path/copilot_token.jsoncargo build # debug build
cargo build --release
cargo test
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt"No authentication token found"
./passenger-rs --login"Only streaming is supported"
Add "stream": true to your request body.
"Address already in use"
Change port in config.toml, or kill the process using port 8081:
lsof -ti:8081 | xargs kill -9Enable debug logging
RUST_LOG=debug ./passenger-rsGPL-3.0 — see LICENSE.
- Based on copilot-to-api
- Built with Axum, Tokio, Clap
Ensure you comply with GitHub's Terms of Service and Copilot's usage policies.

