Skip to main content
Glama

Usher MCP — Movie Detail App

Interactive MCP server and UI widget that renders movie details from TMDB with the MCP Apps spec. The server runs on Cloudflare Workers; the UI is a sandboxed HTML resource served via ASSETS and rendered by MCP hosts.

What’s here

  • MCP server (server/) exposing:

    • ui://widget/movie-detail-widget.html resource (HTML + CSS + JS from ASSETS)

    • Tool get-movie-detail that searches TMDB by title and returns details + cast

  • Widget UI (web/) built with React/Tailwind:

    • Entry: widget.htmlmovie-detail-widget.js/.css

    • MCP Apps lifecycle: ui/initialize, tool input/result notifications, ui/open-link for showtimes

    • Showtimes link opens Google “ showtimes near me” via ui/open-link

  • Root landing page: friendly message at / telling visitors to connect via /mcp

Prerequisites

  • Node 18+

  • Wrangler CLI

  • TMDB API token (v4 bearer) stored as a secret

Install

npm install

Local dev (Workers)

Use .dev.vars for local secrets:

TMDB_TOKEN=your_tmdb_bearer_token

Run dev server:

npm run dev

MCP endpoint will be at http://localhost:8787/mcp.

Build the widget

npm run web:build

Outputs to web/dist/:

  • movie-detail-widget.js

  • movie-detail-widget.css

  • widget.html

These are served by the ASSETS binding for the MCP UI resource.

Deploy to Cloudflare Workers

  1. Set the secret in your account:

wrangler secret put TMDB_TOKEN
  1. Deploy:

npm run deploy

MCP server code pointers

  • server/lib/mcp.ts — registers resource + tool, uses ASSETS to serve built widget, pulls tmdbToken from env binding.

  • server/index.ts — Hono entry, mounts /mcp and root landing page.

  • web/src/movie-detail-widget.tsx — MCP Apps UI logic + render.

  • web/vite.config.ts — builds widget assets with custom filenames for ASSETS.

MCP tool contract

  • Tool: get-movie-detail

  • Input: { "query": "<movie title>" }

  • Returns:

    • content: text fallback

    • structuredContent.movie: movie payload (title, poster/backdrop URLs, runtime, genres, rating, cast, etc.)

Notes for hosts

  • UI resource URI: ui://widget/movie-detail-widget.html

  • MIME: text/html+mcp

  • CSP: allows https://image.tmdb.org/ for posters/backdrops

  • Expects MCP Apps messages:

    • ui/notifications/tool-input / tool-input-partial

    • ui/notifications/tool-result

    • ui/open-link (to open showtimes link)

Type generation

Regenerate Cloudflare binding types if config changes:

npm run cf-typegen

Troubleshooting

  • Missing TMDB token: set TMDB_TOKEN in .dev.vars (local) and via wrangler secret put (prod).

  • Assets not loading: ensure npm run web:build was run and ASSETS binding is present.

  • Host rejects ui/open-link: host must support MCP Apps ui/open-link; otherwise widget will show an error state.

-
security - not tested
F
license - not found
-
quality - not tested

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/khandrew1/usher-mcp'

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