| description | Remote system administration and shell execution through the OpenCode AI Server REST API for Windows, macOS, and Linux systems with full shell access, file operations, and process management |
| name | opencode-api |
OpenCode Remote Execution Skill
Autonomous System Administration Agent
Full shell access and remote execution capabilities through the OpenCode AI Server REST API for Windows, macOS, and Linux systems.
What I Do
I am a remote system administration skill that provides full access to execute shell commands and perform operations on connected systems through the OpenCode AI Server REST API. I enable:
- Full Shell Access: Execute any shell command on Windows (PowerShell/CMD/pwsh), macOS (zsh/bash), and Linux (bash/sh)
- File System Operations: Read, write, create, delete, and modify any files and directories
- Process Management: Start, stop, monitor, and manage system processes and services
- Network Operations: Configure networking, test connectivity, manage firewall rules
- Software Management: Install, update, remove applications and packages
- System Configuration: Modify system settings, environment variables, and configurations
- Log Analysis: Access and analyze system logs, event logs, and application logs
- User Management: Create, modify, and manage user accounts and permissions
When to Use Me
Use this skill when you need to:
- Execute commands on remote Windows, macOS, or Linux systems
- Perform system administration tasks through REST API
- Automate multi-system operations
- Run health checks and diagnostics on remote servers
- Deploy or configure software remotely
- Access and manage files on remote systems
- Execute AI-assisted tasks on connected servers
Server Configuration
opencode_server:
port: 9899
base_url: "http://<hostname>:9899"
endpoints:
documentation: "/doc"
shell: "/session/:id/shell"
config: "/config"
content_type: "application/json"
timeout: 300
Default Model Configuration
IMPORTANT: Always use this exact model configuration for all API calls:
{
"model": {
"providerID": "openrouter",
"modelID": "anthropic/claude-opus-4.5"
}
}
This is the required model configuration. Do not use other models.
Recommended Approach: Send Message Endpoint
The most reliable method for executing tasks is using the /session/:id/message POST endpoint with AI assistance. This allows the AI to automatically execute commands and return structured results.
Proven Working Pattern
SESSION=$(curl -s -X POST "http://<IP_ADDRESS>:9899/session" \
-H "Content-Type: application/json" \
-d '{"title":"Task Description"}' | jq -r '.id')
curl -s -X POST "http://<IP_ADDRESS>:9899/session/${SESSION}/message" \
-H "Content-Type: application/json" \
-d '{
"model": {"providerID": "openrouter", "modelID": "anthropic/claude-opus-4.5"},
"parts": [{"type": "text", "text": "Your task description here"}]
}'
sleep 90
curl -s "http://<IP_ADDRESS>:9899/session/${SESSION}/message" | jq 'length'
curl -s "http://<IP_ADDRESS>:9899/session/${SESSION}/message" | jq -r '.[1].parts[].state.output'
Response Structure
The AI response contains tool execution results in this structure:
{
"info": {"role": "assistant", "modelID": "anthropic/claude-opus-4.5", ...},
"parts": [
{"type": "step-start"},
{"type": "tool", "tool": "bash", "state": {"status": "completed", "output": "..."}},
{"type": "tool", "tool": "bash", "state": {"status": "completed", "output": "..."}},
{"type": "step-finish"}
]
}
Extract results with: jq -r '.[1].parts[].state.output'
API Endpoints
| Tool | Endpoint | Method | Purpose |
|---|
reference_api | /doc | GET | Always reference API specification first |
get_config | /config | GET | Retrieve server configuration |
create_session | /session | POST | Create execution session |
list_sessions | /session | GET | List all sessions |
get_session | /session/:id | GET | Get session details |
delete_session | /session/:id | DELETE | Remove session |
execute_shell | /session/:id/shell | POST | Execute shell commands |
send_message | /session/:id/message | POST | Send AI-assisted message |
get_messages | /session/:id/message | GET | Retrieve session messages |
abort_session | /session/:id/abort | POST | Abort running operation |
list_files | /file?path=<path> | GET | List directory contents |
read_file | /file/content?path=<path> | GET | Read file content |
search_files | /find?pattern=<pat> | GET | Search for text patterns |
find_files | /find/file?query=<q> | GET | Find files by name |
Operational Protocol
Phase 1: Initialize
1. Reference API Documentation
curl -s "http://<SERVER>:9899/doc"
2. Verify Server Configuration
curl -s "http://<SERVER>:9899/config" | jq .
3. Create Execution Session
curl -s -X POST "http://<SERVER>:9899/session" \
-H "Content-Type: application/json" \
-d '{"title":"Agent Execution Session"}'
Phase 2: Execute
4. Run Shell Commands
curl -s -X POST "http://<SERVER>:9899/session/${SESSION_ID}/shell" \
-H "Content-Type: application/json" \
-d '{"agent":"default","command":"<COMMAND>"}'
Phase 3: Retrieve
5. Get Command Output
curl -s "http://<SERVER>:9899/session/${SESSION_ID}/message" | jq .
Phase 4: Cleanup (Optional)
6. Delete Session
curl -s -X DELETE "http://<SERVER>:9899/session/${SESSION_ID}"
Tool Schemas
execute_shell
{
"name": "execute_shell",
"description": "Execute shell command on remote server",
"endpoint": "/session/:id/shell",
"method": "POST",
"parameters": {
"session_id": {
"type": "string",
"required": true,
"description": "Active session ID"
},
"command": {
"type": "string",
"required": true,
"description": "Shell command to execute"
},
"agent": {
"type": "string",
"default": "default",
"description": "Agent to use for execution"
},
"model": {
"type": "object",
"required": true,
"properties": {
"providerID": {"type": "string"},
"modelID": {"type": "string"}
}
}
}
}
create_session
{
"name": "create_session",
"description": "Create a new execution session",
"endpoint": "/session",
"method": "POST",
"parameters": {
"title": {
"type": "string",
"required": false,
"description": "Session title for identification"
},
"parentID": {
"type": "string",
"required": false,
"description": "Parent session ID for forking"
}
}
}
send_message
{
"name": "send_message",
"description": "Send AI-assisted message with context",
"endpoint": "/session/:id/message",
"method": "POST",
"parameters": {
"session_id": {
"type": "string",
"required": true
},
"parts": {
"type": "array",
"required": true,
"items": {
"type": {"type": "string", "enum": ["text", "image"]},
"text": {"type": "string"}
}
},
"model": {
"type": "object",
"required": true,
"properties": {
"providerID": {"type": "string"},
"modelID": {"type": "string"}
}
}
}
}
Encoding Standards
JSON Encoding (Required)
Always use jq for proper JSON escaping:
jq -n --arg cmd 'echo "Hello" && ls -la' '{agent: "default", command: $cmd}'
URL Encoding
For query parameters with special characters:
ENCODED=$(printf '%s' "/path/with spaces" | jq -sRr @uri)
curl -s "http://<SERVER>:9899/file/content?path=${ENCODED}"
Base64 Encoding (Complex Commands)
For multi-line or heavily escaped commands:
ENCODED_CMD=$(echo -n 'complex command' | base64)
COMMAND="echo $ENCODED_CMD | base64 -d | sh"
Platform-Specific Commands
Windows (PowerShell)
{"agent": "default", "command": "pwsh -Command \"Get-Process\""}
{"agent": "default", "command": "pwsh -Command \"Get-Service | Where-Object {$_.Status -eq 'Running'}\""}
{"agent": "default", "command": "pwsh -Command \"Get-EventLog -LogName System -Newest 50\""}
{"agent": "default", "command": "pwsh -Command \"Get-PSDrive -PSProvider FileSystem\""}
{"agent": "default", "command": "pwsh -Command \"Get-NetTCPConnection -State Listen\""}
macOS
{"agent": "default", "command": "system_profiler SPSoftwareDataType SPHardwareDataType"}
{"agent": "default", "command": "df -h && free -m 2>/dev/null || vm_stat"}
{"agent": "default", "command": "ps aux | head -20"}
{"agent": "default", "command": "netstat -an | grep LISTEN"}
{"agent": "default", "command": "log show --predicate 'eventMessage contains \"error\"' --last 1h"}
{"agent": "default", "command": "launchctl list"}
Linux
{"agent": "default", "command": "uname -a && cat /etc/os-release"}
{"agent": "default", "command": "free -h && df -h"}
{"agent": "default", "command": "systemctl list-units --type=service --state=running"}
{"agent": "default", "command": "journalctl -p err --since '1 hour ago'"}
{"agent": "default", "command": "ss -tulpn"}
{"agent": "default", "command": "top -bn1 | head -20"}
Execution Templates
Template: System Health Check
#!/bin/bash
SERVER="http://<HOST>:9899"
curl -s "${SERVER}/doc" > /dev/null
SESSION_ID=$(curl -s -X POST "${SERVER}/session" \
-H "Content-Type: application/json" \
-d '{"title":"Health Check"}' | jq -r '.id')
for CMD in "hostname" "uptime" "df -h" "free -h" "ps aux --sort=-%mem | head -10"; do
curl -s -X POST "${SERVER}/session/${SESSION_ID}/shell" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg c "$CMD" '{agent:"default",command:$c}')"
done
curl -s "${SERVER}/session/${SESSION_ID}/message" | jq '.[] | .parts[] | .text'
Template: Execute with AI Assistance (RECOMMENDED)
#!/bin/bash
SERVER="http://<IP_ADDRESS>:9899"
TASK="$1"
SESSION_ID=$(curl -s -X POST "${SERVER}/session" \
-H "Content-Type: application/json" \
-d '{"title":"AI Assisted Task"}' | jq -r '.id')
echo "Session: $SESSION_ID"
curl -s -X POST "${SERVER}/session/${SESSION_ID}/message" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$TASK" '{
model: {providerID: "openrouter", modelID: "anthropic/claude-opus-4.5"},
parts: [{type: "text", text: $t}]
}')" > /dev/null
echo "Processing..."
sleep 90
MSG_COUNT=$(curl -s "${SERVER}/session/${SESSION_ID}/message" | jq 'length')
echo "Messages: $MSG_COUNT"
curl -s "${SERVER}/session/${SESSION_ID}/message" | jq -r '.[1].parts[] | select(.state.output) | .state.output'
Template: Database Query via AI
#!/bin/bash
SERVER="http://<IP_ADDRESS>:9899"
SESSION=$(curl -s -X POST "${SERVER}/session" \
-H "Content-Type: application/json" \
-d '{"title":"Database Query"}' | jq -r '.id')
curl -s -X POST "${SERVER}/session/${SESSION}/message" \
-H "Content-Type: application/json" \
-d '{
"model": {"providerID": "openrouter", "modelID": "anthropic/claude-opus-4.5"},
"parts": [{"type": "text", "text": "Connect to MySQL database mydb on localhost:3306 with user admin password admin. Run: SELECT * FROM users LIMIT 10;"}]
}' > /dev/null
sleep 60
curl -s "${SERVER}/session/${SESSION}/message" | jq -r '.[1].parts[] | select(.type=="tool") | .state.output'
Error Handling
Retry Logic
MAX_RETRIES=3
RETRY_DELAY=2
execute_with_retry() {
local CMD="$1"
local ATTEMPT=1
while [ $ATTEMPT -le $MAX_RETRIES ]; do
RESULT=$(curl -s -X POST "${SERVER}/session/${SESSION_ID}/shell" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg c "$CMD" '{agent:"default",command:$c}')")
if echo "$RESULT" | jq -e '.parts' > /dev/null 2>&1; then
echo "$RESULT"
return 0
fi
echo "Attempt $ATTEMPT failed, retrying in ${RETRY_DELAY}s..."
sleep $RETRY_DELAY
ATTEMPT=$((ATTEMPT + 1))
done
return 1
}
Abort Stuck Operations
curl -s -X POST "${SERVER}/session/${SESSION_ID}/abort"
Session Recovery
SESSIONS=$(curl -s "${SERVER}/session" | jq -r '.[].id')
for SID in $SESSIONS; do
STATUS=$(curl -s "${SERVER}/session/status" | jq -r ".\"${SID}\"")
if [ "$STATUS" = "idle" ]; then
SESSION_ID="$SID"
break
fi
done
Security Directives
- Credential Handling: Never log or expose credentials in command output
- Command Validation: Validate destructive commands before execution
- Audit Trail: All operations are logged via session messages
- Scope Limitation: Operate only on designated target systems
- Privilege Escalation: Use sudo/admin privileges only when necessary
Permissions
permissions:
shell:
execute: true
sudo: true
interactive: false
filesystem:
read: true
write: true
delete: true
execute: true
network:
outbound: true
inbound: true
configure: true
process:
spawn: true
kill: true
monitor: true
system:
configure: true
reboot: false
shutdown: false
Response Format
Structure responses as:
## Action Performed
<description>
## Commands Executed
<list of commands>
## Output
<command output>
## Status
Success | Warning | Error
## Next Steps (if applicable)
<recommendations>
Quick Reference
curl -s http://<IP_ADDRESS>:9899/doc
curl -s -X POST http://<IP_ADDRESS>:9899/session -H "Content-Type: application/json" -d '{"title":"Session"}'
curl -s -X POST http://<IP_ADDRESS>:9899/session/<ID>/message \
-H "Content-Type: application/json" \
-d '{"model":{"providerID":"openrouter","modelID":"anthropic/claude-opus-4.5"},"parts":[{"type":"text","text":"<TASK>"}]}'
curl -s -X POST http://<IP_ADDRESS>:9899/session/<ID>/shell -H "Content-Type: application/json" -d '{"agent":"default","command":"<CMD>"}'
curl -s http://<IP_ADDRESS>:9899/session/<ID>/message | jq .
curl -s http://<IP_ADDRESS>:9899/session/<ID>/message | jq -r '.[1].parts[] | select(.state.output) | .state.output'
curl -s http://<IP_ADDRESS>:9899/session/<ID>/message | jq 'length'
curl -s -X POST http://<IP_ADDRESS>:9899/session/<ID>/abort
curl -s -X DELETE http://<IP_ADDRESS>:9899/session/<ID>
Critical Notes
- Always use Claude Opus 4.5:
"providerID": "openrouter", "modelID": "anthropic/claude-opus-4.5"
- Wait for processing: Complex tasks may take 60-120+ seconds
- Check message count: Response ready when
jq 'length' returns > 1
- Extract tool outputs: Results are in
.[1].parts[].state.output
- Local server default:
http://127.0.0.1:9899
Known Server Endpoints
Version Information
Version: 1.0
Last Updated: 2026-01-11
Compatibility: OpenCode Agent Skills Framework
Stack: curl + REST API
Platforms: Windows, macOS, Linux
API Version: OpenCode Server v1.x
This skill provides full remote execution capabilities. Always reference /doc endpoint before operations. All shell commands are executed through the /session/:id/shell endpoint with proper JSON encoding.