MAY 25, 2026

8 MIN READ

FLORIAN VALEYE

Let Agents Render the Platform

Let Agents Render the Platform

Charts, queries, and interactive UI, now rendering inside any AI agent through MCP Apps.

Share

Blog

An agent can reach your data. It cannot interact with the interface that makes that data explorable. The answer comes back as text, or a screenshot. The interactive chart stays behind a login.

Every MCP tool we built for our own agents is now available to any agent the user runs: Claude, Codex, Cursor, and whatever the team picks next. They query the same AI-native lakehouse, the same semantic layer.

None of them can hand you the live interface: the chart you hover, the query you re-run, the cohort you re-bucket. So the conversation ends in text, or "open the platform to see more."

MCP Apps close that gap. The platform doesn't move. Its reach does.

Instead of building adapters for each host, we expose the same charts, queries, and interactive components through MCP. They render inside Claude today, and in any other host that adopts MCP Apps.

Some answers need pixels

MCP tools return text, images, or structured JSON. That's enough for "what was our MRR last month." It isn't enough for "compare retention across last quarter's cohorts and let me re-bucket by plan." A chart you can hover, a form you can configure, a query you can iterate on.

In Under the Hood: Agents, we wrote that anything a human can do in the UI, an agent can do through MCP. MCP Apps let us run that the other way.

Anything an agent surfaces through MCP, a human can now touch, inside the chat, without switching tabs.

What MCP Apps actually are

MCP Apps is an extension to the Model Context Protocol, formally SEP-1865, drafted in November 2025 by Ido Salomon, Liad Yosef, and Olivier Chafik, now at Final status. It unifies two parallel efforts that had been prototyping interactive UIs on top of MCP, MCP-UI and OpenAI's Apps SDK, into one open standard.

The protocol is small. Four primitives do the work:

  • ui:// URIs: Every MCP App UI is a ui:// resource. Hosts can discover, prefetch, and audit the HTML before it renders.
  • MIME type profile: Content is served as text/html;profile=mcp-app. The profile= suffix is how hosts recognize the bytes as a renderable app, not arbitrary HTML.
  • Tool-to-UI binding: A tool points to its UI via _meta.ui.resourceUri. That one field is what separates a regular MCP tool from an MCP App tool.
  • postMessage transport: The app runs inside a sandboxed iframe and talks back to the host over postMessage using JSON-RPC, the same wire format as the rest of MCP. Shared methods where they fit (tools/call), ui/-prefixed methods where they don't (ui/initialize).

The security model is layered. The app runs inside a sandboxed iframe, isolated from the host's DOM and cookies. Templates are predeclared and reviewable before they render. Every message between UI and host travels over postMessage and is auditable. And the host mediates any tool call the app initiates.

One protocol, every compliant host, no special deal to sign.

Unlike a URL, an MCP App can talk back: variable changes, fresh agent results, and tool re-runs all happen through the host.

One renderer, two venues

The design decision worth naming up front: we didn't build a second renderer. The chart that renders inside Claude when an agent calls view_insight is built from the same chart components that render on altertable.ai. Same code, same series builders, same legends. The MCP App is how those components travel. It isn't a parallel implementation we have to keep in sync.

That symmetry is the whole point. We build one component library for our own product, and MCP Apps make it available to any AI agent, internal or external, without a bespoke integration per host. One library, two surfaces. Nothing to keep in sync, nothing to re-secure.

Take the SQL Playground. The component used for query_lakehouse results renders inside Claude and is the same one our in-product chat uses. Same SQL editor, same result table, same formatter. The MCP App is how it travels outside the platform. The chat is how it travels inside. Two surfaces. One experience.

The lakehouse matters here specifically. Rendering inside the agent puts agent and human on the same source of truth, at the same instant. Not a sample. Not a stale snapshot.

Insight Viewer

The Insight Viewer renders the chart view_insight returns (segmentation, funnel, or retention), with a variable editor above it when the insight exposes parameters, so the user can tweak inputs and watch the chart re-run in place.

Insight Viewer running inside Claude Code

SQL Playground

The SQL Playground shows the SQL query the agent ran and its results side by side. The statement is pre-loaded into a lightweight SQL editor, and the rows render through the same QueryResultTable that ships in altertable.ai. The user can read, tweak, or re-run the query against the lakehouse, right there in the chat.

SQL Playground running inside Claude Code

How it ships

Backend

The whole MCP Apps surface on our Rails side, built on RubyLLM, lives in a single module plus one resource class per app. A tool becomes an MCP App tool by adding one line:

class ViewInsight < ApplicationTool
tool_name 'view_insight'
meta ui: MCPAppUi.meta(MCPAppUi::INSIGHT_VIEWER_URI)
# [...]
end

