Skip to content

Add a minimal MCP App served at /mcp#57

Open
itamarwe wants to merge 2 commits into
masterfrom
claude/mcp-apps-example
Open

Add a minimal MCP App served at /mcp#57
itamarwe wants to merge 2 commits into
masterfrom
claude/mcp-apps-example

Conversation

@itamarwe

Copy link
Copy Markdown
Owner

First step toward an example MCP App on the site, served at /mcp. This is the most basic version — a starting point to upgrade from.

What it does

Exposes a remote MCP server (Streamable HTTP) with one tool, hello_app, whose result Claude renders as an interactive HTML card inline in the chat rather than as plain text.

How it works (MCP Apps SEP)

  • A UI resource at ui://hello/app.html (mime text/html;profile=mcp-app) holding a self-contained, dependency-free HTML card in the site's dark 3b1b palette.
  • A tool that points at that resource via _meta["ui/resourceUri"]. When it runs, Claude fetches the resource and renders it, passing the tool output as render data (the card reads name, falling back to "there").

Files

  • app/mcp/route.ts — MCP server (mcp-handler + @modelcontextprotocol/sdk).
  • app/mcp/widget.ts — the HTML card + postMessage render-data listener.

Notes

  • The endpoint is configured as /mcp/ because the site uses trailingSlash: true — a POST to /mcp 308-redirects to /mcp/.
  • Dropped @mcp-ui/server from the dep set: it pulls in @modelcontextprotocol/ext-apps as a git dependency with a build step that fails to install in CI, rolling back the whole npm install. The SEP format is just a mime type + a _meta key, so it's inlined directly.

Verified locally

initialize, tools/list (carries ui/resourceUri), tools/call (returns structuredContent + meta), and resources/read (returns the HTML) all respond correctly; the card renders headlessly. tsc --noEmit and lint are clean.

To connect from Claude

Add a custom connector pointing at https://itamar-weiss.com/mcp/ (with the trailing slash), then ask Claude to "show the hello app".

🤖 Generated with Claude Code

A remote MCP server (Streamable HTTP via mcp-handler) exposing one
"MCP App": the `hello_app` tool renders an interactive HTML card inline
in the chat instead of plain text.

- app/mcp/route.ts — MCP server: a `ui://hello/app.html` UI resource
  (mime text/html;profile=mcp-app) plus a tool that points at it via
  _meta["ui/resourceUri"], per the MCP Apps SEP.
- app/mcp/widget.ts — the self-contained, dependency-free HTML card
  (dark 3b1b palette), with a postMessage render-data listener and a
  graceful fallback.

Endpoint is configured as /mcp/ because the site uses trailingSlash:true
(a POST to /mcp 308-redirects to /mcp/).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
itamarwe-github-io Ready Ready Preview, Comment Jun 14, 2026 9:43am

The first cut hand-rolled mcp-ui-style postMessages, which Claude (an MCP
Apps SEP host) doesn't speak — so it never sized the iframe and the card
collapsed to ~0px ("can't see the card", especially in dark mode).

Rebuild the widget on the official MCP Apps client:
- research/mcp-app/ esbuild-bundles the View (src/view.js, using App from
  @modelcontextprotocol/ext-apps) with the vendored SDK into one inline
  <script>, producing the generated app/mcp/widget.ts.
- autoResize reports height over the real JSON-RPC handshake, so the host
  gives the iframe height; theme + tool result arrive via the host context
  and ontoolresult. CSS now honors the host's data-theme + --color-* tokens
  with light/dark fallbacks.

ext-apps is used at build time only (its install rebuilds from source and
fails on Vercel); the site's runtime deps stay mcp-handler + zod.

Build-bug fixed along the way: a String.replace with a string arg let the
bundle's `$\`` sequences inject page content; use a function replacement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants