KESTREL TERMINAL

The market workstation for agents.

A professional trader gets a workstation — screens, charts, market gestalt, and the ability to act from what they see. An agent gets a JSON endpoint. Kestrel Terminal closes that gap.

$ npx kestrel.markets

Free, no signup, no credential. The bare invocation runs today under plain node — it prints the workstation’s verbs and exits.

Perception is the product.

Any broker can carry the order. What a professional pays for is the seeing.

Charts, tape, depth, gestalt — a desk pays for the market as a picture it can act from. Agents are the next professional population at that market. Until now, theirs was the only seat with no screens.

Measured, not designed

In the first live dry run, three frontier models burned 30 to 47% of their turns on the same parse escape. The fix was teaching, not loosening: the prompt now teaches the layout the models kept collapsing, and the fail-closed parser still refuses exactly what it refused before. This workstation is tuned against its reader’s measured failure rates, not a designer’s taste.

Evidence: The grammar, measured

Ships in one command

No appliance, no procurement, no sales call: the whole workstation distributes as the one command above — free, anonymous, before any account exists.

One terminal. Three renderings.

CLI, MCP, and SDK are the same workstation,
rendered where your agent lives.

One terminal. Your agent already holds it wherever it runs: the CLI, the MCP server, and the TypeScript SDK are equal renderings of the same workstation — the same operations, the same receipts, the same proofs. HTTP + SSE is the canonical face underneath; a session started on one rendering is inspected and resumed on any other.

MCP

MCP

The same workstation as a Model Context Protocol server, so an agent drives it natively — a thin, equal wrapper over the canonical endpoints, never an impoverished subset. Paste this into your MCP client config to keep it:

{
  "mcpServers": {
    "kestrel-markets": {
      "type": "streamable-http",
      "url": "https://mcp.kestrel.markets/mcp"
    }
  },
  "description": "kestrel.markets is the managed platform that runs a trading firm on Kestrel: managed data, execution authority, and certified proof. Free, anonymous sims, no signup. Kestrel Terminal — the market workstation for agents.",
  "gap": "A professional trader gets a workstation — screens, charts, market gestalt, and the ability to act from what they see. An agent gets a JSON endpoint. Kestrel Terminal closes that gap.",
  "negativeCapabilities": "Kestrel Terminal does not place live orders, hold funds, or claim alpha; live execution authority exists only behind a separate, human-signed Envelope scope."
}

Read the MCP docs →

CLI

CLI

The open-source local runtime and the hosted verbs from one invocation: parse, frame, grade, and replay on your machine; sim, prove, certify, and verify against the hosted substrate — free and anonymous, ending at a shareable proof URL.

$ npx kestrel.markets

Read the CLI docs →

SDK

TypeScript SDK

A typed client that mirrors the HTTP surface one-to-one: the same operation IDs, events, receipts, and artifacts, with types generated from the same contract. No SDK-only conveniences the wire protocol lacks.

Read the TypeScript SDK docs →

Drive it from anywhere · four equal facesHTTP+SSETypeScript SDKCLIMCPsame Operation IDs, receipts & artifacts

Measured, not designed.

The screen your agent deserves.

The percept is the market rendered as text an agent can reason over: phase-conditioned token budgets (1800 at the OPEN, 400 in a SHOCK), an immutable Kernel, six-way attribution on every value, and explicit UNKNOWN instead of a guess. A token-efficient wrong number is worse than an expensive right number.

Run it now · verbatim output of the published CLI

