The kitty remote control protocol#

The kitty remote control protocol is a simple protocol that involves sending data to kitty in the form of JSON. Any individual command of kitty has the form:

<ESC>P@kitty-cmd<JSON object><ESC>\

Where <ESC> is the byte 0x1b. The JSON object has the form:

{
    "cmd": "command name",
    "version": "<kitty version>",
    "no_response": "<Optional Boolean>",
    "payload": "<Optional JSON object>"
}

The version above is an array of the form [0, 14, 2]. If you are developing a standalone client, use the kitty version that you are developing against. Using a version greater than the version of the kitty instance you are talking to, will cause a failure.

Set no_response to true if you don’t want a response from kitty.

The optional payload is a JSON object that is specific to the actual command being sent. The fields in the object for every command are documented below.

As a quick example showing how easy to use this protocol is, we will implement the @ ls command from the shell using only shell tools.

First, run kitty as:

kitty -o allow_remote_control=socket-only --listen-on unix:/tmp/test

Now, in a different terminal, you can get the pretty printed @ ls output with the following command line:

echo -en '\eP@kitty-cmd{"cmd":"ls","version":[0,14,2]}\e\\' | socat - unix:/tmp/test | awk '{ print substr($0, 13, length($0) - 14) }' | jq -c '.data | fromjson' | jq .

Encrypted communication#

New in version 0.26.0.

When using the remote_control_password option communication to the terminal is encrypted to keep the password secure. A public key is used from the KITTY_PUBLIC_KEY environment variable. Currently, only one encryption protocol is supported. The protocol number is present in KITTY_PUBLIC_KEY as 1. The key data in this environment variable is Base-85 encoded. The algorithm used is Elliptic Curve Diffie Helman with the X25519 curve. A time based nonce is used to minimise replay attacks. The original JSON command has the fields: password and timestamp added. The timestamp is the number of nanoseconds since the epoch, excluding leap seconds. Commands with a timestamp more than 5 minutes from the current time are rejected. The command is then encrypted using AES-256-GCM in authenticated encryption mode, with a symmetric key that is derived from the ECDH key-pair by running the shared secret through SHA-256 hashing, once. An IV of at least 96 bits of CSPRNG data is used. The tag for authenticated encryption must be at least 128 bits long. The tag must authenticate only the value of the encrypted field. A new command is created and transmitted that contains the fields:

{
    "version": "<kitty version>",
    "iv": "base85 encoded IV",
    "tag": "base85 encoded AEAD tag",
    "pubkey": "base85 encoded ECDH public key of sender",
    "encrypted": "The original command encrypted and base85 encoded"
}

close-tab#

Fields are:

match (default: None)

Which tab to close

no_response (default: False)

Boolean indicating whether to wait for a response

self (default: False)

Boolean indicating whether to close the tab of the window the command is run in

ignore_no_match (default: False)

Boolean indicating whether no matches should be ignored or return an error

close-window#

Fields are:

match (default: None)

Which window to close

no_response (default: False)

Boolean indicating whether to wait for a response

self (default: False)

Boolean indicating whether to close the window the command is run in

ignore_no_match (default: False)

Boolean indicating whether no matches should be ignored or return an error

create-marker#

Fields are:

match (default: None)

Which window to create the marker in

self (default: False)

Boolean indicating whether to create marker in the window the command is run in

marker_spec (optional)

A list or arguments that define the marker specification, for example: [‘text’, ‘1’, ‘ERROR’]

detach-tab#

Fields are:

match (default: None)

Which tab to detach

target_tab (default: None)

Which tab to move the detached tab to the OS window it is run in

self (default: False)

Boolean indicating whether to detach the tab the command is run in

detach-window#

Fields are:

match (default: None)

Which window to detach

target_tab (default: None)

Which tab to move the detached window to

self (default: False)

Boolean indicating whether to detach the window the command is run in

disable-ligatures#

Fields are:

strategy (required)

One of never, always or cursor

match_window (optional)

Window to change opacity in

match_tab (default: None)

