Building Interactive UIs in VS Code with MCP Apps

Building Interactive UIs in VS Code with MCP Apps — Marlene Mhangami & Liam Hampton, GitHub

Marlene Mhangami & Liam Hampton · ~16 min · Deep Dive Document
Video thumbnail — Building Interactive UIs in VS Code with MCP Apps
⏱ ~16 min 🎤 Marlene Mhangami & Liam Hampton 🏢 Microsoft / GitHub 🏷 MCP · VS Code · MCP Apps · Rich UI · GitHub Copilot

Overview

Marlene Mhangami and Liam Hampton from the Microsoft/GitHub Developer Advocacy team introduce MCP Apps — a new capability that lets MCP server tools return rich, interactive HTML components directly inside the VS Code chat window. Where MCP previously returned only text, MCP Apps enable sandboxed iframes with live data, interactive diagrams, and even full checkout flows. The session covers the architecture (resource references → HTML → sandboxed iframe), real-world adopters (Shopify, Excalidraw, Figma), and concludes with a live demo profiling a Go application and rendering the results as an interactive flame graph — all without leaving the chat.

1 MCP Fundamentals

▶ 0:14

Marlene opens with a quick refresher on the Model Context Protocol (MCP) — an open protocol created by Anthropic that standardizes how applications provide context to LLMs. The key word is open: the community can build on it freely, and it allows LLMs to access three types of context:

  • Tools — executable functions the LLM can call
  • Prompts — reusable prompt templates
  • Resources — data sources the LLM can read from

The session focuses specifically on MCP tools and how a new primitive — the MCP App — extends what tools can return beyond plain text.

2 Hosts, Clients & Servers

▶ 1:51

Marlene breaks down the three-part MCP architecture that matters for understanding MCP Apps:

  • Hosts — programs like VS Code that want to access data from MCP servers. The host is responsible for rendering UI (this becomes critical for MCP Apps).
  • Clients — maintain the one-to-one connection with servers. Sometimes the same as the host, but not always. In VS Code, the recommended client is GitHub Copilot.
  • Servers — lightweight programs that expose specific capabilities through MCP. You can build your own or use existing ones. In VS Code, typing @mcp in the extensions tab shows available servers.
⚠️ Security note: Marlene explicitly warns against grabbing random MCP servers from the internet — they can contain malicious code. She recommends using the curated server list available in VS Code and GitHub.

3 The Text-Only Limitation

▶ 3:19

When MCP was first released, tools could only return text. Marlene illustrates this with a concrete example: asking the LLM to "draw a diagram explaining what MCP is." The result? ASCII art. She points out a pattern in the community — GitHub repository READMEs became filled with ASCII art and emoji-heavy text because there was no way to generate actual diagrams or rich visual content through MCP tools.

This leads to the core question that motivated MCP Apps:

💡 "How can we create rich UI experiences in chat?" — The fundamental limitation that MCP Apps address.

4 Enter MCP Apps

▶ 4:12

MCP Apps let server tools return rich, interactive components that render directly in the chat window. Instead of getting a text description, the user sees an actual UI element they can click, drag, scroll, and interact with — all without leaving the conversation.

Marlene demonstrates this with the Excalidraw MCP server: the same "draw a diagram of MCP" prompt now produces an actual interactive diagram that the user can:

  • Move elements around
  • Edit text directly
  • Resize and rearrange components

The diagram is a live element in the chat — not a screenshot, not a link to an external tool, but a fully interactive canvas.

5 How MCP Apps Work — The Architecture

▶ 5:15

Marlene walks through the full data flow of an MCP App interaction, step by step:

  1. User sends a prompt — e.g., "Show me analytics"
  2. Agent + LLM decides which tool to call — connects to the appropriate MCP server
  3. Server returns tool results with a UI resource reference — this is the key innovation. The response includes not just data but a reference pointing to an HTML element the server has generated
  4. The host (VS Code) fetches the HTML — note: the host, not the client (GitHub Copilot), fetches the UI
  5. Host renders the app in a sandboxed iframe — the user sees and interacts with the UI directly in chat
  6. App calls back to the server — enabling live, bi-directional interaction
  7. Server returns fresh data — the UI updates dynamically
