Early access — no public build yet

moqtap CLI

Put a proxy between your client and the relay and read every frame as it passes. Degrade the path on purpose — loss, delay, a capped rate, objects dropped by rule — and watch what your player does about it. Record the session and read it back afterwards.

Ask for early access and we will come to you when there is a binary to install. Available today: the WebTransport Inspector and the protocol libraries.

One binary, four jobs

Watch a session go past, make it go badly, ask a relay directly, or read back one you recorded earlier.

Intercept

A transparent proxy that sits between your MoQT client and relay. See control messages, stream lifecycle, objects, datagrams, and errors.

  • Live frame-by-frame decoding
  • Color-coded directional output (C→R / R→C)
  • Session recording to .moqtrace files
  • Filtering by control, data, or session ID
  • JSON output for piping to jq
  • WebTransport support (listen and upstream)

Degrade

Pro

The same proxy, running a scenario file: what the path underneath QUIC does, what each leg negotiates, how egress is shaped, and what happens to individual objects.

  • Networks by name — LTE, Wi-Fi, satellite, 3G
  • Loss, delay, jitter and reordering
  • Bandwidth ceilings and queueing
  • Rules that hit individual objects
  • Conditions that change mid-session
  • The same bad session, on demand

Peek

A lightweight MoQT client that connects directly to a relay to probe its capabilities, discover namespaces and tracks, and retrieve sample data.

  • Relay info & draft version detection
  • Namespace discovery
  • Track enumeration via catalog
  • Data retrieval (latest group or object)
  • Media format detection (JSON, fMP4, LOC, MSF)
  • Pipeable raw output and JSON mode

Replay

A session you recorded, read back from the file: the same decoded view in the terminal, or the same session opened in the browser inspector.

  • Recorded from any session
  • The decoded view again, offline
  • Opens in the browser inspector
  • JSON out, for scripts and diffs
  • An open, documented format
  • Nothing leaves your machine

Intercept mode

MoQT Client ──QUIC──▶ moqtap ──QUIC──▶ MoQT Relay
↓ parses every frame ↓ prints to terminal ↓ writes .moqtrace
moqtap intercept -l 0.0.0.0:4443 -u relay:4443
12:34:56.789 #1 NEW 192.168.1.5:54321 connected
12:34:56.790 #1 C→R SETUP CLIENT_SETUP versions=[4278190087]
12:34:56.791 #1 R→C SETUP SERVER_SETUP version=4278190087
12:34:56.800 #1 C→R CTRL SUBSCRIBE req=1 ns=live track=video
12:34:56.801 #1 R→C CTRL SUBSCRIBE_OK req=1 alias=1
12:34:56.810 #1 R→C UNI subgroup track=1 group=0 subgroup=0
12:34:56.811 #1 R→C OBJ status=Normal len=1234
12:34:56.900 #1 C→R DGRAM track=1 group=1 object=0 payload=56B

Break it on purpose

Pro

Everything works on a clean network. What you need to know is what your player does when the path is not clean — so the proxy that decodes the session is also the thing that can ruin it, from a file that says exactly how.

Scenario-driven degradation is a Pro feature. Default link degradation — offline, 3G and 4G — is free, and the CLI is what runs it. Your browser's own throttling dropdown has no effect on a WebTransport connection, so this is the only way to watch your player on a bad link. From v1 the moqtap Extension detects a running CLI and drives it from the panel.

bad-wifi.json
{
  "version": 1,
  "network": { "preset": "lossy-edge" },
  "rules": [
    {
      "name": "lose-the-first-object-of-every-group",
      "matcher": { "object_id": [{ "start": 0, "end": 0 }] },
      "action": "drop"
    }
  ],
  "timeline": [
    {
      "at": { "secs": 30, "nanos": 0 },
      "network": { "preset": "satellite" }
    }
  ]
}
moqtap intercept -u relay:4443 -s bad-wifi.json
moqtap listening on 127.0.0.1:4443 (negotiating draft per session) -> relay:4443
scenario bad-wifi.json: network, 1 rule(s), 1 timeline step(s) [impaired sockets: one client at a time]
seed 1430453990272362564 (pass --seed 1430453990272362564 to run it again)
12:34:57.104 #1 R→C ACT object drop_elide stream=4 → elided renumbered_successor=true
12:34:57.301 #1 R→C SHAPE stream=8 class=video dropped
12:35:27.002 #1 R→C IMPAIR egress_queue_full stream_id=8

What the scenario did arrives in the same stream as everything else — and in the recording.

Networks by name

LTE, Wi-Fi, satellite, 3G, a lossy access edge, a bufferbloated link — and a clean datacentre path to measure the others against. Or describe your own: loss, delay, jitter, reordering, duplication, corruption, capacity.

