28 Unix tools. One binary. Zero dependencies.·the missing coreutils for the agent era·try vrk in your browser at vrk.sh/play·curl vrk.sh/install.sh | sh - ready in 5 seconds·

SSE stream to text

Raw SSE has protocol framing that other tools cannot read, so sse extracts the text field and prints clean text.

Parse a Server-Sent Events stream from an LLM API and print the streamed text.

Pipeline

curl -sN $API \
  | vrk sse --event content_block_delta \
      --field data.delta.text --raw

Try it in your browser

vrk, compiled to WebAssembly

# stream.sse stands in for curl. It is an OpenAI-style stream, so the field path differs from the Anthropic one above.

Enter runs, Shift+Enter adds a line
    output
    Press RUN. Nothing leaves your browser.

    files you can cat:

    Edit the command and press RUN. Open the full playground for more recipes, or install vrk to run it on your own files.

    The problem

    Streaming LLM APIs (Anthropic, OpenAI) return responses as Server-Sent Events. The raw SSE stream looks like this:

    event: content_block_delta
    data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"}}
    
    event: content_block_delta
    data: {"type":"content_block_delta","delta":{"type":"text_delta","text":" world"}}
    

    You can’t pipe this directly into another tool. You need to parse the SSE framing, filter by event type, and extract the text field from the JSON data.

    How the pipeline works

    vrk sse reads the SSE stream from stdin and parses the event: and data: lines. --event content_block_delta keeps only that event type. --field data.delta.text pulls the nested text value out of each event.

    By default sse prints one value per line. --raw writes each value exactly as it is, with no separator added, so the fragments join into the model’s real text, newlines and all. No tr needed.

    OpenAI streams

    OpenAI puts the text in an array, so use an index in the path:

    curl -sN $API | vrk sse --field 'data.choices[0].delta.content' --raw
    

    If events arrive but the field matches none of them, vrk sse exits 1 and says so on stderr. A wrong path no longer looks like an empty answer.

    Variations

    Capture the events as JSONL for debugging:

    curl -sN $API | vrk sse > stream.jsonl
    

    Filter for a specific event and count occurrences:

    curl -sN $API | vrk sse --event content_block_delta | wc -l
    

    Tools used