🔑 Critical distinction: The host (VS Code) handles rendering, not the client (GitHub Copilot). This separation is what enables the sandboxed iframe model — the client manages the LLM conversation while the host manages the UI layer.

6 Use Cases

▶ 6:33

Marlene outlines two primary use cases that demonstrate the value of MCP Apps:

Data Exploration

Imagine exploring a dataset entirely through text chat — you'd have to type out every follow-up query, every "now show me the bar chart for X," every "zoom into that trend." With MCP Apps, the data visualization renders as an interactive UI: you can click on chart elements, filter data, and drill down visually rather than typing each request. This drastically reduces the friction of iterative data analysis.

E-Commerce

This is where MCP Apps get particularly compelling beyond VS Code. In a chat UI (whether VS Code, OpenAI's interface, or any other host), a user could go through an entire checkout experience — browsing products, selecting options, and completing payment — without ever leaving the chat window. Previously, asking a chat client to help you buy something would result in a list of links, forcing you to navigate to a browser.

💡 "What we want is to keep the user inside the chat and have them interact and have that experience there." — The design philosophy driving MCP Apps beyond developer tooling.

7 Who's Building MCP Apps

▶ 8:06

Three notable companies are already building production MCP Apps:

  • Shopify — building full checkout flows inside chat. Marlene highlights their focus on brand consistency: the in-chat UI elements should match the company's website design so the user experience feels seamless. Users can literally go through the entire purchase process — browsing, selecting, paying — all within the chat window.
  • Excalidraw — interactive diagrams rendered in chat. Popular for architecture diagrams that users can drag, edit, and rearrange. Used by tools like Claude Code to visualize system designs.
  • Figma — generating design components on the fly with MCP Apps. While Marlene notes she couldn't find a good screenshot, Figma's integration lets users create and manipulate design components directly in the chat interface.

8 Anatomy of an MCP App

▶ 9:35

Liam takes over and dives into the code structure. He references a skill from the Model Context Protocol repository (Anthropic's official repo) that he adapted for his demos. An MCP App has three main parts:

  1. The Tool — the LLM-facing interface plus the host (VS Code). This is where the MCP server registers its capabilities.
  2. The Resource — the bundled HTML UI. This can be built with any framework: React, Vue, Svelte, vanilla JS — whatever the developer prefers for rendering the frontend.
  3. The Link — the connection between the tool's data response and the UI resource. The host and MCP server recognize this link to know when and how to render the frontend.

Tool Visibility Modes

Liam explains that MCP Apps support different visibility configurations for who can invoke the tool:

  • Model only — only the LLM can call the tool
  • Model + App — both the LLM and the rendered app can call the tool
  • App only — only the rendered UI can invoke the tool (useful for user-driven interactions)

Skill-Driven Development

The skill file Liam references tells Copilot CLI (or Claude or other AI tools) exactly how to set up, run, and build MCP Apps — including code examples for handlers and visibility configurations. This is a skill-driven workflow: the AI tool reads the skill and generates the correct boilerplate.

9 Live Demo — Flame Graph Profiler

▶ 11:31

Liam demonstrates the full MCP App workflow with a flame graph profiler. The setup:

The Go Application

A simple Go file with two functions: a bubble sort (comparing array values — "standard coding interview stuff") and a Fibonacci sequence (n+1, big O complexity). This provides measurably different performance characteristics for the profiler to capture.

The MCP Server

Written in TypeScript, running on localhost. The server:

  • Bundles up the Go program
  • Runs it with Go's built-in pprof profiler for 5 seconds
  • Captures the profiling data
  • Links the data to a React-based flame graph UI

The React App

A React application (flame-app) using hooks that:

  • Receives tool input from the MCP server
  • Processes the profiling results
  • Renders an interactive flame graph showing where time is spent across functions

The Demo in Action

Liam opens GitHub Copilot in VS Code, verifies the MCP server is running (one tool: "profile the app"), and asks Copilot to profile the application. Copilot:

  1. Recognizes the flame graph profiler tool is available
  2. Calls the tool
  3. The MCP App loads inside the chat window
  4. An interactive flame graph renders, showing top functions and performance summaries

The rendered UI is fully interactive — users can scroll, resize, and explore the flame graph. Liam notes that traditionally, developers would have to copy profiling data, paste it into the chat, and ask "Is this good? Is this bad? Where am I spending my time?" — a tedious back-and-forth. The MCP App eliminates this by making the data visually explorable inline.

🔥 "Of this entire file, this is the one that really matters the most" — Liam points to the TypeScript server code where the MCP bundles the Go program, runs it, profiles it, and spits out data. The magic is in the server-to-UI resource link that triggers the iframe rendering.

10 The Sandbox Model — Why Iframes

▶ 14:47

Liam explains why MCP Apps render inside sandboxed iframes with one of the talk's most memorable analogies:

🐹 "The reason we're doing this in an iframe is the same reason that you put a hamster in a cage. If you don't, it's just going to chew things up."

The sandboxed iframe ensures the MCP App cannot:

  • Interact with VS Code settings
  • Access external APIs
  • Read or modify the user's workspace
  • Interact with other extensions or the editor itself

This is a critical security boundary. The app is fully contained within the chat window — it can only communicate back to its own MCP server through the established channel. This sandboxing is what makes it safe to render arbitrary HTML from third-party MCP servers.

Liam summarizes the complete flow: prompt → LLM → tool call → MCP server runs → JSON data → host recognizes resource link → iframe renders → user interacts inside chat.

🎯 Key Takeaways

🔑 Key Takeaways

  • MCP Apps extend MCP tools beyond text — server tools can now return rich, interactive HTML components that render directly in the chat window, solving the "text-only" limitation of early MCP.
  • Architecture: resource references + sandboxed iframes — the MCP server returns data plus a UI resource reference; the host (not the client) fetches the HTML and renders it in a sandboxed iframe.
  • Host vs. Client distinction matters — VS Code (host) handles rendering, GitHub Copilot (client) handles the LLM conversation. This separation enables secure UI rendering.
  • Any frontend framework works — React, Vue, Svelte, vanilla JS — the UI is just bundled HTML that gets served through the resource reference.
  • Three visibility modes — tools can be invoked by the model only, the model + app, or the app only, giving fine-grained control over interaction patterns.
  • Sandbox = security — iframes prevent MCP Apps from accessing VS Code settings, external APIs, or the user's workspace. "Same reason you put a hamster in a cage."
  • Bidirectional communication — the app can call back to the MCP server for fresh data, and the server can push updates, creating a live interaction loop.
  • Real companies are shipping — Shopify (checkout flows), Excalidraw (interactive diagrams), and Figma (design components) are already building production MCP Apps.
  • Skill-driven development — Liam's workflow uses a skill file from Anthropic's MCP repository to guide AI tools in generating MCP App boilerplate correctly.
  • Beyond developer tools — while the demo is in VS Code, the MCP Apps pattern applies to any chat host: e-commerce, data exploration, and any scenario where keeping the user in the chat improves UX.

🔗 Resources & Links

Timestamp Index

▶ 0:14 Introductions — Marlene & Liam
▶ 0:37 Session agenda overview
▶ 1:01 What is MCP?
▶ 1:51 MCP hosts explained
▶ 2:09 MCP clients — GitHub Copilot
▶ 2:32 MCP servers — extensions tab
▶ 3:19 Early MCP — text-only limitation
▶ 4:12 MCP Apps introduction
▶ 4:45 Excalidraw MCP App demo
▶ 5:15 How MCP Apps work — data flow
▶ 6:33 Use case: data exploration
▶ 7:18 Use case: e-commerce
▶ 8:06 Shopify — checkout in chat
▶ 8:54 Excalidraw & Figma
▶ 9:35 Liam takes over — code walkthrough
▶ 10:08 Three parts of an MCP App
▶ 10:57 Tool visibility modes
▶ 11:31 Demo setup — Go file with bubble sort & Fibonacci
▶ 12:07 MCP server entry point (TypeScript)
▶ 12:38 React flame app hooks
▶ 13:06 Running the profiler in Copilot
▶ 13:40 Flame graph renders in chat
▶ 14:20 Interactive exploration of results
▶ 14:47 Why sandboxed iframes — the hamster analogy
▶ 15:15 Closing — Microsoft Build & GitHub booth