Down to the single object

Rules that pick out a track, a group, a subgroup or one object and drop it, hold it back, or change what it carries. The keyframe at the top of every group, the third subgroup, every object over a size — whatever your player is quietly relying on.

It gets worse while it runs

A session that starts clean and falls apart thirty seconds in, a satellite hop that appears mid-stream, a bandwidth ceiling that drops under a running subscription. Recovery is a behaviour, and it only shows up when conditions move.

The same bad session again

A bad network is random, which normally means the run that broke your player cannot be shown to anyone. Every run prints the seed it drew, and a run given that seed back plays out the same way — for a colleague, for a bug report, for CI.

Peek mode

Connect straight to a relay and ask it what it is, what it is carrying, and what the media looks like — without writing a client to find out.

peek subcommands
moqtap peek # what is this relay, and what does it speak?
moqtap peek namespaces # what is being published?
moqtap peek tracks live/stream1 # what is in it?
moqtap peek data live/stream1 video # and what does the media look like?

Four questions you would otherwise answer by writing a client.

Recorded now, read later

A session you watched go past is gone. A session you recorded is a file — one you can read again, diff against yesterday's, and hand to whoever owns the other end of the connection.

recording, and reading it back
moqtap intercept -u relay:4443 --output session.moqtrace # record while you watch
moqtap trace session.moqtrace # read it back in the terminal
moqtap inspect session.moqtrace # or open it in the browser
It never leaves your machine

Opening a recording in the moqtrace Inspector hands it from your own disk to a page in your own browser. Nothing is uploaded, and there is no account in the way — which is what makes a customer's capture something you can actually look at.

A file you own

.moqtrace is an open format, implemented in both Rust and JavaScript — the CLI, the browser extension and anything you write yourself read the same recording.

Frequently asked questions

What is the moqtap CLI?
moqtap is a command-line tool for debugging MoQT deployments. It intercepts traffic between your client and a relay and decodes every frame as it passes; it degrades that traffic on purpose when a scenario file tells it to; it peeks at a relay directly to probe capabilities, discover namespaces and pull sample data; and it records sessions to .moqtrace files that it reads back in the terminal or opens in the browser inspector.
What is intercept mode?
Intercept mode runs a transparent proxy between your MoQT client and relay. It forwards all bytes unmodified while parsing every frame inline — printing a structured, timestamped, color-coded view of protocol activity. It never participates in MoQT state management, and left alone it changes nothing on the wire — a scenario file is the one thing that makes it act on the traffic rather than watch it.
What is peek mode?
Peek mode connects directly to a relay as a minimal MoQT client. It probes relay capabilities, discovers namespaces, enumerates tracks via catalog, and retrieves sample data from individual tracks — with automatic media format detection (JSON, fMP4, LOC, MSF). It connects, queries, and disconnects.
Can I test what my player does on a bad network?
Yes, and it is as much the point of the tool as decoding is. A scenario describes a whole run: the network underneath the session — loss, delay, jitter, reordering, a capacity ceiling — rules that drop or hold back individual objects, and conditions that change while the session is running. Every run reports the seed it drew, so the run that broke something can be handed to a colleague and played out again exactly.
What is a .moqtrace file?
A recording of a session. moqtap writes one while it watches, reads it back in the terminal afterwards, and opens it in the browser inspector — where it stays on your machine rather than going to a service. The format is open and documented, and the browser extension reads and writes the same files, so a capture from a colleague or a customer opens in whichever tool you have.
How do I configure the relay URL?
On the command line, in an environment variable, or in a config file that moqtap walks up the directory tree to find — so a project you work in every day is a bare `moqtap peek`. Whichever it used, it prints where the URL came from, so there is never a question about which relay you just talked to. The CLI reference has the precedence in full.
Which MoQT draft versions are supported?
moqtap supports drafts 07 through 20. In peek mode, it auto-detects the draft by offering all supported versions in CLIENT_SETUP and reading the relay's response. You can force a specific draft with --draft.
Can I download it?
Not yet. The CLI is in early access — there is no public build, and the tools you can install today are the WebTransport Inspector extension and the protocol libraries. Ask for early access and we will get in touch when there is a binary to give you.
Will the CLI be free?
The plan is a free tier with paid tiers for scenario features, matching the extension. The CLI itself is not open source — the source is proprietary. The MoQT protocol libraries it is built on are open source (MIT) and published to crates.io today.

See inside the protocol

Early access is open, and every command and flag is already in the CLI reference. For MoQT over WebTransport in a page, the WebTransport Inspector brings the same decoding to your browser's DevTools today.