Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,4 @@ Microsoft.FluentUI.AspNetCore.Components.xml
/examples/Demo/FluentUI.Demo.Client/wwwroot/documentation/
api-comments.json
/global.json
/src/Tools/McpServer/FluentUIComponentsDocumentation.json
5 changes: 4 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<RuntimeVersion9>9.0.9</RuntimeVersion9>
<RuntimeVersion9>9.0.10</RuntimeVersion9>
<AspNetCoreVersion9>9.0.9</AspNetCoreVersion9>
<EfCoreVersion9>9.0.9</EfCoreVersion9>
<RuntimeVersion10>10.0.0</RuntimeVersion10>
Expand All @@ -15,6 +15,9 @@
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" version="4.13.1" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Emoji" Version="4.13.1" />
<PackageVersion Include="LoxSmoke.DocXml" Version="3.8.0" />
<!-- MCP Server dependencies -->
<PackageVersion Include="ModelContextProtocol" Version="0.4.0-preview.3" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
<!-- Test dependencies -->
<PackageVersion Include="bunit" Version="2.2.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
Expand Down
154 changes: 152 additions & 2 deletions Microsoft.FluentUI-v5.sln

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions Microsoft.FluentUI-v5.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@
</Project>
<Project Path="src/Core/Microsoft.FluentUI.AspNetCore.Components.csproj" />
</Folder>
<Folder Name="/src/tools/">
<Project Path="src/Tools/McpServer/Microsoft.FluentUI.AspNetCore.Components.McpServer.csproj" />
<Project Path="src/Tools/McpServer.Shared/Microsoft.FluentUI.AspNetCore.Components.McpServer.Shared.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/Core/Components.Tests.csproj" />
<Project Path="tests/Integration/Components.IntegrationTests.csproj">
<Build Solution="Debug|*" Project="false" />
</Project>
</Folder>
<Folder Name="/tests/tools/">
<Project Path="tests/Tools/McpServer.Tests/Microsoft.FluentUI.AspNetCore.Components.McpServer.Tests.csproj" />
</Folder>
</Solution>
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
@using Microsoft.FluentUI.AspNetCore.Components.McpServer.Shared
@using Microsoft.FluentUI.AspNetCore.Components.McpServer.Shared.Models
@using System.Net.Http.Json
@inject HttpClient Http

@if (_loading)
{
<FluentSpinner />
}
else if (_summary is null)
{
<FluentMessageBar Title="Error" Intent="MessageBarIntent.Error">
Failed to load MCP capabilities data.
</FluentMessageBar>
}
else
{
<FluentTabs ActiveTabId="@_activeTab" ActiveTabIdChanged="@OnTabChanged">
<FluentTab Id="tools" Label="@($"Tools ({_summary.Tools.Count})")">
<FluentDataGrid TGridItem="McpToolInfo" Items="@_summary.Tools.AsQueryable()" GridTemplateColumns="1fr 2fr 1fr">
<PropertyColumn Property="@(t => t.Name)" Title="Name" />
<PropertyColumn Property="@(t => t.Description)" Title="Description" />
<TemplateColumn Title="Parameters">
@if (context.Parameters.Count > 0)
{
<FluentStack Orientation="Orientation.Vertical" VerticalGap="0">
@foreach (var param in context.Parameters)
{
<span>
<code>@param.Name</code>
<span class="text-muted">(@param.Type)</span>
@if (param.Required)
{
<span>*</span>
}
</span>
}
</FluentStack>
}
else
{
<span class="text-muted">None</span>
}
</TemplateColumn>
</FluentDataGrid>
</FluentTab>

<FluentTab Id="prompts" Label="@($"Prompts ({_summary.Prompts.Count})")">
<FluentDataGrid TGridItem="McpPromptInfo" Items="@_summary.Prompts.AsQueryable()" GridTemplateColumns="1fr 2fr 1fr">
<PropertyColumn Property="@(p => p.Name)" Title="Name" />
<PropertyColumn Property="@(p => p.Description)" Title="Description" />
<TemplateColumn Title="Parameters">
@if (context.Parameters.Count > 0)
{
<FluentStack Orientation="Orientation.Vertical" VerticalGap="0">
@foreach (var param in context.Parameters)
{
<span>
<code>@param.Name</code>
<span class="text-muted">(@param.Type)</span>
@if (param.Required)
{
<span>*</span>
}
</span>
}
</FluentStack>
}
else
{
<span class="text-muted">None</span>
}
</TemplateColumn>
</FluentDataGrid>
</FluentTab>

<FluentTab Id="resources" Label="@($"Resources ({_summary.Resources.Count})")">
<FluentDataGrid TGridItem="McpResourceInfo" Items="@_summary.Resources.AsQueryable()" GridTemplateColumns="1fr 1fr 2fr 0.5fr">
<PropertyColumn Property="@(r => r.Uri)" Title="URI" />
<PropertyColumn Property="@(r => r.Title)" Title="Title" />
<PropertyColumn Property="@(r => r.Description)" Title="Description" />
<TemplateColumn Title="Type">
@if (context.IsTemplate)
{
<span class="text-muted">Template</span>
}
else
{
<span class="text-muted">Static</span>
}
</TemplateColumn>
</FluentDataGrid>
</FluentTab>
</FluentTabs>
}

