Skip to content

booking-mcp-app: Add view-only MCP App for court availability - #46

Open
dragoscocs wants to merge 1 commit into
xoriors:mainfrom
dragoscocs:dragoscocs/booking-mcp-app
Open

booking-mcp-app: Add view-only MCP App for court availability#46
dragoscocs wants to merge 1 commit into
xoriors:mainfrom
dragoscocs:dragoscocs/booking-mcp-app

Conversation

@dragoscocs

Copy link
Copy Markdown
Contributor

First experiment with MCP Apps (spec 2026-01-26), following up on the generative-ui POC. Read-only for now, before any booking/write.

What it is

An MCP server that exposes one tool, get_court_availability (date + sport), linked to a UI resource (ui://court-availability/panel.html). The host renders it in a sandboxed iframe as a read-only grid of courts x time slots, free vs taken.

The key difference from generative-ui: the input data is for the server, not for the model. The tool is where a real booking backend would sit; the UI only displays what the server returns.

Bidirectional communication

The panel gets its data two ways, both in src/mcp-app.ts:

  • the host pushes a tool result (app.ontoolresult) when the tool is called, e.g. with another date or sport;
  • the app pulls its own initial data (app.callServerTool), the app -> server -> app round trip.

There are no inputs and no submit: changing date/sport happens by calling the tool with different arguments, not from a form.

Stack

@modelcontextprotocol/ext-apps + @modelcontextprotocol/sdk, TypeScript, Vite + vite-plugin-singlefile (the UI bundles to a single self-contained HTML, which keeps the app iframe CSP happy). Availability is deterministic in-memory mock data, no DB.

Try it

cd booking-mcp-app
npm install
npm run build
npm run serve      # http://localhost:3001/mcp

Then point the basic-host from modelcontextprotocol/ext-apps at it:

SERVERS='["http://localhost:3001/mcp"]' npm start   # open http://localhost:8080

Shortcut to auto-call the tool: http://localhost:8080/index.html?tool=get_court_availability&call=true. Verified end to end in that host: connect -> tools/list -> tools/call -> resource read -> ui/initialize -> tool-result render.

Next

The write phase: a book_slot tool that actually saves a booking, if the direction looks right.

An MCP server that exposes court availability for a date and sport, linked to
a ui:// resource that renders it as a read-only courts x slots panel inside an
MCP host.

The data flows to the server, not through the model: the tool is where a real
booking backend would sit. The UI only displays what the server returns. This
is the first phase, read only, before any booking/write.

Reuses the booking domain from generative-ui (Tennis / Football / Basketball /
Padel, courts and slots) with deterministic in-memory mock data.
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.

1 participant