Tab to change opacity in

all (default: False)

Boolean indicating operate on all windows

env#

Fields are:

env (required)

Dictionary of environment variables to values. Empty values cause the variable to be removed.

focus-tab#

Fields are:

match (default: None)

The tab to focus

no_response (default: False)

Boolean indicating whether to wait for a response

focus-window#

Fields are:

match (default: None)

The window to focus

no_response (default: False)

Boolean indicating whether to wait for a response

get-colors#

Fields are:

match (default: None)

The window to get the colors for

configured (default: False)

Boolean indicating whether to get configured or current colors

get-text#

Fields are:

match (default: None)

The window to get text from

extent (default: screen)

One of screen, first_cmd_output_on_screen, last_cmd_output, last_visited_cmd_output, all, or selection

ansi (default: False)

Boolean, if True send ANSI formatting codes

cursor (optional)

Boolean, if True send cursor position/style as ANSI codes

wrap_markers (optional)

Boolean, if True add wrap markers to output

clear_selection (default: None)

Boolean, if True clear the selection in the matched window

self (default: False)

Boolean, if True use window the command was run in

goto-layout#

Fields are:

layout (required)

The new layout name

match (default: None)

Which tab to change the layout of

kitten#

Fields are:

kitten (required)

The name of the kitten to run

args (optional)

Arguments to pass to the kitten as a list

match (default: None)

The window to run the kitten over

last-used-layout#

Fields are:

match (default: None)

Which tab to change the layout of

all (default: False)

Boolean to match all tabs

no_response (default: False)

Boolean indicating whether to wait for a response

launch#

Fields are:

args (required)

The command line to run in the new window, as a list, use an empty list to run the default shell

match (default: None)

The tab to open the new window in

window_title (default: None)

Title for the new window

cwd (default: None)

Working directory for the new window

env (default: [])

List of environment variables of the form NAME=VALUE

tab_title (default: None)

Title for the new tab

type (default: window)

The type of window to open

keep_focus (default: False)

Boolean indicating whether the current window should retain focus or not

copy_colors (default: False)

Boolean indicating whether to copy the colors from the current window

copy_cmdline (default: False)

Boolean indicating whether to copy the cmdline from the current window

copy_env (default: False)

Boolean indicating whether to copy the environ from the current window

hold (default: False)

Boolean indicating whether to keep window open after cmd exits

location (default: default)

Where in the tab to open the new window

allow_remote_control (default: False)

Boolean indicating whether to allow remote control from the new window

remote_control_password (default: [])

A list of remote control passwords

stdin_source (default: none)

Where to get stdin for the process from

stdin_add_formatting (default: False)

Boolean indicating whether to add formatting codes to stdin

stdin_add_line_wrap_markers (default: False)

Boolean indicating whether to add line wrap markers to stdin

spacing (default: [])

A list of spacing specifications, see the docs for the set-spacing command

no_response (default: False)

Boolean indicating whether to send back the window id

marker (default: None)

Specification for marker for new window, for example: “text 1 ERROR”

logo (default: None)

Path to window logo

logo_position (default: None)

Window logo position as string or empty string to use default

logo_alpha (default: -1.0)

Window logo alpha or -1 to use default

self (default: False)

Boolean, if True use tab the command was run in

ls#

Fields are:

all_env_vars (default: False)

Whether to send all environment variables for every window rather than just differing ones

new-window#

Fields are:

args (required)

The command line to run in the new window, as a list, use an empty list to run the default shell

match (default: None)

The tab to open the new window in

title (default: None)

Title for the new window

cwd (default: None)

Working directory for the new window

keep_focus (default: False)

Boolean indicating whether the current window should retain focus or not

window_type (default: kitty)

One of kitty or os

new_tab (default: False)

Boolean indicating whether to open a new tab

tab_title (default: None)

Title for the new tab

no_response (default: False)

Boolean indicating whether to send back the window id

remove-marker#

Fields are:

match (default: None)

Which window to remove the marker from

self (default: False)

Boolean indicating whether to detach the window the command is run in

