mcp-apps-demo-engine

mcp-apps-demo-engine

An extensible MCP server and generative UI engine for hosting interactive B2B enterprise workflows with dynamic styling and stateful simulators.

Category
Visit Server

README

Signal Triage — a context-aware MCP App

An MCP Apps (SEP-1865) experiment that grew from plumbing demo into a small demo engine: signals from multiple mock sources land on one interactive triage board, mapped against a customer case (who the signals matter to) and rendered in a brand (what the customer's world looks like). Both the case and the brand are plain markdown files, swappable at runtime.

Quick start — see it in two minutes

Requires Node 20+. No API keys, no accounts.

npm install
npm run build
npm run serve:http     # terminal 1 — MCP server on http://localhost:3001/mcp
npm run shim           # terminal 2 — minimal host on http://localhost:4180

Open http://localhost:4180/host-shim.html. The shim is a ~100-line reference host: it fetches the UI via resources/read, completes the MCP Apps handshake, and proxies every tool call to the real server — the log under the widget shows each message the app sends. Triage some signals (Keep/Drop/Undo, filter by source), then switch to the Briefing tab and press Draft briefing in chat to watch the v2 hand-back (ui/update-model-context + ui/message) appear in the log.

Triage decisions persist in data/decisions.json (gitignored) — delete it for a fresh board.

What you'll see

v1 — triage. get_signals aggregates all sources and maps each signal to the case's focus areas by keyword (whole-word, plural-tolerant). The board shows focus-area chips with kept/matched counts, source filter tabs, per-row relevance chips ("No direct match" = drop candidate), and Keep/Drop/Undo. Every click travels back as a record_decision tool call (app-only, invisible to the model).

v2 — briefing. The Briefing tab groups kept signals per focus area and flags areas with no kept coverage as gaps. "Draft briefing in chat" pushes the full briefing into model context and sends a short trigger message so the host's assistant drafts the customer-ready briefing. UI-less hosts get the same synthesis from the get_briefing tool.

Both tools keep plain-text fallbacks, so the server stays useful on hosts without MCP Apps support.

The five inputs

Input File Role
Context CUSTOMER_CASE.md An OKF concept document (type: Customer Case); its focus_areas frontmatter (id, title, keywords) is the contract every signal is triaged against.
Style DESIGN.md A design.md-spec token file. design.ts compiles its frontmatter (colors/typography/rounded) into CSS variables injected into the UI resource at serve time.
Data data/sources/ Three mock JSON feeds (external news, market intel, internal ops/HR). Mock by design — no API keys.
Knowledge .claude/skills/signal-triage/ An agent skill whose reference files form an OKF bundle: the case contract, one doc per source, and a triage playbook.
Stories USER_STORIES.md Stories 1–2 produced v1 (git tag v1); story 3 produced v2 (tag v2).

Swapping the inputs (no rebuild, no restart)

Both context and style are runtime inputs — the server re-reads CUSTOMER_CASE.md on every tool call, and compiles DESIGN.md into the UI resource every time it's served:

# Switch customer: every signal re-maps to the new focus areas
cp cases/norrsken-freight.md CUSTOMER_CASE.md

# Switch brand: the widget re-renders in the new design tokens
cp designs/nordfrakt.design.md DESIGN.md

Reload the shim (or let the host re-read tool + resource) and the same 14 signals appear re-mapped and re-branded. Ready-made examples live in cases/ and designs/. Unknown or missing design tokens fall back to built-in defaults, and host-provided style variables always win over both.

Where the files come from is the point of the pipeline:

  • CUSTOMER_CASE.md is the planned bridge target for the organisational-stress-test project — one focus_areas entry per stressed area. Contract details: customer case contract.
  • DESIGN.md is what design-md-generator produces from a live website URL — point it at a customer's site and the demo renders in their brand.

Two verified portability experiments back this up: swapping only the style left every behavior identical, and swapping only the case (Norrsken Freight, a 3PL → Kvist & Söner, an industrial wholesaler) inverted relevance — the warehouse-robotics signal that was noise for Norrsken became Kvist's automation signal, while Norrsken's top talent signal dropped to "No direct match". Relevance is a property of the case, not the signal.

Using it from a real host

For stdio hosts (Claude Desktop / Claude Code style config):

{
  "mcpServers": {
    "signal-triage": {
      "command": "node",
      "args": ["/absolute/path/to/dist/main.js", "--stdio"]
    }
  }
}

For the SDK's reference host: clone ext-apps, cd examples/basic-host, npm install (add tsx, cross-env, @types/cors as dev deps if installing standalone), NODE_ENV=development npm run build, then npx tsx serve.ts and open http://localhost:8080 while this server runs on :3001. No bun required.

npm run dev runs the Vite watcher plus the HTTP server together for iteration (UI changes need a rebuild — the served resource is the compiled dist/mcp-app.html).

Stack

Official SDK + patterns: @modelcontextprotocol/ext-apps, vanilla TS/HTML UI bundled to a single file (Vite + vite-plugin-singlefile), Node + Express for Streamable HTTP, stdio also supported. Frontmatter parsed with yaml.

Versions

  • v1 — user stories 1–2: multi-source board + case relevance.
  • v2 — user story 3: briefing view, gaps, hand-back to chat.
  • after v2: portability experiments, then runtime ingestion of both swappable inputs.

The pre-build design sketch this repo started from is preserved on the initial-draft branch.

Learnings

The reflective deliverable of the original experiment is LEARNINGS.md — including a v2 addendum on what building "one level up" from the plumbing taught. The original scope-setting PRD is preserved as MCP_App_Learning_PRD.md.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured