MCP Apps Interactive UI Builder (VS Code)

Transform any MCP server tool from returning plain text into a fully interactive, sandboxed UI rendered directly inside the chat window of VS Code or another MCP host.

// TL;DR

MCP Apps Interactive UI Builder (VS Code) is a skill for transforming any MCP server tool from returning plain text into a fully interactive, sandboxed UI rendered directly inside the chat window of VS Code or another MCP host. Use it when you need to return rich components—charts, flame graphs, checkout flows, editable diagrams—instead of plain text or ASCII art. The pattern has three parts: a Tool (the LLM-callable capability), a Resource (a bundled HTML UI), and a Link (the reference that tells the host to render an iFrame). It keeps users inside the chat with bidirectional live interactivity.

// When should you use the MCP Apps Interactive UI Builder in VS Code?

Use this skill when you need to design or build an MCP server that should return rich, interactive UI components (charts, diagrams, dashboards, e-commerce flows, etc.) instead of plain text or ASCII art — and you want those components to render live inside the chat, not in an external browser.

// What inputs do you need to build an MCP App?

  • target_tool_descriptionrequired
    What the MCP tool does — e.g. 'profile a Go application and return flame graph data', 'show product analytics', 'render an architecture diagram'.
  • data_shaperequired
    The shape or format of the data the MCP server tool will return (e.g. JSON profiling output, a dataset, a list of products).
  • ui_framework_preference
    Preferred front-end framework for the bundled HTML UI — React, Vue, Svelte, or vanilla JS.
  • invoker_moderequired
    Who invokes the tool: 'model only', 'model and app', or 'app only'. Determines tool visibility and handler wiring.
  • host_environment
    The MCP host that will render the app — typically VS Code with GitHub Copilot as the client.

// What are the core principles behind MCP Apps?

Rich UI over ASCII Art

Early MCP tools and LLMs compensated for the inability to generate real visuals by returning ASCII art and excessive emojis. MCP Apps eliminate that workaround by letting the server return genuine interactive components. Never settle for text when an interactive element serves the user better.

Keep the User Inside the Chat

The core design goal of MCP Apps is to eliminate the round-trip where the model returns a link and the user has to navigate to a browser. The entire interaction — data exploration, checkout, diagram editing — should happen inside the chat window without context switching.

The Three-Part Architecture (Tool / Resource / Link)

Every MCP App has exactly three parts: the Tool (the LLM + host deciding which capability to call), the Resource (the bundled HTML UI the server generates), and the Link (the UI resource reference that tells the host a renderable UI is available). All three must be wired together for the app to work.

Sandboxed iFrame Isolation

The host renders the MCP App inside a sandboxed iFrame — the same reason you put a hamster in a cage rather than letting it loose in a room. This prevents the app from touching VS Code settings, external APIs, or anything outside the chat window. Design your app assuming it lives entirely within that boundary.

Brand Consistency in the Chat

When building MCP Apps for products (e.g. e-commerce), the UI elements rendered in the chat should match the company's brand exactly as if the user were on the company's website. The chat window is not a degraded experience — it should be the full experience.

Bidirectional Live Interaction

The app inside the iFrame can call back to the MCP server and the server can return fresh data, causing the app to update in real time. Design for this loop: user interacts with UI → app calls server → server returns fresh data → app re-renders.

// How do you build an MCP App step by step?

  1. 1

    Define the tool and its data output

    Specify exactly what the MCP server tool does and what raw data it produces (e.g. JSON flame graph data, analytics rows, diagram nodes). This is the Tool layer. Be precise about the data shape — the UI will be built around it.

  2. 2

    Choose your UI framework and build the bundled HTML Resource

    Select React, Vue, Svelte, or vanilla JS. Build a self-contained HTML UI that consumes the tool's data output. This is the Resource layer. The UI must be fully bundled so the host can serve it from a single resource reference. For flame graphs: render top functions, time summaries, and the graph itself. For analytics: render charts with clickable drill-downs.

  3. 3

    Wire the Link between tool result and UI resource

    When the server returns the tool result, it must also return a UI resource reference — a pointer to the HTML element the server has generated. This is the Link layer. The host (e.g. VS Code) will detect this resource reference and know to fetch and render the iFrame. Without this link, the host renders nothing.

  4. 4

    Set the invoker mode in the skill/handler configuration

    Decide who can call the tool: 'model only' (only the LLM triggers it), 'model and app' (both can trigger it), or 'app only' (the iFrame UI triggers it directly). Configure this in your handler. This controls the interaction flow and determines how much autonomy the UI has.

  5. 5

    Run the MCP server locally and register it in the host

    Start the MCP server on localhost. In VS Code, go to the extensions tab, type @MCP, and register your server. Prefer servers from the VS Code or GitHub verified list to avoid security issues from unvetted third-party servers. Confirm the tool appears in the host's tool list before proceeding.

  6. 6

    Trigger the tool via the chat interface and verify iFrame rendering

    Send a natural language prompt in GitHub Copilot chat that would require the tool. The LLM should recognise the registered tool, call it, receive the JSON data + UI resource reference, and the host should render the MCP App in a sandboxed iFrame in the chat window. If the iFrame does not appear, check that the resource reference is correctly returned by the server.

  7. 7

    Implement the app-to-server callback loop for live interactivity

    Wire the iFrame app so user interactions (clicks, filters, edits) can call back to the MCP server. The server returns fresh data and the app re-renders. This bidirectional loop is what distinguishes an MCP App from a static render. Test that the UI updates without the user having to type a new prompt.

  8. 8

    Use a skill file to make the pattern repeatable via AI tooling

    Encode the full MCP App pattern (tool definition, resource bundling, link wiring, handler config, run instructions, code examples) into a skill file. This skill can then be fed to GitHub Copilot CLI, Claude, or any AI tooling to scaffold new MCP Apps from the same template. Store all variants (flame graph, markdown viewer, color picker, etc.) in the same repository.

// What are real-world examples of MCP Apps in action?

A developer wants to profile a backend application and understand where CPU time is being spent, without pasting raw profiling data into the chat repeatedly.

Build an MCP server that runs the profiler over a fixed duration, returns structured JSON profiling data, and bundles a React-based flame graph UI as the Resource. Wire the Link so VS Code detects the resource reference and renders the flame graph in a sandboxed iFrame. The developer prompts 'profile my application' once; the LLM calls the tool, the iFrame renders with top functions, time summaries, and the interactive flame graph. No more back-and-forth asking the model to interpret raw data.

An e-commerce company wants users to be able to browse, configure, and purchase products entirely within a chat interface without navigating to a browser.

Build an MCP server whose tool returns product data plus a UI resource reference pointing to a branded HTML checkout component. The iFrame renders the full checkout flow — product images, options, cart, payment — matching the company's visual brand exactly. The app calls back to the server to update inventory, pricing, and order state in real time. The user completes the purchase without leaving the chat window.

An architect wants to generate and edit system architecture diagrams from a chat prompt, not receive ASCII art representations.

Use an Excalidraw-based MCP App. The tool receives a description of the system, generates diagram node data, and returns it with a UI resource reference pointing to an interactive Excalidraw component. VS Code renders the diagram in an iFrame. The user can drag nodes, edit labels, and update the diagram live — all inside the chat, with no external browser tab.

// What mistakes should you avoid when building MCP Apps?

  • Using unvetted third-party MCP servers from the open internet — these can contain malicious code. Always prefer servers from the VS Code extensions tab (@MCP) or the official GitHub/Anthropic repositories.
  • Skipping the sandboxed iFrame boundary — allowing the MCP App to interact with VS Code settings, external APIs, or the file system defeats the security model and creates unpredictable side effects.
  • Returning only the tool result without the UI resource reference — if the server does not return the resource reference alongside the data, the host has no signal to render the iFrame and the user sees plain text.
  • Designing the UI as a one-way render — failing to implement the app-to-server callback loop means users still have to type follow-up prompts instead of clicking within the UI, losing the core benefit of MCP Apps.
  • Not specifying the invoker mode — leaving handler visibility undefined means you cannot control whether the model, the app, or both can call the tool, leading to unexpected invocation behaviour.
  • Compensating with ASCII art or excessive emojis instead of building a proper MCP App — this was the early-days workaround and is now an anti-pattern when MCP Apps are available.

// What do the key terms in MCP Apps mean?

MCP App
An MCP server tool that returns not just data but also a UI resource reference, causing the host to render a rich, interactive HTML component inside a sandboxed iFrame directly in the chat window.
MCP Host
The program (e.g. VS Code) that wants to access data from MCP servers, fetches the HTML from the UI resource reference, and renders the MCP App inside a sandboxed iFrame.
MCP Client
The component that maintains the one-to-one connection with MCP servers. In the VS Code context this is GitHub Copilot. Sometimes the same as the host, sometimes distinct.
MCP Server
A lightweight program that exposes specific capabilities through the MCP protocol. It runs the tool logic, generates the HTML UI resource, and returns both the data result and the UI resource reference.
Resource (UI Resource Reference)
The MCP resource object returned by the server alongside tool results. It points to the bundled HTML UI the server has generated. The host detects this reference and uses it to render the iFrame.
Tool
The LLM-callable capability registered on the MCP server. The LLM decides which tool to call based on the user's prompt. The tool executes the server-side logic and returns data plus the UI resource reference.
Link
The wiring between the tool result and the UI resource reference that signals to the host that a renderable UI is available. The third structural part of every MCP App alongside the Tool and the Resource.
Sandboxed iFrame
The isolated rendering container the host uses to display the MCP App inside the chat window. It prevents the app from accessing VS Code settings, external APIs, or anything outside the chat — 'the same reason you put a hamster in a cage'.
Invoker Mode
The handler configuration that determines who can call a tool: 'model only', 'model and app', or 'app only'. Controls whether the LLM, the iFrame UI, or both can trigger tool calls.
Skill (Skill File)
A reusable template file stored in a repository that encodes the full MCP App pattern — tool definition, resource bundling, link wiring, handler config, and run instructions — so AI tooling like GitHub Copilot CLI or Claude can scaffold new MCP Apps from it automatically.
Bidirectional Live Interaction
The callback loop where a user interacts with the iFrame UI, the app calls back to the MCP server, the server returns fresh data, and the app re-renders — enabling real-time interactivity without new chat prompts.

