OpenCode CLI API Controller
by @malek262
A powerful skill to control Open Code CLI via a local web server API. Allows executing commands, managing sessions, and automating code generation remotely i...
clawhub install opencode-api-control-skillπ About This Skill
name: OpenCode-CLI-Controller description: A powerful skill to control Open Code CLI via a local web server API. Allows executing commands, managing sessions, and automating code generation remotely in the local network. version: 1.1.0 emoji: ποΈ author: Malek-Rsh tags: - cli - api - automation - web-server - opencode metadata: openclaw: requires: bins: - curl - jq - bash
install: | chmod +x scripts/*.sh if ! command -v jq &> /dev/null; then echo "Warning: jq is required but not installed." fi run: | echo "OpenCode Control Skill is ready for use." echo "Please ensure the OpenCode server is running on port 4099."
OpenCode CLI API Control
> [!IMPORTANT]
> OPERATIONAL GUIDELINES:
> While you may use ls or basic file system checks to verify that files/directories exist, you are EXPLICITLY PROHIBITED from reading or modifying the project's source code files directly.
> Your primary channel for task execution and progress monitoring is the OpenCode API and the provided scripts.
Overview
This skill provides a set of tools to programmatically interface with the Open Code CLI through its local web server API. It enables you to act as a Supervisor/Orchestrator who directs OpenCode to handle all coding, file operations, and quality checks.Core Mandate: Orchestrator vs. Executor
When to Use
Prerequisites
1. OpenCode server running (Preferred:bash ./scripts/start_server.sh)
2. Configuration file exists: ./config.json
3. Required scripts in ./scripts/ directoryConfiguration
Read settings from ./config.json:
BASE_URL=$(jq -r '.base_url' ./config.json)
PROJECTS_DIR=$(jq -r '.projects_base_dir' ./config.json)
Important Agent Responsibilities
Your Role as Orchestrator
You are the supervisor and communication bridge between the user and OpenCode.Operational Boundaries:
ls or simple directory checks only to confirm file existence if necessary.Required Workflow:
monitor_session.sh or check_status.sh to track progress.get_diff.sh to see a summary of what was changed.Server Initialization Wait
CRITICAL: After starting OpenCode web server, it takes 10-15 seconds to fully initialize. You MUST verify server readiness before sending any requests.
Correct initialization sequence:
# Start server using the robust backgrounding script
bash ./scripts/start_server.sh3. Now safe to proceed with operations
bash ./scripts/update_providers.sh
... continue workflow
Never send requests immediately after starting the server - always verify health first.
Intelligent Task Monitoring
For long-running tasks, use smart monitoring strategies:
Option 1: Event-based monitoring (Recommended)
# Start task
bash ./scripts/send_message.sh "Complex task" &Monitor events (blocks until completion)
bash ./scripts/monitor_session.sh
Option 2: Intelligent polling
# For environments where event streaming is unreliable
bash ./scripts/send_message.sh "Build application"Smart polling with exponential backoff
SLEEP_TIME=2
MAX_SLEEP=30while true; do
STATUS=$(bash ./scripts/check_status.sh)
if [ "$STATUS" = "idle" ]; then
echo "β Task completed"
break
elif [ "$STATUS" = "busy" ]; then
echo "β³ Still working... (checking again in ${SLEEP_TIME}s)"
sleep $SLEEP_TIME
# Increase wait time (but cap at MAX_SLEEP)
SLEEP_TIME=$((SLEEP_TIME < MAX_SLEEP ? SLEEP_TIME + 2 : MAX_SLEEP))
else
echo "β Unexpected status: $STATUS"
break
fi
done
Option 3: Timeout-based waiting
# For predictable task durations
bash ./scripts/send_message.sh "Quick task"Wait reasonable time before checking
sleep 10Then check once
if [ "$(bash ./scripts/check_status.sh)" = "idle" ]; then
bash ./scripts/get_diff.sh
fi
Anti-patterns to AVOID:
ls or file system checks for progressBest practices:
monitor_session.sh for real-time updatesTask Initiation Protocol
Before starting any task (new project, code analysis, debugging, etc.), ask the user in ONE message:
> I'll help you with that. Two quick questions: > 1. Provider: Use default from config, or specify a provider (opencode, anthropic, gemini, etc.)? > 2. Monitoring: > - Standard (recommended): Send task β wait for completion summary β notify you when done (saves tokens) > - Real-time: Show live progress, file edits, and events as they happen (uses more tokens) > > How would you like to proceed?
Default if not specified: Use config defaults + Standard mode.
Why This Matters
send_message.sh β waits β shows final summary. Efficient for most tasks.monitor_session.sh with event streaming. Good for long/complex tasks where you want visibility.Example Response Handling
select_provider.sh then monitor_session.shTask Completion Verification
When a task completes, get summary via:
# Get file changes summary (not individual files)
bash ./scripts/get_diff.shOutput example:
added: src/App.tsx (+120/-0)
modified: package.json (+5/-2)
added: src/components/Dashboard.tsx (+89/-0)
This gives you all information needed to report to the user without reading actual file contents.
Only read specific files if:
Otherwise, trust the diff summary and OpenCode's implementation.
Core Workflow
Step 1: Verify Server
# Check health
curl -s "$BASE_URL/global/health" | jqExpected: {"healthy": true, "version": "..."}
Step 2: Update Providers Cache
# Run provider update script
bash ./scripts/update_providers.sh
This caches only connected providers to ./providers.json.
Step 3: Create or Select Project
New Project:
PROJECT_NAME="dashboard-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
mkdir -p "$PROJECT_PATH"
Existing Project:
PROJECT_NAME="existing-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
Verify exists
[ -d "$PROJECT_PATH" ] || { echo "Project not found"; exit 1; }
Step 4: Create Session
Create a session in the project directory using the provided script:SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECT_PATH" "Session Title")
Step 5: Save Session State
# Use state management script
bash ./scripts/save_state.sh "$SESSION_ID" "$PROJECT_PATH"
Step 6: Send Message
Use the provided script to send prompts to the AI:# Use defaults from config
bash ./scripts/send_message.sh "Your prompt here"Or use a specific provider and model
bash ./scripts/send_message.sh "Your prompt" "anthropic" "claude-sonnet-4-5"
Step 7: Monitor Progress (For Long Tasks)
# Start monitoring in background
bash ./scripts/monitor_session.sh &Or check status periodically
bash ./scripts/check_status.sh
Provider Selection
Automatic (uses default from config.json)
bash ./scripts/send_message.sh "Create app"
User Specifies Provider
When the user specifies a provider (e.g., "use Gemini Pro" or "with Claude Sonnet"), use the search script:# Search for provider and model hints
RESULT=$(bash ./scripts/select_provider.sh "gemini" "pro")
Returns: gemini gemini-3-pro
Extract and use the returned values
PROVIDER_ID=$(echo "$RESULT" | cut -d' ' -f1)
MODEL_ID=$(echo "$RESULT" | cut -d' ' -f2)bash ./scripts/send_message.sh "Your prompt" "$PROVIDER_ID" "$MODEL_ID"
Agent Selection
Default (no agent specified - recommended):
bash ./scripts/send_message.sh "Build app"
Planning phase:
bash ./scripts/send_message.sh "Analyze requirements" "plan"
Implementation phase:
bash ./scripts/send_message.sh "Implement features" "build"
Common Patterns
Pattern 1: New Project from Scratch
# 1. Update providers
bash ./scripts/update_providers.sh2. Create project directory
mkdir -p "$PROJECTS_DIR/new-app"3. Create session
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECTS_DIR/new-app" "New App")4. Send initial task
bash ./scripts/send_message.sh "Create React app with TypeScript and Tailwind"5. Monitor progress
bash ./scripts/monitor_session.sh
Pattern 2: Continue Existing Project
# 1. Load saved project state
bash ./scripts/load_project.sh "existing-app"2. Send new task
bash ./scripts/send_message.sh "Add authentication feature"
Pattern 3: Multi-Phase Development
# Phase 1: Planning
bash ./scripts/create_session.sh "$PROJECT_PATH" "Planning"
bash ./scripts/send_message.sh "Plan e-commerce platform" "plan"Phase 2: Implementation
bash ./scripts/send_message.sh "Implement the plan" "build"Phase 3: Review
bash ./scripts/get_diff.sh
Pattern 4: Use Specific Provider
# User says: "Create dashboard using Claude Sonnet"1. Select provider
PROVIDER_MODEL=$(bash ./scripts/select_provider.sh "claude" "sonnet")
PROVIDER_ID=$(echo "$PROVIDER_MODEL" | cut -d' ' -f1)
MODEL_ID=$(echo "$PROVIDER_MODEL" | cut -d' ' -f2)2. Create project and session
mkdir -p "$PROJECTS_DIR/dashboard"
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECTS_DIR/dashboard" "Dashboard")3. Send with selected provider
bash ./scripts/send_message.sh "Create dashboard" "$PROVIDER_ID" "$MODEL_ID"
Event Monitoring
For long-running tasks, monitor events:
# Start monitoring (shows progress in real-time)
bash ./scripts/monitor_session.shThis will:
- Show text deltas as they're generated
- Display status changes (busy/idle)
- Show final token count and cost
- Exit when task completes
State Management
All session state is saved in ./state/:
# Save current session
bash ./scripts/save_state.sh "$SESSION_ID" "$PROJECT_PATH"Load state (sets environment variables)
source ./scripts/load_state.sh
echo $SESSION_ID
echo $PROJECT_PATHSave project-specific state
bash ./scripts/save_project.sh "project-name"Load project-specific state
bash ./scripts/load_project.sh "project-name"List all saved projects
ls -1 ./state/*.json | grep -v current.json | xargs -n1 basename .json
File Operations
Get session changes:
bash ./scripts/get_diff.sh
Get file content:
curl -s "$BASE_URL/file/content?directory=$PROJECT_PATH&path=src/App.tsx" \
jq -r '.content'
List directory:
curl -s "$BASE_URL/file?directory=$PROJECT_PATH&path=src" \
jq -r '.[] | "\(.type): \(.path)"'
Error Handling
All scripts return proper exit codes:
0 = Success1 = ErrorCheck script status:
if bash ./scripts/send_message.sh "prompt"; then
echo "Success"
else
echo "Failed - check server or authentication"
fi
Authentication
This skill assumes the OpenCode server is running in a trusted local environment and does not use password authentication by default.
Quick Reference
| Task | Command |
|------|---------|
| Update providers | bash ./scripts/update_providers.sh |
| Create session | bash ./scripts/create_session.sh "$PATH" "Title" |
| Send message | bash ./scripts/send_message.sh "prompt" |
| With provider | bash ./scripts/send_message.sh "prompt" "provider" "model" |
| Monitor progress | bash ./scripts/monitor_session.sh |
| Check status | bash ./scripts/check_status.sh |
| Get changes | bash ./scripts/get_diff.sh |
| Save state | bash ./scripts/save_state.sh "$SID" "$PATH" |
| Load state | source ./scripts/load_state.sh |
| Save project | bash ./scripts/save_project.sh "name" |
| Load project | bash ./scripts/load_project.sh "name" |
| Select provider | bash ./scripts/select_provider.sh "name" "model" |
Important Notes
1. Always run from skill directory: Scripts use relative paths 2. Update providers at workflow start: Ensures cache is fresh 3. Create projects in PROJECTS_BASE_DIR: Configured in config.json 4. Each session belongs to one project directory: Don't mix 5. Load state before curl commands: Ensures variables are set 6. Scripts handle authentication: No need to add headers manually
Troubleshooting
"No active session":
# Load or create session first
bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
"Provider not found":
# Update providers cache
bash ./scripts/update_providers.shCheck available providers
jq -r '.providers[] | .id' ./providers.json
"HTML response instead of JSON":
directory parameterAdvanced Usage
For complex workflows, state management, or advanced patterns, see:
Reference/STATE_MANAGEMENT.md - Advanced state handlingReference/PROVIDERS_REFERENCE.md - Provider selection detailsReference/EVENTS_GUIDE.md - Event monitoring patternsReference/COMPLETE_EXAMPLES.md - Full workflow examplesReference/API_QUICK_REFERENCE.md - Raw API endpointsDirectory Structure
opencode-api-control/
βββ SKILL.md # This file
βββ config.json # Configuration
βββ providers.json # Connected providers cache
βββ scripts/ # Helper scripts
β βββ update_providers.sh
β βββ create_session.sh
β βββ send_message.sh
β βββ monitor_session.sh
β βββ check_status.sh
β βββ get_diff.sh
β βββ save_state.sh
β βββ load_state.sh
β βββ save_project.sh
β βββ load_project.sh
β βββ select_provider.sh
βββ state/ # Session state
β βββ current.json
β βββ project-name.json
βββ Reference/ # Reference docs
βββ STATE_MANAGEMENT.md
βββ PROVIDERS_REFERENCE.md
βββ EVENTS_GUIDE.md
βββ COMPLETE_EXAMPLES.md
βββ API_QUICK_REFERENCE.md
Author: Malek RSH | Repository: OpenCode-CLI-Controller
β‘ When to Use
βοΈ Configuration
Read settings from ./config.json:
BASE_URL=$(jq -r '.base_url' ./config.json)
PROJECTS_DIR=$(jq -r '.projects_base_dir' ./config.json)
π Tips & Best Practices
"No active session":
# Load or create session first
bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
"Provider not found":
# Update providers cache
bash ./scripts/update_providers.shCheck available providers
jq -r '.providers[] | .id' ./providers.json
"HTML response instead of JSON":
directory parameter