flicker_

Agent-first terminal text animations — library, MCP server, CLI.

Install

Install once, or run on demand with npx:

$ npm install -g @capitalthought/flicker
$ npx @capitalthought/flicker typewriter "hello, flicker"

Node >= 20. No native deps. Zero secrets at runtime.

Install as an MCP server

The MCP server is the primary surface. Wire it into Claude Code with one command:

claude mcp add flicker npx @capitalthought/flicker mcp↑ triple-click to select, or just paste it as-is

You'll then have five verb-first tools: play_typewriter, play_spinner, play_progress, estimate, overview. The renderer writes to /dev/tty, never to MCP stdio — so JSON-RPC stays clean.

Effects

Three v0.1 effects. The previews below are HTML approximations of what runs in your real terminal — same cadence, same final frames.

typewriter

Characters appear one at a time at N cps. Determinate — plan() knows the total cost up front.

$ flicker typewriter "hello, flicker" --cps 30
_

spinner

Animated glyph + label. Omit --duration and it runs indeterminate, capped at 60 s (fallback: "duration_cap").

$ flicker spinner "Connecting" --duration 2000 --kind dots

progress

Determinate bar with --total, or bouncing indeterminate when total is null.

$ flicker progress "Downloading" --total 100 --steps 20

MCP tools

ToolPurpose
play_typewriter Render typewriter text. Returns a Receipt with bytes, duration, fallback tier, and cost.
play_spinner Render a spinner. Three kinds: dots, bar, pulse. Hangs are impossible.
play_progress Render a progress bar. Determinate (total: N) or indeterminate (total: null).
estimate Pure planning. Returns a CostEstimate with worst-case and stripped dollar cost. No render.
overview Server status: uptime, mode, terminal caps, last 20 receipts, cumulative cost. Inspectable State.

Why agent-first

Agents now run inside terminals. They want decorative output — a typewriter intro, a progress bar, a spinner — without three failure modes that ordinary animation libraries don't handle:

MCP stdio safety. Any ANSI escape on a server's stdout breaks JSON-RPC; the host drops the connection. flicker's renderer writes to /dev/tty (or stderr, or nothing) — never to MCP stdout. Three rendering tiers — full, reduced, plain — are auto-selected based on /dev/tty, MCP_CLIENT, AGENT, CI, and NO_COLOR.

Cost transparency. A two-sentence model reply that ran a spinner during the call has been measured at ~15KB of escape noise to ~200 bytes of content. Every effect can be estimate'd without rendering — dollars_worst_case is what you'd pay if every escape byte hit your context, dollars_stripped is what you'd pay after stripping. The gap is the ANSI tax.

CSI allowlist. LLM-generated output can embed CSI / OSC / DCS sequences that hijack a terminal. flicker emits only a small allowlisted set and rejects caller text that smuggles its own (no OSC 8 hyperlinks, no OSC 52 clipboard, no mouse modes, no Sixel).