The matching resource class declares its URI and MIME type, then reads the app's HTML straight from /mcp-apps/* at request time rather than baking it into the Rails asset pipeline. The UI ships without a backend redeploy.

That request-time read is a small choice with a big quality-of-life win during iteration. The MCP mount itself auto-discovers every registered resource and wires a single handler that injects the _meta.ui payload the spec requires on every app response, leaving no registry or dispatch to maintain by hand.

Frontend

Every MCP App in mcp-apps/ is a single self-contained HTML file. The build inlines CSS, JS, and assets so the ui:// resource fetches one response and renders. No chunked loading from a sandboxed iframe. It's a deliberate shortcut: simple to ship and audit today, but heavy enough that we won't keep it as is.

A shared McpAppShell component handles the protocol boilerplate: the handshake (via @modelcontextprotocol/ext-apps, the reference SDK), result parsing, theme, and the frame-check guard that surfaces a clear error if the app gets loaded standalone. Each app lives above the shell and imports straight from the product tree. The Insight Viewer calls view_insight again when a user tweaks a variable. The SQL Playground does the same with its SQL editor and query_lakehouse. The production chart and table components don't know or care that they're running inside a sandboxed iframe, inside someone else's chat.

One app or many?

The spec lets you fuse everything into one app, or split by UI shape. We split by shape, not by tool: view_insight and preview_insight share the Insight Viewer, query_lakehouse has the SQL Playground.

Each ui:// is a self-contained bundle, and bundles pay for what they include. The Insight Viewer ships at 479 KB gzipped, the SQL Playground at 296 KB. A fused bundle would ship Recharts on every SQL call and the SQL editor on every chart call.

A new UI is a new directory under mcp-apps/. Vite picks it up. Tools that share a UI share its ui://. Nothing gets everything.

No adapters, no winners

The other way to do this would have been to build a Claude integration. Then a Codex integration. Then a Cursor one, then a Gemini one, and whatever ships next week. We would have picked winners, written adapters, and spent the next year chasing SDKs.

MCP is the bet that we don't have to do any of that. It's the neutral surface between the lakehouse and whatever agent the user prefers using. External agents come in through the same OAuth flow we built for our own. Their tokens hit the same scopes, their tool calls hit the same handlers. Internal, external, vendor, or the agent your platform team built last quarter: they're all MCP clients, and none of them is a special case.

Alpic AI is building Skybridge on the same standard, a likely fit as we move off our single-HTML shortcut.

Each step pushed the boundary further out. Local first. Then remote. Now the interface.

The lakehouse stops being a destination and becomes portable.

Share

Florian Valeye, Staff Backend Engineer at Altertable

Florian Valeye

Staff Backend Engineer

Data platform expert with deep expertise in distributed systems and modern data infrastructure. Delta Lake committer and contributor, previously scaled data pipelines at Back Market.

Stay Updated

Get the latest insights on data, AI, and modern infrastructure delivered to your inbox

For more information, please consult our Privacy Policy

Related Articles

Continue exploring topics related to this article

Memory Is Not a Database
MAY 18TH, 2026
Florian Valeye

Memory Is Not a Database

AI Agents, Architecture, Engineering

Intelligence without memory is nothing. The right model is memory that lives, forgets, and knows where it belongs.

READ ARTICLE
Under the Hood: Agents
JULY 15TH, 2025
Sylvain Utard

Under the Hood: Agents

AI Agents, Architecture, Engineering

Altertable agents think ahead. Powered by custom lakehouse and MCP, they monitor, investigate, and act on your data autonomously.

READ ARTICLE
What We're Building
JULY 8TH, 2025
Sylvain Utard

What We're Building

Product, Architecture, AI Agents

Most data platforms wait for questions. Altertable doesn't. We're building an AI-native data OS that turns raw data into continuous insight.

READ ARTICLE
Upstreaming with AI
SEPTEMBER 23RD, 2025
Sylvain Utard

Upstreaming with AI

Open Source, Engineering, AI Agents

How we contributed 17 upstream PRs in 90 days—where AI accelerated our workflow, what we learned, and practical tips for open source success with AI assistance.

READ ARTICLE
Upside-Down Architecture
JANUARY 20TH, 2026
Yannick Utard

Upside-Down Architecture

Architecture, Engineering

Most analytics queries scan <100MB. We explore a hybrid architecture where compute moves between servers and your local machine, powered by DuckDB and DuckLake.

READ ARTICLE
Altertable Logo

A lakehouse your apps, BI, and agents share

DuckDB workers on open formats, federated SQL across your existing systems,
and an MCP server for agents — at flat monthly pricing.