Skip to main content
Glama
vpm238
by vpm238

mcp-a2ui-vega

UI가 A2UI이고 차트가 Vega-Lite인 MCP 앱.

Claude에게 티켓 판매 대시보드를 요청하면 대화에 나타납니다: 지표, 차트, 최신 주문 표, CSV를 놓을 수 있는 공간. 그런 다음 변경을 요청하세요 — 판매 차트를 꺾은선형으로 바꾸고 오늘의 판매를 초록색으로 표시해 줘, 구매 시간대 히트맵을 추가해 줘 — 그러면 대시보드가 처음부터 다시 그려지는 것이 아니라 그 자리에서 편집됩니다. CSV를 그 안에 놓거나 스크립트에서 행을 추가하면 모든 차트가 스스로 움직입니다.

대시보드는 모델이 생성한 그림이 아닙니다. 에이전트가 타입이 지정된 카탈로그에서 구성한 컴포넌트 트리이며, Google의 A2UI 렌더러(@a2ui/react)로 그려지고, 변경 사항을 푸시하는 데이터셋에 바인딩됩니다.

구성 요소

조각

역할

packages/catalog

A2UI 카탈로그 — 컴포넌트 API, 함수, 그리고 이들로부터 생성된 JSON-Schema 문서. 에이전트와 렌더러 사이의 계약.

packages/renderer

MCP 앱 뷰: React + @a2ui/react, 카탈로그의 Vega-Lite 구현, 그리고 MCP Apps 브리지.

packages/server

Cloudflare Worker: MCP 서버, 데이터셋 저장소, 저장된 위젯 라이브러리, 그리고 ui:// 리소스.

data

실제 브로드웨이 주간 매출에 기반한 데이터셋.

skills/a2ui-dashboards

에이전트가 이러한 대시보드를 잘 구성하고 재구성하도록 가르치는 스킬.

tools

데이터셋 빌더, 실시간 추가 피드, 호스트 하네스, 엔드투엔드 테스트.

API 키가 필요 없습니다. 이 저장소에는 모델이 없습니다. 에이전트는 연결하는 MCP 호스트가 무엇이든 그 호스트입니다. 서버는 행을 저장하고 JSON을 구성하며, 렌더러는 결정적입니다. 관련된 유일한 자격 증명은 Worker를 배포하는 데 필요한 Cloudflare 자격 증명뿐입니다.

Related MCP server: vegalite-viewer

A2UI의 용어로 본 이 프로젝트

Google의 A2UI and MCP Apps 게시물은 두 프로토콜이 결합하는 세 가지 방식을 설명합니다. 이 저장소는 패턴 3: MCP Apps 내부의 A2UI입니다 — MCP 앱 번들이 자체 A2UI 렌더러를 포함하며, 이 덕분에 A2UI를 들어본 적 없는 호스트(현재의 Claude)도 에이전트가 구성한 UI를 표시할 수 있습니다.

이것은 A2UI를 흉내낸 것이 아니라 실제 A2UI입니다. 렌더러는 @a2ui/react@a2ui/web_coreMessageProcessor를 구동하는 방식입니다 — Google의 패키지를 수정 없이 사용합니다. 와이어 형식은 A2UI v0.9 메시지입니다: createSurface, updateComponents, updateDataModel. 카탈로그는 A2UI의 기본 카탈로그를 대체하지 않고 확장하므로, Column, Card, ChoicePicker는 Google의 것이고 VegaChart는 우리의 것이며, 하나의 카탈로그 id 아래에 있습니다.

또한 패턴 1: MCP 위의 A2UI를 두 번째 경로로 구현합니다 — 동일한 대시보드가 a2ui://dashboard/ticket_sales에서 application/a2ui+json으로 제공되므로, 자체 A2UI 렌더러(Flutter, Angular, 네이티브 클라이언트)를 가진 호스트는 iframe 없이 그릴 수 있습니다. 그 페이로드가 이식 가능한 산출물이며, MCP 앱은 다른 모든 사람이 그것을 볼 수 있는 방법입니다.

대시보드가 계속 살아 있는 방법

agent ──render_dashboard──▶ server ──A2UI messages in _meta──▶ view

                     ┌──────── change stream (SSE) ────────┐
server ──────────────┘  "ticket_sales moved"               ▼
   ▲                                                      view
   └── get_dataset_rows, through the host's tool proxy ──── │
                                                            │
                                          updateDataModel ──┘  every chart,
                                                               tile and table
                                                               re-renders

네 가지 결정이 대부분의 작업을 수행합니다:

