{"id":51376109,"url":"https://github.com/ftian1/copilot-gateway","last_synced_at":"2026-07-03T12:41:12.072Z","repository":{"id":365522613,"uuid":"1272052217","full_name":"ftian1/copilot-gateway","owner":"ftian1","description":"Gateway exposing GitHub Copilot LLM services to other agents like Claude.","archived":false,"fork":false,"pushed_at":"2026-06-17T17:50:32.000Z","size":53,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T19:04:30.606Z","etag":null,"topics":["agent","claude-code","copilot","gateway"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ftian1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-17T08:43:07.000Z","updated_at":"2026-06-17T17:51:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ftian1/copilot-gateway","commit_stats":null,"previous_names":["ftian1/copilot-gateway"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ftian1/copilot-gateway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftian1%2Fcopilot-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftian1%2Fcopilot-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftian1%2Fcopilot-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftian1%2Fcopilot-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ftian1","download_url":"https://codeload.github.com/ftian1/copilot-gateway/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ftian1%2Fcopilot-gateway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35086520,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","claude-code","copilot","gateway"],"created_at":"2026-07-03T12:41:11.316Z","updated_at":"2026-07-03T12:41:12.058Z","avatar_url":"https://github.com/ftian1.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Copilot Gateway\n\nA minimal, standalone gateway that provides **OpenAI-compatible** and **Anthropic-compatible** API endpoints to access GitHub Copilot's LLM services. On first launch it walks you through GitHub OAuth device-code authentication right in the terminal. The token is persisted to disk so subsequent starts are instant. Tracks token usage and **prints a running cost summary every 3 seconds** — useful now that Copilot bills per token (AI Credits).\n\n## Architecture\n\n```\n┌── Upper App ───┐                      ┌── Copilot Gateway ──┐                      ┌ GitHub Copilot API ─┐\n│  OpenAI SDK    │──── OpenAI request ─\u003e│  • same API         │──── forward (same) ─\u003e│  /chat/completions  │\n│                │                      │    → forward        │                      │  /responses         │\n│  Anthropic SDK │─ Anthropic request ─\u003e│  • different API    │── convert (An↔OAI) ─\u003e│  /v1/messages       │\n│                │                      │    → convert        │                      │  (Claude only)      │\n│                │\u003c── SSE stream ───────│                     │\u003c── SSE stream ───────│                     │\n└────────────────┘                      └─────────────────────┘                      └─────────────────────┘\n```\n\n## Quick Start\n\n### 1. Install dependencies\n\n```bash\npip install -r requirements.txt\n```\n\n### 2. Start the gateway\n\n```bash\npython main.py\n```\n\nThe gateway starts on `http://localhost:9992`. If no token is found, it auto-initiates the GitHub device-code flow and prints instructions to the terminal. A **running cost summary** refreshes every 3 seconds right in the terminal — no extra flags needed.\n\nTo skip the interactive prompt and auth via curl instead:\n\n```bash\npython main.py --no-auth-prompt\n```\n\n### 3. Authenticate (interactive — default)\n\nThe gateway prints a banner with a URL and a code. Open the URL, enter the code, approve the device. The token is automatically saved to `~/.copilot-gateway/token.json`. Next time you start the gateway, auth is skipped.\n\n### 4. Authenticate (via curl — alternative)\n\n```bash\n# Step 1: initiate device code\ncurl -X POST http://localhost:9992/auth/device\n\n# Step 2: open the verification_uri in a browser, enter the user_code\n\n# Step 3: poll for token\ncurl -X POST http://localhost:9992/auth/token \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"device_code\": \"...\"}'\n```\n\n### 5. Make LLM requests\n\n**OpenAI:**\n```bash\ncurl -X POST http://localhost:9992/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gpt-4o\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]\n  }'\n```\n\n**Anthropic:**\n```bash\ncurl -X POST http://localhost:9992/v1/messages \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"claude-sonnet-4-6\",\n    \"system\": \"You are a helpful assistant.\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}],\n    \"max_tokens\": 100\n  }'\n```\n\n**Streaming:** Add `\"stream\": true` to any request body.\n\n## CLI Flags\n\n```\npython main.py [options]\n\n  -v, --verbose        Dump raw GitHub Copilot /models response at startup\n  -p, --port PORT      Listen port (default: 9992, env: GATEWAY_PORT)\n  --enterprise DOMAIN  GitHub Enterprise domain\n  --no-auth-prompt     Skip interactive auth; use /auth endpoints instead\n  -h, --help           Show help\n```\n\n## Using with SDKs\n\n### OpenAI Python SDK\n\n```python\nfrom openai import OpenAI\n\nclient = OpenAI(\n    base_url=\"http://localhost:9992/v1\",\n    api_key=\"not-needed\"  # gateway handles auth\n)\n\nresponse = client.chat.completions.create(\n    model=\"gpt-4o\",\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}]\n)\nprint(response.choices[0].message.content)\n```\n\n### Anthropic Python SDK\n\n```python\nfrom anthropic import Anthropic\n\nclient = Anthropic(\n    base_url=\"http://localhost:9992/v1\",\n    api_key=\"not-needed\"  # gateway handles auth\n)\n\nresponse = client.messages.create(\n    model=\"claude-sonnet-4-6\",\n    system=\"You are a helpful assistant.\",\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}],\n    max_tokens=100\n)\nprint(response.content[0].text)\n```\n\n### Claude Code\n\nStart [Claude Code](https://docs.anthropic.com/en/docs/claude-code) against the gateway by setting these environment variables, then launch `claude`:\n\n```bash\nexport ANTHROPIC_BASE_URL=http://localhost:9992\nexport ANTHROPIC_AUTH_TOKEN=dummy\nexport ANTHROPIC_MODEL=claude-opus-4.8\nexport ANTHROPIC_DEFAULT_OPUS_MODEL=claude-opus-4.8\nexport ANTHROPIC_DEFAULT_SONNET_MODEL=claude-sonnet-4.6\nexport ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-4.5\nexport CLAUDE_CODE_SUBAGENT_MODEL=claude-haiku-4.5\nexport DISABLE_NON_ESSENTIAL_MODEL_CALLS=1\nexport CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\nexport IS_SANDBOX=1\nexport ENABLE_TOOL_SEARCH=true\nexport CLAUDE_CODE_ATTRIBUTION_HEADER=0\n\n# Then start Claude Code\nclaude --dangerously-skip-permissions\n```\n\n\u003e **Note:** Model IDs must match what the Copilot API exposes. Run `curl http://localhost:9992/v1/models | python3 -m json.tool` to see available models and pick the ones you want.\n\n## Configuration\n\n| Env Variable                 | Default                         | Description                                       |\n|------------------------------|---------------------------------|---------------------------------------------------|\n| `GATEWAY_PORT`               | `9992`                          | Listen port                                       |\n| `GATEWAY_HOST`               | `0.0.0.0`                       | Listen host                                       |\n| `GATEWAY_ENTERPRISE_DOMAIN`  | _(empty)_                       | GitHub Enterprise domain (e.g. `company.ghe.com`) |\n| `GATEWAY_TOKEN_FILE`         | `~/.copilot-gateway/token.json` | OAuth token persistence path                      |\n| `GATEWAY_MODEL_REFRESH_SECS` | `300`                           | Model list refresh interval (seconds)             |\n| `GATEWAY_NO_AUTH_PROMPT`     | _(empty)_                       | Set to `1` to skip interactive auth at startup    |\n\n## API Endpoints\n\n### LLM Endpoints\n\n| Method | Path                   | Description                                                                     |\n|--------|------------------------|---------------------------------------------------------------------------------|\n| `GET`  | `/v1/models`           | List models (OpenAI format, includes `supported_endpoints`, `anthropic_native`) |\n| `GET`  | `/v1/models/debug`     | Full parsed model metadata (pricing, limits, capabilities)                      |\n| `GET`  | `/v1/models/raw`       | **Untouched** upstream Copilot `/models` JSON — for inspecting raw Copilot data |\n| `GET`  | `/v1/usage`            | Cumulative token usage \u0026 estimated cost per model (live)                        |\n| `POST` | `/v1/chat/completions` | OpenAI Chat Completions                                                         |\n| `POST` | `/v1/responses`        | OpenAI Responses API                                                            |\n| `POST` | `/v1/messages`         | Anthropic Messages API                                                          |\n\n### Auth Endpoints\n\n| Method | Path           | Description                     |\n|--------|----------------|---------------------------------|\n| `POST` | `/auth/device` | Initiate OAuth device code flow |\n| `POST` | `/auth/token`  | Poll for access token           |\n| `GET`  | `/auth/status` | Check authentication status     |\n\n### Health\n\n| Method | Path      | Description                                                            |\n|--------|-----------|------------------------------------------------------------------------|\n| `GET`  | `/health` | Health check (`{\"status\":\"ok\",\"authenticated\":true,\"models_count\":N}`) |\n\n## Routing Logic\n\n### GPT-5 Model Routing\n\nGPT-5+ models (except `gpt-5-mini`) are automatically routed to the **Responses API** instead of Chat Completions, matching GitHub Copilot's own routing logic.\n\n### Anthropic Protocol Support\n\n- **Models with `/v1/messages` in `supported_endpoints`** (e.g., Claude models): Anthropic requests are forwarded directly to Copilot's native `/v1/messages` endpoint.\n- **Models without `/v1/messages`** (e.g., GPT models): Anthropic requests are converted to OpenAI Chat Completions format, proxied, and the response is converted back to Anthropic format. This includes full SSE streaming conversion.\n\nCheck which protocol each model supports:\n\n```bash\ncurl http://localhost:9992/v1/models | python3 -m json.tool\n```\n\nLook at the `anthropic_native` and `supported_endpoints` fields per model.\n\n## Usage Tracking\n\nSince GitHub Copilot moved to **per-token billing** (AI Credits = $0.01 each) on June 1, 2026, the gateway tracks token usage from every API response — both streaming and non-streaming — and computes cost using each model's pricing from Copilot's own `/models` endpoint.\n\n**Terminal output:** A cost summary refreshes every 3 seconds, tracking input/output/cache tokens and estimated spend:\n\n```\n── Usage ──\n─────────────────────────────────────────────────────────────────────────────────────────────────\n  claude-opus-4.8         req:   12  in:   52K  out:   18K  cache_r:  30K  cache_w:   5K  $0.0710\n  claude-sonnet-4-6       req:   47  in:  120K  out:   45K  cache_r:  80K  cache_w:  12K  $0.1035\n  gpt-5                   req:   31  in:   80K  out:   32K  cache_r:  10K  cache_w:   0K  $0.0420\n  TOTAL                   req:   90  in:  252K  out:   95K  cache_r: 120K  cache_w:  17K  $0.2165\n─────────────────────────────────────────────────────────────────────────────────────────────────\n```\n\n**JSON endpoint:**\n\n```bash\ncurl http://localhost:9992/v1/usage | python3 -m json.tool\n```\n\nReturns per-model breakdown with token counts and estimated cost. Reset counters with `DELETE /v1/usage`.\n\n\u003e **Note:** The gateway computes cost from real token counts × Copilot's published per-model prices. It does not query GitHub's credit balance (no public API exists for that).\n\n## Docker\n\n```bash\n# Build\ndocker build -t copilot-gateway .\n\n# Run (mount a volume for token persistence)\ndocker run -p 9992:9992 \\\n  -e GATEWAY_PORT=9992 \\\n  -v ~/.copilot-gateway:/home/gateway/.copilot-gateway \\\n  copilot-gateway\n```\n\n## Enterprise GitHub\n\n```bash\npython main.py --enterprise company.ghe.com\n# or\nGATEWAY_ENTERPRISE_DOMAIN=company.ghe.com python main.py\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fftian1%2Fcopilot-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fftian1%2Fcopilot-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fftian1%2Fcopilot-gateway/lists"}