Frequently Asked Questions About MCP Apps Interactive UI Builder (VS Code)

21 answers covering everything from basics to advanced usage.

// Basics

What is the difference between an MCP server and an MCP App?

An MCP server is a lightweight program that exposes capabilities through the MCP protocol. An MCP App is an MCP server tool that goes further by returning both data and a UI resource reference, causing the host to render an interactive HTML component inside a sandboxed iFrame. Every MCP App runs on an MCP server, but not every MCP server produces an MCP App—only those that bundle a UI Resource and wire the Link do.

What is the difference between an MCP host and an MCP client?

The MCP host is the program (e.g., VS Code) that wants to access data from MCP servers and renders the MCP App inside a sandboxed iFrame. The MCP client is the component that maintains the one-to-one connection with MCP servers—in VS Code, this is GitHub Copilot. Sometimes they are the same program, sometimes distinct. The host handles rendering; the client handles protocol communication.

What is a UI resource reference in MCP?

A UI resource reference is 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 fetch and render the iFrame. Without this reference, the host has no signal that a renderable UI is available, and the user sees plain text instead of an interactive component.

What is a skill file in the context of MCP Apps?

A skill file is a reusable template that encodes the full MCP App pattern—tool definition, resource bundling, link wiring, handler configuration, and run instructions. It can be fed to AI tooling like GitHub Copilot CLI or Claude to scaffold new MCP Apps automatically from the same template. Store all variants (flame graph, markdown viewer, color picker) in the same repository for easy reuse.

// How To

How do I choose between React, Vue, Svelte, or vanilla JS for my MCP App?

Choose based on your team's familiarity and the complexity of the UI. React is ideal for complex interactive dashboards with many state updates. Vue works well for mid-complexity apps with clear component hierarchies. Svelte produces smaller bundles, which matters since the UI must be fully self-contained. Vanilla JS is best for simple UIs like color pickers or single-chart displays. The UI must be fully bundled into a single resource regardless of framework.

How do I implement the app-to-server callback loop in an MCP App?

Wire the iFrame app so that user interactions (clicks, filters, edits) trigger calls back to the MCP server. The server processes the request, returns fresh data, and the app re-renders within the iFrame. Set the invoker mode to 'model and app' or 'app only' so the iFrame UI has permission to call the tool directly. Test that the UI updates without the user typing a new prompt—this bidirectional loop is what makes MCP Apps truly interactive.

How do I bundle the HTML UI so it works as a single MCP resource?

Build a self-contained HTML file that includes all CSS, JavaScript, and assets inline or bundled together. Use build tools like Vite, Webpack, or esbuild to produce a single HTML output. The host serves the UI from a single resource reference, so external dependencies or CDN links may not resolve inside the sandboxed iFrame. Test the bundled file by opening it standalone in a browser before deploying it as an MCP resource.

How do I test an MCP App locally before deploying?

Start the MCP server on localhost and register it in VS Code via the extensions tab (@MCP). Open GitHub Copilot chat and type a natural language prompt that should trigger your tool. Verify the tool appears in the host's tool list, the server returns the UI resource reference, and the iFrame renders correctly. Test the bidirectional callback loop by interacting with the UI and confirming it updates without new prompts. Also open the bundled HTML in a standalone browser to catch JavaScript errors.

// Troubleshooting

How do I debug an MCP App that doesn't render in VS Code?

First, verify your MCP server is running and registered in VS Code (extensions tab → @MCP). Check that the tool appears in the host's tool list. Confirm the server returns the UI resource reference alongside the data result—without it, the host renders nothing. Inspect server logs for errors in resource generation. Ensure the invoker mode is set correctly. If the iFrame appears blank, check for JavaScript errors in the bundled HTML by opening it in a standalone browser.

Why does my MCP App show plain text instead of an interactive UI?

The most common cause is a missing UI resource reference in the tool's return payload. The server must return both the data result and the resource reference that points to the bundled HTML. Without the Link, the host has no signal to render an iFrame and falls back to displaying plain text. Check your server code to ensure the resource reference is included in every tool response that should produce a UI.

Why isn't my MCP App updating when users interact with it?

You likely haven't implemented the bidirectional callback loop. The iFrame app must be wired so user interactions call back to the MCP server, and the invoker mode must be set to 'model and app' or 'app only' to permit the iFrame to trigger tool calls. If the invoker mode is 'model only,' only the LLM can trigger the tool, and clicks in the UI do nothing. Check your handler configuration and verify the callback wiring.

