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.
Scanned 9/7/2026
Install to Claude Code
npx -y skills add modbender/skill-library-mcp --skill opencode-api-control-skill --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Opencode Api Control Skill?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/modbender-opencode-api-control-skill)More formats (shields.io, HTML) on the badges page.
---
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
- **You are NOT the Coder**: You do not write or verify code directly. OpenCode handles the implementation.
- **You are the Orchestrator**: You send high-level instructions to OpenCode, monitor its progress, and report the outcome to the user.
- **Trust the System**: OpenCode is responsible for its own file operations. Your job is to wait for it to finish and then check the *status* and *diff summary*, not the file contents.
## When to Use
- User requests creating or managing projects through OpenCode
- User asks for coding tasks, debugging, or code analysis via OpenCode
- User wants AI-powered development with specific providers/models
- User needs to manage multiple OpenCode sessions or monitor tasks
## Prerequisites
1. OpenCode server running (Preferred: `bash ./scripts/start_server.sh`)
2. Configuration file exists: `./config.json`
3. Required scripts in `./scripts/` directory
## Configuration
Read settings from `./config.json`:
```bash
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**:
- ❌ **NEVER** read or edit the code files generated by OpenCode directly for development tasks.
- ❌ **NEVER** try to fix or verify code logic by inspecting the project files yourself.
- ✅ **MAY** use `ls` or simple directory checks only to confirm file existence if necessary.
- ⚠️ **PREFER** using the provided scripts and API for all project-related information.
**Required Workflow**:
- ✅ **PRIMARY**: Use `monitor_session.sh` or `check_status.sh` to track progress.
- ✅ **PRIMARY**: Use `get_diff.sh` to see a summary of what was changed.
- ✅ **ALWAYS** report the results based on the API response or script output.
- ✅ **TRUST** OpenCode's implementation of the requested features.
### 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**:
```bash
# Start server using the robust backgrounding script
bash ./scripts/start_server.sh
# 3. 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)**
```bash
# Start task
bash ./scripts/send_message.sh "Complex task" &
# Monitor events (blocks until completion)
bash ./scripts/monitor_session.sh
```
**Option 2: Intelligent polling**
```bash
# For environments where event streaming is unreliable
bash ./scripts/send_message.sh "Build application"
# Smart polling with exponential backoff
SLEEP_TIME=2
MAX_SLEEP=30
while 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**
```bash
# For predictable task durations
bash ./scripts/send_message.sh "Quick task"
# Wait reasonable time before checking
sleep 10
# Then check once
if [ "$(bash ./scripts/check_status.sh)" = "idle" ]; then
bash ./scripts/get_diff.sh
fi
```
**Anti-patterns to AVOID**:
- ❌ Checking status every 1-2 seconds (wastes resources)
- ❌ Reading files repeatedly to see if task is done
- ❌ Using `ls` or file system checks for progress
- ❌ Making multiple API calls without waiting
**Best practices**:
- ✅ Use `monitor_session.sh` for real-time updates
- ✅ Use exponential backoff for polling (start 2s, increase to 30s)
- ✅ Estimate task duration and wait appropriately
- ✅ Only check final results after confirmation of completion
- ✅ Let OpenCode agents work independently - don't micromanage
## Task 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
- **Standard mode**: Uses `send_message.sh` → waits → shows final summary. Efficient for most tasks.
- **Real-time mode**: Uses `monitor_session.sh` with event streaming. Good for long/complex tasks where you want visibility.
### Example Response Handling
- "Default provider, standard mode" → Proceed immediately
- "Use Claude Sonnet, real-time" → Run `select_provider.sh` then `monitor_session.sh`
- "Gemini Pro" → Find provider + ask monitoring preference if not specified
---
### Task Completion Verification
When a task completes, get summary via:
```bash
# Get file changes summary (not individual files)
bash ./scripts/get_diff.sh
# Output 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**:
- User explicitly asks to see code
- User requests explanation of specific implementation
- Debugging a reported issue
Otherwise, trust the diff summary and OpenCode's implementation.
## Core Workflow
### Step 1: Verify Server
```bash
# Check health
curl -s "$BASE_URL/global/health" | jq
# Expected: {"healthy": true, "version": "..."}
```
### Step 2: Update Providers Cache
```bash
# 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**:
```bash
PROJECT_NAME="dashboard-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
mkdir -p "$PROJECT_PATH"
```
**Existing Project**:
```bash
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:
```bash
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECT_PATH" "Session Title")
```
### Step 5: Save Session State
```bash
# 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:
```bash
# 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)
```bash
# 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
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:
```bash
# 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
bash ./scripts/send_message.sh "Build app"
```
**Planning phase**:
```bash
bash ./scripts/send_message.sh "Analyze requirements" "plan"
```
**Implementation phase**:
```bash
bash ./scripts/send_message.sh "Implement features" "build"
```
## Common Patterns
### Pattern 1: New Project from Scratch
```bash
# 1. Update providers
bash ./scripts/update_providers.sh
# 2. 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
```bash
# 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
```bash
# 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
```bash
# 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:
```bash
# Start monitoring (shows progress in real-time)
bash ./scripts/monitor_session.sh
# This 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/`:
```bash
# 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_PATH
# Save 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
bash ./scripts/get_diff.sh
```
Get file content:
```bash
curl -s "$BASE_URL/file/content?directory=$PROJECT_PATH&path=src/App.tsx" \
jq -r '.content'
```
List directory:
```bash
curl -s "$BASE_URL/file?directory=$PROJECT_PATH&path=src" \
jq -r '.[] | "\(.type): \(.path)"'
```
## Error Handling
All scripts return proper exit codes:
- `0` = Success
- `1` = Error
Check script status:
```bash
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"**:
```bash
# Load or create session first
bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
```
**"Provider not found"**:
```bash
# Update providers cache
bash ./scripts/update_providers.sh
# Check available providers
jq -r '.providers[] | .id' ./providers.json
```
**"HTML response instead of JSON"**:
- Missing `directory` parameter
- Check: Are you using full PROJECT_PATH?
## Advanced Usage
For complex workflows, state management, or advanced patterns, see:
- `Reference/STATE_MANAGEMENT.md` - Advanced state handling
- `Reference/PROVIDERS_REFERENCE.md` - Provider selection details
- `Reference/EVENTS_GUIDE.md` - Event monitoring patterns
- `Reference/COMPLETE_EXAMPLES.md` - Full workflow examples
- `Reference/API_QUICK_REFERENCE.md` - Raw API endpoints
## Directory 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](https://github.com/malek262) | **Repository:** [OpenCode-CLI-Controller](https://github.com/malek262/opencode-api-control-skill)Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!