Kou

Kou

Virtual terminal engine

License: SySL-1.0 GitHub Checks Docs docs.rs

English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Français · Español · Русский · العربية

Introduction

kou is a standalone virtual-terminal engine — PTY management, a VT100/ANSI screen emulator, and screen rendering that draws glyphs. It is the vtty core extracted from the tairitsu packager, hardened into a library and CLI of its own.

Three things set it apart from a bare PTY wrapper:

Quick Start

CLI

# Launch a command in a virtual terminal and drive it from a REPL.
kou launch bash --cols 80 --rows 24
# > echo hello
# > screen        # prints the current screen text

npx (no Rust toolchain required)

Prebuilt binaries are published to npm, so you can run kou with a single command — no cargo build:

npx @celestia-island/kou launch bash
npx @celestia-island/kou mcp        # the MCP server (needs the mcp build)

The @celestia-island/kou root package pulls the right platform subpackage (-linux-x64 / -darwin-arm64 / -win32-x64) automatically. To pin a version:

npx @celestia-island/kou@0.1.0 launch bash

Library

use kou::{FontCache, FontSet, VttyManager, render_png};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mgr = VttyManager::new();
    let id = mgr.launch("bash", None, 80, 24).await?;
    mgr.send_text(&id, "echo hello\n").await?;

    // Plain text.
    println!("{}", mgr.screenshot(&id).await?);

    // A real PNG, rendered with auto-fetched fonts (Latin + CJK fallback).
    let fonts = FontCache::load(&FontSet::from_env(), 16.0);
    let screen = mgr.screen(&id).await?;
    let png = render_png(&screen, &fonts, 16.0)?;
    std::fs::write("screen.png", png)?;
    Ok(())
}

Graphics protocols

KOU_GRAPHICSProtocolTerminals
kitty / kitty2kitty APC graphicskitty, wezterm, Ghostty
iterm / iterm2OSC 1337 inline imageiTerm2, wezterm
sixelDCS sixel(placeholder — needs a rasterizer)
off (default)none — render a PNG out of bandall
use kou::{FontCache, FontSet, GraphicsProtocol, VttyManager, render_graphics};
let frame = render_graphics(&screen, &FontCache::load(&FontSet::from_env(), 16.0), 16.0,
                            GraphicsProtocol::from_env());
if let Some(escape) = frame {
    print!("{escape}"); // capable terminals render the pixels inline
}

Fonts & fetching

kou pre-downloads one font per script into a shared cache at build time:

ScriptFont
LatinFira Code
CJK (中文 · 日本語 · 한국어)Source Han Sans SC (思源黑体)

Override any family at build time with KOU_FONT_PRIMARY / KOU_FONT_CJK, or pin local files with KOU_FONT_PATH / KOU_FONT_CJK_PATH. Downloads can be routed through an HTTP(S) proxy via KOU_DOWNLOAD_PROXY (passed directly to reqwest).

EnvPurpose
KOU_FONT_PRIMARYOverride the Latin font family.
KOU_FONT_CJKOverride / disable the CJK font (none to disable).
KOU_FONT_MIRRORSubstitute the download host with a mirror.
KOU_DOWNLOAD_PROXYRoute downloads through an HTTP(S) proxy (reqwest).
KOU_DOWNLOAD_TIMEOUT_SECSPer-request timeout (default 120).
KOU_SKIP_FONT_FETCHDisable fetching.

MCP server

Build kou with the mcp feature and run the stdio server — it exposes the virtual-terminal engine to AI coding assistants over the Model Context Protocol (no browser or daemon required):

kou mcp

The server advertises eleven tools — vtty_launch, vtty_kill, vtty_send_keys, vtty_send_text, vtty_screenshot, vtty_wait, vtty_ready, vtty_scrollback, vtty_resize, vtty_list, vtty_ping — each delegating in-process to the same VttyManager the library exposes. Screenshots render through the same font + theme stack as the library, so vtty_screenshot returns a real PNG (or themed text) for vision-capable models.

Wire it into an MCP client:

{
  "mcpServers": {
    "kou": { "command": "kou", "args": ["mcp"] }
  }
}

Set KOU_PROJECT_ROOT to pin the working directory for launched sessions when the client does not advertise a project root.

Development

cargo check --all-features
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
Screenshots

kou snapshot

License

SySL-1.0 (Synthetic Source License). See LICENSE.