This project uses MCP Apps to render interactive UI for tool results (currently find-tasks-by-date).
- The tool returns structured data.
- The tool metadata includes
_meta.ui.resourceUri. - The server registers the UI resource with
registerAppResource. - MCP hosts fetch the HTML via
resources/readand render it in a sandboxed iframe. - The app connects via the MCP Apps bridge and can call server tools (e.g.,
complete-tasks) or open links.
The task-list app adds params._meta['todoist.com/ui-source'] = 'task-list' to its
find-tasks-by-date pagination calls and complete-tasks calls. Hosts that forward this
metadata let the server distinguish these app requests from untagged tool calls. The marker
does not change the tool arguments or permissions and is not proof of the caller's identity.
- App source:
src/mcp-apps/task-list/ - Build output:
dist/mcp-apps/index.html(single-file HTML) - Build command:
npm run build:apps - Full build:
npm run build(library + apps) - Dev:
npm run dev(watch library + apps, restart server on JS/HTML changes) - App-only dev rebuilds:
npm run dev:apps
The server computes a content hash of index.html at startup and uses it in the ui:// resource URI for cache-busting.
npm run build:apps
open dist/mcp-apps/index.htmlWithout a host bridge, the app will show a loading/connection state.