LLM and agent UI integration

May 31, 2026 · View on GitHub

quikdown is built for the model ↔ markdown ↔ human loop: small parser for chat bubbles, rich fences for artifacts, embeddable editor for documents agents read and write.

PatternExampleWhen to use
AI Canvasexamples/ai-canvas/Chat + document editor; simulated or live LLM (BYOK)
MCP doc copilotexamples/mcp-doc-host/Node bridges MCP to browser editor; 24 tools
Agent tool editorexamples/llm-tool-editor/Function calling: read_editor, write_editor, undo, stats
Stream into editorexamples/llm-stream-editor/Long artifact; editor.setMarkdown(buffer) on each chunk
Parser streampages/examples/integration-llm-stream.htmlTokens → quikdown(buffer) in a div (chat reply)
Chat + markdownpages/examples/integration-quikchat.htmlquikchat widget renders bubbles

Run local examples: npm run servehttp://localhost:6811/examples/…

Three surfaces

┌─────────────────────────────────────────────────────────────┐
│  Chat bubble     quikdown(md)        Short replies, streaming│
├─────────────────────────────────────────────────────────────┤
│  Editor canvas   QuikdownEditor      Artifacts users edit    │
├─────────────────────────────────────────────────────────────┤
│  Agent tools     getMarkdown/setMarkdown   LLM mutates doc   │
└─────────────────────────────────────────────────────────────┘

1. Render-only (parser)

import quikdown from 'quikdown';

let buffer = '';
for await (const chunk of streamFromLLM()) {
  buffer += chunk;
  preview.innerHTML = quikdown(buffer, { lazy_linefeeds: true });
}
  • XSS-safe by default — treat LLM output as untrusted.
  • Re-parse whole buffer — parser is ~10 KB; fast enough per chunk for typical chat.

2. Stream into the editor

import QuikdownEditor from 'quikdown/edit';

const editor = new QuikdownEditor('#artifact', { mode: 'split' });
let buffer = '';

for await (const chunk of streamFromLLM()) {
  buffer += chunk;
  editor.setMarkdown(buffer);
}

Use when the output is a document (spec, report, README) with fences the user may edit after generation.

See examples/llm-stream-editor/README.md.

3. Agent tool calling (editor as canvas)

Register tools with your LLM API; execute against the editor in the browser:

ToolEditor API
read_editoreditor.getMarkdown()
write_editoreditor.setMarkdown(content)
replace_textget → replace first match → set
extract_textline slice (read-only)
get_statsword/line/char counts
undo / redoeditor.undo() / editor.redo()

Use stream: false during tool-call rounds so JSON parses completely. Keep a separate message array with tool_calls / tool_call_id fields.

Reference implementation: examples/shared/agent-tools.js
Simulated demo: examples/llm-tool-editor/
Live BYOK demo: quikchat example_tool_editor.html

Pair with the quikchat chat widget for UI, or your own input component.

4. MCP server (Model Context Protocol)

For agents that support MCP (Cursor, Claude Desktop, VS Code Copilot, Windsurf), quikdown ships a JSON-RPC 2.0 server that exposes 24 tools over stdio:

npx quikdown-mcp --root=.          # headless + filesystem tools

Path A (IDE): Agent calls MCP tools (markdown_to_html, read_file_markdown, write_html_to_file, etc.) while the human edits files in their IDE as usual. No browser window.

Path B (Doc copilot): A Node host serves QuikdownEditor in a browser tab and bridges MCP stdio to the editor. Agent drives the same buffer the human sees — full buffer control, regex search, rendered HTML export.

Tool groupCountWhat it does
Headless6Parse, convert, AST/JSON, stats — no file I/O or editor
Filesystem5Sandboxed read/write of markdown and HTML files
Editor13Buffer control, regex search/replace, undo/redo, rendered export

Path A config: add npx quikdown-mcp --root=. to your host's MCP config.

Path B config (doc copilot, from quikdown repo after npm run build):

{
  "mcpServers": {
    "quikdown-doc": {
      "command": "node",
      "args": ["examples/mcp-doc-host/start-mcp.js"]
    }
  }
}

Opens a browser tab with QuikdownEditor; see examples/mcp-doc-host/README.md.

Setup guides per host: docs/quikdown-mcp.md.

Programmatic use:

import { createMcpServer } from 'quikdown/mcp';
const mcp = createMcpServer({ root: '.' });
const result = mcp.callTool('markdown_to_html', { markdown: '# Hello' });

Dependencies and footprint

ModuleRuntime depsTypical size
quikdownZero~14.9 KB min
quikdown/bdZero~19.7 KB min
quikdown/editLazy CDN for fences~98 KB + on-demand libs
quikdown_edit_standaloneBundled fences~7.7 MB min (~1.0 MB gz)
quikdown/mcpquikdown + quikdown_bd~26 KB (JSON-RPC server)

For air-gapped agent UIs, use the standalone editor — highlight.js, Mermaid, DOMPurify, Leaflet, Three.js, ABCJS, Vega, Vega-Lite, Vega-Embed, and MathJax bundled.

Framework wrappers

React and Vue patterns: framework-integration.md
Full editor API: quikdown-editor.md

Security checklist

  • Default parser options for any user/LLM-visible HTML path.
  • Do not set allow_unsafe_html: true on untrusted markdown without a whitelist (security.md).
  • Sanitize or render model chat replies with quikdown even when the document canvas uses the editor.
  • Block javascript: and non-image data: URLs (default).