mcpField
M
mcp-visual-output

mcp-visual-output

github.com/yonatangross设计与 UI29999 次安装今天更新
代码仓库

关于 mcp-visual-output

面向开发者的技能包,用于为新建或现有 MCP 服务添加由 JSON 规范驱动的交互式视觉输出。内容涵盖配置、安全沙箱、渐进式渲染和仪表板模式。

主要功能

  1. 01为新服务配置视觉输出
  2. 02为现有服务添加渲染工具
  3. 03配置 iframe 沙箱与 CSP
  4. 04渐进式流式传输规范
  5. 05应用仪表板布局模式

适用场景

  1. 01构建多指标仪表板
  2. 02呈现五行以上的数据表
  3. 03展示多个系统的状态

MCP 相关

指导开发者通过 MCP 工具和资源提供 JSON 渲染界面,并使用 `@json-render/mcp`。涵盖 stdio 和 Streamable HTTP 传输方式。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yonatangross/orchestkit --skill mcp-visual-output

安装后在 Claude Code 中输入/mcp-visual-output确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

test-cases.json
references/
component-recipes.md
mcp-integration.md
upstream-mcp.md
rules/
_sections.md
_template.md
dashboard-patterns.md
mcp-app-setup.md
sandbox-csp.md
streaming-output.md

详细介绍

上游版本参考:@json-render/mcp 0.21.0(2026-09-30)。

MCP 可视化输出

将普通的 MCP 工具响应升级为在 AI 对话中呈现的交互式仪表板。基于 @json-render/mcp 构建,它将 json-render 规范系统与 MCP 的工具/资源模型连接起来——AI 生成类型化 JSON 规范,沙盒 iframe 将其渲染为交互式 UI。

从头开始构建 MCP 服务? 使用 ork:mcp-patterns 设置服务、传输和安全性。本技能聚焦于服务运行后所需的可视化输出层。

需要完整的组件目录? 请参阅 ork:json-render-catalog,了解所有可用组件、属性和组合模式。

决策树——阅读哪个文件

What are you doing?
|
+-- Setting up visual output for the first time
|   +-- New MCP server -----------> rules/mcp-app-setup.md
|   +-- Existing MCP server ------> rules/mcp-app-setup.md (registerJsonRenderTool section)
|
+-- Configuring security / sandbox
|   +-- CSP declarations ----------> rules/sandbox-csp.md
|   +-- Iframe permissions --------> rules/sandbox-csp.md
|
+-- Rendering strategy
|   +-- Progressive streaming -----> rules/streaming-output.md
|   +-- Dashboard layouts ----------> rules/dashboard-patterns.md
|
+-- API reference
|   +-- Server-side API -----------> references/mcp-integration.md
|   +-- Component recipes ----------> references/component-recipes.md

快速参考

类别规则影响关键模式
设置mcp-app-setup.md高createMcpApp() 和 registerJsonRenderTool()
安全性sandbox-csp.md高CSP 声明、iframe 沙盒化
渲染streaming-output.md中通过 JSON Patch 渐进式渲染
模式dashboard-patterns.md中统计网格、状态徽标、数据表

共计:3 个类别中的 4 条规则

工作原理

  1. 定义目录——使用 defineCatalog() + Zod 定义类型化组件架构
  2. 向 MCP 注册——新服务使用 createMcpApp(),现有服务使用 registerJsonRenderTool()
  3. AI 生成规范——模型生成符合目录的 JSON 规范
  4. iframe 渲染规范——沙盒 iframe 内打包的 React 应用使用 useJsonRenderApp() + <Renderer /> 渲染规范

AI 不会编写 HTML 或 CSS。它会生成引用目录组件类型的结构化 JSON 规范。iframe 应用使用预先构建的注册表渲染这些组件。

快速入门——新建 MCP 服务

import { createMcpApp } from '@json-render/mcp'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { buildAppHtml } from '@json-render/mcp/app'
import { catalog } from './catalog'

// Generate the iframe HTML from the bundled JS/CSS (docs-prescribed generator).
const bundledHtml = buildAppHtml({ entry: './app.tsx' })

// 1. Create the MCP app (async; returns an McpServer, no .start()/.close()).
//    name + version are required; tool config nests under `tool`
//    (default tool name is 'render-ui'). There is no top-level `csp`.
const server = await createMcpApp({
  name: 'my-app',
  version: '1.0.0',
  catalog,           // component schemas the AI can use
  html: bundledHtml, // pre-built iframe app (single HTML file)
  tool: {
    name: 'render-dashboard',
    description: 'Render an interactive dashboard from a json-render spec',
  },
})

// 2. Connect a transport -- stdio, Streamable HTTP, or any MCP transport
await server.connect(new StdioServerTransport())

快速入门——为现有服务添加可视化输出

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { registerJsonRenderTool, registerJsonRenderResource } from '@json-render/mcp'
import { buildAppHtml } from '@json-render/mcp/app'
import { catalog } from './catalog'

const server = new McpServer({ name: 'my-server', version: '1.0.0' })

// Generate the iframe HTML from the bundled JS/CSS (docs-prescribed generator).
const bundledHtml = buildAppHtml({ entry: './app.tsx' })

const resourceUri = 'ui://my-server/dashboard'

// Register the render tool (lets the model return specs).
// name, title, description, and resourceUri are all required.
registerJsonRenderTool(server, {
  catalog,
  name: 'render-dashboard',
  title: 'Render Dashboard',
  description: 'Render an interactive dashboard from a json-render spec',
  resourceUri,
})

