Skip to content

Latest commit

 

History

History
237 lines (190 loc) · 9.72 KB

README.en.md

File metadata and controls

237 lines (190 loc) · 9.72 KB

OpenCode2API

Version License Node

English | 简体中文

Turns a local OpenCode runtime into an OpenAI-compatible API gateway, so any client can use unlimited free OpenCode Zen models.

✨ Features

  • OpenAI compatible — /v1/models, /v1/chat/completions, /v1/responses with full SSE streaming
  • Reasoning control — supports reasoning_effort and reasoning: {"effort": "high"}
  • Session chaining — Responses API supports previous_response_id, 30-minute TTL, upstream sessions cleaned up on expiry
  • External tool bridge — client-supplied tools return standard tool_calls / function_call from the proxy, never touching OpenCode built-in tools
  • Built-in tool allowlist — requests without tools only allow built-ins listed in OPENCODE_INTERNAL_ALLOWED_TOOLS
  • Observability — /health/details structured diagnostics, /metrics Prometheus metrics
  • Web Panel — optional built-in dashboard at /panel (read-only status/models/diagnostics), off by default
  • Docker deployment — one command starts the stack and the OpenCode backend

🚀 Quick Start

Docker (recommended)

git clone https://github.com/TiaraBasori/opencode2api.git
cd opencode2api
cp .env.example .env        # Edit .env; API_KEY and OPENCODE_SERVER_PASSWORD are required
docker compose up -d
curl http://127.0.0.1:10000/health

The default Compose file does not mount the host project directory, since that would shadow the node_modules baked into the image. Use a separate dev Compose override for source hot-reload.

Node.js (local development)

# Install the OpenCode CLI
npm install -g opencode-ai@1.19.0
# or curl -fsSL https://opencode.ai/install | bash

git clone https://github.com/TiaraBasori/opencode2api.git
cd opencode2api
npm install
cp config.json.example config.json
npm start

💡 Usage Examples

Chat Completions

curl -X POST http://127.0.0.1:10000/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "opencode/big-pickle",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": false
  }'

Responses API (streaming + reasoning)

curl -N -X POST http://127.0.0.1:10000/v1/responses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt5-nano",
    "input": "Say hi in one sentence.",
    "reasoning": {"effort": "high"},
    "stream": true
  }'

External tools

curl -X POST http://127.0.0.1:10000/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "opencode/big-pickle",
    "messages": [{"role": "user", "content": "Fetch https://example.com and tell me the title"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "web_fetch",
        "description": "Fetch a URL and return its content summary",
        "parameters": {
          "type": "object",
          "properties": {"url": {"type": "string"}},
          "required": ["url"]
        }
      }
    }]
  }'

When the model calls tools, non-streaming responses return message.tool_calls and streaming responses return delta.tool_calls.

Anthropic Messages API (/v1/messages)

An endpoint for Claude SDK / Anthropic clients. Authentication uses the x-api-key header (Authorization: Bearer also works), and tool calls come back as tool_use content blocks.

curl -X POST http://127.0.0.1:10000/v1/messages \
  -H "x-api-key: ***" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "opencode/big-pickle",
    "max_tokens": 1024,
    "system": "You are concise.",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'

Tool round-trip (send results back as tool_result blocks):

curl -X POST http://127.0.0.1:10000/v1/messages \
  -H "x-api-key: ***" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "opencode/big-pickle",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Fetch the title of https://example.com"}],
    "tools": [{
      "name": "web_fetch",
      "description": "Fetch a URL and return its content summary",
      "input_schema": {
        "type": "object",
        "properties": {"url": {"type": "string"}},
        "required": ["url"]
      }
    }]
  }'

The response contains a {"type":"tool_use","id":"…","name":"web_fetch","input":{…}} content block (stop_reason: "tool_use"); send the result back as a {"type":"tool_result","tool_use_id":"…","content":"…"} user block to continue the conversation. With stream: true the proxy emits the Anthropic SSE sequence message_start → content_block_* → message_delta → message_stop.

⚙️ Configuration

