Use async *run to stream chunks incrementally. Yield objects for structured data or plain strings for text.
Basic Streaming
Return an async generator to stream output:
Output
Each yielded value is written as a line in human/TOON mode.
Streaming Objects
Yield structured data:
Output (TOON)
With --format jsonl, each chunk becomes a JSON object:
This format is ideal for:
- Log aggregation
- Real-time monitoring
- Piping to other tools
Streaming with CTAs
Use c.ok() as the return value to attach CTAs or signal completion:
Output
Error Handling
Return c.error() to signal failure:
Output
Streaming with Delays
Simulate real-time streaming:
Output
Real-Time Logs
Stream logs from an external process:
Streaming from APIs
Stream data from HTTP endpoints:
Buffered Streaming
Buffer chunks before yielding:
MCP Streaming
When running as an MCP server (--mcp), streaming chunks are sent as progress notifications:
When invoked via MCP:
- Each
yield sends a progress notification to the agent
- The final
return value becomes the tool result
Agents receive incremental updates and can show progress in real-time.
Streaming vs Non-Streaming
Non-streaming (returns once)
Streaming (yields multiple times)
Use streaming when:
- Output is produced incrementally
- Long-running operations need progress updates
- Real-time data needs to be displayed
- Logs or events are being tailed
Return Values
Async generators can return values:
Output
The return value is displayed after all yielded chunks.
Implementation
Streaming detection is automatic based on the function signature:
When run is an async generator, incur:
- Iterates over each yielded value
- Formats and writes each chunk to stdout
- Handles the final return value as the result
Use streaming for long-running operations to provide real-time feedback to agents and humans.