File size: 28,864 Bytes
f8f1e1e 6172a47 f8f1e1e 6172a47 f8f1e1e 6172a47 749ae63 6172a47 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | ---
title: Free Claude Code Proxy
emoji: π€
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860
pinned: false
---
<div align="center">
# π€ Free Claude Code
### Use Claude Code CLI & VSCode for free. No Anthropic API key required.
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/downloads/)
[](https://github.com/astral-sh/uv)
[](https://github.com/Alishahryar1/free-claude-code/actions/workflows/tests.yml)
[](https://pypi.org/project/ty/)
[](https://github.com/astral-sh/ruff)
[](https://github.com/Delgan/loguru)
A lightweight proxy that routes Claude Code's Anthropic API calls to **NVIDIA NIM** (40 req/min free), **OpenRouter** (hundreds of models), **DeepSeek** (direct API), **LM Studio** (fully local), or **llama.cpp** (local with Anthropic endpoints).
[Quick Start](#quick-start) Β· [Providers](#providers) Β· [Discord Bot](#discord-bot) Β· [Configuration](#configuration) Β· [Development](#development) Β· [Contributing](#contributing)
---
</div>
<div align="center">
<!-- pic.png removed for HF Space compatibility -->
<p><em>Claude Code running via NVIDIA NIM, completely free</em></p>
</div>
## Features
| Feature | Description |
| -------------------------- | ----------------------------------------------------------------------------------------------- |
| **Zero Cost** | 40 req/min free on NVIDIA NIM. Free models on OpenRouter. Fully local with LM Studio |
| **Drop-in Replacement** | Set 2 env vars. No modifications to Claude Code CLI or VSCode extension needed |
| **5 Providers** | NVIDIA NIM, OpenRouter, DeepSeek, LM Studio (local), llama.cpp (`llama-server`) |
| **Per-Model Mapping** | Route Opus / Sonnet / Haiku to different models and providers. Mix providers freely |
| **Thinking Token Support** | Parses `<think>` tags and `reasoning_content` into native Claude thinking blocks |
| **Heuristic Tool Parser** | Models outputting tool calls as text are auto-parsed into structured tool use |
| **Request Optimization** | 5 categories of trivial API calls intercepted locally, saving quota and latency |
| **Smart Rate Limiting** | Proactive rolling-window throttle + reactive 429 exponential backoff + optional concurrency cap |
| **Discord / Telegram Bot** | Remote autonomous coding with tree-based threading, session persistence, and live progress |
| **Subagent Control** | Task tool interception forces `run_in_background=False`. No runaway subagents |
| **Extensible** | Clean `BaseProvider` and `MessagingPlatform` ABCs. Add new providers or platforms easily |
## Quick Start
### Prerequisites
1. Get an API key (or use LM Studio / llama.cpp locally):
- **NVIDIA NIM**: [build.nvidia.com/settings/api-keys](https://build.nvidia.com/settings/api-keys)
- **OpenRouter**: [openrouter.ai/keys](https://openrouter.ai/keys)
- **DeepSeek**: [platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys)
- **LM Studio**: No API key needed. Run locally with [LM Studio](https://lmstudio.ai)
- **llama.cpp**: No API key needed. Run `llama-server` locally.
2. Install [Claude Code](https://github.com/anthropics/claude-code)
### Install `uv`
```bash
# Install uv (required to run the project)
pip install uv
```
If uv is already installed, run uv self update to get the latest version.
### Clone & Configure
```bash
git clone https://github.com/Alishahryar1/free-claude-code.git
cd free-claude-code
cp .env.example .env
```
Choose your provider and edit `.env`:
<details>
<summary><b>NVIDIA NIM</b> (40 req/min free, recommended)</summary>
```dotenv
NVIDIA_NIM_API_KEY="nvapi-your-key-here"
MODEL_OPUS="nvidia_nim/z-ai/glm4.7"
MODEL_SONNET="nvidia_nim/moonshotai/kimi-k2-thinking"
MODEL_HAIKU="nvidia_nim/stepfun-ai/step-3.5-flash"
MODEL="nvidia_nim/z-ai/glm4.7" # fallback
# Global switch for provider reasoning requests and Claude thinking blocks.
ENABLE_THINKING=true
```
</details>
<details>
<summary><b>OpenRouter</b> (hundreds of models)</summary>
```dotenv
OPENROUTER_API_KEY="sk-or-your-key-here"
MODEL_OPUS="open_router/deepseek/deepseek-r1-0528:free"
MODEL_SONNET="open_router/openai/gpt-oss-120b:free"
MODEL_HAIKU="open_router/stepfun/step-3.5-flash:free"
MODEL="open_router/stepfun/step-3.5-flash:free" # fallback
```
</details>
<details>
<summary><b>DeepSeek</b> (direct API)</summary>
```dotenv
DEEPSEEK_API_KEY="your-deepseek-key-here"
MODEL_OPUS="deepseek/deepseek-reasoner"
MODEL_SONNET="deepseek/deepseek-chat"
MODEL_HAIKU="deepseek/deepseek-chat"
MODEL="deepseek/deepseek-chat" # fallback
```
</details>
<details>
<summary><b>LM Studio</b> (fully local, no API key)</summary>
```dotenv
MODEL_OPUS="lmstudio/unsloth/MiniMax-M2.5-GGUF"
MODEL_SONNET="lmstudio/unsloth/Qwen3.5-35B-A3B-GGUF"
MODEL_HAIKU="lmstudio/unsloth/GLM-4.7-Flash-GGUF"
MODEL="lmstudio/unsloth/GLM-4.7-Flash-GGUF" # fallback
```
</details>
<details>
<summary><b>llama.cpp</b> (fully local, no API key)</summary>
```dotenv
LLAMACPP_BASE_URL="http://localhost:8080/v1"
MODEL_OPUS="llamacpp/local-model"
MODEL_SONNET="llamacpp/local-model"
MODEL_HAIKU="llamacpp/local-model"
MODEL="llamacpp/local-model"
```
</details>
<details>
<summary><b>Mix providers</b></summary>
Each `MODEL_*` variable can use a different provider. `MODEL` is the fallback for unrecognized Claude models.
```dotenv
NVIDIA_NIM_API_KEY="nvapi-your-key-here"
OPENROUTER_API_KEY="sk-or-your-key-here"
MODEL_OPUS="nvidia_nim/moonshotai/kimi-k2.5"
MODEL_SONNET="open_router/deepseek/deepseek-r1-0528:free"
MODEL_HAIKU="lmstudio/unsloth/GLM-4.7-Flash-GGUF"
MODEL="nvidia_nim/z-ai/glm4.7" # fallback
```
</details>
> Migration: `NIM_ENABLE_THINKING` was removed in this release. Rename it to `ENABLE_THINKING`.
<details>
<summary><b>Optional Authentication</b> (restrict access to your proxy)</summary>
Set `ANTHROPIC_AUTH_TOKEN` in `.env` to require clients to authenticate:
```dotenv
ANTHROPIC_AUTH_TOKEN="your-secret-token-here"
```
**How it works:**
- If `ANTHROPIC_AUTH_TOKEN` is empty (default), no authentication is required (backward compatible)
- If set, clients must provide the same token via the `ANTHROPIC_AUTH_TOKEN` header
- The `claude-pick` script automatically reads the token from `.env` if configured
**Example usage:**
```bash
# With authentication
ANTHROPIC_AUTH_TOKEN="your-secret-token-here" \
ANTHROPIC_BASE_URL="http://localhost:8082" claude
# claude-pick automatically uses the configured token
claude-pick
```
Use this feature if:
- Running the proxy on a public network
- Sharing the server with others but restricting access
- Wanting an additional layer of security
</details>
### Run It
**Terminal 1:** Start the proxy server:
```bash
uv run uvicorn server:app --host 0.0.0.0 --port 8082
```
**Terminal 2:** Run Claude Code:
Point `ANTHROPIC_BASE_URL` at the proxy root URL, not `http://localhost:8082/v1`.
#### Powershell
```powershell
$env:ANTHROPIC_AUTH_TOKEN="freecc"; $env:ANTHROPIC_BASE_URL="http://localhost:8082"; claude
```
#### Bash
```bash
ANTHROPIC_AUTH_TOKEN="freecc" ANTHROPIC_BASE_URL="http://localhost:8082" claude
```
That's it! Claude Code now uses your configured provider for free.
<details>
<summary><b>VSCode Extension Setup</b></summary>
1. Start the proxy server (same as above).
2. Open Settings (`Ctrl + ,`) and search for `claude-code.environmentVariables`.
3. Click **Edit in settings.json** and add:
```json
"claudeCode.environmentVariables": [
{ "name": "ANTHROPIC_BASE_URL", "value": "http://localhost:8082" },
{ "name": "ANTHROPIC_AUTH_TOKEN", "value": "freecc" }
]
```
4. Reload extensions.
5. **If you see the login screen**: Click **Anthropic Console**, then authorize. The extension will start working. You may be redirected to buy credits in the browser; ignore it β the extension already works.
To switch back to Anthropic models, comment out the added block and reload extensions.
</details>
<details>
<summary><b>IntelliJ Extension Setup</b></summary>
1. Open the configuration file:
- **Windows**: `C:\Users\%USERNAME%\AppData\Roaming\JetBrains\acp-agents\installed.json`
- **Linux/macOS**: `~/.jetbrains/acp.json`
2. Inside acp.registry.claude-acp, change:
```
"env": {}
```
to
```
"env": {
"ANTHROPIC_AUTH_TOKEN": "freecc",
"ANTHROPIC_BASE_URL": "http://localhost:8082"
}
```
3. Start the proxy server
4. Restart IDE
</details>
<details>
<summary><b>Multi-Model Support (Model Picker)</b></summary>
`claude-pick` is an interactive model selector that lets you choose any model from your active provider each time you launch Claude, without editing `MODEL` in `.env`.
https://github.com/user-attachments/assets/9a33c316-90f8-4418-9650-97e7d33ad645
**1. Install [fzf](https://github.com/junegunn/fzf)**:
```bash
brew install fzf # macOS/Linux
```
**2. Add the alias to `~/.zshrc` or `~/.bashrc`:**
```bash
alias claude-pick="/absolute/path/to/free-claude-code/claude-pick"
```
Then reload your shell (`source ~/.zshrc` or `source ~/.bashrc`) and run `claude-pick`.
**Or use a fixed model alias** (no picker needed):
```bash
alias claude-kimi='ANTHROPIC_BASE_URL="http://localhost:8082" ANTHROPIC_AUTH_TOKEN="freecc:moonshotai/kimi-k2.5" claude'
```
</details>
### Install as a Package (no clone needed)
```bash
uv tool install git+https://github.com/Alishahryar1/free-claude-code.git
fcc-init # creates ~/.config/free-claude-code/.env from the built-in template
```
Edit `~/.config/free-claude-code/.env` with your API keys and model names, then:
```bash
free-claude-code # starts the server
```
> To update: `uv tool upgrade free-claude-code`
---
## How It Works
```
βββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββ
β Claude Code ββββββββ>β Free Claude Code ββββββββ>β LLM Provider β
β CLI / VSCode β<ββββββββ Proxy (:8082) β<ββββββββ NIM / OR / LMS β
βββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββββββ
Anthropic API OpenAI-compatible
format (SSE) format (SSE)
```
- **Transparent proxy**: Claude Code sends standard Anthropic API requests; the proxy forwards them to your configured provider
- **Per-model routing**: Opus / Sonnet / Haiku requests resolve to their model-specific backend, with `MODEL` as fallback
- **Request optimization**: 5 categories of trivial requests (quota probes, title generation, prefix detection, suggestions, filepath extraction) are intercepted and responded to locally without using API quota
- **Format translation**: Requests are translated from Anthropic format to the provider's OpenAI-compatible format and streamed back
- **Thinking tokens**: `<think>` tags and `reasoning_content` fields are converted into native Claude thinking blocks when `ENABLE_THINKING=true`
The proxy also exposes Claude-compatible probe routes: `GET /v1/models`, `POST /v1/messages`, `POST /v1/messages/count_tokens`, plus `HEAD`/`OPTIONS` support for the common probe endpoints.
---
## Providers
| Provider | Cost | Rate Limit | Best For |
| -------------- | ------------ | ---------- | ------------------------------------ |
| **NVIDIA NIM** | Free | 40 req/min | Daily driver, generous free tier |
| **OpenRouter** | Free / Paid | Varies | Model variety, fallback options |
| **DeepSeek** | Usage-based | Varies | Direct access to DeepSeek chat/reasoner |
| **LM Studio** | Free (local) | Unlimited | Privacy, offline use, no rate limits |
| **llama.cpp** | Free (local) | Unlimited | Lightweight local inference engine |
Models use a prefix format: `provider_prefix/model/name`. An invalid prefix causes an error.
| Provider | `MODEL` prefix | API Key Variable | Default Base URL |
| ---------- | ----------------- | -------------------- | ----------------------------- |
| NVIDIA NIM | `nvidia_nim/...` | `NVIDIA_NIM_API_KEY` | `integrate.api.nvidia.com/v1` |
| OpenRouter | `open_router/...` | `OPENROUTER_API_KEY` | `openrouter.ai/api/v1` |
| DeepSeek | `deepseek/...` | `DEEPSEEK_API_KEY` | `api.deepseek.com` |
| LM Studio | `lmstudio/...` | (none) | `localhost:1234/v1` |
| llama.cpp | `llamacpp/...` | (none) | `localhost:8080/v1` |
<details>
<summary><b>NVIDIA NIM models</b></summary>
Popular models (full list in [`nvidia_nim_models.json`](nvidia_nim_models.json)):
- `nvidia_nim/minimaxai/minimax-m2.5`
- `nvidia_nim/qwen/qwen3.5-397b-a17b`
- `nvidia_nim/z-ai/glm5`
- `nvidia_nim/moonshotai/kimi-k2.5`
- `nvidia_nim/stepfun-ai/step-3.5-flash`
Browse: [build.nvidia.com](https://build.nvidia.com/explore/discover) Β· Update list: `curl "https://integrate.api.nvidia.com/v1/models" > nvidia_nim_models.json`
</details>
<details>
<summary><b>OpenRouter models</b></summary>
Popular free models:
- `open_router/arcee-ai/trinity-large-preview:free`
- `open_router/stepfun/step-3.5-flash:free`
- `open_router/deepseek/deepseek-r1-0528:free`
- `open_router/openai/gpt-oss-120b:free`
Browse: [openrouter.ai/models](https://openrouter.ai/models) Β· [Free models](https://openrouter.ai/collections/free-models)
</details>
<details>
<summary><b>DeepSeek models</b></summary>
DeepSeek currently exposes the direct API models:
- `deepseek/deepseek-chat`
- `deepseek/deepseek-reasoner`
Browse: [api-docs.deepseek.com](https://api-docs.deepseek.com)
</details>
<details>
<summary><b>LM Studio models</b></summary>
Run models locally with [LM Studio](https://lmstudio.ai). Load a model in the Chat or Developer tab, then set `MODEL` to its identifier.
Examples with native tool-use support:
- `LiquidAI/LFM2-24B-A2B-GGUF`
- `unsloth/MiniMax-M2.5-GGUF`
- `unsloth/GLM-4.7-Flash-GGUF`
- `unsloth/Qwen3.5-35B-A3B-GGUF`
Browse: [model.lmstudio.ai](https://model.lmstudio.ai)
</details>
<details>
<summary><b>llama.cpp models</b></summary>
Run models locally using `llama-server`. Ensure you have a tool-capable GGUF. Set `MODEL` to whatever arbitrary name you'd like (e.g. `llamacpp/my-model`), as `llama-server` ignores the model name when run via `/v1/messages`.
See the Unsloth docs for detailed instructions and capable models:
[https://unsloth.ai/docs/models/qwen3.5#qwen3.5-small-0.8b-2b-4b-9b](https://unsloth.ai/docs/models/qwen3.5#qwen3.5-small-0.8b-2b-4b-9b)
</details>
---
## Discord Bot
Control Claude Code remotely from Discord (or Telegram). Send tasks, watch live progress, and manage multiple concurrent sessions.
**Capabilities:**
- Tree-based message threading: reply to a message to fork the conversation
- Session persistence across server restarts
- Live streaming of thinking tokens, tool calls, and results
- Unlimited concurrent Claude CLI sessions (concurrency controlled by `PROVIDER_MAX_CONCURRENCY`)
- Voice notes: send voice messages; they are transcribed and processed as regular prompts
- Commands: `/stop` (cancel a task; reply to a message to stop only that task), `/clear` (reset all sessions, or reply to clear a branch), `/stats`
### Setup
1. **Create a Discord Bot**: Go to [Discord Developer Portal](https://discord.com/developers/applications), create an application, add a bot, and copy the token. Enable **Message Content Intent** under Bot settings.
2. **Edit `.env`:**
```dotenv
MESSAGING_PLATFORM="discord"
DISCORD_BOT_TOKEN="your_discord_bot_token"
ALLOWED_DISCORD_CHANNELS="123456789,987654321"
```
> Enable Developer Mode in Discord (Settings β Advanced), then right-click a channel and "Copy ID". Comma-separate multiple channels. If empty, no channels are allowed.
3. **Configure the workspace** (where Claude will operate):
```dotenv
CLAUDE_WORKSPACE="./agent_workspace"
ALLOWED_DIR="C:/Users/yourname/projects"
```
4. **Start the server:**
```bash
uv run uvicorn server:app --host 0.0.0.0 --port 8082
```
5. **Invite the bot** via OAuth2 URL Generator (scopes: `bot`, permissions: Read Messages, Send Messages, Manage Messages, Read Message History).
### Telegram
Set `MESSAGING_PLATFORM=telegram` and configure:
```dotenv
TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrSTUvwxYZ"
ALLOWED_TELEGRAM_USER_ID="your_telegram_user_id"
```
Get a token from [@BotFather](https://t.me/BotFather); find your user ID via [@userinfobot](https://t.me/userinfobot).
### Voice Notes
Send voice messages on Discord or Telegram; they are transcribed and processed as regular prompts.
| Backend | Description | API Key |
| --------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------- |
| **Local Whisper** (default) | [Hugging Face Whisper](https://huggingface.co/openai/whisper-large-v3-turbo) β free, offline, CUDA compatible | not required |
| **NVIDIA NIM** | Whisper/Parakeet models via gRPC | `NVIDIA_NIM_API_KEY` |
**Install the voice extras:**
```bash
# If you cloned the repo:
uv sync --extra voice_local # Local Whisper
uv sync --extra voice # NVIDIA NIM
uv sync --extra voice --extra voice_local # Both
# If you installed as a package (no clone):
uv tool install "free-claude-code[voice_local] @ git+https://github.com/Alishahryar1/free-claude-code.git"
uv tool install "free-claude-code[voice] @ git+https://github.com/Alishahryar1/free-claude-code.git"
uv tool install "free-claude-code[voice,voice_local] @ git+https://github.com/Alishahryar1/free-claude-code.git"
```
Configure via `WHISPER_DEVICE` (`cpu` | `cuda` | `nvidia_nim`) and `WHISPER_MODEL`. See the [Configuration](#configuration) table for all voice variables and supported model values.
---
## Configuration
### Core
| Variable | Description | Default |
| -------------------- | --------------------------------------------------------------------- | ------------------------------------------------- |
| `MODEL` | Fallback model (`provider/model/name` format; invalid prefix β error) | `nvidia_nim/stepfun-ai/step-3.5-flash` |
| `MODEL_OPUS` | Model for Claude Opus requests (falls back to `MODEL`) | `nvidia_nim/z-ai/glm4.7` |
| `MODEL_SONNET` | Model for Claude Sonnet requests (falls back to `MODEL`) | `open_router/arcee-ai/trinity-large-preview:free` |
| `MODEL_HAIKU` | Model for Claude Haiku requests (falls back to `MODEL`) | `open_router/stepfun/step-3.5-flash:free` |
| `NVIDIA_NIM_API_KEY` | NVIDIA API key | required for NIM |
| `ENABLE_THINKING` | Global switch for provider reasoning requests and Claude thinking blocks. Set `false` to hide thinking across all providers. | `true` |
| `OPENROUTER_API_KEY` | OpenRouter API key | required for OpenRouter |
| `DEEPSEEK_API_KEY` | DeepSeek API key | required for DeepSeek |
| `LM_STUDIO_BASE_URL` | LM Studio server URL | `http://localhost:1234/v1` |
| `LLAMACPP_BASE_URL` | llama.cpp server URL | `http://localhost:8080/v1` |
| `NVIDIA_NIM_PROXY` | Optional proxy URL for NVIDIA NIM requests (`http://...` or `socks5://...`) | `""` |
| `OPENROUTER_PROXY` | Optional proxy URL for OpenRouter requests (`http://...` or `socks5://...`) | `""` |
| `LMSTUDIO_PROXY` | Optional proxy URL for LM Studio requests (`http://...` or `socks5://...`) | `""` |
| `LLAMACPP_PROXY` | Optional proxy URL for llama.cpp requests (`http://...` or `socks5://...`) | `""` |
### Rate Limiting & Timeouts
| Variable | Description | Default |
| -------------------------- | ----------------------------------------- | ------- |
| `PROVIDER_RATE_LIMIT` | LLM API requests per window | `40` |
| `PROVIDER_RATE_WINDOW` | Rate limit window (seconds) | `60` |
| `PROVIDER_MAX_CONCURRENCY` | Max simultaneous open provider streams | `5` |
| `HTTP_READ_TIMEOUT` | Read timeout for provider requests (s) | `120` |
| `HTTP_WRITE_TIMEOUT` | Write timeout for provider requests (s) | `10` |
| `HTTP_CONNECT_TIMEOUT` | Connect timeout for provider requests (s) | `2` |
### Messaging & Voice
| Variable | Description | Default |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- |
| `MESSAGING_PLATFORM` | `discord` or `telegram` | `discord` |
| `DISCORD_BOT_TOKEN` | Discord bot token | `""` |
| `ALLOWED_DISCORD_CHANNELS` | Comma-separated channel IDs (empty = none allowed) | `""` |
| `TELEGRAM_BOT_TOKEN` | Telegram bot token | `""` |
| `ALLOWED_TELEGRAM_USER_ID` | Allowed Telegram user ID | `""` |
| `CLAUDE_WORKSPACE` | Directory where the agent operates | `./agent_workspace` |
| `ALLOWED_DIR` | Allowed directories for the agent | `""` |
| `MESSAGING_RATE_LIMIT` | Messaging messages per window | `1` |
| `MESSAGING_RATE_WINDOW` | Messaging window (seconds) | `1` |
| `VOICE_NOTE_ENABLED` | Enable voice note handling | `true` |
| `WHISPER_DEVICE` | `cpu` \| `cuda` \| `nvidia_nim` | `cpu` |
| `WHISPER_MODEL` | Whisper model (local: `tiny`/`base`/`small`/`medium`/`large-v2`/`large-v3`/`large-v3-turbo`; NIM: `openai/whisper-large-v3`, `nvidia/parakeet-ctc-1.1b-asr`, etc.) | `base` |
| `HF_TOKEN` | Hugging Face token for faster downloads (local Whisper, optional) | β |
<details>
<summary><b>Advanced: Request optimization flags</b></summary>
These are enabled by default and intercept trivial Claude Code requests locally to save API quota.
| Variable | Description | Default |
| --------------------------------- | ------------------------------ | ------- |
| `FAST_PREFIX_DETECTION` | Enable fast prefix detection | `true` |
| `ENABLE_NETWORK_PROBE_MOCK` | Mock network probe requests | `true` |
| `ENABLE_TITLE_GENERATION_SKIP` | Skip title generation requests | `true` |
| `ENABLE_SUGGESTION_MODE_SKIP` | Skip suggestion mode requests | `true` |
| `ENABLE_FILEPATH_EXTRACTION_MOCK` | Mock filepath extraction | `true` |
</details>
See [`.env.example`](.env.example) for all supported parameters.
---
## Development
### Project Structure
```
free-claude-code/
βββ server.py # Entry point
βββ api/ # FastAPI routes, request detection, optimization handlers
βββ providers/ # BaseProvider, OpenAICompatibleProvider, NIM, OpenRouter, DeepSeek, LM Studio, llamacpp
β βββ common/ # Shared utils (SSE builder, message converter, parsers, error mapping)
βββ messaging/ # MessagingPlatform ABC + Discord/Telegram bots, session management
βββ config/ # Settings, NIM config, logging
βββ cli/ # CLI session and process management
βββ tests/ # Pytest test suite
```
### Commands
```bash
uv run ruff format # Format code
uv run ruff check # Lint
uv run ty check # Type checking
uv run pytest # Run tests
```
### Extending
**Adding an OpenAI-compatible provider** (Groq, Together AI, etc.) β extend `OpenAICompatibleProvider`:
```python
from providers.openai_compat import OpenAICompatibleProvider
from providers.base import ProviderConfig
class MyProvider(OpenAICompatibleProvider):
def __init__(self, config: ProviderConfig):
super().__init__(config, provider_name="MYPROVIDER",
base_url="https://api.example.com/v1", api_key=config.api_key)
```
**Adding a fully custom provider** β extend `BaseProvider` directly and implement `stream_response()`.
**Adding a messaging platform** β extend `MessagingPlatform` in `messaging/` and implement `start()`, `stop()`, `send_message()`, `edit_message()`, and `on_message()`.
---
## Contributing
- Report bugs or suggest features via [Issues](https://github.com/Alishahryar1/free-claude-code/issues)
- Add new LLM providers (Groq, Together AI, etc.)
- Add new messaging platforms (Slack, etc.)
- Improve test coverage
- Not accepting Docker integration PRs for now
```bash
git checkout -b my-feature
uv run ruff format && uv run ruff check && uv run ty check && uv run pytest
# Open a pull request
```
---
## License
MIT License. See [LICENSE](LICENSE) for details.
Built with [FastAPI](https://fastapi.tiangolo.com/), [OpenAI Python SDK](https://github.com/openai/openai-python), [discord.py](https://github.com/Rapptz/discord.py), and [python-telegram-bot](https://python-telegram-bot.org/).
|