Skill skill

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://gith…

Updated Apr 1, 2026 By One Person Company Editorial Team Skill system

Overview

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 ActionHowStart OpenCodebash(command: "opencode acp", background: true)Send messageprocess.write(sessionId, data: "<json-rpc>\n")Read responseprocess.poll(sessionId) - repeat every 2 secondsStop OpenCodeprocess.kill(sessionId)List sessionsbash(command: "opencode session list", workdir: "...")Resume sessionList sessions → ask user → session/loadCheck versionbash(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: {"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

{"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

{"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)

{"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
  • stopReasonMeaningend_turnAgent finished respondingcancelledYou cancelled the promptmax_tokensToken limit reached
  • Error Handling
  • IssueSolutionEmpty poll responseKeep polling - agent is thinkingParse errorSkip malformed line, continueProcess exitedRestart OpenCodeNo response after 5minKill process, start fresh
  • Example: Complete Interaction
  • bash(command: "opencode acp", background: true, workdir: "/home/user/myproject")
  • -> processSessionId: "bg_42"
  • process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":0,"method":"initialize",...}\n')
  • process.poll(sessionId: "bg_42") -> initialize response
  • 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"
  • 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')
  • process.poll(sessionId: "bg_42") every 2 sec until stopReason
  • -> Collect all session/update content
  • -> Final response: stopReason: "end_turn"
  • 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?
  • ses_451cd8ae... (12 messages, updated 2026-01-11)
  • ses_451a89e6... (5 messages, updated 2026-01-10)
  • 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..."):

  • Start OpenCode ACP:
  • bash(command: "opencode acp", background: true, workdir: "/path/to/project")
  • Initialize:
  • {"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}
  • Load the session:
  • {"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:

  • Stop all running OpenCode processes:
  • process.list() # Find all "opencode acp" processes
  • process.kill(sessionId) # For each running instance
  • Restart instances (OpenCode auto-downloads new binary on start):
  • bash(command: "opencode acp", background: true, workdir: "/path/to/project")
  • 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-side

SKILL.md file

Embedded doc viewer SKILL.md
Markdown source

Preview raw SKILL.md. Open the full source below. Scroll, inspect, then download the exact SKILL.md file if you want the original.

# opencode-acp-control

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
ActionHowStart OpenCodebash(command: "opencode acp", background: true)Send messageprocess.write(sessionId, data: "<json-rpc>\n")Read responseprocess.poll(sessionId) - repeat every 2 secondsStop OpenCodeprocess.kill(sessionId)List sessionsbash(command: "opencode session list", workdir: "...")Resume sessionList sessions → ask user → session/loadCheck versionbash(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:
{"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
{"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
{"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)
{"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
stopReasonMeaningend_turnAgent finished respondingcancelledYou cancelled the promptmax_tokensToken limit reached
Error Handling
IssueSolutionEmpty poll responseKeep polling - agent is thinkingParse errorSkip malformed line, continueProcess exitedRestart OpenCodeNo response after 5minKill 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..."):
Start OpenCode ACP:
bash(command: "opencode acp", background: true, workdir: "/path/to/project")
Initialize:
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}
Load the session:
{"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:
Stop all running OpenCode processes:
process.list()  # Find all "opencode acp" processes
process.kill(sessionId) # For each running instance
Restart instances (OpenCode auto-downloads new binary on start):
bash(command: "opencode acp", background: true, workdir: "/path/to/project")
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-side

Comments & Discussion

Add a comment