npx -y kestrel.markets frame briefing.jsonreal CLI output · npm package · plain node
$ curl -sO https://kestrel.markets/examples/briefing.json \
&& npx -y kestrel.markets frame briefing.json
KESTREL · OPEN briefing · T-92m to close · regular · 13:24 ET
instruments:
SPY index signal mult 100 tick 0.05
levels · SPY
spot 520.80 · prior_close 498.30 · hod 521.90 · lod 491.50 · vwap 499.10 · or —–—
tape 5m · axis 505.90→521.90 · anchor @ 13:04 ET
13:04 ─██─
13:09 ─███─
13:14 ██████─
13:19 ████████████████████████
13:24 ─█████───
chain (near-money) · SPY
strike R bid ask fair flags
520 C 1.70 2.05 1.84 b76 nLiq=6 —
macro: unavailable (v1 harness)
KERNEL (acting)
positions:
(none)
resting:
(none)
fills since last:
(none)
budget: used +0.00 / remaining +1000.00 (total 1000)
plans:
(none)
The real output of the command above: the published npm package rendering the hosted briefing.json under plain node. Copy it and run it; you get these exact 31 lines (today's published CLI prefixes them with its non-configurable safety kernel block).

The trace on the left is the two-command percept path: curl the hosted briefing, render it with the npm package under plain node. The panes below are the day verb's file handshake on the choppy-1101 tape: the CLI writes the briefing, your agent answers with a Kestrel document, and every wake ends with the same question. The interface is files, no SDK. Run bare, the command below refuses with a typed NO_AUTHOR exit; the session opens when your agent drops plans-0.kestrel into the day directory.

curl -sO https://kestrel.markets/examples/choppy-1101.jsonl && mkdir -p day && npx -y kestrel.markets day --bus choppy-1101.jsonl --dir day --fill strict-cross-v1 --r-usd 10000
stepped session · writes day/briefing.txt, then waits for your agent's plans-0.kestrel — the reply opens the session
day · briefing.txt (excerpt)
=== KESTREL OPEN BRIEFING (keyframe) ===
instruments: QQQ
phase: pre close: 16:00 ET
spot: 100.00 prior_close: —
chain @ 100.00 (0dte):
98 C bid 2.68 ask 2.74
99 C bid 1.69 ask 1.74
100 C bid 0.70 ask —
100 P bid 0.70 ask 0.74
101 P bid 1.70 ask 1.74
kernel (acting): flat budget 10000.00/R committed 0.00
→ author <dir>/plans-0.kestrel to open the session.
day · plans-0.kestrel
PLAN atm-rider budget 0.5R ttl +60m
WHEN phase open
DO buy 1 atm C @ lean(bid, fair, 0.5)
day · frame-1-0910.txt (excerpt)
=== WAKE 1 @ 0910 ET (delta) ===
phase: regular spot: 100.27 vwap: 99.92 hod: 100.27 lod: 99.59
tape (since last vantage):
0908 100.16
0909 100.26
0909 100.27
plans:
atm-rider: managing (held 1)
resting: (none)
fills:
atm-rider entry buy 1 100C @ 0.71
budget: committed 71.00 (R=10000.00)
→ author <dir>/revision-1.kestrel (supersede) OR touch <dir>/pass-1 (no change).

Percept v5 is the contract the runtime is converging to: the full pane library, six-way attribution, and fail-closed postures (a SHOCK withholds the story; a lost canonical source de-arms dependent Wakes and Plans). Where the CLI renders less, that is a filed requirement, not a looser contract. Derived, not raw. Impersonal by default. The screen, in full.

Four statements. One document.

A complete strategy,
small enough to stay in context.

One bounded thesis. The strategy is the artifact, written in a notation of four statements: you read, diff, and replay it byte-for-byte.

momentum-breakout.kestrel
PLAN momentum-breakout budget 0.25R ttl +30m regime {intraday: trend}
USING signal SPX exec SPY 0dte
WHEN spot crosses above hod AND velocity(1m) >= p95
DO buy 2 +1 C @ min(fair-3c, mid) peg esc fair 2m esc ask 4m cap fair cancel-if spot < vwap
EXIT spot < vwap held 60s @ fair esc mid 30s
  • PLANOne bounded thesis. budget 0.25R makes risk a type, not a comment; ttl +30m expires the authority; the regime tag scopes when this thesis is even eligible.
  • USINGRead the signal on the index, execute on the liquid proxy. The signal/exec split is first-class, not a convention.
  • WHENThe trigger the runtime watches every tick: a breakout of the high of day, confirmed by 1-minute velocity above its 95th percentile.
  • DOThe bounded action, priced off honest anchors: start at min(fair-3c, mid), escalate to fair after 2 minutes and toward the ask after 4, capped at fair, and cancel the resting order if spot loses VWAP.
  • EXITThe exit reflex: if spot holds below VWAP for 60 seconds, leave at fair, escalating to mid after 30 seconds. Authored now, fired later without a model in the loop.

View · what should I see?

Selects panes at a token budget. Materializes into an attributed Frame; the renderer never invents a value.

VIEW · complete statement
VIEW open budget 1800
macro week quarter rv20
vol straddle expected-move
tape skyline 5m vwap detector-strip
levels registry
chain fair realness

Wake · when should I look?

Events, not polling. The runtime watches all day; your context wakes only when something actually moves.

WAKE · complete statement
WAKE fast-move
WHEN velocity(1m) > p99
DELIVER zoom-1m KEYFRAME

Plan · what may execute?

Judgment in advance, fired at the tick. The runtime executes in milliseconds and wakes you in parallel.

PLAN · complete statement
PLAN atm-rider budget 0.5R ttl +60m
WHEN phase open
DO buy 1 atm C @ lean(bid, fair, 0.5)

Grade · did it actually work?

Counterfactual evaluation under pinned data and fill models, with a replayable certified receipt.

GRADE · complete statement
GRADE plan fade-ladder OVER 2025-01..2026-06 FILL maker-v1
VS ungated null
BY regime.intraday, lineage
slow judgment, compiled into a fast reflex.The agent authors; the runtime fires; Risk can clamp anyone, and may never open risk.

The workstation is open source.

Kestrel Terminal is the open-source workstation: your agent's eyes on the market, and hands that fire at the tick. kestrel.markets runs the firm around it: managed data, execution authority, certified proof.

Agent twin: /terminal.md