Environment variable Default Description
API_KEY (empty) Proxy Bearer auth key
OPENCODE_API_KEYS (empty) Multi-user API key list, comma-separated name:key (see Configuration)
OPENCODE_SERVER_PASSWORD (empty) OpenCode backend password
OPENCODE_PROXY_PORT / PORT 10000 Proxy port
OPENCODE_SERVER_PORT 10001 Backend port (applies when OPENCODE_SERVER_URL is not set)
OPENCODE_SERVER_URL http://127.0.0.1:10001 Backend URL
OPENCODE_DISABLE_TOOLS true Disable OpenCode built-in tools
OPENCODE_INTERNAL_ALLOWED_TOOLS (empty) Built-ins allowed when a request has no tools, comma-separated
OPENCODE_PROXY_OMIT_SYSTEM_PROMPT false Ignore the incoming system prompt
OPENCODE_PROXY_AUTO_CLEANUP_CONVERSATIONS false Auto-clean session storage
OPENCODE_USE_ISOLATED_HOME false Use an isolated OpenCode config directory
OPENCODE_WEB_PANEL_ENABLED false Serve the built-in Web Panel at /panel
OPENCODE_PROXY_DEBUG false Debug logging

📄 Full reference: Configuration

Recommended production settings:

API_KEY=your-secret-key
OPENCODE_SERVER_PASSWORD=your-password
OPENCODE_DISABLE_TOOLS=true
OPENCODE_INTERNAL_ALLOWED_TOOLS=web_fetch
OPENCODE_PROXY_OMIT_SYSTEM_PROMPT=true
OPENCODE_PROXY_AUTO_CLEANUP_CONVERSATIONS=true

🔌 API Endpoints

Method Path Description
GET /health Health check
GET /health/details Structured diagnostics (toggle/auth configurable)
GET /metrics Prometheus metrics (toggle/auth configurable)
GET /panel Web Panel page (off by default; enable with OPENCODE_WEB_PANEL_ENABLED=true)
GET /panel/data.json Web Panel data feed (Bearer/PUBLIC_DIAGNOSTICS gated, never returns secret values)
GET /v1/models Model list
POST /v1/chat/completions Chat Completions
POST /v1/responses Responses API
POST /v1/messages Anthropic Messages API (Claude SDK compatible)
GET /admin/keys Multi-user key list and usage (admin auth, available once API_KEYS is configured)
POST /admin/keys Add a user key at runtime (admin auth)
DELETE /admin/keys/:name Remove a user key (admin auth)

Model names: opencode/big-pickle, gpt5-nano (auto-resolved to gpt-5-nano), opencode/gpt5-nano.

📖 See API Reference

👥 Full details on multi-user keys, per-key usage metering, and the admin endpoints: Configuration.

🖥️ Web Panel

Set OPENCODE_WEB_PANEL_ENABLED=true (or "WEB_PANEL_ENABLED": true in config.json) and open http://127.0.0.1:10000/panel in a browser for a read-only dashboard: runtime status (status/uptime/backend URL), the model list, and backend diagnostics (tool-mode counters, cache state). Dark theme, zero external dependencies — no external CSS/JS, CSP locked to same-origin.

With API_KEY configured, enter the proxy key in the page (kept in the browser's localStorage and used to call /panel/data.json); with PUBLIC_DIAGNOSTICS=true or no API_KEY no key is needed. When the panel is disabled both routes return 404, and the data feed never returns any secret values. See Configuration.

🔧 Troubleshooting

  • Requests hang but /v1/models works — set OPENCODE_USE_ISOLATED_HOME=false to reuse the local login state
  • Model not found — run curl http://127.0.0.1:10000/v1/models to confirm the model ID
  • No reasoning output — use the Responses API with stream: true and send reasoning.effort

📖 More: Troubleshooting

📚 Documentation

Document Description
Getting Started Install and first run
Configuration All env vars and config.json
API Reference Endpoints, params, error codes
Docker Deployment Deployment and operations
Troubleshooting Common issues
Development Local development and testing

📄 License

MIT · see LICENSE

🙏 Acknowledgements