โš ๏ธ This blog post was created with the help of AI tools. Yes, I used a bit of magic from language models to organize my thoughts and automate the boring parts, but the geeky fun and the ๐Ÿค– in C# are 100% mine.

Hi!

Airport Time = Coding Time! โœˆ๏ธ

I’m sitting at the airport right now, and you know what that means โ€“ perfect time to cook up some code! I just discovered that MCP Apps were announced, and I noticed something interesting: there are no C# samples in the official repository yet. Well, challenge accepted!

MCP Apps are super new โ€“ literally just announced yesterday โ€“ and I couldn’t resist putting together a .NET implementation while waiting for my flight.

Note: as soon as the official MCP C# SDK supports MCP Apps, I’ll regenerate the demo using the new SDK!

What are MCP Apps?

MCP (Model Context Protocol) Apps are a new extension to the protocol that allows MCP servers to provide interactive UI components. Instead of just returning text responses, your MCP tools can now return rich, interactive HTML-based interfaces that integrate seamlessly with the host application (like VS Code).

Think of it as bringing UI to your AI assistant interactions. Your tools can now display color pickers, file explorers, forms, charts โ€“ basically any web-based UI you can imagine!

The Sample: An Interactive Color Picker

For this sample, I built a Color Picker MCP App. When you invoke the ColorPicker tool, it returns an interactive color picker UI with:

  • Visual color selection with real-time preview
  • HEX, RGB, and HSL format display with copy buttons
  • A quick color palette for fast selection
  • Random color generator
  • Full VS Code theme integration

Building It in C#

Here’s how to create an MCP App in .NET:

Step 1: Create the Project

dotnet new web -n ColorPickerMcp
cd ColorPickerMcp

Step 2: Add the MCP SDK

dotnet add package ModelContextProtocol.AspNetCore --version 0.2.0-preview.1

Step 3: Configure the MCP Server

In your Program.cs, set up the MCP server with HTTP transport:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls("http://localhost:3001");
builder.Services.AddMcpServer()
.WithHttpTransport()
.WithToolsFromAssembly();
var app = builder.Build();
// MCP endpoint
app.MapMcp("/mcp");
// Serve the color picker UI
app.MapGet("/ui/color-picker", async () =>
{
var html = await GetColorPickerHtml();
return Results.Content(html, "text/html");
});
await app.RunAsync();

Step 4: Define Your MCP Tool

Use the [McpServerToolType] and [McpServerTool] attributes to define your tool:

[McpServerToolType]
public static class ColorPickerTools
{
[McpServerTool]
[Description("Open an interactive color picker to select a color visually.")]
public static ColorPickerResult ColorPicker(
[Description("Initial color in hex format (e.g., #FF5733). Default: #3498DB")]
string? initialColor = "#3498DB")
{
return new ColorPickerResult
{
InitialColor = initialColor ?? "#3498DB",
UiResourceUri = "ui://color-picker/app.html",
Message = "Opening color picker UI..."
};
}
}

Step 5: Create the UI

The UI is an embedded HTML string with full CSS and JavaScript. It uses VS Code’s CSS variables to automatically adapt to the user’s theme:

body {
background: var(--vscode-editor-background, #1e1e1e);
color: var(--vscode-editor-foreground, #cccccc);
}

The complete UI includes:

  • A native color input for picking colors
  • Value displays for HEX, RGB, and HSL formats
  • Copy-to-clipboard functionality
  • A preset color palette
  • Random color generation

Running the Sample

  1. Clone the repository:
    git clone https://github.com/elbruno/mcpapp-colorpicker.git
    cd mcpapp-colorpicker
  2. Run the server:
    dotnet run
  3. Configure VS Code by adding to .vscode/mcp.json:
    { "servers": { "color-picker": { "type": "http", "url": "http://localhost:3001/mcp" } } }
  4. Use it! In VS Code with the MCP extension, invoke the ColorPicker tool.

Exposing Your MCP App Remotely with ngrok

What if you want to access your MCP app from outside your local network, or share it with team members? That’s where ngrok comes in!

ngrok is a tool that creates secure tunnels to your local server, exposing it over the internet with a public URL. Here’s how to set it up:

Get ngrok

  1. Head over to ngrok.com
  2. Create a free account
  3. Download ngrok for your OS (Windows, macOS, or Linux)
  4. Extract and place it somewhere accessible, or add it to your PATH

Expose Your Server

With your MCP server running on localhost:3001, open a new terminal and run:

ngrok http 3001

You’ll see output like:

Session Status online
Account <your-email>
Version 3.x.x
Region us (United States)
Latency 25ms
Web Interface http://127.0.0.1:4040
Forwarding https://abc123def456.ngrok.io -> http://localhost:3001

That https://abc123def456.ngrok.io URL is your public tunnel URL!

Update Your MCP Configuration

Now update your .vscode/mcp.json to use the ngrok URL:

{
"servers": {
"color-picker": {
"type": "http",
"url": "https://abc123def456.ngrok.io/mcp"
}
}
}

And that’s it! Your MCP app is now accessible from anywhere. Every time you run ngrok, you’ll get a new public URL (unless you have a paid plan for custom domains).

Key Takeaways

  1. MCP Apps are easy to build in .NET – The ModelContextProtocol.AspNetCore package handles all the protocol details.
  2. Attribute-based tool definition – Just decorate your methods and the SDK discovers them automatically.
  3. HTTP transport – Unlike traditional MCP servers using stdin/stdout, MCP Apps use HTTP for better web integration.
  4. VS Code theme integration – Use CSS variables to make your UI feel native.

Resources

Want to learn more about MCP Apps? Here are the official resources:

Get the Code

The complete source code is available on GitHub:

๐Ÿ‘‰ github.com/elbruno/mcpapp-colorpicker

Feel free to fork it, extend it, or use it as a starting point for your own MCP Apps in .NET!

Happy coding!

Greetings

El Bruno

More posts in my blog ElBruno.com.

More info in https://beacons.ai/elbruno


Leave a comment

Discover more from El Bruno

Subscribe now to keep reading and get access to the full archive.

Continue reading