Agent Control Protocol (ACP)
Agent Harbor implements the Agent Control Protocol (ACP) for standardized communication between IDEs, CLI tools, and AI coding agents.
Overview
ACP is a JSON-RPC 2.0 based protocol that standardizes how clients communicate with AI coding agents. Agent Harbor acts as an access point (server) that:
- Routes sessions to downstream ACP-compliant agents
- Provides sandboxed execution environments
- Manages filesystem snapshots and workspaces
- Exposes Harbor-specific extensions for time-travel and branching
Roles and Transports
Access Point (Server): ah agent access-point exposes ACP over Unix domain socket and stdio. It routes sessions to downstream ACP agents and rewrites model lists with per-agent prefixes.
Client Tunnel: ah acp is a thin stdio/UDS/WebSocket tunnel used by IDEs and CLIs. It keeps stdout JSON-only and logs to files.
Commands
ah acp
Connect to an ACP access point:
ah acp [OPTIONS]Options:
--endpoint <URL|PATH>: Access point WS URL or UDS path (defaults to platform ACP socket path)--ws: Force WebSocket transport--uds: Force Unix socket transport--remote-server <URL>: Target Harbor REST server (resolves to<url>/acp/v1/connect)--session <ID>: Load and attach to an existing ACP session--daemonize <MODE>: Behavior when no access point is running:auto(default): Start daemon with idle timeout if missingnever: Run inline; no multi-client reusedisabled: Fail if no access point is running
--idle-timeout <SECS>: Idle shutdown timer when daemonized (default: 86400)
Examples:
# Use local default UDS; auto-start daemon if missing
ah acp
# Connect to remote WS access point
ah acp --endpoint wss://ah.example.com/acp/v1/connect
# Bridge to REST server without daemon auto-start
ah acp --remote-server https://ah.example.com --daemonize disabledah agent access-point
Run a local access point daemon:
ah agent access-point [OPTIONS]Options:
--acp-uds <PATH>: Enable ACP over Unix domain socket at PATH--acp-ws <yes|no>: Enable ACP over WebSocket at/acp/v1/connect(default: yes)--acp-agent-cmd <CMD>: Command to launch an ACP agent
Session Lifecycle
Session Creation
When a client sends session/new:
- Access point selects the downstream agent (by model prefix or default)
- Prepares a writable workspace using the filesystem snapshot system:
- Provider chosen automatically (ZFS, Btrfs, AgentFS, or Git)
- Working copy mounted so agent sees original repo path (CoW overlay) when supported
- Cleanup token recorded for teardown
- Session state stored: snapshot provider, working copy mode, exec path, cleanup token, sandbox policy
Sandboxed Execution
Commands from downstream agents run inside Harbor’s sandbox:
- Process isolation with PID limits
- Network disabled by default (opt-in via config)
- Filesystem illusion: paths match user’s repo path
- Build caches mounted read-only unless explicitly allowed
Command Execution
When the downstream agent sends terminal/create:
- Access point intercepts the request
- Command launched via Passthrough recorder inside session sandbox
- PTY output and metadata captured
- Client receives a follower command to attach to the session
- Multiple followers can attach simultaneously
- Exit codes come from the sandboxed process
Clean Shutdown
On client disconnect or idle timeout:
- All sandboxed terminals/processes terminated
- Workspace cleaned up via stored cleanup token
- Socket listeners closed; stale sockets removed on next launch
Model Discovery & Routing
On startup, the access point:
- Probes each downstream agent (
initialize+session/newprobe) - Collects their
availableModels - Advertises combined list with agent name prefixes (e.g.,
opencode/grok-code-fast-1)
When a client requests a prefixed model, the access point routes to that agent and strips the prefix before forwarding.
Harbor Extensions
Agent Harbor extends ACP with custom methods under the _ah/* namespace. These are advertised during initialize via the _meta.agent.harbor capability block.
Capability Advertisement
{
"agentCapabilities": {
"loadSession": true,
"_meta": {
"agent.harbor": {
"snapshots": {
"version": 1,
"supportsTimelineSeek": true,
"supportsBranching": true,
"supportsFollowPlayback": true
},
"pipelineIntrospection": {
"version": 1,
"supportsStepStreaming": true
},
"workspace": {
"version": 1,
"supportsDiffs": true
}
}
}
}
}Terminal Methods
_ah/terminal/follow: Subscribe to a PTY stream. Replays any buffered backlog then streams live output as session/update events.
_ah/terminal/write: Send input to a terminal session.
_ah/terminal/detach: Detach from a terminal stream and stop receiving events.
Workspace Methods
_ah/workspace/info: Returns metadata about the Harbor-managed workspace (provider, working copy mode, exec path, disk usage).
Snapshot Methods
_ah/snapshot_create: Create a manual snapshot of the current workspace with optional label and anchor.
Branching Methods
_ah/branch_create: Create a new session from an existing snapshot or timeline moment. Supports launching multiple agents per branch.
Multi-Agent Sessions
_ah/session/new: Launch multiple agents from one request. Each agent gets its own isolated ACP session.
Planned Methods
The following extension methods are specified but not yet implemented. They are included here for completeness and to document the intended API surface.
_ah/workspace/list: Browse the workspace tree with optional filters_ah/workspace/diff: Fetch file diffs in unified format_ah/workspace/file: Fetch file metadata and content_ah/snapshot_list: List snapshots with filtering_ah/branch_list,_ah/branch_delete: Enumerate and remove branches_ah/session_seek: Mount a read-only filesystem view at a specific snapshot_ah/tool_pipeline_list: Returns pipelines and steps for an execution_ah/tool_pipeline_stream: Stream stdout/stderr for a pipeline step
Notifications
Harbor sends real-time notifications via session/update:
| Notification | Purpose |
|---|---|
harbor/snapshot_created | Snapshot captured (auto or manual) |
harbor/branch_created | New branch and sessions created |
harbor/branch_updated | Branch status changed (running, paused, merged) |
harbor/branch_deleted | Cleanup confirmation |
harbor/timeline_checkpoint | Recorder event for timeline markers |
harbor/pipeline_detected | New pipeline recorded |
harbor/pipeline_step_updated | Pipeline step progress update |
Configuration
ACP settings in ah.toml or environment:
| Key | Description |
|---|---|
acp.daemonize | auto (default), never, or disabled |
acp.socket-path | Unix socket path for access point |
acp.ws-url | WebSocket URL for access point |
acp.transport | websocket (default) or stdio |
Event Pipeline
For ACP agents in TaskManager context, events flow through a direct semantic path:
ACP Agent stdout (JSON-RPC)
│
▼
AcpAgentSession
│ Parses JSON-RPC directly
▼
acp_message_to_task_events()
│ Converts to TaskEvents
▼
TaskManagerMessage::SessionEvent
│
▼
LocalTaskManager / RestTaskManagerEnable with --task-manager-socket:
ah agent start --task-manager-socket /path/to/socketThis provides semantic events extracted directly from JSON-RPC without PTY parsing.