How to Build Interactive Profiling UIs in VS Code Chat

For Backend developers and DevOps engineers · Based on MCP Apps Interactive UI Builder (VS Code)

// TL;DR

Backend developers and DevOps engineers can use MCP Apps Interactive UI Builder to render flame graphs, performance dashboards, and monitoring UIs directly inside VS Code's chat window. Instead of pasting raw profiling JSON into the chat or switching to a browser-based tool, you build an MCP server that returns structured profiling data alongside a bundled interactive UI. The flame graph, top function summaries, and time breakdowns render in a sandboxed iFrame. Users interact by clicking functions to drill down—no follow-up prompts needed.

Why should backend developers use MCP Apps for profiling?

Traditional profiling workflows force you to switch contexts: run a profiler, export data, open a separate tool or browser tab, and interpret the results manually. If you ask an LLM to analyze raw profiling output, you get text-based interpretations that lack the visual clarity of a flame graph.

MCP Apps eliminate this friction entirely. You build an MCP server that runs the profiler, structures the output as JSON, and bundles a React or Svelte-based flame graph UI as the Resource. When you type 'profile my application' in GitHub Copilot chat, the LLM calls your tool, and VS Code renders a fully interactive flame graph in the chat window.

How do you build a profiling MCP App step by step?

Start by defining your MCP server tool. Specify what it does—e.g., 'profile a Go application for 30 seconds and return structured CPU profiling data.' Define the data shape: a JSON object containing function names, call stacks, durations, and percentages.

Next, choose your UI framework. React is ideal for flame graphs because of its component model and state management. Build a self-contained HTML file that imports your flame graph component, consumes the JSON profiling data, and renders the visualization. Bundle everything into a single file using Vite or Webpack.

Wire the Link by ensuring your server's tool response includes both the profiling data and a UI resource reference pointing to your bundled HTML. Set the invoker mode to 'model and app' so the LLM can trigger the initial profile, and the user can click within the flame graph to drill down without typing new prompts.

Register your MCP server in VS Code via the extensions tab (@MCP). Send a natural language prompt like 'profile my application' in GitHub Copilot chat. The LLM recognizes the tool, calls it, and VS Code renders the flame graph in a sandboxed iFrame.

Finally, implement the callback loop. When a user clicks a function in the flame graph, the app calls back to the MCP server to fetch detailed data for that function, and the UI re-renders with the drill-down view. This bidirectional interaction is what makes the experience superior to static profiling reports.

What pitfalls should backend developers watch for?

The biggest mistake is returning profiling data without the UI resource reference. If the server omits the Link, VS Code renders plain text and the user sees raw JSON instead of a flame graph. Always verify your server's response includes both the data and the resource reference.

Another common error is designing the flame graph as a one-way render without the callback loop. If users can't click to drill down, they're forced to type follow-up prompts like 'show me details for function X,' which defeats the purpose of building an MCP App.

Also, ensure your bundled HTML is fully self-contained. External CDN references may not resolve inside the sandboxed iFrame.

What's the next step?

Encode your profiling MCP App pattern into a skill file. This lets you or any AI tool scaffold new profiling MCP Apps—for different languages, profiling tools, or performance metrics—from the same template. Store it in your repository alongside your existing MCP server code.

// FREQUENTLY ASKED QUESTIONS

Can I profile applications in any language using an MCP App?

Yes. The MCP server tool handles the profiling logic, so you can wrap any language's profiler (Go pprof, Python cProfile, Java JFR) in your server. The key requirement is that the profiler output is converted to structured JSON that your bundled flame graph UI can consume. The UI framework is language-agnostic—it renders whatever data the server returns.

How do I handle large profiling datasets in the iFrame?

For very large datasets, implement server-side aggregation before returning data to the iFrame. Return summary-level data initially, and use the callback loop to fetch detailed drill-down data on demand when the user clicks a specific function or call stack. This keeps the initial render fast and avoids overwhelming the sandboxed iFrame with too much data at once.

Can I compare two profiling runs side by side in an MCP App?

Yes. Build your bundled HTML UI with a split-view layout that accepts two profiling datasets. Your MCP server tool can accept parameters for two different runs and return both datasets alongside the UI resource reference. The iFrame renders both flame graphs side by side, and the callback loop can highlight differences between runs.