OpenClaw Remote Control & Agent Config¶
TL;DR / when to use this: How to configure agents per platform (OpenCode agent files, MCP, skills, instructions) and how to expose an agent remotely with serve behind a systemd service. The pattern generalizes across agent CLIs: config files define agent behavior; a serve command exposes it over the network with auth.
Agent config files (OpenCode example)¶
Config locations — project config overrides global:
Agents as markdown files (JSON works too):
---
description: Reviews code for quality and best practices
mode: subagent
model: anthropic/claude-sonnet-4-20250514
---
You are in code review mode. Focus on:
- Code quality and best practices
- Potential bugs and edge cases
- Performance implications
- Security considerations
Provide constructive feedback without making direct changes.
- Primary vs subagent: primary agents are the ones you talk to; they can spawn subagents. Custom subagents are defined by config files like the above.
- Agent locations:
~/.config/opencode/agents/(global),.opencode/agents/(project). - Skills:
.opencode/skills/<name>/SKILL.md(project),~/.config/opencode/skills/(global), plus Claude-compatible (.claude/skills/) and agent-compatible (.agents/skills/) paths. - Instructions have no default file — define them in config:
- MCP servers go inside the config file:
{
"mcp": {
"playwright": {
"type": "local",
"command": ["npx", "@playwright/mcp@latest"],
"enabled": true
}
}
}
Remote serve¶
opencode serve [--port <number>] [--hostname <string>] [--cors <origin>] ties into existing sessions and creates new ones with a selectable project directory. Run it as a systemd service so it survives reboots:
# ~/.config/systemd/user/opencode-server.service
[Unit]
Description=OpenCode Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/home/thomas/.openclaw/workspace-senior/
ExecStart=/home/thomas/.opencode/bin/opencode serve --hostname 0.0.0.0 --port 4096 --cors http://localhost:4090 --cors https://opencode.<domain>.com
Environment="OPENCODE_SERVER_PASSWORD=<password>"
Restart=on-failure
Lock it down: password env var, explicit CORS origins, and put it behind the reverse proxy (SWAG or Pangolin) rather than exposing the port raw.