@code {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't display the source code in the .md file, can you move this code to a .cs file ?

private string _activeTab = "tools";
private McpSummary? _summary;
private bool _loading = true;

protected override async Task OnInitializedAsync()
{
try
{
// Try to get from static cache first (works in Server mode)
if (McpCapabilitiesData.IsInitialized)
{
_summary = McpCapabilitiesData.GetSummary();
}
else
{
// Fetch from API (for WebAssembly mode)
_summary = await Http.GetFromJsonAsync<McpSummary>("/api/mcp/capabilities");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final hosting will be on a static web site. So not API available :-(

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have an API with SWA

}
}
catch
{
_summary = null;
}
finally
{
_loading = false;
}
}

private void OnTabChanged(string? tabId)
{
_activeTab = tabId ?? "tools";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
title: MCP Server
order: 0012
category: 10|Get Started
route: /mcp-server
---

# MCP Server

**Model Context Protocol (MCP)** is an open protocol that enables seamless integration between LLM applications and external data sources and tools.
The Fluent UI Blazor library provides an MCP server that gives AI assistants access to component documentation, enabling them to generate accurate, up-to-date Fluent UI Blazor code.

## What is MCP?

MCP provides a standardized way for AI assistants (like GitHub Copilot, Claude, and others) to access external context.
Instead of relying solely on training data, AI assistants can query real-time documentation, search for specific components, and get accurate parameter information.

Learn more: [Model Context Protocol](https://modelcontextprotocol.io/)

## Installation

### As a .NET Global Tool

```bash
dotnet tool install -g Microsoft.FluentUI.AspNetCore.Components.McpServer --prerelease
```

### From Source

```bash
cd examples/Mcp/FluentUI.Mcp.Server
dotnet build
```

## Configuration

### VS Code / GitHub Copilot

Add to your `.vscode/mcp.json` or user settings:

```json
{
"servers": {
"fluentui-blazor": {
"command": "fluentui-mcp",
"args": []
}
}
}
```

### Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
"mcpServers": {
"fluentui-blazor": {
"command": "fluentui-mcp",
"args": []
}
}
}
```

### Running from Source

If running from source, use the full path:

```json
{
"servers": {
"fluentui-blazor": {
"command": "dotnet",
"args": ["run", "--project", "path/to/FluentUI.Mcp.Server"]
}
}
}
```

## Available Capabilities

The MCP server exposes three types of primitives:

- **Tools**: Model-controlled functions for dynamic queries (search, get details)
- **Resources**: User-selected static content (component lists, guides)
- **Prompts**: Pre-defined templates for common tasks (create component, migrate code)

{{ McpCapabilities }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to display the source code of this component. You can add SourceCode="false" to hide the source tab.


## Usage Examples

### Ask for Component Help

> "How do I use FluentDataGrid with pagination?"
The AI will use the `GetComponentDetails` tool to fetch accurate parameter information.

### Generate Code

> "Create a form with name, email, and a submit button using Fluent UI Blazor"
The AI will use the `create_form` prompt combined with component documentation.

### Migration Assistance

> "Migrate this v4 code to v5"
The AI will use the `migrate_to_v5` prompt and the migration guide resource.

## Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ AI Assistant β”‚
β”‚ (Copilot, Claude, etc.) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”‚ MCP Protocol (stdio)
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FluentUI MCP Server β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Tools β”‚ Resources β”‚ Prompts β”‚
β”‚ ─────────── β”‚ ──────────── β”‚ ──────────── β”‚
β”‚ ListComponents β”‚ components β”‚ create_component β”‚
β”‚ GetDetails β”‚ categories β”‚ create_form β”‚
β”‚ SearchEnums β”‚ guides/* β”‚ migrate_to_v5 β”‚
β”‚ ... β”‚ ... β”‚ ... β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ FluentUIDocumentationService β”‚
β”‚ (Reflection + XML Docs) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”‚ Assembly Reflection
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Microsoft.FluentUI.AspNetCore.Components β”‚
β”‚ (Component Library) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## Source Code

The MCP server source code is available in the repository:

[examples/Mcp/FluentUI.Mcp.Server](https://github.com/microsoft/fluentui-blazor/tree/dev/examples/Mcp/FluentUI.Mcp.Server)
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

<ItemGroup>
<ProjectReference Include="..\..\..\src\Core\Microsoft.FluentUI.AspNetCore.Components.csproj" />
<ProjectReference Include="..\..\..\src\Tools\McpServer.Shared\Microsoft.FluentUI.AspNetCore.Components.McpServer.Shared.csproj" />
<ProjectReference Include="..\..\Tools\FluentUI.Demo.DocViewer\FluentUI.Demo.DocViewer.csproj" />
<ProjectReference Include="..\..\Tools\FluentUI.Demo.SampleData\FluentUI.Demo.SampleData.csproj" />
</ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion examples/Demo/FluentUI.Demo/FluentUI.Demo.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
ο»Ώ<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
Expand All @@ -10,6 +10,7 @@

<ItemGroup>
<ProjectReference Include="..\..\..\src\Core\Microsoft.FluentUI.AspNetCore.Components.csproj" />
<ProjectReference Include="..\..\..\src\Tools\McpServer\Microsoft.FluentUI.AspNetCore.Components.McpServer.csproj" />
<ProjectReference Include="..\FluentUI.Demo.Client\FluentUI.Demo.Client.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
</ItemGroup>
Expand Down
9 changes: 9 additions & 0 deletions examples/Demo/FluentUI.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

using FluentUI.Demo.Client;
using Microsoft.FluentUI.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components.McpServer.Services;
using Microsoft.FluentUI.AspNetCore.Components.McpServer.Shared;

var builder = WebApplication.CreateBuilder(args);

Expand Down Expand Up @@ -32,6 +34,9 @@
// Add Demo server services
builder.Services.AddFluentUIDemoServices().ForServer();

// Initialize MCP capabilities data from the MCP Server assembly
McpCapabilitiesData.Initialize(typeof(FluentUIDocumentationService).Assembly);

var app = builder.Build();

// Configure the HTTP request pipeline.
Expand All @@ -54,6 +59,10 @@
// Use the localization services
app.UseRequestLocalization(new RequestLocalizationOptions().AddSupportedUICultures(["en", "fr"]));

// API endpoint to expose MCP capabilities for WebAssembly clients
app.MapGet("/api/mcp/capabilities", () => McpCapabilitiesData.GetSummary())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you add this API? The Blazor Demo project can be published using Server but also WASM mode to be hosted on a static website.

.WithName("GetMcpCapabilities");

app.MapRazorComponents<FluentUI.Demo.Components.App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
Expand Down
Loading
Loading