mcpField
M
mcp-visual-output

mcp-visual-output

github.com/yonatangrossデザイン・UI29999 回インストール今日更新
リポジトリ

mcp-visual-output について

新規または既存の MCP サーバーに、JSON仕様を使ったインタラクティブなビジュアル出力を追加するスキルです。セットアップ、サンドボックスのセキュリティ、段階的なレンダリング、ダッシュボードのパターンを扱います。

主な機能

  1. 01新規サーバーのビジュアル出力設定
  2. 02既存サーバーへのレンダリングツール追加
  3. 03iframeサンドボックスとCSPの設定
  4. 04仕様の段階的なストリーミング
  5. 05ダッシュボードレイアウトの適用

活用シーン

  1. 01複数指標のダッシュボード作成
  2. 025行以上のデータテーブル表示
  3. 03複数システムの状態表示

MCP 対応

`@json-render/mcp`を使い、MCPツールとリソースを通じてJSONレンダリングのUIを提供する方法を案内します。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.mdHIGHcreateMcpApp() と registerJsonRenderTool()
セキュリティsandbox-csp.mdHIGHCSP 宣言、iframe のサンドボックス化
レンダリングstreaming-output.mdMEDIUMJSON Patch による段階的なレンダリング
パターンdashboard-patterns.mdMEDIUM統計グリッド、ステータスバッジ、データテーブル

合計: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. json-render の仕様ではなく、MCP ツールから生の HTML 文字列を返す(型安全性が損なわれ、ストリーミングできません)
  2. 段階的にストリーミングできないほど深くネストされたコンポーネントツリーを作成する(フラットに保ちます)
  3. CSP 宣言で script-src 'unsafe-inline' を使用する(セキュリティリスクがあり、不要です)
  4. レンダリング前に仕様全体が揃うのを待つ(段階的なレンダリングの利点が失われます)
  5. 1 つのカタログで 20 種類を超えるコンポーネントタイプを定義する(プロンプトのトークンコストが増加します)
  6. createMcpApp() の設定に html バンドルがない(iframe にレンダリングするものがありません)

関連するスキル

  • ork:mcp-patterns -- MCP サーバーの構築、トランスポート、セキュリティ
  • ork:json-render-catalog -- コンポーネントカタログと合成パターンの全容
  • ork:multi-surface-render -- Claude、Cursor、ChatGPT、ウェブにわたるレンダリング
  • ork:ai-ui-generation -- AI 生成インターフェースのための GenUI パターン

コメント