The Gateway
Category: Explanation
Byte's gateway is a WebSocket JSON-RPC 2.0 server that exposes an authenticated RPC interface for external clients. Editors, IDE plugins, and custom tooling connect to the gateway and invoke Byte remotely—adding files to context, configuring models, receiving streaming responses in real time. The gateway owns the full connection lifecycle: auth handshake, session management, request dispatch, and asynchronous notifications back to the client.
What Is the Gateway?
The gateway is not a REST API or a CLI wrapper. It's a persistent, stateful WebSocket server that maintains a single authenticated session per client connection. Connect, authenticate, then issue RPC requests and receive streaming notifications for as long as the session is alive.
The design is deliberate: one session per connection keeps client-side state in sync with Byte's internal state. No polling, no request batching ambiguity, no stateless HTTP overhead. Messages flow bidirectionally in real time.
How It Works
Auth Handshake
The first message on any new WebSocket connection must be an auth request with a valid token:
The token is generated when the gateway starts and written to .byte/cache/gateway.token with 0o600 permissions—readable only by the user running Byte. External clients read that file to authenticate. An invalid token closes the connection immediately. A valid token opens the session.
Session Lifecycle
Once authenticated, a session is created for the connection. It processes inbound RPC requests, routes them to handlers, and returns RpcResponse objects (success or error). It also receives events from other parts of Byte and pushes RpcNotification objects to the client asynchronously.
The session lives until the client disconnects or an error occurs. State is tied to the connection—one session, one client, one coherent view of Byte's state.
Streaming Notifications
RPC requests get a single RpcResponse back—synchronous, one-to-one. Notifications are different: they flow asynchronously from server to client only. When Byte has updates to push—streamed response chunks, tool execution results, status changes—it sends RpcNotification objects without waiting for a request. Your client receives these interleaved with response completions, enabling real-time updates throughout the session.
The Protocol
The gateway speaks JSON-RPC 2.0. Every message is a JSON object with "jsonrpc": "2.0".
RpcRequest
Inbound requests from the client. Required fields: jsonrpc, id, method. Optional: params.
{
"jsonrpc": "2.0",
"id": "request-123",
"method": "add_file",
"params": { "file_path": "src/main.py" }
}
RpcResponse
The final result for a request. Contains either result (success) or error (failure)—never both.
RpcNotification
Outbound streaming events with no request id. Sent asynchronously by the server.
{
"jsonrpc": "2.0",
"method": "stream/response",
"params": { "content": "The answer is...", "done": false }
}
RpcError
Embedded in error responses. Contains code (integer), message (string), and optional data.
Standard JSON-RPC error codes apply: -32700 (Parse Error), -32600 (Invalid Request), -32601 (Method Not Found). Custom codes: -32000 (Unauthorized), -32001 (Internal Error).
Connection Flow
graph TD
Client["🖥️ External Client<br/>(editor, plugin, tooling)"]
Connect["WebSocket Connect"]
Auth["auth request<br/>{ token: '...' }"]
Validate["Token Validation"]
Reject["Connection Closed<br/>(invalid token)"]
Session["Session Created<br/>(authenticated)"]
RPC["RPC Request<br/>method + params"]
Handler["Request Handler<br/>(dispatch to Byte)"]
Response["RpcResponse<br/>(result or error)"]
Notify["RpcNotification<br/>(async push to client)"]
Disconnect["Client Disconnects<br/>Session Ends"]
Client -->|opens connection| Connect
Connect --> Auth
Auth --> Validate
Validate -->|invalid| Reject
Validate -->|valid| Session
Session -->|send request| RPC
RPC --> Handler
Handler -->|returns| Response
Response --> Session
Session -->|push updates| Notify
Notify --> Client
Session -->|on disconnect| Disconnect
Configuration
Enable and configure the gateway in .byte/config.jsonc:
enable— Whether the gateway server starts at boot. Defaults tofalse.host— The hostname to bind to. Defaults to"127.0.0.1"(localhost only).port— The port to bind to. Defaults to0(OS assigns an available port). Set a fixed port if your client needs a stable address—you own managing port conflicts.
When the gateway starts, it writes a discovery file to .byte/cache/gateway.json with the actual host, port, and token file path. External clients read this file to locate the server.
Security
The gateway is built for local development and scoped accordingly.
Token authentication is the primary control. The token is generated with secrets.token_urlsafe(32)—cryptographically strong—and written to disk with 0o600 permissions. Only the user who started Byte can read it.
Discovery file (.byte/cache/gateway.json) tells clients where the server is running and where to find the token. It's regenerated on every startup.
Localhost by default. The gateway binds to 127.0.0.1, rejecting all remote connections. Built for developers who want a secure local interface without network exposure. If you expose the gateway to a network, the token becomes your only protection—layer additional auth (mutual TLS, API keys, OAuth) on top for distributed scenarios.
Available Requests
add_file
Add file to AI context as editable.
Method name: add_file
Parameters:
file_path(string, required) — Relative or absolute path to the file
Response: {"ok": true}
Errors: -32001 (Internal Error) if operation fails
configure
Configure gateway parameters.
Method name: configure
Parameters:
model(string, optional) — The LLM model to usecontext_limit(integer, optional) — Maximum context length
Response: {"ok": true}
Errors: -32001 (Internal Error) if operation fails
context_add_file
Add file contents to session context.
Method name: context_add_file
Parameters:
file_path(string, required) — Relative or absolute path to the file
Response: {"ok": true}
Errors: -32001 (Internal Error) if operation fails
context_drop_file
Drop file contents from session context.
Method name: context_drop_file
Parameters:
file_path(string, required) — Relative or absolute path to the file
Response: {"ok": true}
Errors: -32001 (Internal Error) if operation fails
drop_file
Remove file from AI context.
Method name: drop_file
Parameters:
file_path(string, required) — Relative or absolute path to the file
Response: {"ok": true}
Errors: -32001 (Internal Error) if operation fails
Available Notifications
The gateway pushes notifications to connected clients asynchronously—no request required. Your client receives these whenever Byte has state changes to report. All notifications follow the RpcNotification format with no id field.
messages/response
Streamed response chunks from Byte. Sent repeatedly as the response generates, with done: true on the final chunk.
Parameters:
content(string) — The response text fragmentdone(boolean) —trueon the final chunk;falsefor all intermediate chunks
messages/update_files
Reports the current number of files tracked in the AI context.
Parameters:
count(integer) — The total number of files currently in context
messages/update_context
Reports the current number of items in the session context.
Parameters:
context_count(integer) — The total number of context items currently loaded
messages/command_execution_started
Signals that Byte has begun executing a command. No parameters.
Parameters: {}
messages/command_execution_completed
Signals that Byte has finished executing a command. No parameters.
Parameters: {}
messages/status
Sent when Byte encounters an error condition. Only fired on error state—not for informational or success status updates.
Parameters:
message(string) — A human-readable description of the error
Key Takeaways
- The gateway is a persistent WebSocket server — not a REST API; the connection stays open for the lifetime of the session
- Authentication is mandatory — every connection must send an
authrequest as its first message; invalid tokens are rejected immediately - One session per connection — state is tied to the connection, keeping client and server in sync without polling
- Requests are synchronous, notifications are async — RPC requests get a single response; notifications flow from server to client whenever Byte has updates to push
- JSON-RPC 2.0 is the protocol — standard error codes, structured messages, and bidirectional communication
- Localhost by default — the gateway binds to
127.0.0.1; exposing it to a network requires you to add additional auth on top - Discovery is file-based —
.byte/cache/gateway.jsontells clients where to connect;.byte/cache/gateway.tokenholds the auth token