Interaction patterns for MCP Apps

Point, open, go deeper — inside the MCP view.

mcpview explores how people and agents work together in MCP Apps: the user acts in the view, the model follows along. Recorded on a live ERPNext.

Deno-first · Node 20+ · TypeScript · MIT

01 · Click to share context

Four more interactions

Inside the view

02

Double-click to open

The record opens inside the same view (double-click, or the › button).

03

Go deeper, come back

List → record → related list, with a breadcrumb inside the view.

04

Edits flow back up

Submit a record and the parent list refreshes in the same window.

05

The host sets theme and language

Light/dark and locale come from the host context and apply live — right-to-left included.

Recorded with mcp-erpnext 3.2.0 on a live ERPNext instance.

Try it

These are the real mcp-erpnext viewers, running in a small MCP Apps host on this page. Click, double-click, jump — the panel shows exactly what the view hands to the model.

Waiting to load…
Open standalone

Viewer bundles from mcp-erpnext 3.2.0 and the standard AppBridge from @modelcontextprotocol/ext-apps. Sample data runs in your browser; nothing is sent anywhere.

Beyond one view

Compose views into one surface

Each MCP App stays its own view. Compose lays them out as tiles and keeps them synchronized; Bridge takes them where your users already are.

@mcpview/composeLay several MCP Apps out as tiles on one surface and keep them synchronized.JSR npm

Beyond the host

Take the same view anywhere

Bridge serves any tool with a ui:// resource as a Telegram Mini App or a LINE LIFF app. It can also route tool calls from a cloud endpoint to a private network over an outbound WebSocket.

@mcpview/bridgeTelegram Mini Apps, LINE LIFF, and private-network routing.JSR npm

One shared contract

Typed contracts between server, view and host

Contracts has no dependencies — no DOM, no MCP SDK, no React or Preact — so servers, hosts, agents and browser Apps import the same manifest.

manifest.ts
import {
  defineViewAppManifest,
  VIEW_APP_MANIFEST_SCHEMA,
  VIEWER_SESSION_APPLY_ACTION,
} from "@mcpview/contracts";

export const manifest = defineViewAppManifest({
  schemaVersion: VIEW_APP_MANIFEST_SCHEMA,
  app: { id: "io.casys.cad.results", title: "CAD results", version: "1.0.0" },
  resources: [{
    uri: "ui://mcp-cad/results-viewer",
    ownership: "whole-view",
    resultSchemas: ["io.casys.cad.execution/1.0"],
    acceptedActions: [VIEWER_SESSION_APPLY_ACTION],
    sessionSchemas: ["io.casys.thread.cad-viewer-session/1.0"],
  }],
});
  • no DOM
  • no MCP SDK
  • no React / Preact
  • exact versions: /1.0, never latest

@mcpview/contractsDependency-free manifests for apps, resources, composition and recorded sessions.JSR npm

Quickstart

Deno-first, with a native Node build — same API on both. One server, one tool, one view.

Install

terminal
deno add jsr:@mcpview/server
deno add jsr:@mcpview/view
terminal
npm i @mcpview/server @mcpview/view

Server — one tool, one view

server.ts
import { MCP_APP_MIME_TYPE, McpApp } from "@mcpview/server";

const server = new McpApp({ name: "invoices", version: "1.0.0" });

// The view: a single-file HTML bundle served as an ui:// resource.
server.registerResource(
  { uri: "ui://invoices/list-viewer", name: "Invoice list" },
  async (uri) => ({
    uri: uri.toString(),
    mimeType: MCP_APP_MIME_TYPE,
    text: "<!doctype html><html><!-- your bundled view --></html>",
  }),
);

