{"id":48008009,"url":"https://github.com/passcod/first-officer","last_synced_at":"2026-04-04T13:26:07.748Z","repository":{"id":339133718,"uuid":"1160585020","full_name":"passcod/first-officer","owner":"passcod","description":"Proxy exposing Copilot as an Anthropic/Claude Code compatible API","archived":false,"fork":false,"pushed_at":"2026-02-18T09:37:39.000Z","size":1357,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-18T11:17:57.074Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/passcod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","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-02-18T05:48:42.000Z","updated_at":"2026-02-18T09:37:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/passcod/first-officer","commit_stats":null,"previous_names":["passcod/first-officer"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/passcod/first-officer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passcod%2Ffirst-officer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passcod%2Ffirst-officer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passcod%2Ffirst-officer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passcod%2Ffirst-officer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/passcod","download_url":"https://codeload.github.com/passcod/first-officer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passcod%2Ffirst-officer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31402179,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-04-04T13:26:07.650Z","updated_at":"2026-04-04T13:26:07.714Z","avatar_url":"https://github.com/passcod.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# First Officer\n\nUse GitHub Copilot as if it was the Anthropic API (e.g. for Claude Code).\n\nThis was inspired by \u003chttps://github.com/ericc-ch/copilot-api\u003e but in Rust with a different feature set to make it easier to use with things that expect the Claude Code / Anthropic API.\n\nCompared to the original, there's also no persistent state, so it can be scaled, and you can use multiple github tokens (ie it can be used by multiple people).\nSee below for more features.\n\n## Quick start\n\nStart the server:\n\n```console\n$ docker run -d --rm -p 4141:4141 ghcr.io/passcod/first-officer:latest\n```\n\nGrab a GitHub Copilot token:\n\n```console\n$ npx copilot-api@latest auth\n$ cat ~/.local/share/copilot-api/github_token\n```\n\nUse the token to authenticate with the server:\n\n```console\n$ env ANTHROPIC_BASE_URL=\"http://localhost:4141\" ANTHROPIC_AUTH_TOKEN=\"ghp_...\" claude\n```\n\nOr add this to `~/.claude/settings.json`:\n\n```json\n{\n  \"apiKeyHelper\": \"cat ~/.local/share/copilot-api/github_token\",\n  \"env\": {\n    \"ANTHROPIC_BASE_URL\": \"http://localhost:4141\"\n  }\n}\n```\n\n## Configuration\n\nEntirely done by environment variables, all of them optional:\n\n- `PORT`: The port to listen on. Defaults to `4141`.\n- `RUST_LOG`: The log level.\n- `VSCODE_VERSION`: The version of VS Code we're pretending to be. Defaults to `1.100.0`.\n- `ACCOUNT_TYPE`: Set to `business` or `enterprise` if using those GitHub account types.\n\n## Authentication Token\n\nTo use the API, you need a GitHub token. See how to get one in the Quick Start section.\n\nYou can either:\n\n- use the token as an Anthropic API key (or in the OpenAI convention, that works too);\n- set the `GH_TOKEN` environment variable on the server, and use any value (e.g. `-`) as the API key.\n\nIf you don't provide a valid token one way or another, you'll get a 403 response.\nIf you provide a token as an API key and the `GH_TOKEN` variable was set, the API key will be preferred (it acts as a fallback).\nThat way you can have the service work for multiple people with independent tokens.\n\n## Model renaming\n\nThe way GitHub names its models is not quite how Anthropic names its models.\nYou _can_ configure Claude Code or whatever to use the right models using its config file, but then you need to always keep that updated.\n\nFirst Officer instead dynamically translates model names between how they are in the Copilot API to a naming scheme like Claude Code expects.\nThis means it will also work with other software that expects the Anthropic model names.\nIt's not a hard-coded mapping, so when new models become available in Copilot, this software usually doesn't need an update.\n\nThere's also two environment variables available to further customise this:\n\n- `MODEL_RENAME_AUTO` — set to `false` to disable pattern-based auto renaming.\n- `MODEL_RENAME_MAP` — JSON object `{\"copilot-name\": \"api-name\", ...}` applied on top of auto rules (custom entries take priority).\n\nWe also strip date-pinned model names, so if something requests `claude-sonnet-4-5-20250115` we'll just serve `claude-sonnet-4-5`.\n\n## Thinking emulation\n\nThe Copilot API doesn't support Anthropic's \"thinking\" mode, but First Officer emulates it.\nYou can disable this by setting `EMULATE_THINKING` to `false`.\n\n## Model list cache\n\nThe `/v1/models` route returns the list of available models, as expected in the OpenAI API.\nHowever, to save on API calls, that list is cached, with an default TTL of 1 hour.\nYou can change that with the `MODELS_CACHE_TTL` and an integer value in seconds.\nSet to 0 to disable caching.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpasscod%2Ffirst-officer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpasscod%2Ffirst-officer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpasscod%2Ffirst-officer/lists"}