My MCP App tries to access external APIs but fails—why?

The MCP App runs inside a sandboxed iFrame that prevents access to external APIs, VS Code settings, or anything outside the chat window. This is by design for security. If your app needs external data, route all requests through the MCP server itself. The app calls the server, the server makes the external API call, and returns the data to the app within the iFrame. Never try to break out of the sandbox boundary.

What happens if the MCP server goes down while the iFrame is open?

If the MCP server stops while the iFrame is active, any callback from the app to the server will fail. The UI will remain in its last rendered state but cannot update or fetch fresh data. Design your app to handle server disconnection gracefully—show an error message, disable interactive elements, or prompt the user to restart the server. The sandboxed iFrame itself will not crash, but interactivity will be lost until the server is restored.

// Comparisons

How do MCP Apps compare to VS Code webview extensions?

VS Code webview extensions run as full extension panels with broader API access to VS Code internals. MCP Apps are sandboxed iFrames rendered inside the chat window with no access to VS Code settings or APIs. MCP Apps are triggered by LLM tool calls via natural language prompts, making them more accessible and contextual. Webview extensions require manual installation and activation. Choose MCP Apps when the UI is data-driven and conversational; choose webview extensions when you need deep IDE integration.

How do MCP Apps compare to Streamlit or Gradio for building AI UIs?

Streamlit and Gradio produce standalone web applications that run in a browser. MCP Apps render directly inside the chat window of an MCP host like VS Code, eliminating context switching. Streamlit and Gradio are better for sharing public-facing dashboards. MCP Apps are better for developer workflows where the user is already in an IDE and wants interactive results inline with their conversation. MCP Apps also integrate natively with LLM tool calling, which Streamlit and Gradio do not.

// Advanced

Can I use MCP Apps outside of VS Code?

Yes. MCP Apps work with any MCP host that supports rendering UI resource references in a sandboxed iFrame. VS Code with GitHub Copilot is the primary host today, but the MCP protocol is host-agnostic. As more MCP hosts adopt the standard—including other IDEs, chat clients, and agent frameworks—your MCP App will render in those environments without modification, as long as the host supports the iFrame rendering specification.

Can I build multi-step wizards or flows inside a single MCP App?

Yes. Since the iFrame app can call back to the MCP server and re-render with fresh data, you can build multi-step flows like e-commerce checkout wizards, onboarding sequences, or configuration workflows. Each step sends the user's choices back to the server, which returns the next step's data and the app re-renders. The entire flow happens inside the chat window without new prompts. Set the invoker mode to 'app only' or 'model and app' to enable UI-driven progression.

How do I ensure brand consistency in an MCP App?

Treat the chat window as a first-class surface for your brand. When building the bundled HTML Resource, apply the same CSS, typography, colors, and imagery you use on your company's website. The MCP App should be visually indistinguishable from your product's native UI. Do not accept a degraded experience just because it renders in chat. Test the bundled HTML alongside your brand guidelines before deploying.

What security risks should I consider when building MCP Apps?

The primary risk is using unvetted third-party MCP servers that may contain malicious code. Always use verified servers from the VS Code extensions tab or official GitHub/Anthropic repositories. The sandboxed iFrame provides isolation, but you should also validate all data passed between the iFrame and the MCP server. Never allow the app to break out of the sandbox. Treat the MCP server as you would any API endpoint—validate inputs, sanitize outputs, and use authentication where appropriate.

Can I pass user authentication tokens to an MCP App?

The sandboxed iFrame restricts direct access to the host's authentication context. If your MCP App needs authenticated data, handle authentication at the MCP server level. The server can manage tokens, sessions, or API keys and return authenticated data to the iFrame app through the callback loop. Do not attempt to pass sensitive tokens directly into the iFrame's HTML or JavaScript, as the sandbox model does not guarantee their protection.

Can multiple MCP Apps render simultaneously in the same chat window?

This depends on the MCP host's implementation. In VS Code with GitHub Copilot, each tool call that returns a UI resource reference renders its own sandboxed iFrame. Multiple iFrames can appear in the chat history as the user triggers different tools. Each iFrame is independently sandboxed and isolated from the others. However, they do not share state—if you need coordinated multi-panel views, build them as a single MCP App with multiple components inside one iFrame.