// FREQUENTLY ASKED QUESTIONS

What is an MCP App in VS Code?

An MCP App is an MCP server tool that returns both data and a UI resource reference, causing the host (like VS Code) to render a rich, interactive HTML component inside a sandboxed iFrame directly in the chat window. Instead of getting plain text or ASCII art, users see fully interactive elements—flame graphs, checkout flows, editable diagrams—without leaving the chat. Every MCP App consists of three parts: the Tool, the Resource, and the Link.

What is the three-part architecture of MCP Apps?

Every MCP App consists of exactly three parts: the Tool (the LLM-callable capability that runs server-side logic), the Resource (a bundled HTML UI the server generates), and the Link (the UI resource reference that tells the host a renderable UI is available). All three must be wired together for the app to work. Without the Link, the host renders nothing; without the Resource, there is no UI to display; without the Tool, the LLM cannot trigger the capability.

How do I build an MCP App that renders inside VS Code chat?

Define your MCP server tool and its data output, then build a self-contained HTML UI (using React, Vue, Svelte, or vanilla JS) that consumes that data. Wire the Link by having the server return a UI resource reference alongside the tool result. Register the server in VS Code via the extensions tab (@MCP), set the invoker mode, and trigger the tool via GitHub Copilot chat. The host detects the resource reference and renders the UI in a sandboxed iFrame.

How do I register an MCP server in VS Code?

Start your MCP server on localhost, then open VS Code's extensions tab and type @MCP to register the server. Prefer servers from the VS Code or GitHub verified list to avoid security risks from unvetted third-party servers. Confirm the tool appears in the host's tool list before triggering it via chat. If it doesn't appear, check your server configuration and ensure it's running and returning the correct MCP protocol responses.

How does MCP Apps compare to returning links that open in a browser?

MCP Apps eliminate the round-trip where the model returns a link and the user navigates to a browser. Instead, the entire interaction—data exploration, checkout, diagram editing—happens inside the chat window. There is no context switching. The user stays in their IDE, and the app updates in real time via bidirectional callbacks to the MCP server, making the experience faster and more integrated than any browser-based approach.

When should I use MCP Apps instead of plain text MCP tool responses?

Use MCP Apps whenever an interactive element serves the user better than text. If your tool returns data that benefits from visualization (flame graphs, charts, diagrams), user interaction (filters, edits, clicks), or branded experiences (e-commerce checkout), an MCP App is the right choice. Never settle for ASCII art or emoji-heavy text when you can render genuine interactive components. If the output is a simple string or confirmation, plain text is fine.

What results can I expect after building an MCP App?

Users will see fully interactive UI components rendered directly in the chat window—flame graphs with clickable functions, branded checkout flows, editable architecture diagrams—without leaving VS Code. The bidirectional callback loop means users interact by clicking within the UI instead of typing follow-up prompts, dramatically reducing friction. Development teams can encode the pattern into a skill file and scaffold new MCP Apps automatically using AI tooling like GitHub Copilot CLI or Claude.

What is a sandboxed iFrame in MCP Apps?

The sandboxed iFrame is the isolated rendering container the host uses to display the MCP App inside the chat window. It prevents the app from accessing VS Code settings, external APIs, or anything outside the chat—described as 'the same reason you put a hamster in a cage.' This security boundary ensures MCP Apps cannot cause unpredictable side effects. Design your app assuming it lives entirely within that boundary.

What is invoker mode in MCP Apps?

Invoker mode is the handler configuration that determines who can call a tool: 'model only' (only the LLM triggers it), 'model and app' (both the LLM and the iFrame UI can trigger it), or 'app only' (the iFrame UI triggers it directly). This controls the interaction flow and determines how much autonomy the UI has. Not specifying invoker mode leads to unexpected invocation behavior.

Can MCP Apps update in real time without new chat prompts?

Yes. MCP Apps support bidirectional live interaction through a callback loop. When a user interacts with the iFrame UI (clicks, filters, edits), the app calls back to the MCP server, the server returns fresh data, and the app re-renders—all without the user typing a new prompt. This loop is what distinguishes an MCP App from a static render and is the core benefit of the architecture.

Is it safe to use third-party MCP servers?

Use caution with third-party MCP servers from the open internet, as they can contain malicious code. Always prefer servers from the VS Code extensions tab (@MCP) or the official GitHub and Anthropic repositories. Verified servers undergo review and are safer to use. Even with the sandboxed iFrame providing isolation, unvetted servers pose risks and should be avoided in production environments.

// GET THIS SKILL — FREE

Use this skill in your AI

Every skill on SkillForge is free. Drop your email and copy this skill straight into Claude, ChatGPT, or any LLM.

We'll email you when new skills drop. Unsubscribe anytime.