Skip to content

MAXeaglet/commandcode-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Command Code Proxy

中文文档

A reverse proxy that converts Command Code API to OpenAI / Anthropic compatible endpoints. Single file, zero external dependencies.

Built by analyzing official CLI v0.32.3 network traffic to accurately replicate the Command Code API request protocol.

Features: OpenAI Chat Completions + Anthropic Messages API | Streaming & non-streaming | Tool calling (tool_use) | Multimodal image input | Reasoning effort | Dynamic model list | Cache hit metrics | 30s/90s stream timeout

Community: Linux.do — a friendly Chinese tech community.

Quick Start

npm start        # Start (default http://0.0.0.0:3000)
npm run dev      # Watch mode (auto-reload on file changes)

API Key is passed via the Authorization request header — no need to store it in config files. Key must start with user_ (automatically matched with any prefix, e.g. Bearer token_user_xxx):

curl http://127.0.0.1:3050/v1/chat/completions \
  -H "Authorization: Bearer user_xxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek/deepseek-v4-flash","messages":[{"role":"user","content":"hi"}]}'

File Structure

commandcode/
├── config.json     # Port / log path etc.
├── LICENSE         # MIT License
├── package.json    # npm start / npm run dev
├── proxy.mjs       # Single-file proxy core (~1400 lines)
├── AGENTS.md       # AI dev instructions
├── README.md       # This document (English)
└── README_zh.md    # Chinese documentation

Configuration

config.json

Field Default Description
port 3000 Listen port
host 0.0.0.0 Listen address
apiBase https://api.commandcode.ai CC API base URL
projectSlug cc-proxy x-project-slug header
logFile "" Log file path (empty = console only)
logLevel info Log level
useProviderModels true Dynamically fetch model list from Provider API
modelRefreshIntervalMs 300000 Model list cache refresh interval (5 min)

Environment Variables

Variable Overrides
PORT port
HOST host
CC_API_BASE apiBase
PROJECT_SLUG projectSlug
LOG_FILE logFile
CC_USE_PROVIDER_MODELS useProviderModels

API Endpoints

POST /v1/chat/completions

OpenAI Chat Completions compatible. Supports streaming, non-streaming, tool calling, multimodal image input, and reasoning effort.

Request parameters:

Parameter Required Description
model Yes Model ID (see model list)
messages Yes Conversation messages, supports system/user/assistant/tool roles
max_tokens No Max tokens to generate (default 64000)
stream No SSE streaming (default false)
temperature No Sampling temperature (0-2)
reasoning_effort No Reasoning intensity: low/medium/high/max
tools No Tool definitions (OpenAI function calling format)
tool_choice No Tool selection strategy
parallel_tool_calls No Allow parallel tool calls

Simple request:

{
  "model": "deepseek/deepseek-v4-flash",
  "messages": [{ "role": "user", "content": "hello" }],
  "stream": true
}

Multimodal image input (vision model required):

{
  "model": "xiaomi/mimo-v2.5",
  "messages": [{
    "role": "user",
    "content": [
      { "type": "text", "text": "Describe this image" },
      { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,..." } }
    ]
  }]
}

Tool calling:

{
  "model": "deepseek/deepseek-v4-flash",
  "messages": [...],
  "tools": [{
    "type": "function",
    "function": { "name": "get_weather", "description": "...", "parameters": {...} }
  }],
  "tool_choice": "auto"
}

Streaming response (SSE):

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","reasoning_content":"thinking..."}}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hello"}}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":10,"completion_tokens":20,"total_tokens":30,"prompt_tokens_details":{"cached_tokens":8}}}

data: [DONE]

Non-streaming response (with cache hits):

{
  "id": "chatcmpl-xxx",
  "object": "chat.completion",
  "created": 1234567890,
  "model": "deepseek/deepseek-v4-flash",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "Hello!",
      "reasoning_content": "The user said hello, I should respond."
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 7558,
    "completion_tokens": 42,
    "total_tokens": 7600,
    "prompt_tokens_details": { "cached_tokens": 7552 }
  }
}

POST /v1/messages

Anthropic Messages API compatible endpoint. Supports streaming, non-streaming, and tool calling.

Request body:

{
  "model": "claude-sonnet-4-6",
  "max_tokens": 1000,
  "system": "You are a helpful assistant.",
  "messages": [
    { "role": "user", "content": "hello" }
  ],
  "stream": true
}

Anthropic protocol conversion (automatic):

Concept Anthropic Format Conversion
System prompt Top-level system field Auto-converted to OpenAI system message
Message content content array (text/tool_use/tool_result) Auto-mapped to corresponding roles
Tool results tool_result blocks in user messages Auto-converted to role: "tool"
Tool definitions input_schema Auto-mapped to parameters
tool_choice {type:"auto"/"any"/"tool"} anyrequired, tool→function object
Reasoning thinking.budget_tokens Auto-mapped to reasoning_effort (≥10000→high, ≥5000→medium, ≥2000→low)
Stop reason end_turn/max_tokens/tool_use Auto-mapped to stop/length/tool_calls
Token usage input_tokens/output_tokens + cache Passed through, cache fields mapped to Anthropic format

Streaming response (SSE, Anthropic format):

