Markdown as Protocol for Agentic UI with Streaming Execution

A developer built a prototype exploring how to combine generative UI with code execution for AI agents using Markdown as a unified protocol. The system streams text, executable code, and data in a single response, with code executing incrementally as it arrives.
The Protocol: Markdown with Three Block Types
The approach uses standard Markdown syntax that LLMs already understand, avoiding the need to teach new formats. It defines three block types:
- Text blocks: Plain Markdown formatting that streams to the user
- Code fences:
```tsx agent.runexecutes TypeScript/JSX code on the server in a persistent context - Data fences:
```json agent.data => "id"streams JSON data into UI components
These blocks can be interleaved in any order within a single response. The parser handles them incrementally as tokens arrive from the LLM.
Streaming Execution
Code executes statement-by-statement as the LLM generates it, without waiting for the full code fence to close. This allows API calls to start, UI to render, and errors to surface while the LLM is still sending tokens. The developer built bun-streaming-exec to handle this, using vm.Script with custom wrapping since streaming execution isn't a standard runtime primitive.
Agentic UI with mount() Primitive
The system uses React for UI generation since LLMs have extensive exposure to React components and JSX. The core primitive is mount():
mount({
ui: () => <Card>Hello from the agent!</Card>
});When the LLM generates this code and the server executes it, mount() serializes the React component and sends it to the client for rendering within the chat interface.
Data Flow Patterns
The prototype implements four distinct patterns for data movement:
- Client → Server (forms): The agent can wait for user input through forms
- Server → Client (streamed data): Data fences stream JSON directly into mounted UIs
- Server → LLM (console.log):
console.logoutput and exceptions feed back to the LLM as a new turn - LLM → Server → Client (full roundtrip): Complete cycles where the LLM generates code that fetches data and renders UI with that data
Feedback Loop
The system uses console.log as the mechanism for the agent to talk to itself. When the LLM generates Markdown with code blocks, text streams to the user while code executes incrementally. Any console.* output or exceptions feed back to the LLM as a new turn. If there's no output or exceptions, the system waits for a new user query.
This allows the agent to react to its own execution, such as checking message counts or pausing to wait for user input before proceeding.
📖 Read the full source: HN AI Agents
👀 See Also

Pneuma: An AI-Generated Desktop Environment Where Software Materializes from Descriptions
Pneuma is a desktop computing environment where you describe what you want—a CPU monitor, game, notes app, or data visualizer—and a working program materializes in seconds. The system generates self-contained Rust modules, compiles them to WebAssembly, and executes them in sandboxed Wasmtime instances with GPU rendering via wgpu.

OpenRouter Model Pricing and Intelligence-per-Dollar Analysis
A Reddit user compiled OpenRouter API pricing for 16 AI models and calculated intelligence-per-dollar values, identifying MiMo-V2-Flash as best value at $0.09/M tokens and GPT-5.4 as most intelligent at $2.50/M tokens.
PullMD v2.4.1 Adds Native MCP Connector for claude.ai Web and Multi-User Auth
PullMD v2.4.1 now supports the claude.ai web custom connector dialog via OAuth 2.1 + PKCE-S256 and adds multi-user auth modes. Turn any URL into clean Markdown via self-hosted MCP.

Zeude: Self-Hosted Monitoring Dashboard for Claude Code and OpenAI Codex
Zeude is a self-hosted dashboard that tracks Claude Code and OpenAI Codex usage, providing per-prompt token and cost breakdowns, weekly leaderboards, and team skill management. Version 1.0.0 adds Windows support, Codex integration, and per-user skill opt-out.