hkqr/my-free-code: a multi-provider gateway for Claude Code
Open-source multi-provider AI gateway for Claude Code and other coding agents, with model routing, streaming, tools, reasoning, fallbacks, and local model support
At a glance
- What is it?
- My Free Code v0.8 is a local FastAPI proxy that speaks Anthropic Messages and OpenAI Responses, routes Claude tiers to third-party or local models, and falls back in order. It is a young MIT project with thin operational documentation.
- Who is it for?
- Adopt it if you want to point Claude Code at OpenRouter, Groq, DeepSeek or a local Ollama model without editing the client, and you are comfortable reading providers/adapters.py when a provider misbehaves. Do not adopt it if you need a hosted gateway, a documented upgrade path or anything beyond local use, because the README says the project is intended for local use and documents no release or migration process.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: one client, many providers, one model name
Claude Code talks to an Anthropic-shaped endpoint. If you want it to use a free OpenRouter model, a Groq-hosted Llama, or a model running in Ollama on your laptop, you either patch the client or put something in front of it that speaks the same wire protocol. My Free Code is that something. It serves the Anthropic Messages API at /v1/messages, Anthropic token counting at /v1/messages/count_tokens, an OpenAI Responses-compatible surface at /v1/responses, model discovery at /v1/models, and a health endpoint at /health. The audience is narrow and specific: developers already using a coding agent who want provider choice without changing the agent. The README is explicit that this is an independent implementation and is not affiliated with Anthropic.
How the gateway routes a Claude tier to a provider
The architecture diagram in the README puts coding agents and IDEs at the top, then two wire protocols (Anthropic Messages and OpenAI Responses), then a FastAPI gateway, then a model router, then primary and fallback branches, then a provider runtime split into an OpenAI-compatible adapter, a specialized adapter and a local runtime. The separation is deliberate: HTTP adapters, application routing, provider runtime and CLI adapters are distinct layers.
Configuration drives routing. MODEL_FABLE, MODEL_OPUS, MODEL_SONNET and MODEL_HAIKU each bind a Claude tier to a provider-qualified model ID, and FALLBACK_MODELS holds an ordered list. The README gives a concrete chain: with MODEL_SONNET=deepseek/deepseek-chat and FALLBACK_MODELS=groq/llama-3.3-70b-versatile,ollama/llama3.1, a Sonnet request goes to DeepSeek, then to Groq on failure before output, then to Ollama. The constraint that matters is stated plainly: once a streaming response has committed output, the gateway does not silently switch providers and duplicate the turn. Fallback is a pre-first-token mechanism, not a mid-stream rescue.
Two design choices deserve scrutiny. First, the public model identity stays as the gateway model even when the request is routed upstream, so logs on the provider side will not show the name your client used. Second, the provider catalog is broad by name but the README warns that entries are not claims of universal support: providers with unusual authentication or protocols need a dedicated adapter, and only the common OpenAI-compatible providers share the transport. Treat the catalog as a list of intended integrations, not verified ones.
Installing my-free-code and pointing Claude Code at it
The README requires Python 3.10+, which pyproject.toml confirms with requires-python = ">=3.10". Create a virtual environment first:
python -m venv .venvOn macOS or Linux, activate it, install the pinned dependencies and copy the example environment file:
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .envThe Windows path in the README uses PowerShell equivalents (.venv\Scripts\Activate.ps1 and copy .env.example .env). Then start the server:
python -m my_free_codeThe README states the default address is http://127.0.0.1:8082, matching HOST=127.0.0.1 and PORT=8082 in .env.example. To give it a real model, edit .env. The README example binds each Claude tier and sets a fallback chain:
MODEL=open_router/openrouter/free
MODEL_SONNET=deepseek/deepseek-chat
MODEL_HAIKU=groq/llama-3.3-70b-versatile
MODEL_OPUS=nvidia_nim/meta/llama-3.3-70b-instruct
FALLBACK_MODELS=deepseek/deepseek-chat,ollama/llama3.1Each provider you name needs its key present. .env.example lists the variables, including OPENROUTER_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY, NVIDIA_NIM_API_KEY and OLLAMA_API_KEY. Then launch the client with the gateway as its base URL:
python -m my_free_code.cli.mfc claudeThe README also shows the manual environment route for PowerShell: set ANTHROPIC_BASE_URL to http://127.0.0.1:8082, set ANTHROPIC_AUTH_TOKEN to local, set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY to 1, then run claude. The same launcher module accepts codex, pi, opencode, cline, hermes, deepseek-harness, grok and muse as subcommands, and the README notes the installed client must already exist on PATH. A local admin UI is served at http://127.0.0.1:8082/admin, with JSON endpoints at /api/admin/status, /api/admin/models and /api/admin/providers.
Local models, concurrency limits and the security posture
Three local runtimes are wired in through base URLs. Ollama uses OLLAMA_BASE_URL=http://127.0.0.1:11434/v1 with MODEL=ollama/llama3.1. LM Studio uses LM_STUDIO_BASE_URL=http://127.0.0.1:1234/v1 with MODEL=lmstudio/qwen3.5-coder. llama.cpp uses LLAMACPP_BASE_URL=http://127.0.0.1:8080/v1 with MODEL=llamacpp/my-model. This is the most useful part of the project for anyone who wants a fallback that keeps working when a free tier rate-limits.
Provider load is bounded by PROVIDER_MAX_CONCURRENCY=5, PROVIDER_RATE_LIMIT=10 and PROVIDER_RATE_WINDOW=3 in .env.example, with HTTP_TIMEOUT=180. The README also lists provider health backoff and rate-window control as agent features. The defaults are conservative, and a gateway fronting several agents will queue rather than fan out; that is a tuning surface, not a bug.
The security section is blunt and worth repeating: this is intended for local use. Keep HOST=127.0.0.1, set a non-trivial PROXY_AUTH_TOKEN (the example ships the literal value local), never commit .env, and do not expose the admin endpoints directly to the Internet. The README adds that provider credentials remain in environment or configuration and are never sent to another provider. That last claim is architectural, not audited: it follows from the adapter layout in providers/, and you should confirm it in the code before trusting it with keys that matter.
Where my-free-code is the wrong tool
The README documents no rollback procedure, no release notes and no migration path between versions; the repository has no retrieved releases, and pyproject.toml carries version 0.8.0. If you need a gateway with a published changelog and a deprecation policy, this is not it yet.
Fallback semantics are narrower than they sound. The gateway switches providers only on failure before output, so a provider that starts streaming and then stalls will not be replaced. There is no documented mechanism for mid-stream recovery, and the README frames that as intentional to avoid duplicating a turn.
Provider breadth is also a trap. The catalog names dozens of providers, but the README states that providers with unusual authentication or protocols require a dedicated adapter and that only OpenAI-compatible providers share the transport. A provider appearing in the catalog is not evidence that it works. Finally, the launcher layer delegates to clients that must already be installed and on PATH; the gateway does not install or manage them.
Alternatives and the actual difference in approach
The obvious comparison is LiteLLM, a widely used Python proxy that exposes an OpenAI-compatible API over many providers. The difference is the wire protocol the client speaks. LiteLLM's primary surface is OpenAI-shaped, so an Anthropic-protocol client like Claude Code needs a translation layer or a different base URL contract. My Free Code implements the Anthropic Messages protocol natively at /v1/messages, including /v1/messages/count_tokens, and treats OpenAI Responses as the second surface at /v1/responses. That is the whole reason the project exists: the client stays unmodified.
A second alternative is running a local router such as Ollama's own OpenAI-compatible endpoint directly and pointing the agent at it. That works for a single local model but gives you no tier routing, no ordered cross-provider fallback and no per-provider concurrency control. My Free Code sits one layer above, and the cost is another process to run and configure.
Maintenance, upgrades and the MIT licence
The repository is not archived and the last push was on 2026-09-09, eight days before this writing, so the codebase is moving. That is the only maintenance signal available: there are no retrieved releases, so no changelog, no tagged upgrade path and no stated compatibility policy between versions. Upgrading means pulling the branch and re-running pip install -r requirements.txt, whose four runtime dependencies (fastapi, uvicorn[standard], httpx, python-dotenv) are version-bounded with upper limits in pyproject.toml. The test extra adds pytest and pytest-asyncio, and the README shows pytest -q for the deterministic suite covering routing, protocol conversion, auth, reasoning, model catalog and streaming primitives. Running that suite after an upgrade is the only documented verification step.
The licence is MIT, stated in the README and present as a LICENSE file at the repository root. That permits commercial and private use and modification with attribution and the licence text retained. This is a description of the licence terms, not legal advice; if you redistribute the gateway inside a product, have counsel review the notice requirements.
Editorial conclusion
Adopt it if you want to point Claude Code at OpenRouter, Groq, DeepSeek or a local Ollama model without editing the client, and you are comfortable reading providers/adapters.py when a provider misbehaves. Do not adopt it if you need a hosted gateway, a documented upgrade path or anything beyond local use, because the README says the project is intended for local use and documents no release or migration process. Before wiring it into a daily workflow, verify three things yourself: that your chosen provider IDs resolve in the catalog, that fallback triggers only before output is committed, and that PROXY_AUTH_TOKEN is set to something other than the local default.
Frequently asked questions
How do I get my-free-code running?
Install Python 3.10 or newer, create a virtual environment, run pip install -r requirements.txt, copy .env.example to .env, then start it with python -m my_free_code. The README gives the default address as http://127.0.0.1:8082.
Where does my-free-code run?
It runs locally. The README states the default address is http://127.0.0.1:8082, and the security section says to keep HOST=127.0.0.1 and not expose the admin endpoints directly to the Internet.
Can my-free-code route Claude Code to a free provider?
Yes. The README shows MODEL_SONNET=deepseek/deepseek-chat with FALLBACK_MODELS=groq/llama-3.3-70b-versatile,ollama/llama3.1, so a Sonnet request goes to DeepSeek and falls back in order. You still need the corresponding API keys in .env.
Does my-free-code support local models?
The README documents three local runtimes: Ollama at OLLAMA_BASE_URL, LM Studio at LM_STUDIO_BASE_URL and llama.cpp at LLAMACPP_BASE_URL, each with a matching MODEL value such as ollama/llama3.1.
Does my-free-code switch providers mid-stream if a response stalls?
No. The README states that once a streaming response has committed output, the gateway does not silently switch providers and duplicate the turn. Fallback applies to failures before output.
Community notes