Provides a widget that can open Google search results for movie showtimes using the 'ui/open-link' feature to search for ' showtimes near me'.
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.htmlresource (HTML + CSS + JS from ASSETS)Tool
get-movie-detailthat searches TMDB by title and returns details + cast
Widget UI (
web/) built with React/Tailwind:Entry:
widget.html→movie-detail-widget.js/.cssMCP Apps lifecycle:
ui/initialize, tool input/result notifications,ui/open-linkfor showtimesShowtimes 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
Local dev (Workers)
Use .dev.vars for local secrets:
Run dev server:
MCP endpoint will be at http://localhost:8787/mcp.
Build the widget
Outputs to web/dist/:
movie-detail-widget.jsmovie-detail-widget.csswidget.html
These are served by the ASSETS binding for the MCP UI resource.
Deploy to Cloudflare Workers
Set the secret in your account:
Deploy:
MCP server code pointers
server/lib/mcp.ts— registers resource + tool, uses ASSETS to serve built widget, pullstmdbTokenfrom env binding.server/index.ts— Hono entry, mounts/mcpand 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-detailInput:
{ "query": "<movie title>" }Returns:
content: text fallbackstructuredContent.movie: movie payload (title, poster/backdrop URLs, runtime, genres, rating, cast, etc.)
Notes for hosts
UI resource URI:
ui://widget/movie-detail-widget.htmlMIME:
text/html+mcpCSP: allows
https://image.tmdb.org/for posters/backdropsExpects MCP Apps messages:
ui/notifications/tool-input/tool-input-partialui/notifications/tool-resultui/open-link(to open showtimes link)
Type generation
Regenerate Cloudflare binding types if config changes:
Troubleshooting
Missing TMDB token: set
TMDB_TOKENin.dev.vars(local) and viawrangler secret put(prod).Assets not loading: ensure
npm run web:buildwas run and ASSETS binding is present.Host rejects
ui/open-link: host must support MCP Appsui/open-link; otherwise widget will show an error state.