Live Demo
These are actual rendered outputs from the engine — zero dependencies, self-contained HTML. Each demo is generated from a single function call.
[
{ "name": "Alice", "role": "Admin", "status": "Active", "email": "alice@example.com" },
{ "name": "Bob", "role": "Editor", "status": "Active", "email": "bob@example.com" },
{ "name": "Charlie", "role": "Viewer", "status": "Inactive", "email": "charlie@example.com" },
{ "name": "Diana", "role": "Admin", "status": "Active", "email": "diana@example.com" }
]
{
"project": "MCP-HTML-Bridge",
"version": "0.5.1",
"totalDownloads": 12483,
"weeklyGrowth": 23.5,
"openIssues": 7,
"stars": 342,
"license": "MIT",
"dependencies": 0,
"status": "stable"
}
{
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search keywords" },
"category": { "type": "string", "enum": ["Books", "Electronics", "Clothing", "Food"] },
"maxPrice": { "type": "number", "minimum": 0, "maximum": 10000 },
"inStock": { "type": "boolean", "default": true }
},
"required": ["query"]
}
This is the structural fallback mode (no LLM). With an LLM configured, the output is even richer — the model understands data semantics and renders SVGs, markdown, charts, etc.
Quick Start
# 1. Install
npm install -g @mcp-html-bridge/claude-skill
# 2. Configure your LLM provider once
mcp-html-skill config --api-url http://localhost:11434/v1 --model qwen2
# 3. Render any JSON
echo '{"name":"Alice","scores":[98,85,92]}' > /tmp/data.json
mcp-html-skill render --data /tmp/data.json --open
# Or skip LLM, use structural rendering
mcp-html-skill render --data /tmp/data.json --no-llm --open
Or without installing:
npx @mcp-html-bridge/claude-skill render --data /tmp/data.json --open
LLM Configuration
Configure once, use everywhere. Supports any OpenAI-compatible API.
mcp-html-skill config --api-url <url> --model <model> [--api-key <key>]
Provider Examples
# Local Ollama (no API key needed)
mcp-html-skill config --api-url http://localhost:11434/v1 --model qwen2
# DeepSeek
mcp-html-skill config --api-url https://api.deepseek.com/v1 \
--api-key sk-xxx --model deepseek-chat
# Baidu ERNIE
mcp-html-skill config \
--api-url https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop \
--api-key xxx --model ernie-4.0-8k
Manage Config
mcp-html-skill config --show # View current config
mcp-html-skill config --clear # Clear config
Resolution Priority
CLI flags > Environment variables > Config file > No LLM (structural fallback)
Env vars: MCP_HTML_LLM_API_URL / MCP_HTML_LLM_API_KEY / MCP_HTML_LLM_MODEL
Config file: ~/.mcp-html-bridge/config.json
Rendering Modes
LLM Semantic Rendering
The model understands what the data means and produces the best HTML. No hardcoded patterns. Handles SVGs, markdown, charts, images, code — anything.
Structural Fallback
When no LLM is configured. Maps JSON shapes to HTML mechanically: arrays → tables, objects → key-value pairs, nesting → collapsible sections.
| JSON Shape | Rendered As |
|---|---|
| Array of objects | Sortable table |
| Flat object | Key-value pairs |
| Nested object | Collapsible sections |
| Primitive value | Inline display |
| Mixed / complex | Auto-detected composite |
Library API
Async LLM Rendering
import { renderFromData } from '@mcp-html-bridge/ui-engine';
const html = await renderFromData(data, {
title: 'API Result',
llm: {
apiUrl: 'http://localhost:11434/v1',
model: 'qwen2',
},
});
Sync Structural Rendering
import { renderFromDataSync } from '@mcp-html-bridge/ui-engine';
const html = renderFromDataSync(data, { title: 'API Result' });
Form from JSON Schema
import { renderFromSchema } from '@mcp-html-bridge/ui-engine';
const html = renderFromSchema({
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' },
category: { type: 'string', enum: ['Books', 'Electronics'] },
maxPrice: { type: 'number', minimum: 0 },
},
required: ['query'],
}, {
toolName: 'search_products',
});
Form Widget Mapping
| Schema Type | Widget |
|---|---|
string | Text input |
string + enum | Capsule radio group |
string + format: "date" | Date picker |
number / integer | Number input with min/max |
boolean | Toggle switch |
object + properties | Collapsible nested section |
array | Textarea (JSON input) |
CLI Usage
# Render with LLM (auto-loads config)
mcp-html-skill render --data result.json --open
# Force structural, no LLM
mcp-html-skill render --data result.json --no-llm --open
# Schema → interactive form
mcp-html-skill render --schema tool-schema.json --open
# Inline JSON
mcp-html-skill render --json '{"users":[{"name":"Alice"}]}' --open
# Stdout
mcp-html-skill render --data result.json --stdout > output.html
All Options
| Flag | Description |
|---|---|
--data <file> | Input JSON data file |
--schema <file> | Input JSON Schema (renders as form) |
--json <string> | Inline JSON string |
--title | Page title |
--debug | Add debug playground panel |
--open | Auto-open in browser |
--stdout | Print raw HTML to stdout |
--no-llm | Force structural rendering |
--api-url / --api-key / --model | Override LLM config for this call |
Claude Code Integration
# Install /mcp-render command
mcp-html-skill install
# Then in any Claude Code conversation:
/mcp-render
Tailwind Utility Classes
Every generated page includes Tailwind-compatible atomic classes mapped to the CSS variable theme. Both the LLM and hand-written HTML can use them.
Layout
flex grid block hidden flex-col grid-cols-1~4
Alignment
items-center justify-between justify-center shrink-0 grow
Spacing
gap-1~8 p-0~8 px-* py-* m-* mx-auto
Typography
text-xs~3xl font-bold font-mono text-center truncate
Colors
text-primary bg-primary bg-elevated bg-accent-subtle bg-success-subtle
Borders & Effects
border rounded-lg shadow-md overflow-hidden transition
Responsive Prefixes
sm:grid-cols-2 sm:flex-row sm:text-lg sm:p-6 /* ≥640px */
md:grid-cols-3 md:flex-row md:text-2xl md:p-8 /* ≥768px */
Bridge Protocol
Every generated page includes a bridge script for bidirectional iframe communication.
Inside the HTML
__mcpBridge.callTool('search_products', { query: 'laptop' });
__mcpBridge.onResult(function(data) { console.log(data); });
From the Parent Frame
window.addEventListener('message', (evt) => {
if (evt.data?.type === 'MCP_TOOL_CALL') {
iframe.contentWindow.postMessage({ type: 'MCP_RESULT', data: result }, '*');
}
if (evt.data?.type === 'MCP_RESIZE') {
iframe.style.height = evt.data.height + 'px';
}
});
Architecture
Proxy Mode
Transparently forwards all MCP messages while appending rendered HTML to tool results.
npx @mcp-html-bridge/proxy "npx -y @modelcontextprotocol/server-filesystem /tmp"
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@mcp-html-bridge/proxy",
"npx -y @modelcontextprotocol/server-filesystem /tmp"]
}
}
}
Packages
| Package | Description |
|---|---|
@mcp-html-bridge/ui-engine | Core engine (LLM renderer + structural fallback + Tailwind utilities) |
@mcp-html-bridge/claude-skill | Claude Code integration (CLI + /mcp-render) |
@mcp-html-bridge/mcp-client | Lightweight MCP stdio client |
@mcp-html-bridge/cli | CLI adapter (mcp-bridge) |
@mcp-html-bridge/proxy | MCP proxy server |
Recipes
Embed in React (sync)
import { renderFromDataSync } from '@mcp-html-bridge/ui-engine';
function MCPViewer({ data }) {
const html = useMemo(() => renderFromDataSync(data), [data]);
return <iframe srcDoc={html} sandbox="allow-scripts"
style={{ width: '100%', border: 'none' }} />;
}
Embed in React (async LLM)
import { renderFromData } from '@mcp-html-bridge/ui-engine';
function MCPViewer({ data }) {
const [html, setHtml] = useState('');
useEffect(() => {
renderFromData(data, {
llm: { apiUrl: 'http://localhost:11434/v1', model: 'qwen2' },
}).then(setHtml);
}, [data]);
if (!html) return <div>Rendering...</div>;
return <iframe srcDoc={html} sandbox="allow-scripts"
style={{ width: '100%', border: 'none' }} />;
}
在线演示
以下是引擎的实际渲染输出 —— 零依赖、自包含 HTML。每个 demo 来自一次函数调用。
这是结构化兜底模式(无 LLM)。配置 LLM 后,输出更加丰富 —— 模型理解数据语义,自动渲染 SVG、markdown、图表等。
快速开始
# 1. 安装
npm install -g @mcp-html-bridge/claude-skill
# 2. 配置一次 LLM
mcp-html-skill config --api-url http://localhost:11434/v1 --model qwen2
# 3. 渲染任意 JSON
echo '{"name":"Alice","scores":[98,85,92]}' > /tmp/data.json
mcp-html-skill render --data /tmp/data.json --open
# 跳过 LLM,纯结构化渲染
mcp-html-skill render --data /tmp/data.json --no-llm --open
LLM 配置
mcp-html-skill config --api-url <url> --model <model> [--api-key <key>]
示例
# 本地 Ollama
mcp-html-skill config --api-url http://localhost:11434/v1 --model qwen2
# DeepSeek
mcp-html-skill config --api-url https://api.deepseek.com/v1 \
--api-key sk-xxx --model deepseek-chat
# 百度文心
mcp-html-skill config \
--api-url https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop \
--api-key xxx --model ernie-4.0-8k
CLI 参数 > 环境变量 > 配置文件 > 无 LLM
渲染模式
LLM 语义渲染
模型理解数据语义,自己决定最佳渲染方式。代码零模式匹配。
结构化兜底
没配 LLM 时按 JSON 形状机械映射:数组 → 表格,对象 → 键值对。
库 API
// 异步 LLM 渲染
const html = await renderFromData(data, {
title: '结果',
llm: { apiUrl: 'http://localhost:11434/v1', model: 'qwen2' },
});
// 同步结构化渲染(无网络)
const html = renderFromDataSync(data, { title: '结果' });
// Schema → 表单
const html = renderFromSchema(schema, { toolName: 'search' });
CLI 使用
mcp-html-skill render --data result.json --open # LLM 渲染
mcp-html-skill render --data result.json --no-llm --open # 结构化
mcp-html-skill render --schema schema.json --open # 表单
Claude Code 集成
mcp-html-skill install # 安装 /mcp-render 命令
/mcp-render # 在 Claude Code 中使用
Tailwind 原子化样式
每个生成的页面自动包含 Tailwind 兼容原子类,映射到 CSS 变量主题系统。
布局
flex grid flex-col grid-cols-1~4
间距
gap-* p-* m-* px-* py-*
文字
text-xs~3xl font-bold text-center
颜色 & 边框
text-primary bg-elevated border rounded-lg shadow-md
包一览
| 包名 | 说明 |
|---|---|
@mcp-html-bridge/ui-engine | 核心引擎 |
@mcp-html-bridge/claude-skill | Claude Code 集成 |
@mcp-html-bridge/mcp-client | MCP 客户端 |
@mcp-html-bridge/cli | CLI 工具 |
@mcp-html-bridge/proxy | MCP 代理 |