opencode-acp-control
Control OpenCode directly via the Agent Client Protocol (ACP). Start sessions, send prompts, resume conversations, and manage OpenCode updates.
Best use case
opencode-acp-control is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Control OpenCode directly via the Agent Client Protocol (ACP). Start sessions, send prompts, resume conversations, and manage OpenCode updates.
Teams using opencode-acp-control should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/opencode-acp-control/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How opencode-acp-control Compares
| Feature / Agent | opencode-acp-control | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Control OpenCode directly via the Agent Client Protocol (ACP). Start sessions, send prompts, resume conversations, and manage OpenCode updates.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
Best AI Skills for Claude
Explore the best AI skills for Claude and Claude Code across coding, research, workflow automation, documentation, and agent operations.
ChatGPT vs Claude for Agent Skills
Compare ChatGPT and Claude for AI agent skills across coding, writing, research, and reusable workflow execution.
SKILL.md Source
# OpenCode ACP Skill
Control OpenCode directly via the Agent Client Protocol (ACP).
## Metadata
- For ACP Protocol Docs (for Agents/LLMs): https://agentclientprotocol.com/llms.txt
- GitHub Repo: https://github.com/bjesuiter/opencode-acp-skill
- If you have issues with this skill, please open an issue ticket here: https://github.com/bjesuiter/opencode-acp-skill/issues
## Quick Reference
| Action | How |
|--------|-----|
| Start OpenCode | `bash(command: "opencode acp", background: true)` |
| Send message | `process.write(sessionId, data: "<json-rpc>\n")` |
| Read response | `process.poll(sessionId)` - repeat every 2 seconds |
| Stop OpenCode | `process.kill(sessionId)` |
| List sessions | `bash(command: "opencode session list", workdir: "...")` |
| Resume session | List sessions → ask user → `session/load` |
| Check version | `bash(command: "opencode --version")` |
## Starting OpenCode
```
bash(
command: "opencode acp",
background: true,
workdir: "/path/to/your/project"
)
```
Save the returned `sessionId` - you'll need it for all subsequent commands.
## Protocol Basics
- All messages are **JSON-RPC 2.0** format
- Messages are **newline-delimited** (end each with `\n`)
- Maintain a **message ID counter** starting at 0
## Step-by-Step Workflow
### Step 1: Initialize Connection
Send immediately after starting OpenCode:
```json
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{"fs":{"readTextFile":true,"writeTextFile":true},"terminal":true},"clientInfo":{"name":"clawdbot","title":"Clawdbot","version":"1.0.0"}}}
```
Poll for response. Expect `result.protocolVersion: 1`.
### Step 2: Create Session
```json
{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/path/to/project","mcpServers":[]}}
```
Poll for response. Save `result.sessionId` (e.g., `"sess_abc123"`).
### Step 3: Send Prompts
```json
{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_abc123","prompt":[{"type":"text","text":"Your question here"}]}}
```
Poll every 2 seconds. You'll receive:
- `session/update` notifications (streaming content)
- Final response with `result.stopReason`
### Step 4: Read Responses
Each poll may return multiple lines. Parse each line as JSON:
- **Notifications**: `method: "session/update"` - collect these for the response
- **Response**: Has `id` matching your request - stop polling when `stopReason` appears
### Step 5: Cancel (if needed)
```json
{"jsonrpc":"2.0","method":"session/cancel","params":{"sessionId":"sess_abc123"}}
```
No response expected - this is a notification.
## State to Track
Per OpenCode instance, track:
- `processSessionId` - from bash tool (clawdbot's process ID)
- `opencodeSessionId` - from session/new response (OpenCode's session ID)
- `messageId` - increment for each request you send
## Polling Strategy
- Poll every **2 seconds**
- Continue until you receive a response with `stopReason`
- Max wait: **5 minutes** (150 polls)
- If no response, consider the operation timed out
## Common Stop Reasons
| stopReason | Meaning |
|------------|---------|
| `end_turn` | Agent finished responding |
| `cancelled` | You cancelled the prompt |
| `max_tokens` | Token limit reached |
## Error Handling
| Issue | Solution |
|-------|----------|
| Empty poll response | Keep polling - agent is thinking |
| Parse error | Skip malformed line, continue |
| Process exited | Restart OpenCode |
| No response after 5min | Kill process, start fresh |
## Example: Complete Interaction
```
1. bash(command: "opencode acp", background: true, workdir: "/home/user/myproject")
-> processSessionId: "bg_42"
2. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":0,"method":"initialize",...}\n')
process.poll(sessionId: "bg_42") -> initialize response
3. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/home/user/myproject","mcpServers":[]}}\n')
process.poll(sessionId: "bg_42") -> opencodeSessionId: "sess_xyz789"
4. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_xyz789","prompt":[{"type":"text","text":"List all TypeScript files"}]}}\n')
5. process.poll(sessionId: "bg_42") every 2 sec until stopReason
-> Collect all session/update content
-> Final response: stopReason: "end_turn"
6. When done: process.kill(sessionId: "bg_42")
```
---
## Resume Session
Resume a previous OpenCode session by letting the user choose from available sessions.
### Step 1: List Available Sessions
```
bash(command: "opencode session list", workdir: "/path/to/project")
```
Example output:
```
ID Updated Messages
ses_451cd8ae0ffegNQsh59nuM3VVy 2026-01-11 15:30 12
ses_451a89e63ffea2TQIpnDGtJBkS 2026-01-10 09:15 5
ses_4518e90d0ffeJIpOFI3t3Jd23Q 2026-01-09 14:22 8
```
### Step 2: Ask User to Choose
Present the list to the user and ask which session to resume:
```
"Which session would you like to resume?
1. ses_451cd8ae... (12 messages, updated 2026-01-11)
2. ses_451a89e6... (5 messages, updated 2026-01-10)
3. ses_4518e90d... (8 messages, updated 2026-01-09)
Enter session number or ID:"
```
### Step 3: Load Selected Session
Once user responds (e.g., "1", "the first one", or "ses_451cd8ae..."):
1. **Start OpenCode ACP**:
```
bash(command: "opencode acp", background: true, workdir: "/path/to/project")
```
2. **Initialize**:
```json
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}
```
3. **Load the session**:
```json
{"jsonrpc":"2.0","id":1,"method":"session/load","params":{"sessionId":"ses_451cd8ae0ffegNQsh59nuM3VVy","cwd":"/path/to/project","mcpServers":[]}}
```
**Note**: `session/load` requires `cwd` and `mcpServers` parameters.
On load, OpenCode streams the full conversation history back to you.
### Resume Workflow Summary
```
function resumeSession(workdir):
# List available sessions
output = bash("opencode session list", workdir: workdir)
sessions = parseSessionList(output)
if sessions.empty:
notify("No previous sessions found. Starting fresh.")
return createNewSession(workdir)
# Ask user to choose
choice = askUser("Which session to resume?", sessions)
selectedId = matchUserChoice(choice, sessions)
# Start OpenCode and load session
process = bash("opencode acp", background: true, workdir: workdir)
initialize(process)
session_load(process, selectedId, workdir, mcpServers: [])
notify("Session resumed. Conversation history loaded.")
return process
```
### Important Notes
- **History replay**: On load, all previous messages stream back
- **Memory preserved**: Agent remembers the full conversation
- **Process independent**: Sessions survive OpenCode restarts
---
## Updating OpenCode
OpenCode auto-updates when restarted. Use this workflow to check and trigger updates.
### Step 1: Check Current Version
```
bash(command: "opencode --version")
```
Returns something like: `opencode version 1.1.13`
Extract the version number (e.g., `1.1.13`).
### Step 2: Check Latest Version
```
webfetch(url: "https://github.com/anomalyco/opencode/releases/latest", format: "text")
```
The redirect URL contains the latest version tag:
- Redirects to: `https://github.com/anomalyco/opencode/releases/tag/v1.2.0`
- Extract version from the URL path (e.g., `1.2.0`)
### Step 3: Compare and Update
If latest version > current version:
1. **Stop all running OpenCode processes**:
```
process.list() # Find all "opencode acp" processes
process.kill(sessionId) # For each running instance
```
2. **Restart instances** (OpenCode auto-downloads new binary on start):
```
bash(command: "opencode acp", background: true, workdir: "/path/to/project")
```
3. **Re-initialize** each instance (initialize + session/load for existing sessions)
### Step 4: Verify Update
```
bash(command: "opencode --version")
```
If version still doesn't match latest:
- Inform user: "OpenCode auto-update may have failed. Current: X.X.X, Latest: Y.Y.Y"
- Suggest manual update: `curl -fsSL https://opencode.dev/install | bash`
### Update Workflow Summary
```
function updateOpenCode():
current = bash("opencode --version") # e.g., "1.1.13"
latestPage = webfetch("https://github.com/anomalyco/opencode/releases/latest")
latest = extractVersionFromRedirectUrl(latestPage) # e.g., "1.2.0"
if semverCompare(latest, current) > 0:
# Stop all instances
for process in process.list():
if process.command.includes("opencode"):
process.kill(process.sessionId)
# Wait briefly for processes to terminate
sleep(2 seconds)
# Restart triggers auto-update
bash("opencode acp", background: true)
# Verify
newVersion = bash("opencode --version")
if newVersion != latest:
notify("Auto-update may have failed. Manual update recommended.")
else:
notify("OpenCode is up to date: " + current)
```
### Important Notes
- **Sessions persist**: `opencodeSessionId` survives restarts — use `session/load` to recover
- **Auto-update**: OpenCode downloads new binary automatically on restart
- **No data loss**: Conversation history is preserved server-sideRelated Skills
opencode-controller
Control and operate Opencode via slash commands. Use this skill to manage sessions, select models, switch agents (plan/build), and coordinate coding through Opencode.
portfolio-watcher
Monitor stock/crypto holdings, get price alerts, track portfolio performance
portainer
Control Docker containers and stacks via Portainer API. List containers, start/stop/restart, view logs, and redeploy stacks from git.
portable-tools
Build cross-device tools without hardcoding paths or account names
polymarket
Trade prediction markets on Polymarket. Analyze odds, place bets, track positions, automate alerts, and maximize returns from event outcomes. Covers sports, politics, entertainment, and more.
polymarket-traiding-bot
No description provided.
polymarket-analysis
Analyze Polymarket prediction markets for trading edges. Pair Cost arbitrage, whale tracking, sentiment analysis, momentum signals, user profile tracking. No execution.
polymarket-agent
Autonomous prediction market agent - analyzes markets, researches news, and identifies trading opportunities
polymarket-5
Query Polymarket prediction markets. Use for questions about prediction markets, betting odds, market prices, event probabilities, or when user asks about Polymarket data.
polymarket-4
Query Polymarket prediction markets. Use for questions about prediction markets, betting odds, market prices, event probabilities, or when user asks about Polymarket data.
polymarket-3
Query Polymarket prediction market odds and events via CLI. Search for markets, get current prices, list events by category. Supports sports betting (NFL, NBA, soccer/EPL, Champions League), politics, crypto, elections, geopolitics. Real money markets = more accurate than polls. No API key required. Use when asked about odds, probabilities, predictions, or "what are the chances of X".
polymarket-2
Query Polymarket prediction markets - check odds, trending markets, search events, track prices.