// One tool. Hosts discover its view from _meta on the definition;
// the model's text stays tiny while the view renders the full data.
server.registerTool(
  {
    name: "invoice_list",
    description: "List recent invoices",
    inputSchema: {
      type: "object",
      properties: { limit: { type: "number" } },
    },
    _meta: { ui: { resourceUri: "ui://invoices/list-viewer" } },
  },
  async ({ limit = 20 }) => {
    const invoices = await listInvoices(limit); // your data source
    return {
      content: [{ type: "text", text: invoices.length + " invoices" }],
      structuredContent: {
        doctype: "Sales Invoice",
        count: invoices.length,
        data: invoices,
      },
      _meta: { ui: { resourceUri: "ui://invoices/list-viewer" } },
    };
  },
);

await server.start(); // stdio — or server.startHttp({ port: 3000 })

View — iframe runtime

view.ts (bundled to one HTML file)
import { createMcpApp, defineView } from "@mcpview/view";

const app = await createMcpApp({
  info: { name: "Invoice list", version: "1.0.0" },
  root: document.getElementById("root")!,
  views: {
    list: defineView({ render: () => "<h1>Invoices</h1>" }),
  },
  initialView: "list",
});

Then point any MCP Apps host at your stdio command (or at the HTTP endpoint from startHttp()) and call invoice_list. Hosts without view support still get the short text result.

Packages moving to @mcpview — previously @casys/mcp-*.

Packages

Six packages under the @mcpview scope, for JSR and npm.

@mcpview/server

MCP server framework for Deno and Node — concurrency, OAuth, HTTP/stdio, MCP Apps resources.

JSRnpmSource

@mcpview/view

Browser-side runtime for MCP Apps — iframe lifecycle, routing, tool results, events.

JSRnpmSource

@mcpview/components

Optional Preact component kit, theme, and presentation runtime for views.

JSRnpmSource

@mcpview/contracts

Dependency-free contracts — app manifests, composition, selection, recorded sessions.

JSRnpmSource

@mcpview/compose

Multi-view dashboards — compose and synchronize several MCP Apps in one surface.

JSRnpmSource

@mcpview/bridge

Bridge MCP Apps to external hosts such as Telegram and LINE, or to a private network.

JSRnpmSource

Where MCP views run

As of October 2026.

HostMCP Apps viewsModel context (ui/update-model-context)
Claude (web, desktop)YesYes — the model reads the view's context when it needs it
ChatGPTYesPartial — delivery depends on the host
VS Code (GitHub Copilot)Yes — tested by a userNot verified yet
GooseYesNot verified yet

— : not verified yet. Running views in another host? Tell us.

Built with it

Every MCP server we publish is built on the mcpview server framework — and others have started building on it too.

@casys/mcp-erpnext

ERPNext with interactive viewers — the pilot behind these videos.

JSRGitHub

@casys/mcp-einvoice

French e-invoicing, platform-agnostic.

JSR

@casys/mcp-syson

SysML v2 models through SysON.

JSR

@casys/mcp-modelica

Modelica simulation with run evidence.

JSR

@casys/mcp-calculix

Finite-element analysis of STEP parts (CalculiX).

JSR

@casys/mcp-spice

Circuit analyses with ngspice.

JSR

@casys/mcp-chrono

Rigid-body kinematics.

JSR

@casys/mcp-build123d

build123d CAD models.

JSR

@casys/mcp-onshape

Onshape CAD/PDM, with interactive viewers.

JSR

@casys/mcp-prusaslicer

Print time and material from the PrusaSlicer CLI.

JSR

@casys/mcp-dfm

Design-for-manufacturability checks on STEP geometry.

JSR

@casys/mcp-tolerance

ISO 286 tolerances and stack-ups.

JSR

@casys/mcp-std

A broad standard tool library for MCP.

JSR

From the community

@hvgllc/hvgerp-mcp

An ERPNext server forked from mcp-erpnext, built on the mcpview server (as @casys/mcp-server).

npm

@memetaltin/mcp-carbon-erp

Carbon ERP (Dokos / ERPNext), derived from mcp-erpnext.

npm