- Python 100%
| src | ||
| tests | ||
| app.py | ||
| config.yaml | ||
| LICENSE | ||
| README.md | ||
| requirements.txt | ||
| usage.json | ||
cmdcode2apipy
cmdcode2apipy is a small OpenAI-compatible gateway for commandcode CLI. It lets OpenAI-style clients call commandcode.ai models through familiar endpoints such as /v1/chat/completions and /v1/models.
Made specifically for commandcode Go 1 USD/m plan
An adapter like this is required as the cheapest 1 USD/m commandcode.ai Go plan does not provide direct access to it's OpenAI-compatible API: you have to host an adapter like this on your own.
Features
- OpenAI-compatible HTTP API
POST /v1/chat/completionsGET /v1/models
- Streaming and non-streaming chat completions
- OpenAI
image_urlinput conversion to commandcode.ai / Anthropic-style image blocks - Local bearer-token auth for clients
- CORS enabled for local UI clients
- Usage counter persisted to
usage.json - Health endpoint:
GET /health - Usage endpoint:
GET /usage
Setup & Run
-
Clone the project:
git clone https://git.blackruby.hu/blackruby/cmdcode2apipy.git && cd cmdcode2apipy -
Install dependencies:
pip install -r requirements.txt -
Configure the gateway: Create a
config.yaml. The app will auto-generate a default one on first run if missing.api_key: "ccgw-your-local-client-key" commandcode: api_key: "your-command-code-api-key" base_url: "https://api.commandcode.ai" host: "localhost" port: 11434 exclude_models: - "gpt-" - "claude-" - "gemini-"Note: You can obtain your commandcode.ai API key through the commandcode.ai CLI or dashboard.
-
Run the server:
python app.py(Alternatively, use uvicorn directly:
uvicorn app:app --host localhost --port 11434) -
Run tests:
pytest tests/ -v
Project Layout
python/
├── app.py # FastAPI application entry point
├── config.yaml # Gateway configuration
├── requirements.txt # Python dependencies
├── src/
│ ├── __init__.py
│ ├── config.py # Config loading and generation
│ ├── models.py # Pydantic models (OpenAI & CC formats)
│ ├── client.py # Async httpx client for CC API
│ ├── translation.py # OpenAI <-> CC request/response mapping
│ ├── handlers.py # FastAPI routes, middleware, and SSE logic
│ └── usage.py # Thread-safe usage tracking
└── tests/ # pytest test suite
Configuration
config.yaml is created automatically and intentionally ignored by git.
Fields:
api_key— local bearer token required by clients calling this gateway.commandcode.api_key— Your commandcode.ai API key.commandcode.base_url— commandcode.ai API base URL.host— HTTP listen host. Defaults tolocalhost. Use0.0.0.0to listen on all interfaces.port— local listen port. Defaults to11434.exclude_models— model ID prefixes hidden from/v1/modelsand rejected by/v1/chat/completions.
New configs exclude gpt-, claude-, and gemini- by default as commandcode.ai Go plan does not provide access to them. These prefixes match both plain model IDs such as gpt-4 and provider-qualified IDs such as openai/gpt-4 by checking the part after the final /.
To make all models available, remove the entries or set an empty list:
exclude_models: []
Use with OpenAI-compatible clients
Set the base URL to your local gateway:
http://localhost:11434/v1
Use the generated api_key from config.yaml as the bearer token.
curl example
curl http://localhost:11434/v1/chat/completions \
-H "Authorization: Bearer <local-api-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro",
"messages": [
{"role": "user", "content": "Hello!"}
],
"stream": false
}'
Streaming
curl http://localhost:11434/v1/chat/completions \
-H "Authorization: Bearer <local-api-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro",
"messages": [
{"role": "user", "content": "Write a short haiku."}
],
"stream": true
}'
Endpoints
GET /health
No authentication required.
{"status":"ok"}
GET /usage
No authentication required. Returns locally accumulated usage counters:
{
"total_requests": 1,
"prompt_tokens": 7527,
"completion_tokens": 55,
"cache_read_tokens": 7424,
"cache_write_tokens": 0
}
Usage is persisted to usage.json, which is ignored by git.
GET /v1/models
Returns the model list after applying exclude_models filtering.
POST /v1/chat/completions
Accepts OpenAI-style chat completion requests and forwards them to commandcode.ai.
Requests for excluded models return 404 with the existing OpenAI-compatible error JSON shape.
Supported request styles:
- Plain text messages
- Multimodal content arrays with
image_url stream: trueserver-sent eventsstream: falseJSON response
Notes
The project is a Python rewrite of cmdcode2api originally written in Go, which is no longer actively maintained nor is accepting contributions.
This is gateway currently targets the commandcode.ai API shape observed during development. If commandcode.ai changes its internal API, the adapter may need updates.