rexd is a lightweight remote execution and filesystem plane implementing the REXD v1 JSON-RPC protocol.
Protocol spec: docs/spec/rexd_v1_protocol.md
- opencode-rexd-target: OpenCode plugin for routing tools to remote REXD targets.
- JSON-RPC 2.0 over NDJSON stdio (
rexd --stdio) - Optional HTTP + WebSocket transport (
--http :8080) - Session lifecycle (
session.open,session.info,session.close) - Process lifecycle (
exec.start,exec.wait,exec.kill,exec.input) - Filesystem surface (
fs.read,fs.write,fs.list,fs.glob,fs.stat,fs.edit,fs.patch) - PTY extension (
pty.open,pty.input,pty.resize,pty.close) - Event streaming (
exec.stdout,exec.stderr,exec.exit,pty.output,pty.exit) - Security guardrails (allowlisted roots, configurable limits, audit logging)
go build ./cmd/rexdOr with Make:
make buildLatest release:
curl -fsSL https://raw.githubusercontent.com/samiralibabic/rexd/main/scripts/install.sh | bashPinned version:
curl -fsSL https://raw.githubusercontent.com/samiralibabic/rexd/main/scripts/install.sh | REXD_VERSION=v0.1.4 bashCustom install dir:
curl -fsSL https://raw.githubusercontent.com/samiralibabic/rexd/main/scripts/install.sh | REXD_INSTALL_DIR="$HOME/.local/bin" bashrexd requires a config file with at least one security.allowed_roots entry. If this is missing, clients will fail to access files/commands as expected.
Default config path is /etc/rexd/config.toml.
sudo mkdir -p /etc/rexd
sudo curl -fsSL https://raw.githubusercontent.com/samiralibabic/rexd/main/rexd.example.toml -o /etc/rexd/config.toml
sudo $EDITOR /etc/rexd/config.tomlAt minimum, update the [[security.allowed_roots]] paths to match the real directories you want to expose.
Update the binary by rerunning the installer:
curl -fsSL https://raw.githubusercontent.com/samiralibabic/rexd/main/scripts/install.sh | bashIf rexd is managed as a service, restart it after update (example):
sudo systemctl restart rexdIf you also use opencode-rexd-target, update rexd on remote hosts first, then update the plugin.
./rexd --stdio --config ./rexd.example.tomlOver SSH:
ssh deploy@server-a /usr/local/bin/rexd --stdio./rexd --http :8080 --config ./rexd.example.toml- HTTP JSON-RPC endpoint defaults to
/rpc - WS JSON-RPC endpoint defaults to
/ws
Open session:
{"jsonrpc":"2.0","id":1,"method":"session.open","params":{"client_name":"my-agent","workspace_roots":["/srv/myapp"]}}Start command:
{"jsonrpc":"2.0","id":2,"method":"exec.start","params":{"session_id":"s_1","argv":["git","status","--short"],"cwd":"/srv/myapp"}}Shell mode notes:
- Non-PTY
exec.startwithshell=truedefaults to non-login shell behavior for predictable automation. - Use
login=trueonly for compatibility with legacy environments that require login-shell startup files.
Read file:
{"jsonrpc":"2.0","id":3,"method":"fs.read","params":{"session_id":"s_1","path":"/srv/myapp/README.md"}}Edit file:
{"jsonrpc":"2.0","id":4,"method":"fs.edit","params":{"session_id":"s_1","path":"/srv/myapp/README.md","old_string":"Hello","new_string":"REXD","replace_all":false}}Apply patch:
{"jsonrpc":"2.0","id":5,"method":"fs.patch","params":{"session_id":"s_1","cwd":"/srv/myapp","patch_text":"*** Begin Patch\n*** Update File: README.md\n@@\n-Hello\n+REXD\n*** End Patch"}}Use the example file at rexd.example.toml as a template. In production, place config at /etc/rexd/config.toml.
After go build -o rexd ./cmd/rexd, run:
bash ./scripts/verify-all.shOr run individual checks:
bash ./scripts/verify-stdio.sh
bash ./scripts/verify-http.sh
bash ./scripts/verify-ws.shNotes:
- The scripts generate a temporary config with the repo root as the allowed root.
verify-ws.shrequireswebsocat(brew install websocat).
make tidy
make test
make verify- License:
LICENSE - Contributing guide:
CONTRIBUTING.md - Code of conduct:
CODE_OF_CONDUCT.md - Security policy:
SECURITY.md