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

架构

  1. createMcpApp()
    creates an
    McpServer
    that registers a
    render-ui
    tool and a
    ui://
    HTML resource
  2. The tool description includes the catalog prompt so the LLM knows how to generate valid specs
  3. The HTML resource is a Vite-bundled single-file React app with json-render renderers
  4. Inside the iframe,
    useJsonRenderApp()
    connects to the host via
    postMessage
    and renders specs
  1. createMcpApp()
    会创建一个
    McpServer
    ,该服务器会注册
    render-ui
    工具和
    ui://
    HTML资源
  2. 工具描述包含目录提示词,便于LLM知晓如何生成有效的规范
  3. HTML资源是由Vite打包的单文件React应用,内置json-render渲染器
  4. 在iframe内部,
    useJsonRenderApp()
    通过
    postMessage
    连接到宿主环境并渲染规范

Server API

服务端API

  • createMcpApp(options)
    - main entry, creates a full MCP server
  • registerJsonRenderTool(server, options)
    - register a json-render tool on an existing server
  • registerJsonRenderResource(server, options)
    - register the UI resource
  • createMcpApp(options)
    - 主入口,创建完整的MCP服务器
  • registerJsonRenderTool(server, options)
    - 在现有服务器上注册json-render工具
  • registerJsonRenderResource(server, options)
    - 注册UI资源

Client API (
@json-render/mcp/app
)

客户端API(
@json-render/mcp/app

  • useJsonRenderApp(options?)
    - React hook, returns
    { spec, loading, connected, error, callServerTool }
  • buildAppHtml(options)
    - generate HTML from bundled JS/CSS
  • useJsonRenderApp(options?)
    - React Hook,返回
    { spec, loading, connected, error, callServerTool }
  • buildAppHtml(options)
    - 从打包的JS/CSS生成HTML

Building the iframe HTML

构建iframe HTML

Bundle the React app into a single self-contained HTML file using Vite +
vite-plugin-singlefile
:
typescript
// 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 +
vite-plugin-singlefile
将React应用打包为单个独立的HTML文件:
typescript
// 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(
.cursor/mcp.json

json
{
  "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
undefined
bash
undefined

Server

服务端

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
undefined
npm install -D vite @vitejs/plugin-react vite-plugin-singlefile
undefined