Integrations
RPC Mode
Control Autohand programmatically via JSON protocol over stdin/stdout. Perfect for building custom UIs, IDE integrations, and automation tools.
Overview
RPC mode enables headless operation of the Autohand CLI via a JSON-RPC protocol. This allows external applications to:
- Send prompts and receive streaming responses
- Monitor tool execution in real-time
- Handle permission requests programmatically
- Control auto-mode, plan mode, and YOLO mode
- Manage skills and MCP servers
- Build custom UIs and IDE extensions
- Create automated pipelines with full agent control
Looking for session-managed connections? If you need persistent sessions, model switching, and editor-style integration, see ACP Mode instead.
Getting Started
Start RPC Mode
Launch Autohand in RPC mode:
# Basic RPC mode
autohand --mode rpc
# With options
autohand --mode rpc --model nvidia/nemotron-3-super-120b-a12b:free --ephemeral
# All options
autohand --mode rpc \
--model <model-id> \
--ephemeral \
--thinking <level> \
--config <path>
Protocol Basics
The protocol uses newline-delimited JSON (JSON Lines):
- Commands: JSON objects sent to stdin, one per line
- Responses: JSON objects with
type: "response" - Events: JSON objects streamed during agent operation
Correlation IDs: Include an optional id field in commands. The corresponding response will include the same id for matching.
Core Commands
prompt
Send an instruction to the agent:
{"type": "prompt", "message": "Create a hello.ts file", "id": "1"}
// With file context
{"type": "prompt", "message": "Review this file", "mentions": ["src/index.ts"]}
abort
Cancel the current operation:
{"type": "abort"}
reset
Clear conversation context:
{"type": "reset"}
get_state
Get current agent state:
{"type": "get_state"}
// Response
{
"type": "response",
"command": "get_state",
"success": true,
"data": {
"model": "nvidia/nemotron-3-super-120b-a12b:free",
"provider": "openrouter",
"workspace": "/path/to/project",
"isProcessing": false,
"contextPercent": 85,
"messageCount": 5
}
}
get_messages
Get conversation history:
{"type": "get_messages"}
get_history
Get the full session history including tool calls and results:
{"type": "get_history"}
// Response
{
"type": "response",
"command": "get_history",
"success": true,
"data": {
"messages": [...],
"toolCalls": [...],
"totalTokens": 12500
}
}
permission_response
Respond to a permission request:
{"type": "permission_response", "requestId": "perm-123", "approve": true}
Auto-Mode Commands
Control the autonomous execution mode programmatically. Auto-mode lets the agent work through tasks without requiring manual prompt-by-prompt interaction.
automode_start
Start auto-mode with an initial instruction:
{"type": "automode_start", "message": "Refactor the auth module", "id": "am-1"}
// Response
{
"type": "response",
"command": "automode_start",
"success": true,
"data": {"status": "running"}
}
automode_status
Check the current auto-mode status:
{"type": "automode_status"}
// Response
{
"type": "response",
"command": "automode_status",
"success": true,
"data": {
"active": true,
"paused": false,
"turnsCompleted": 3,
"turnsRemaining": 7
}
}
automode_pause
Pause a running auto-mode session:
{"type": "automode_pause"}
automode_resume
Resume a paused auto-mode session:
{"type": "automode_resume"}
automode_cancel
Cancel auto-mode entirely:
{"type": "automode_cancel"}
automode_get_log
Get the auto-mode execution log:
{"type": "automode_get_log"}
// Response
{
"type": "response",
"command": "automode_get_log",
"success": true,
"data": {
"entries": [
{"turn": 1, "action": "Read file src/auth.ts", "timestamp": "..."},
{"turn": 2, "action": "Edited src/auth.ts", "timestamp": "..."}
]
}
}
Skill Commands
Manage the agent's skill registry programmatically.
get_skills_registry
List all available skills:
{"type": "get_skills_registry"}
// Response
{
"type": "response",
"command": "get_skills_registry",
"success": true,
"data": {
"skills": [
{
"name": "commit",
"description": "Create a git commit",
"source": "builtin"
},
{
"name": "review-pr",
"description": "Review a pull request",
"source": "plugin:code-review"
}
]
}
}
install_skill
Install a skill from a registry or path:
{
"type": "install_skill",
"source": "npm:@autohand/skill-tdd",
"id": "sk-1"
}
// Response
{
"type": "response",
"command": "install_skill",
"success": true,
"data": {"name": "tdd", "installed": true}
}
MCP Commands
Manage Model Context Protocol servers and tools.
mcp_list_servers
List configured MCP servers:
{"type": "mcp_list_servers"}
// Response
{
"type": "response",
"command": "mcp_list_servers",
"success": true,
"data": {
"servers": [
{"name": "context7", "status": "connected", "tools": 2},
{"name": "brave-search", "status": "connected", "tools": 1}
]
}
}
mcp_list_tools
List all available MCP tools across servers:
{"type": "mcp_list_tools"}
// Response
{
"type": "response",
"command": "mcp_list_tools",
"success": true,
"data": {
"tools": [
{"name": "query-docs", "server": "context7"},
{"name": "brave_web_search", "server": "brave-search"}
]
}
}
mcp_get_server_configs
Get the full configuration for all MCP servers:
{"type": "mcp_get_server_configs"}
// Response
{
"type": "response",
"command": "mcp_get_server_configs",
"success": true,
"data": {
"configs": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"]
}
}
}
}
mcp_set_vscode_tools
Configure MCP tools for VS Code integration. This syncs tool availability between the CLI and VS Code extension:
{
"type": "mcp_set_vscode_tools",
"tools": ["query-docs", "brave_web_search"]
}
mcp_invoke_response
Send the result of an MCP tool invocation back to the agent. Used when the host application handles tool execution:
{
"type": "mcp_invoke_response",
"toolCallId": "call_abc123",
"result": {"content": "Search results..."}
}
Mode Commands
Control agent operation modes.
plan_mode_set
Toggle plan mode on or off. In plan mode, the agent designs an approach before making changes:
// Enable plan mode
{"type": "plan_mode_set", "enabled": true}
// Disable plan mode
{"type": "plan_mode_set", "enabled": false}
// Response
{
"type": "response",
"command": "plan_mode_set",
"success": true,
"data": {"planMode": true}
}
yolo_set
Toggle YOLO mode. When enabled, the agent auto-approves all tool executions without permission prompts:
// Enable YOLO mode
{"type": "yolo_set", "enabled": true}
// With specific patterns
{"type": "yolo_set", "enabled": true, "patterns": ["npm *", "git *"]}
// Response
{
"type": "response",
"command": "yolo_set",
"success": true,
"data": {"yolo": true}
}
Use YOLO mode with care: Auto-approving all operations can lead to unwanted changes. Consider using patterns to limit which commands are auto-approved.
File Change Commands
changes_decision
Accept or reject file changes proposed by the agent. When the agent writes or edits files, you can review and decide on each change:
// Accept changes
{
"type": "changes_decision",
"changeId": "chg-456",
"decision": "accept"
}
// Reject changes
{
"type": "changes_decision",
"changeId": "chg-456",
"decision": "reject"
}
// Response
{
"type": "response",
"command": "changes_decision",
"success": true,
"data": {"applied": true}
}
Events
Events are streamed to stdout during agent operation:
| Event | Description |
|---|---|
agent_start |
Agent ready to accept commands |
agent_end |
Agent shutting down |
turn_start |
Started processing a prompt |
turn_end |
Finished processing a prompt |
message_start |
LLM response started |
message_update |
Streaming content delta |
message_end |
LLM response completed |
tool_execution_start |
Tool execution started |
tool_execution_update |
Tool output chunk |
tool_execution_end |
Tool execution completed |
permission_request |
Awaiting approval for action |
automode_turn |
Auto-mode completed a turn |
automode_complete |
Auto-mode finished all turns |
file_change |
File was created, modified, or deleted |
error |
Error occurred |
Event Examples
// Turn lifecycle
{"type": "turn_start", "timestamp": "...", "data": {"instruction": "Create a file"}}
{"type": "turn_end", "timestamp": "...", "data": {"success": true}}
// Message streaming
{"type": "message_update", "timestamp": "...", "data": {"delta": "I'll create "}}
// Tool execution
{"type": "tool_execution_start", "timestamp": "...", "data": {
"toolName": "write_file",
"toolCallId": "call_abc",
"args": {"path": "hello.ts"}
}}
{"type": "tool_execution_end", "timestamp": "...", "data": {
"toolName": "write_file",
"toolCallId": "call_abc",
"success": true,
"duration": 150
}}
// Permission request
{"type": "permission_request", "timestamp": "...", "data": {
"requestId": "perm-123",
"tool": "run_command",
"message": "Execute: npm install?"
}}
// Auto-mode events
{"type": "automode_turn", "timestamp": "...", "data": {
"turn": 3,
"total": 10,
"action": "Edited src/auth.ts"
}}
{"type": "automode_complete", "timestamp": "...", "data": {
"turnsCompleted": 5,
"success": true
}}
// File change
{"type": "file_change", "timestamp": "...", "data": {
"path": "src/hello.ts",
"action": "created",
"changeId": "chg-456"
}}
Examples
Python Client
import subprocess
import json
proc = subprocess.Popen(
["autohand", "--mode", "rpc", "--ephemeral"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
def send(cmd):
proc.stdin.write(json.dumps(cmd) + "\n")
proc.stdin.flush()
def read_events():
for line in proc.stdout:
yield json.loads(line)
# Wait for ready
for event in read_events():
if event.get("type") == "agent_start":
break
# Send prompt
send({"type": "prompt", "message": "Hello!", "id": "1"})
# Process events
for event in read_events():
if event.get("type") == "message_update":
print(event["data"]["delta"], end="", flush=True)
if event.get("type") == "permission_request":
# Handle permission
send({
"type": "permission_response",
"requestId": event["data"]["requestId"],
"approve": True
})
if event.get("type") == "turn_end":
print()
break
proc.terminate()
Node.js Client
const { spawn } = require("child_process");
const readline = require("readline");
const agent = spawn("autohand", ["--mode", "rpc", "--ephemeral"]);
const rl = readline.createInterface({ input: agent.stdout });
rl.on("line", (line) => {
const event = JSON.parse(line);
if (event.type === "message_update") {
process.stdout.write(event.data.delta);
}
if (event.type === "permission_request") {
agent.stdin.write(JSON.stringify({
type: "permission_response",
requestId: event.data.requestId,
approve: true
}) + "\n");
}
if (event.type === "turn_end") {
console.log("\n--- Done ---");
}
});
// Send prompt after ready
setTimeout(() => {
agent.stdin.write(JSON.stringify({
type: "prompt",
message: "List files in current directory"
}) + "\n");
}, 1000);
process.on("SIGINT", () => {
agent.stdin.write(JSON.stringify({ type: "abort" }) + "\n");
agent.kill();
});
Auto-Mode Example
import subprocess
import json
proc = subprocess.Popen(
["autohand", "--mode", "rpc"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
def send(cmd):
proc.stdin.write(json.dumps(cmd) + "\n")
proc.stdin.flush()
def read_events():
for line in proc.stdout:
yield json.loads(line)
# Wait for ready
for event in read_events():
if event.get("type") == "agent_start":
break
# Enable YOLO mode for auto-approval
send({"type": "yolo_set", "enabled": True, "patterns": ["git *"]})
# Start auto-mode
send({
"type": "automode_start",
"message": "Add unit tests for the auth module"
})
# Monitor progress
for event in read_events():
if event.get("type") == "automode_turn":
d = event["data"]
print(f"Turn {d['turn']}/{d['total']}: {d['action']}")
if event.get("type") == "automode_complete":
print("Auto-mode finished!")
break
proc.terminate()
Use Cases
IDE Extensions
Build VS Code, JetBrains, or Zed extensions that embed Autohand:
- Spawn RPC process on extension activation
- Send file context with
mentions - Display streaming responses in editor panels
- Handle permission requests via UI dialogs
Custom Web UIs
Create browser-based interfaces:
- Backend spawns RPC process
- WebSocket bridges JSON events to browser
- React/Vue components render streaming output
- Users approve/deny via web interface
CI/CD Integration
Programmatic control in pipelines:
- Auto-approve safe operations with YOLO patterns
- Use auto-mode for multi-step tasks
- Collect structured output for reports
- Chain multiple prompts in sequence
Error Handling
Failed commands return responses with success: false:
{
"type": "response",
"command": "prompt",
"success": false,
"error": "Agent is already processing a request"
}
// Parse errors
{
"type": "response",
"command": "parse",
"success": false,
"error": "Invalid JSON: Unexpected token..."
}
Always handle errors: Check success field in responses and listen for error events to handle failures gracefully.
Future Commands
These commands are planned for future releases:
- Model:
set_model,cycle_model,get_available_models - Thinking:
set_thinking_level,cycle_thinking_level - Compaction:
compact,set_auto_compaction