Protocol Reference
This page documents the IPC protocol that clients use to communicate with the carryOn daemon. It is intended for contributors building new clients or integrations, not for day-to-day use of carryOn.
Connection
Section titled “Connection”The daemon listens on a Unix domain socket. Clients connect to the socket to send commands and receive events.
| Platform | Path |
|---|---|
| macOS / Linux | ~/.carryon/daemon.sock |
| Windows | Named pipe: \\.\pipe\carryon-daemon |
All communication happens over a single bidirectional connection using a binary framing protocol with JSON-RPC messages inside.
Frame format
Section titled “Frame format”Every message on the wire is wrapped in a binary frame:
[type:1][sessionIdLen:4][sessionId:N][payloadLen:4][payload:N]| Field | Size | Description |
|---|---|---|
type | 1 byte | Frame type identifier (see table below) |
sessionIdLen | 4 bytes | Length of the session ID string (big-endian uint32) |
sessionId | N bytes | Session ID as a UTF-8 string. May be empty (length 0) for frames not associated with a session. |
payloadLen | 4 bytes | Length of the payload (big-endian uint32) |
payload | N bytes | Frame-type-specific data |
Frame types
Section titled “Frame types”| Name | Type byte | Direction | Payload |
|---|---|---|---|
| TerminalData | 0x01 | Both | Raw terminal I/O bytes. Client-to-daemon carries user input; daemon-to-client carries terminal output. |
| Resize | 0x02 | Client-to-daemon | Terminal dimensions as JSON: {"cols": 80, "rows": 24} |
| StreamClose | 0x03 | Daemon-to-client | Signals that the stream for a session has ended. No payload. |
| JsonRpc | 0xFF | Both | A JSON-RPC 2.0 request, response, or notification (UTF-8 encoded). |
TerminalData frames carry the session ID of the target session. JsonRpc frames may have an empty session ID when the request is not session-specific.
JSON-RPC methods
Section titled “JSON-RPC methods”All RPC communication uses JSON-RPC 2.0 encoded inside JsonRpc frames. Methods are grouped by category below.
Client methods
Section titled “Client methods”| Method | Params | Description |
|---|---|---|
client.identify | { clientType, clientName } | Identify the connecting client. Should be sent immediately after connecting. |
Session methods
Section titled “Session methods”| Method | Params | Description |
|---|---|---|
session.create | { name?, backend? } | Create a new session. Returns the session ID and name. |
session.list | none | List all active sessions with their metadata. |
session.attach | { sessionId } | Attach to a session and begin receiving its output. |
session.detach | { sessionId } | Detach from a session. |
session.kill | { sessionId } | Terminate a session and its processes. |
session.rename | { sessionId, newName } | Rename a session. |
Daemon methods
Section titled “Daemon methods”| Method | Params | Description |
|---|---|---|
daemon.status | none | Return unified status including daemon, local server, remote access, and backends. |
daemon.stop | none | Request a graceful daemon shutdown. |
Config methods
Section titled “Config methods”| Method | Params | Description |
|---|---|---|
config.get | { key } | Read a config value. |
config.set | { key, value } | Write a config value. |
config.reload | none | Reload configuration from disk. |
config.path | none | Return the path to the config file. |
config.set side effects
Section titled “config.set side effects”Some config keys trigger immediate side effects when set:
| Key | Side effect |
|---|---|
local.enabled | Starts or stops the local HTTP server |
local.port | Restarts the local server if running |
local.expose | Restarts the local server if running |
remote.enabled | Connects or disconnects remote access |
Project methods
Section titled “Project methods”| Method | Params | Description |
|---|---|---|
project.init | { path } | Create a .carryon.json file at the given path. |
project.terminals | { path } | Start the terminals defined in the project config at the given path. |
project.associate | { path } | Associate a directory with its project sessions. |
project.disassociate | { path } | Remove the project association for a directory. |
Server-push notifications
Section titled “Server-push notifications”The daemon sends unsolicited JSON-RPC notifications to connected clients when state changes. These use the standard JSON-RPC notification format (no id field).
| Notification | Data | Description |
|---|---|---|
session.created | { sessionId, name, backend } | A new session was created. |
session.closed | { sessionId } | A session was terminated. |
session.renamed | { sessionId, oldName, newName } | A session was renamed. |
client.attached | { sessionId, clientType, clientName } | A client attached to a session. |
client.detached | { sessionId, clientType, clientName } | A client detached from a session. |
local.statusChanged | { enabled } | The web UI was started or stopped. |
Holder protocol
Section titled “Holder protocol”Each session backend uses a “holder” process that owns the actual terminal. The holder protocol defines how the daemon communicates with these processes to manage the terminal lifecycle, relay I/O, and handle resizing.
The full holder protocol specification is available in the CLI repository at docs/PROTOCOL.md.