| name | opencode-driver |
|---|---|
| version | 1.0.0 |
| description | Programmatic OpenCode control via HTTP server API for planning, implementation, and code generation tasks. |
A NetClaw skill for programmatic OpenCode control via its HTTP server API. Drives OpenCode's session/message model for planning, implementation, and code generation tasks.
- OpenCode must be installed (
opencodeon PATH) - OpenCode server must be running (
opencode serve)
| Variable | Purpose |
|---|---|
OPENCODE_API_URL |
Override default server URL (default: http://localhost:4096) |
OPENCODE_SERVER_PASSWORD |
Basic auth password if required |
check_availability→ verify OpenCode is installed, server is running, and providers are connectedcreate_session→ start a new session with titlesend_message→ single-shot (blocking) orsend_message_async→ fire-and-forgetget_session_status→ check for stuck/retry loopsabort_session→ kill a wedged session before starting fresh
Models are objects with providerID and modelID. Configure your preferred providers in your OpenCode config:
| Provider | Model | When to Use |
|---|---|---|
openai |
gpt-4o |
Default for all coding tasks. Fast, cheap, great at real-time codegen. |
openai |
o4-mini (extended thinking) |
Super-complicated tasks. Use when Spark stalls or you need deep reasoning/architecture. Slow but thorough. |
ollama |
qwen2.5-coder:32b or llama3.1:8b |
Local fallback when cloud providers are down or for quick internal checks. |
local-llm |
qwen2.5:32b-instruct |
Local fallback via your dedicated GPU. |
Run this first. Verifies OpenCode is installed, server is reachable, and providers are connected.
# Step 1: Verify binary exists
which opencode
opencode --version
# Step 2: Verify server is responding
GET {OPENCODE_API_URL}/global/health
# Step 3: Verify providers are connected
GET {OPENCODE_API_URL}/provider
Returns success if all three pass. If the server isn't running but the binary is, the skill should start it:
opencode serve --port 4096 --hostname 127.0.0.1 &
Start a new session. Always use this for automation — never reuse old sessions.
POST {OPENCODE_API_URL}/session
Body: { "title": "task-description-here" }
Returns session object with id and slug.
Send a prompt to a session and wait for the full response.
POST {OPENCODE_API_URL}/session/{SESSION_ID}/message
Body: {
"model": { "providerID": "openai", "modelID": "gpt-5.3-codex-spark" },
"parts": [{ "type": "text", "text": "Your prompt here" }],
"thinking": { "type": "enabled", "budget_tokens": 8192 }
}
Critical: Wrap in timeout. If response doesn't return within 60s, abort the session and try again. See "Safety" section.
The thinking field enables OpenAI's effort/extended thinking for Codex. budget_tokens controls how much the model can think before responding.
Fire-and-forget prompt. Returns 204 No Content immediately.
POST {OPENCODE_API_URL}/session/{SESSION_ID}/prompt_async
Body: (same as send_message above)
Check progress via get_session_status or poll GET {OPENCODE_API_URL}/session/status.
Check if a session is ready, busy, or stuck in retry.
GET {OPENCODE_API_URL}/session/status
Returns:
{
"ses_abc123": { "type": "ready" },
"ses_def456": { "type": "busy" },
"ses_ghi789": { "type": "retry", "attempt": 42, "next": 1234567890 }
}If type is "retry", the session is stuck. Do NOT send messages to it. Delete or kill it.
Interrupt a running session (abort in-progress generation).
POST {OPENCODE_API_URL}/session/{SESSION_ID}/abort
Returns true if aborted successfully.
Permanently remove a session and all its data.
DELETE {OPENCODE_API_URL}/session/{SESSION_ID}
List all sessions.
GET {OPENCODE_API_URL}/session
Show available models from configured providers.
GET {OPENCODE_API_URL}/provider
These are non-negotiable for reliable external control:
-
NEVER reuse sessions for automation. Create a new session per task. Delete it when done.
-
Always check session status before sending. If
typeis"retry", the session is permanently stuck until the process is killed. Abort it immediately. -
Always abort before sending to a session that may have prior activity. Call
abort_sessionfirst if there's any chance the session has a hanging request. -
Timeout on all message calls. If a message call doesn't return within 60 seconds, abort that session. OpenCode's retry loops will never recover on their own.
-
Kill stuck processes. If the server itself shows multiple sessions in retry, kill the
opencodeprocess:kill -9 <PID>. Restart the server afterwards. -
No silent failures. If the server returns an error (connection refused, auth failure, model not found), report it and stop — don't retry indefinitely.
check_availability
create_session(title="architecture-plan")
send_message(model="openai/gpt-5.3-codex-spark", text="Design a clean architecture for X...")
→ Receive plan
delete_session()
# Use GPT-5.5 when Spark is too shallow or the problem is highly complex
check_availability
create_session(title="deep-architecture-plan")
send_message(
model="openai/gpt-5.5",
text="Design a high-performance distributed system for X with these constraints: [...]"
)
→ Receive deep analysis
delete_session()
# Step 1: Plan
create_session(title="impl-plan")
send_message(model="openai/gpt-5.3-codex-spark", text="Plan steps for X...")
→ Get plan steps
# Step 2: Implement (new session, passes plan as context)
create_session(title="impl-phase1")
send_message(
model="openai/gpt-5.3-codex-spark",
text="Implement: [paste plan steps]"
)
→ Receive implementation
# Continue existing session with additional context
create_session(title="followup")
send_message(
parent_id="ses_previous_plan", # Optional: reference prior session
text="Based on the previous plan, now implement step 3..."
)
create_session(title="batch-1")
send_message_async(model="openai/gpt-5.3-codex-spark", text="Task A")
create_session(title="batch-2")
send_message_async(model="openai/gpt-5.3-codex-spark", text="Task B")
# Poll until complete
while status["ses_batch_1"].type == "busy" or status["ses_batch_2"].type == "busy":
sleep(2)
status = get_session_status()
# Retrieve results
messages = GET /session/{session_id}/message
OpenCode isn't installed. Install via: npm install -g @opencode-ai/opencode or brew install opencode or curl -fsSL https://opencode.ai/install.sh | bash.
OpenCode server isn't running. Start it: opencode serve --port 4096 --hostname 127.0.0.1 &
The LLM provider is unreachable (OpenAI, Ollama, etc.). Verify the provider is configured and accessible. This is NOT a retry situation — fix the provider and abort the session.
Bad model spec. Models must be {"providerID": "...", "modelID": "..."}, not a string.
Server requires basic auth. Set OPENCODE_SERVER_PASSWORD env var or pass -u opencode -p <password> to curl.
The session has a stuck request. Delete it: DELETE /session/{id} and start fresh. If the process count grows, kill opencode and restart.
Your OpenCode config lives at ~/.config/opencode/opencode.json. The server inherits this config.
Default model (used when not specified in message body):
{
"model": "openai/gpt-5.3-codex-spark"
}You can override per-request by passing the model field in the message body.
- OpenCode sessions maintain full conversation history (message chain)
- The
thinking/budget_tokensfields are OpenAI-specific for Codex extended thinking. Usebudget_tokens: 8192for heavy reasoning tasks on GPT-5.5. - For local models (Ollama, petabridge-big-gpu), omit
thinking— those providers don't support it yet - Each message call is a full LLM round-trip (not streaming)
- SSE events at
GET {OPENCODE_API_URL}/eventprovide real-time output if you want streaming