mcp
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese@json-render/mcp
@json-render/mcp
MCP Apps integration that serves json-render UIs as interactive MCP Apps inside Claude, ChatGPT, Cursor, VS Code, and other MCP-capable clients.
可将json-render UI作为交互式MCP App运行在Claude、ChatGPT、Cursor、VS Code及其他支持MCP的客户端中的MCP Apps集成方案。
Quick Start
快速开始
Server (Node.js)
服务端(Node.js)
typescript
import { createMcpApp } from "@json-render/mcp";
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react/schema";
import { shadcnComponentDefinitions } from "@json-render/shadcn/catalog";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import fs from "node:fs";
const catalog = defineCatalog(schema, {
components: { ...shadcnComponentDefinitions },
actions: {},
});
const server = createMcpApp({
name: "My App",
version: "1.0.0",
catalog,
html: fs.readFileSync("dist/index.html", "utf-8"),
});
await server.connect(new StdioServerTransport());typescript
import { createMcpApp } from "@json-render/mcp";
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react/schema";
import { shadcnComponentDefinitions } from "@json-render/shadcn/catalog";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import fs from "node:fs";
const catalog = defineCatalog(schema, {
components: { ...shadcnComponentDefinitions },
actions: {},
});
const server = createMcpApp({
name: "My App",
version: "1.0.0",
catalog,
html: fs.readFileSync("dist/index.html", "utf-8"),
});
await server.connect(new StdioServerTransport());Client (React, inside iframe)
客户端(React,iframe内运行)
tsx
import { useJsonRenderApp } from "@json-render/mcp/app";
import { JSONUIProvider, Renderer } from "@json-render/react";
function McpAppView({ registry }) {
const { spec, loading, error } = useJsonRenderApp();
if (error) return <div>Error: {error.message}</div>;
if (!spec) return <div>Waiting...</div>;
return (
<JSONUIProvider registry={registry} initialState={spec.state ?? {}}>
<Renderer spec={spec} registry={registry} loading={loading} />
</JSONUIProvider>
);
}tsx
import { useJsonRenderApp } from "@json-render/mcp/app";
import { JSONUIProvider, Renderer } from "@json-render/react";
function McpAppView({ registry }) {
const { spec, loading, error } = useJsonRenderApp();
if (error) return <div>Error: {error.message}</div>;
if (!spec) return <div>Waiting...</div>;
return (
<JSONUIProvider registry={registry} initialState={spec.state ?? {}}>
<Renderer spec={spec} registry={registry} loading={loading} />
</JSONUIProvider>
);
}Architecture
架构
- creates an
createMcpApp()that registers aMcpServertool and arender-uiHTML resourceui:// - The tool description includes the catalog prompt so the LLM knows how to generate valid specs
- The HTML resource is a Vite-bundled single-file React app with json-render renderers
- Inside the iframe, connects to the host via
useJsonRenderApp()and renders specspostMessage
- 会创建一个
createMcpApp(),该服务器会注册McpServer工具和render-uiHTML资源ui:// - 工具描述包含目录提示词,便于LLM知晓如何生成有效的规范
- HTML资源是由Vite打包的单文件React应用,内置json-render渲染器
- 在iframe内部,通过
useJsonRenderApp()连接到宿主环境并渲染规范postMessage
Server API
服务端API
- - main entry, creates a full MCP server
createMcpApp(options) - - register a json-render tool on an existing server
registerJsonRenderTool(server, options) - - register the UI resource
registerJsonRenderResource(server, options)
- - 主入口,创建完整的MCP服务器
createMcpApp(options) - - 在现有服务器上注册json-render工具
registerJsonRenderTool(server, options) - - 注册UI资源
registerJsonRenderResource(server, options)
Client API (@json-render/mcp/app
)
@json-render/mcp/app客户端API(@json-render/mcp/app
)
@json-render/mcp/app- - React hook, returns
useJsonRenderApp(options?){ spec, loading, connected, error, callServerTool } - - generate HTML from bundled JS/CSS
buildAppHtml(options)
- - React Hook,返回
useJsonRenderApp(options?){ spec, loading, connected, error, callServerTool } - - 从打包的JS/CSS生成HTML
buildAppHtml(options)
Building the iframe HTML
构建iframe HTML
Bundle the React app into a single self-contained HTML file using Vite + :
vite-plugin-singlefiletypescript
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { viteSingleFile } from "vite-plugin-singlefile";
export default defineConfig({
plugins: [react(), viteSingleFile()],
build: { outDir: "dist" },
});使用Vite + 将React应用打包为单个独立的HTML文件:
vite-plugin-singlefiletypescript
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { viteSingleFile } from "vite-plugin-singlefile";
export default defineConfig({
plugins: [react(), viteSingleFile()],
build: { outDir: "dist" },
});Client Configuration
客户端配置
Cursor (.cursor/mcp.json
)
.cursor/mcp.jsonCursor(.cursor/mcp.json
)
.cursor/mcp.jsonjson
{
"mcpServers": {
"my-app": {
"command": "npx",
"args": ["tsx", "server.ts", "--stdio"]
}
}
}json
{
"mcpServers": {
"my-app": {
"command": "npx",
"args": ["tsx", "server.ts", "--stdio"]
}
}
}Claude Desktop
Claude Desktop
json
{
"mcpServers": {
"my-app": {
"command": "npx",
"args": ["tsx", "/path/to/server.ts", "--stdio"]
}
}
}json
{
"mcpServers": {
"my-app": {
"command": "npx",
"args": ["tsx", "/path/to/server.ts", "--stdio"]
}
}
}Dependencies
依赖
bash
undefinedbash
undefinedServer
服务端
npm install @json-render/mcp @json-render/core @modelcontextprotocol/sdk
npm install @json-render/mcp @json-render/core @modelcontextprotocol/sdk
Client (iframe)
客户端(iframe)
npm install @json-render/react @json-render/shadcn react react-dom
npm install @json-render/react @json-render/shadcn react react-dom
Build tools
构建工具
npm install -D vite @vitejs/plugin-react vite-plugin-singlefile
undefinednpm install -D vite @vitejs/plugin-react vite-plugin-singlefile
undefined