행은 모델을 통과하지 않습니다. render_dashboard는 레이아웃과 행 수를 반환합니다. 뷰는 get_dataset_rows로 행을 직접 가져오며, 이 도구의 _meta.ui.visibility["app"]이므로 에이전트의 도구 목록에 절대 나타나지 않습니다. 12,000개의 주문은 컨텍스트 창이 아니라 차트에 속합니다.

대시보드는 이미지가 아니라 컴포넌트입니다. 하나의 차트를 변경하는 것은 하나의 id를 지정하는 update_dashboard 하나입니다. 사용자의 필터, 정렬 순서, 스크롤 위치는 다른 것이 건드려지지 않았으므로 유지됩니다.

업데이트는 대시보드를 본 적 없는 뷰에서도 렌더링되어야 합니다. 호스트는 도구 결과를 실행 중인 뷰로 라우팅하는 대신 결과마다 새 뷰를 열 수 있으며, 순수한 updateComponents 페이로드는 그곳에서 업데이트할 것이 없습니다 — A2UI는 surface not found로 거부하고, 사용자는 변경을 요청한 곳에 빈 패널을 받습니다. 따라서 서버는 구성된 트리를 기억하고, 모든 업데이트는 두 가지 형태로 전달됩니다: _meta['a2ui/messages']는 전체 표면을 처음부터 다시 빌드하고, _meta['a2ui/patch']는 델타만 전달합니다. 뷰는 이미 보유한 것에 맞는 것을 적용하므로, 서버는 어떤 뷰와 대화 중인지 추측할 필요가 없습니다.

서버가 시점을 말하고, 호스트는 여전히 데이터를 전달합니다. MCP에는 서버→뷰 채널이 없으므로, 뷰는 Worker로 직접 변경 스트림을 열어 둡니다 — 앱 리소스가 csp.connectDomains에서 허용하는 유일한 것입니다. 내려오는 것은 알림이지 데이터가 아닙니다: 행은 여전히 호스트의 도구 프록시를 통해 가져오므로, 모든 데이터 바이트는 감사 가능합니다. 유휴 대시보드는 요청을 전혀 하지 않으며, 변경 사항은 약 1초 안에 도달합니다.

카탈로그가 이름을 지정하지 않은 차트를 포함한 모든 차트

VegaChart는 전체 Vega-Lite 스펙을 속성으로 받습니다. 히트맵, 상자 그림, 패싯 소형 다중 — 이들 중 어느 것도 카탈로그에 없지만 모두 작동합니다. 카탈로그의 경계는 차트의 종류가 아니라 컴포넌트의 종류이기 때문입니다.

사용자가 마음에 드는 차트가 있으면 save_widget이 이름으로 보관하고, render_dashboard({widgets: ["sales_by_hour_heatmap"]})는 나중 대화에서 다시 가져옵니다 — 여전히 실시간 데이터셋에 바인딩되어 있으므로 다른 모든 것처럼 업데이트됩니다.

데이터

data/ticket_sales.csv는 12개의 브로드웨이 쇼에 걸친 티켓 주문당 한 행입니다. 쇼, 극장, 객석 규모, 주별 수용률, 가격 수준은 브로드웨이 주간 매출 데이터셋(Playbill, TidyTuesday 경유)에서 가져온 실제 데이터입니다. 개별 주문은 해당 수치를 기반으로 모델링되었습니다. 소스가 주간 집계이기 때문입니다. data/README.md는 어느 부분이 실제인지 정확히 설명합니다.

npm run data:build                    # rebuild, 90 days ending now
npm run data:append -- --watch 10     # a live feed: new orders every 10s

--url https://your-worker.workers.dev로 배포에 연결하면, 보고 있는 동안 대시보드가 움직이는 것을 볼 수 있습니다 — 각 추가 후 1초 이내에, 서버가 알려주기 때문입니다.

실행

npm install
npm run data:build          # build the dataset (downloads the source CSV once)
npm run build               # catalog → renderer → single-file app → worker
npm run dev -w @mcp-a2ui-vega/server

그런 다음 http://localhost:8788/app.html을 열어 대시보드를 단독으로 보거나, http://localhost:8788/에서 연결 지침을 확인하세요.

Claude에 설치

먼저 배포하세요(아래) — 사용자 지정 커넥터는 Anthropic의 클라우드에서 접근되며, 로컬 머신에서 접근되지 않으므로 localhost로는 안 됩니다.

Claude Code, 이 저장소에서 직접:

/plugin marketplace add vpm238/mcp-a2ui-vega
/plugin install a2ui-vega-dashboards@mcp-a2ui-vega