event: message_start
data: {"type":"message_start","message":{"id":"msg_xxx","type":"message","role":"assistant","content":[],"model":"...","usage":{"input_tokens":0,"output_tokens":0}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":10,"cache_read_input_tokens":0,"input_tokens":100}}

event: message_stop
data: {"type":"message_stop"}

Non-streaming response:

{
  "id": "msg_xxx",
  "type": "message",
  "role": "assistant",
  "model": "deepseek/deepseek-v4-flash",
  "content": [{ "type": "text", "text": "Hello!" }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 7558,
    "output_tokens": 42,
    "cache_read_input_tokens": 7552,
    "cache_creation_input_tokens": null
  }
}

GET /v1/models

Returns available model list. Fetched dynamically from Provider API (5 min cache), falls back to hardcoded list on failure.

GET /health

Health check. Returns OK.

Error Codes

HTTP Status Description
400 Invalid request format
401 API Key missing / invalid format / rejected (Key must start with user_)
429 Rate limited (includes retry_after field)
502 CC upstream error
503 Service temporarily unavailable

Model List

The proxy returns a live model list via GET /v1/models. Below are common models for reference; the actual list depends on the live API response — see Command Code Pricing for plan details.

Common Models

Model ID Description Features
deepseek/deepseek-v4-flash DeepSeek V4 Flash Fast, general-purpose
deepseek/deepseek-v4-pro DeepSeek V4 Pro High-precision reasoning
claude-sonnet-4-6 Claude Sonnet 4.6 Long context
claude-opus-4-8 Claude Opus 4.8 Best reasoning
moonshotai/Kimi-K2.5 Kimi K2.5 Multimodal / frontend
xiaomi/mimo-v2.5 MiMo V2.5 Image input supported
Qwen/Qwen3.7-Max Qwen 3.7 Max Large parameters
google/gemini-3.5-flash Gemini 3.5 Flash Reasoning model

⚠️ Some models (e.g. deepseek-v4-flash, claude-sonnet-4-6) do not support image input. Use xiaomi/mimo-v2.5, Kimi-K2.5, or other vision models for multimodal.

Integration Examples

Python (OpenAI SDK)

from openai import OpenAI

client = OpenAI(
    api_key="user_xxxxxxxxx",
    base_url="http://127.0.0.1:3050/v1",
)

response = client.chat.completions.create(
    model="deepseek/deepseek-v4-flash",
    messages=[{"role": "user", "content": "hello"}],
    stream=True,
)
for chunk in response:
    print(chunk.choices[0].delta.content or "", end="")

cURL

curl http://127.0.0.1:3050/v1/chat/completions \
  -H "Authorization: Bearer user_xxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4-flash",
    "messages": [{"role": "user", "content": "hello"}],
    "stream": true
  }'

Cursor

Add a Custom Provider in Cursor settings:

  • API Base URL: http://127.0.0.1:3050/v1
  • API Key: user_xxxxxxxxx
  • Model: Choose from the model list

Anthropic (Python SDK)

import anthropic

client = anthropic.Anthropic(
    api_key="user_xxxxxxxxx",
    base_url="http://127.0.0.1:3050",
)
message = client.messages.create(
    model="deepseek/deepseek-v4-flash",
    max_tokens=1000,
    system="You are helpful.",
    messages=[{"role": "user", "content": "hello"}],
)
print(message.content[0].text)

OpenCode

{
  "provider": "openai-compatible",
  "baseUrl": "http://127.0.0.1:3050/v1",
  "apiKey": "user_xxxxxxxxx"
}

Anti-Detection

Based on analysis of official CLI v0.32.3 traffic:

Mechanism Implementation
Per-Key Session One session per API key, 12h expiry + 1h random jitter
Version x-command-code-version auto-fetched from npm registry (24h refresh)
CLI Envelope config/memory/taste/permissionMode/params/threadId
OpenTelemetry traceparent (W3C Trace Context)
Environment x-cli-environment: production
Project Slug Custom x-project-slug
Reasoning Effort reasoning_effort pass-through (low/medium/high/max)
Key Validation Regex user_[a-zA-Z0-9_-]+, auto-cleans extra paths/prefixes, rejects sk-xxx format
Stream Timeout 30s streaming / 90s non-streaming auto-abort on idle

Protocol Details

CC API Request Structure

{
  "config": {
    "workingDir": "C:\\project",
    "date": "2026-06-07",
    "environment": "win32-x64, Node.js v24.16.0",
    "structure": [],
    "isGitRepo": false,
    "currentBranch": "",
    "mainBranch": "",
    "gitStatus": "",
    "recentCommits": []
  },
  "memory": "",
  "taste": "",
  "skills": "",
  "permissionMode": "standard",
  "params": {
    "model": "deepseek/deepseek-v4-flash",
    "messages": [...],
    "max_tokens": 64000,
    "stream": true,
    "reasoning_effort": "max"
  },
  "threadId": "<uuid>"
}

CC API Image Message Format

The CLI sends images in this format:

{
  "role": "user",
  "content": [
    { "type": "image", "image": "data:image/jpeg;base64,..." },
    { "type": "text", "text": "What does this image say?" }
  ]
}

The proxy receives OpenAI image_url format and converts it to the above CC format transparently.

Disclaimer

This project is for educational and research purposes only.

  • Unofficial: This project is not affiliated with Command Code in any way.
  • Personal Use: Users assume all responsibility. Please comply with the Command Code Terms of Service.
  • API Key: This project does not collect, upload, or leak your API Key. The key must be sent in every request via the Authorization: Bearer <key> header and is never stored in configuration.
  • Compliance: The protocol is based on passive observation of local CLI network traffic. No unauthorized access, cracking, or tampering of the server has been performed.
  • Account Risk: Keep usage frequency consistent with normal CLI usage. Extremely high concurrent calls may trigger risk controls.

Development

# Start with watch mode (auto-reload on file changes)
npm run dev

About

Command Code API → OpenAI 兼容接口的反代代理

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors