Kitty Color Protocol (OSC 21)

Query, set, or reset terminal palette and special colors using Kitty's extended color protocol.

  1. 0x1B
    ESC
  2. 0x5D
    ]
  3. 0x32 0x31
    21
  4. 0x3B
    ;
  5. ____
    k
  6. 0x3D
    =
  7. ____
    v
  8. 0x3B
    ;
  9. ____
    ...
  10. 0x1B
    ESC
  11. 0x5C
    \

OSC 21 is Kitty's extended color protocol. It supersedes the older OSC 4, OSC 5, and OSC 10-19 sequences by unifying queries, sets, and resets for the entire palette and a set of named "special" colors into a single sequence. The parser accepts at most 526 entries, and it counts only the pairs it understood: a pair with an unknown key or an unparseable color is skipped and never reaches the list. In practice the 2048-byte OSC capture buffer fills up before the entry count does for most realistic requests. Hitting either limit discards the whole sequence rather than truncating it.

Reference: Kitty color protocol.

Keys

Each pair's key identifies which color to operate on, and the value determines the operation:

Key formTarget
0-255Palette entry by index.
foregroundDefault text color.
backgroundDefault background color.
cursorCursor color.
cursor_textText color when drawn under the cursor.
selection_foregroundText color for selected cells.
selection_backgroundBackground color for selected cells.
visual_bellColor flashed on the visual bell.
second_transparent_backgroundSecondary transparent background tint.

Operations

The value of each pair determines what to do with that color:

Value formOperation
<empty> (e.g. cursor=)Reset the color to its configured default.
? (e.g. foreground=?)Query the current color. The terminal replies with the same key.
Any color specSet the color (see color specifications).

Accepted color specifications include #rrggbb, rgb:rr/gg/bb, rgbi:r/g/b, and named CSS-style colors like aliceblue.

Examples

Query the foreground, set the background, and reset the cursor in a single sequence:

printf '\033]21;foreground=?;background=rgb:f0/f8/ff;cursor=\033\\'

Swap the palette colors 0 and 7:

printf '\033]21;0=#000000;7=#ffffff\033\\'

Behavior in Wintty

Note

Wintty parses every key listed above, but the executor only acts on three special colors plus the numeric palette:

KeySet / ResetQuery
0-255YesYes
foregroundYesYes
backgroundYesYes
cursorYesYes
cursor_text, selection_foreground, selection_background, visual_bell, second_transparent_backgroundParsed, ignoredParsed, no reply

Every answered query in one request is batched into a single reply of the form ESC ] 21 ; key=rgb:rr/gg/bb ST, repeating ;key=value once per answered key and echoing back the same string terminator the request used. A supported key that currently has no color set replies with an empty value (;key=). The five remaining special colors are simply left out of the reply, but a reply is still sent: the ESC ] 21 prefix is written before any key is checked for support, so a request that queries only unsupported keys gets back a bare ESC ] 21 ST with no pairs in it. Callers can wait for a reply, but they must handle one that carries no values.

Relation to color "stack" semantics

The upstream Kitty documentation also describes a color stack that lets fullscreen TUIs push the current palette state, install a fresh one, and restore it on exit (using a separate push/pop/current parameter set). Wintty does not currently implement the push/pop variant. For applications that need to restore the user's palette on exit, the recommended portable pattern is to query the colors at startup with ?, remember the responses, and apply them back with explicit set sequences before exit.

See also