examples/stories/apps/README.md
MCP Apps: a tool carries a _meta.ui.resourceUri reference to a ui://
resource that the host renders as an interactive surface. The server opts in via
the Apps extension (io.modelcontextprotocol/ui); the client negotiates it by
advertising the text/html;profile=mcp-app MIME type.
# stdio (default — the client spawns the server as a subprocess)
uv run python -m stories.apps.client
# HTTP — the client self-hosts the server on a free port, runs, then tears it down
uv run python -m stories.apps.client --http
server.py MCPServer("apps-example", extensions=[apps]) — the extension
advertises io.modelcontextprotocol/ui under ServerCapabilities.extensions
and contributes the UI-bound tool and its ui:// resource. MCPServer itself
never learns about "ui"; it applies a closed set of contributions.server.py @apps.tool(resource_uri=...) — stamps _meta.ui.resourceUri on
the tool; add_html_resource registers the matching ui:// resource at
text/html;profile=mcp-app.server.py client_supports_apps(ctx) — SEP-2133 graceful degradation: a
client that did not negotiate Apps gets a text-only result.client.py Client(target, extensions=[advertise(...)]) — the client advertises Apps
support so the server returns the UI-enabled result, then reads the tool's
_meta.ui.resourceUri and fetches that resource.MCP Apps — extensions · SEP-2133 — extensions capability
custom_methods/ (registering a non-spec method without an extension).