socket-pty
@ai-zen/socket-pty is a cross-platform PTY transport layer. It spawns a real terminal process (bash, vim, node -i, etc.) and exposes it as a network endpoint; any client that can establish a socket connection and speaks JSON-RPC 2.0 can read/write that terminal.
- Real screen: renders the terminal's current actual screen (what you see is what you get) with
@xterm/headless, rather than an unbounded historical log. - Thin capability core: the main entry exposes only the capability and protocol, without embedding any entry adapter; the MCP adapter ships as a separate subpath.
- Single source of truth: this repo's
docs/is the only source of documentation; the website only aggregates and renders it.
Features
- Cross-platform: Unix domain socket (Linux/macOS) and TCP loopback (preferred on Windows).
- Standard protocol: one JSON-RPC 2.0 message per line over the socket, newline-delimited.
- Decoupled client/backend: depends only on the
IPtySessionabstraction, usesnode-ptyby default, and is easy to inject a mock in tests. - MCP adapter: can expose terminal-operation tools as an MCP server (stdio).
Entry points
The package provides two entry points:
| Entry | Contents | Purpose |
|---|---|---|
@ai-zen/socket-pty (main entry .) | PtyServer / PtySession / createSocketPty / protocol and types | Start/hold a terminal service programmatically |
@ai-zen/socket-pty/mcp (./mcp) | serveMCP / MCPManager / ConnectionPool | Expose terminal-operation tools as an MCP server |
Core concepts
Endpoint
An endpoint is the network location a hosted terminal listens on. It has two forms: unix and tcp.
- Unix domain socket:
{ type: "unix", path: "/path/to.sock" }, addressunix:/path/to.sock. - TCP loopback:
{ type: "tcp", port: 5174, host: "127.0.0.1" }, addresstcp:127.0.0.1:5174.
The endpoint address is explicitly specified by the launcher (--socket / --port, choose one). Connecting to a terminal requires knowing its address; serve / createSocketPty do not auto-assign an address. Only MCP's spawn is the exception — it self-allocates a local temporary endpoint and returns it.
Protocol
One JSON-RPC 2.0 message per line over the socket:
jsonc
Request: {"jsonrpc":"2.0","method":"pty/read","params":{},"id":7}
Success: {"jsonrpc":"2.0","result":{...},"id":7}
Failure: {"jsonrpc":"2.0","error":{"code":-32601,"message":"..."},"id":7}- Requests must include an
id(string or number); notifications are not supported (requests without anidare rejected). - Each request corresponds to exactly one response, which echoes the same
id. paramsmust be an object.
Screen semantics
- The screen is maintained on the server side (endpoint side) with xterm-headless; it is the terminal's current actual screen.
pty/readreturns the whole current screen (rowslines), not a history log — content scrolled off-screen does not appear.pty/readcan select a subset of the current screen (top/bottomorstart+end).- A client disconnecting does not stop the terminal; reconnecting still reads the current screen.
Session lifecycle
- Resident: processes started by
serve/spawnlive independently; a client disconnect/reconnect does not affect their lifetime or current screen. - Termination:
pty/killterminates the session and closes the endpoint; afterwards the endpoint can no longer be connected to. - Cleanup: when a Unix socket endpoint is closed, the corresponding socket file is removed.
Documentation navigation
- Getting Started — Installation, environment requirements, CLI and programmatic examples, and a protocol walkthrough.
- API Reference — JSON-RPC methods, error codes, programmatic API, CLI options, and exported types.
- MCP Adapter — Registering the MCP server and its tools.