이렇게 하면 MCP 서버와 스킬이 함께 설치됩니다. 서버 URL은 .claude-plugin/plugin.json에 있습니다 — 자체 Worker를 배포하는 경우 그 한 줄을 변경하고 /plugin marketplace update mcp-a2ui-vega를 실행하세요.

Claude 웹 또는 데스크톱: 설정 → 커넥터 → 사용자 지정 커넥터 추가를 선택하고 https://your-worker.workers.dev/mcp를 붙여넣으세요. OAuth도 키도 없습니다. 그런 다음 스킬을 추가하세요: skills/a2ui-dashboards 폴더를 zip으로 압축하고 — 폴더 자체가 zip의 루트에 있어야 합니다 — 설정 → 기능 → 스킬에서 업로드하세요.

스킬은 어느 쪽이든 선택 사항입니다: 서버는 MCP 핸드셰이크에서 사용 지침을 보냅니다. 후속 요청을 좋게 만드는 것은 스킬입니다 — 모든 것을 다시 그리는 대신 하나의 컴포넌트를 편집하고, 마음에 든 차트를 기억합니다.

그런 다음 티켓 판매 대시보드를 요청하세요.

배포

Worker만 호스팅하면 됩니다. GitHub Pages는 독립형 데모를 제공합니다.

npx wrangler login
npm run deploy -w @mcp-a2ui-vega/server

이렇게 하면 KV 네임스페이스가 아직 없으면 생성하고, 그 id를 wrangler.toml에 쓰고, 앱과 시드 데이터를 번들링하고, 배포합니다.

또는 두 개의 저장소 시크릿을 추가하고 main에 푸시하세요 — 워크플로우가 네임스페이스 생성까지 포함해 모든 것을 처리하며, 시크릿이 없으면 실패하는 대신 경고와 함께 배포를 건너뜁니다:

시크릿

설명

CLOUDFLARE_API_TOKEN

Edit Cloudflare Workers 템플릿의 토큰

CLOUDFLARE_ACCOUNT_ID

Workers 대시보드의 계정 id

동일한 워크플로우는 설정 → Pages에서 소스 GitHub Actions로 Pages가 활성화되면 독립형 데모를 GitHub Pages에 게시합니다. 활성화될 때까지 워크플로우는 경고로 알리고 녹색을 유지합니다.

테스트

npm test                                       # dataset and catalog checks
npm run dev -w @mcp-a2ui-vega/server           # terminal 1
python3 -m http.server 8479                    # terminal 2, at the repo root
node tools/e2e.mjs                             # a real browser, the real protocol

로컬 Worker 대신 배포에 대해 동일한 스위트를 실행하려면:

node tools/relay.mjs https://your-worker.workers.dev     # terminal 3
SERVER_URL=http://localhost:8790 node tools/e2e.mjs

릴레이가 존재하는 이유는 제한적인 프록시 뒤의 브라우저가 Node는 가능한데 Cloudflare에 도달하지 못할 수 있기 때문입니다. 모든 바이트는 여전히 실제 배포에서 옵니다. 응답을 버퍼링하므로 변경 스트림을 전달하지 않습니다 — 뒤에 있는 뷰는 폴링으로 대체되며, 이 역시 테스트해 볼 가치가 있습니다.

tools/e2e.mjstools/harness.html을 구동합니다 — 수작업으로 작성된 MCP Apps 호스트, 약 120줄, 의도적으로 앱과 코드를 공유하지 않아 프로토콜 실수가 양쪽에서 눈에 띄지 않게 지나갈 수 없습니다. 타입 체커가 확인할 수 없는 것들을 확인합니다: 대시보드가 그려지는지, 재구성이 나머지를 방해하지 않고 하나의 타일을 색칠하는지, 추가된 행이 요청 없이 도착하는지, 필터가 지표와 표를 함께 움직이는지, 저장된 위젯이 돌아오는지.

tools/push-latency.mjs는 아키텍처가 주장하는 것을 측정합니다: 유휴 대시보드는 요청을 전혀 하지 않으며, 변경 사항은 정확히 한 번의 fetch로 약 0.5초 안에 도달합니다.

node tools/push-latency.mjs https://your-worker.workers.dev

라이선스

MIT.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    B
    maintenance
    MCP server that lets agents create, display, and export rich UI widgets (cards, dashboards, charts, forms) inline in conversations, with interactive iframe support in MCP Apps hosts and PNG image fallback for other clients.
    3

View all related MCP servers

Related MCP Connectors

  • Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.

  • Build, deploy, and operate hosted web apps on VibeKit (vibekit.bot) from any MCP client.

  • MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vpm238/mcp-a2ui-vega'

If you have feedback or need assistance with the MCP directory API, please join our Discord server