resize-os-window#

Fields are:

match (default: None)

Which window to resize

self (default: False)

Boolean indicating whether to close the window the command is run in

incremental (default: False)

Boolean indicating whether to adjust the size incrementally

action (default: resize)

One of resize, toggle-fullscreen or toggle-maximized

unit (default: cells)

One of cells or pixels

width (default: 0)

Integer indicating desired window width

height (default: 0)

Integer indicating desired window height

resize-window#

Fields are:

match (default: None)

Which window to resize

self (default: False)

Boolean indicating whether to resize the window the command is run in

increment (default: 2)

Integer specifying the resize increment

axis (default: horizontal)

One of horizontal, vertical or reset

scroll-window#

for unscrolling by lines.

Fields are:

amount (required)

The amount to scroll, a two item list with the first item being either a number or the keywords, start and end. And the second item being either ‘p’ for pages or ‘l’ for lines or ‘u’

match (default: None)

The window to scroll

no_response (default: False)

Boolean indicating whether to wait for a response

select-window#

Fields are:

match (default: None)

The tab to open the new window in

self (default: False)

Boolean, if True use tab the command was run in

title (default: None)

A title for this selection

exclude_active (default: False)

Exclude the currently active window from the list to pick

reactivate_prev_tab (default: False)

Reactivate the previously activated tab when finished

send-text#

Fields are:

data (required)

The data being sent. Can be either: text: followed by text or base64: followed by standard base64 encoded bytes

match (default: None)

A string indicating the window to send text to

match_tab (default: None)

A string indicating the tab to send text to

all (default: False)

A boolean indicating all windows should be matched.

exclude_active (default: False)

A boolean that prevents sending text to the active window

session_id (optional)

A string that identifies a “broadcast session”

set-background-opacity#

Fields are:

opacity (required)

A number between 0.1 and 1

match_window (optional)

Window to change opacity in

match_tab (default: None)

Tab to change opacity in

all (default: False)

Boolean indicating operate on all windows

set-colors#

Fields are:

colors (required)

An object mapping names to colors as 24-bit RGB integers or null for nullable colors

match_window (optional)

Window to change colors in

match_tab (default: None)

Tab to change colors in

all (default: False)

Boolean indicating change colors everywhere or not

configured (default: False)

Boolean indicating whether to change the configured colors. Must be True if reset is True

reset (default: False)

Boolean indicating colors should be reset to startup values

set-enabled-layouts#

Fields are:

layouts (required)

The list of layout names

match (default: None)

Which tab to change the layout of

configured (default: False)

Boolean indicating whether to change the configured value

set-font-size#

Fields are:

size (required)

The new font size in pts (a positive number)

all (default: False)

Boolean whether to change font size in the current window or all windows

increment_op (optional)

The string + or - to interpret size as an increment

set-spacing#

Fields are:

settings (required)

An object mapping margins/paddings using canonical form {‘margin-top’: 50, ‘padding-left’: null} etc

match_window (optional)

Window to change paddings and margins in

match_tab (default: None)

Tab to change paddings and margins in

all (default: False)

Boolean indicating change paddings and margins everywhere or not

configured (default: False)

Boolean indicating whether to change the configured paddings and margins. Must be True if reset is True

set-tab-color#

Fields are:

colors (required)

An object mapping names to colors as 24-bit RGB integers. A color value of null indicates it should be unset.

match (default: None)

Which tab to change the color of

self (default: False)

Boolean indicating whether to use the tab of the window the command is run in

set-tab-title#

Fields are:

title (required)

The new title

match (default: None)

Which tab to change the title of

set-window-title#

Fields are:

title (optional)

The new title

match (default: None)

Which windows to change the title in

temporary (default: False)

Boolean indicating if the change is temporary or permanent

signal-child#

Fields are:

signals (optional)

The signals, a list of names, such as SIGTERM, SIGKILL, SIGUSR1, etc.

match (default: None)

Which windows to send the signals to

no_response (default: False)

Boolean indicating whether to wait for a response