Skip to content

feat(mcp-apps): experimental inline view for Alexandria results (off by default) - #522

Draft
nickscamara wants to merge 10 commits into
mainfrom
feat/mcp-apps-alexandria-results
Draft

nickscamara wants to merge 10 commits into
mainfrom
feat/mcp-apps-alexandria-results

Conversation

@nickscamara

@nickscamara nickscamara commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Spike, draft. This server returns no UI today. It adds one MCP Apps view behind a flag so we can try server-provided inline UI for Alexandria in ChatGPT and Claude.

What the clients need (Oct 2026)

There are two separate things called "inline UI".

  • Model-generated: ChatGPT's GPT-6 "Intelligent UI" (launched 10-07) and Claude's in-chat visuals. The model composes charts, forms and widgets from its own component library, using whatever data it has. That data includes our tool results, so the "one prompt, something visual" demo works today with no server change.
  • Server-provided, MCP Apps (io.modelcontextprotocol/ui, stable 2026-01-26): ChatGPT and Claude both render it. A tool declares _meta.ui.resourceUri pointing at a ui:// resource served as text/html;profile=mcp-app. The host renders it in a sandboxed iframe and sends it the tool result over the ui/* postMessage bridge. ChatGPT also accepts openai/outputTemplate and window.openai as aliases, but recommends the standard keys. Claude's help center says it uses a connector's interactive interface when one fits, and generates its own visuals only otherwise.

What this PR adds

When FIRECRAWL_MCP_APPS=true is set (or mcpApps: true for createFirecrawlMcpServer embedders):

  • firecrawl_scrape gets _meta.ui.resourceUri = "ui://firecrawl/alexandria-results.html", added next to the existing anthropic/alwaysLoad.
  • The server serves that resource: a self-contained HTML view with no external scripts, styles or network access, so it needs no CSP domains. The view runs the ui/initialize handshake and reads structuredContent from ui/notifications/tool-result. It renders each Alexandria call as a table (up to 50 rows and 6 scalar columns). When one column is numeric it adds a bar chart, and when a call fails it shows the error. It follows the host's theme variables and reports its size.
  • Tool inputs, outputs and text content are unchanged, and the flag is off by default, so the contract snapshots don't change. Hosts without MCP Apps ignore _meta.ui.

Alexandria results view rendered through the MCP Apps bridge

The screenshot comes from a local host harness that runs the real ui/initialize handshake and tool-result flow with a FRED result. It is not a ChatGPT or Claude session: testing in those needs this build deployed behind a connector.

Known limits before this could leave the flag

  • The view is bound to every firecrawl_scrape call, not just Alexandria ones. resourceUri is static per tool, so URL scrapes also get the frame, which renders empty. In Claude, that may also take the place of its own generated visual. A clean fix means splitting Alexandria execution into its own tool or switching the binding per call, which changes the public tool contract. That is a separate proposal, not part of this PR.
  • No per-session gating yet. The spec says servers SHOULD register UI tools only when the client advertises io.modelcontextprotocol/ui. This prototype uses a process flag instead.
  • No "Connect Firecrawl" view. An MCP App renders only after a connected server's tool is called, so it can't help a user install the server in the first place. One-click install stays with ChatGPT and Claude directory links.

Tests

tests/mcp-apps.test.mjs:

  • With the flag off, the scrape tool has no ui metadata and no resources are listed.
  • With the flag on, the tool metadata, resource list and resources/read (mime type, _meta.ui.prefersBorder, no external assets) are checked, and an Alexandria call still returns the same result.
  • The view's table and chart extraction skips find-tools calls, flattens nested records, charts numeric columns and shows errors.

tsc, lint and pnpm test (170 tests) pass locally.

Open in Capy


Summary by cubic

Adds an experimental MCP Apps view that renders Alexandria results from firecrawl_scrape in hosts like ChatGPT and Claude. It's off by default, and tool inputs, outputs, and text content are unchanged.

New Features

  • With FIRECRAWL_MCP_APPS=true (or mcpApps: true for embedders), the scrape tool declares _meta.ui.resourceUri and the server serves ui://firecrawl/alexandria-results.html as text/html;profile=mcp-app.
  • The view runs the ui/initialize handshake, renders each Alexandria call as a table, adds a bar chart when one column is numeric, shows call errors, and follows host theme variables.
  • Hosts without MCP Apps ignore the metadata; when the flag is off, tool metadata and the resource list are unchanged.

Known Limits

  • The view attaches to every firecrawl_scrape call, not just Alexandria ones, so URL scrapes render an empty frame.
  • There's no per-session gating yet; the spec recommends registering UI tools only when a client advertises io.modelcontextprotocol/ui, whereas this uses a process flag.

Written for commit f634922. Summary will update on new commits.

View guided diff Turn on auto-fix

nickscamara and others added 10 commits October 9, 2026 17:53
…by default)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
#	src/index.ts
#	src/server.ts
…ria-results

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md

This branch has not been deployed

No deployments
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