// Serve the bundled HTML iframe app as a resource (new in 0.15).
// resourceUri must match the tool's resourceUri.
registerJsonRenderResource(server, { resourceUri, html: bundledHtml })

registerJsonRenderResource() 在 0.15 版本中新增,用于将工具注册与 UI 资源提供分离——当主机缓存打包后的 HTML 时非常有用(客户端:Claude、ChatGPT、Cursor、VS Code Copilot、Goose、Postman)。支持 stdio 和 Streamable HTTP(Express)两种传输方式。本技能已针对 @json-render/mcp 0.20.0 验证;该版本没有任何代码变更:除版本号及其固定的 @json-render/core 依赖外,每个已发布文件都与 0.19.0 逐字节相同。因此,该版本新增的能力属于 core 和 react,而非此软件包。间接影响 MCP 渲染 iframe 的功能包括命名插槽和嵌套重复,以及一项修复:命名的 onSuccess/onError 链式操作现在会实际接收其配置的 params。

客户端 iframe 应用

iframe 应用从 MCP 主机接收规范并进行渲染:

import { useJsonRenderApp } from '@json-render/mcp/app'
import { Renderer } from '@json-render/react'
import { registry } from './registry'

function App() {
  const { spec, loading } = useJsonRenderApp()
  if (loading) return <Skeleton />
  return <Renderer spec={spec} registry={registry} />
}

目录定义

目录定义 AI 可以使用哪些组件。每个组件都通过 Zod 定义类型化属性:

import { defineCatalog } from '@json-render/core'
import { schema } from '@json-render/react/schema'
import { z } from 'zod'

export const dashboardCatalog = defineCatalog(schema, {
  components: {
    StatGrid: {
      props: z.object({
        items: z.array(z.object({
          label: z.string(),
          value: z.string(),
          trend: z.enum(['up', 'down', 'flat']).optional(),
          color: z.enum(['green', 'red', 'yellow', 'blue']).optional(),
        })),
      }),
      children: false,
    },
    StatusBadge: {
      props: z.object({
        label: z.string(),
        status: z.enum(['success', 'warning', 'error', 'info', 'pending']),
      }),
      children: false,
    },
    DataTable: {
      props: z.object({
        columns: z.array(z.object({ key: z.string(), label: z.string() })),
        rows: z.array(z.record(z.string())),
      }),
      children: false,
    },
  },
})

示例:评估结果仪表板

AI 生成的规范如下——扁平元素映射,嵌套不超过 2 层:

{
  "root": "dashboard",
  "elements": {
    "dashboard": {
      "type": "Card",
      "props": { "title": "Eval Results -- v7.21.1" },
      "children": ["stats", "table"]
    },
    "stats": {
      "type": "StatGrid",
      "props": {
        "items": [
          { "label": "Skills Evaluated", "value": "94", "trend": "flat" },
          { "label": "Pass Rate", "value": "97.8%", "trend": "up", "color": "green" },
          { "label": "Avg Score", "value": "8.2/10", "trend": "up" }
        ]
      }
    },
    "table": {
      "type": "DataTable",
      "props": {
        "columns": [
          { "key": "skill", "label": "Skill" },
          { "key": "score", "label": "Score" },
          { "key": "status", "label": "Status" }
        ],
        "rows": [
          { "skill": "implement", "score": "9.1", "status": "pass" },
          { "skill": "verify", "score": "8.7", "status": "pass" }
        ]
      }
    }
  }
}

关键决策

决策建议
新建服务还是使用现有服务新建时使用 createMcpApp();向现有服务添加功能时使用 registerJsonRenderTool()
CSP 策略尽量精简——仅声明实际需要的域名
流式传输始终启用渐进式渲染;不要等待完整规范
仪表板深度保持元素树扁平(最多 2-3 层),以便流式传输
组件数量每个目录包含 3-5 种组件类型即可满足大多数仪表板需求
可视化与文本多指标视图使用可视化输出;单个值使用纯文本

CC 2.1.113 修复了 MCP 并发调用超时处理问题——卡住的工具调用现在会正常报错,不再阻塞队列。从仪表板并行调用工具更加安全;无需变通方案。

何时使用可视化输出与纯文本

场景使用可视化输出使用纯文本
一目了然地查看多个指标是 -- StatGrid否
表格数据(5 行以上)是 -- DataTable否
查看多个系统的状态是 -- StatusBadge 网格否
单个数值答案否是
错误消息否是
文件内容 / 代码否是

常见错误

  1. MCP 工具返回原始 HTML 字符串,而不是 json-render 规范(会破坏类型安全,且无法流式传输)
  2. 组件树嵌套过深,无法逐步流式传输(保持扁平)
  3. 在 CSP 声明中使用 script-src 'unsafe-inline'(存在安全风险,而且没有必要)
  4. 等待完整规范生成后再渲染(违背渐进式渲染的初衷)
  5. 在单个目录中定义 20 多种组件类型(会增加提示词 Token 开销)
  6. 在 createMcpApp() 配置中缺少 html bundle(iframe 没有可渲染的内容)

相关技能

  • ork:mcp-patterns -- MCP 服务构建、传输与安全
  • ork:json-render-catalog -- 完整的组件目录和组合模式
  • ork:multi-surface-render -- 在 Claude、Cursor、ChatGPT 和 Web 中渲染
  • ork:ai-ui-generation -- AI 生成界面的 GenUI 模式

评论

支持 Markdown