Skip to content

Commit b56d137

Browse files
AClerboisCopilotaclerbois-oresvnbaaij
authored
Add documentation to the mcp's tools and resources (#4476)
* Add GetStarted documentation tools, resources, and service Introduces GetStartedDocumentationService to load and parse embedded markdown docs (excluding "mcp"), along with the GetStartedInfo model. Adds MCP tools and resources for listing, searching, and retrieving onboarding, installation, and migration guides. Updates service registration, project file for resource embedding, and README for new usage. Includes comprehensive unit tests for all new functionality. Enables LLM-powered access to onboarding and migration docs. * Refactor GetStarted docs to generic Documentation service Renamed all "GetStarted" documentation services, tools, and resources to "Documentation" for broader applicability. This includes replacing `GetStartedDocumentationService` with `DocumentationService`, and updating all usages, tests, and references accordingly. Updated README and resource URIs to reflect the new naming. Improves clarity, extensibility, and consistency for documentation features. * Refactor documentation classes and fix YAML parsing bug Renamed documentation resource and tool classes, tests, and files for clarity and consistency. Standardized license headers. Fixed YAML front matter parsing in DocumentationService to use the correct regex group. No functional changes to business logic; code is now more maintainable and readable. * Refactor documentation service and tests to use generic terminology * Update src/Tools/McpServer/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Refactor documentation structure to use generic terminology and improve clarity * Delete src/Tools/McpServer/Models/GetStartedInfo.cs --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Adrien Clerbois <uvu447@ores.be> Co-authored-by: Vincent Baaij <vnbaaij@outlook.com>
1 parent 2159f04 commit b56d137

File tree

12 files changed

+1323
-0
lines changed

12 files changed

+1323
-0
lines changed

src/Tools/McpServer/Extensions/ServiceCollectionExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public static IServiceCollection AddFluentUIDocumentation(this IServiceCollectio
4242
// Falls back to embedded resource if no external file is found
4343
services.AddSingleton(_ => new FluentUIDocumentationService(externalJsonPath));
4444

45+
// Documentation service
46+
// Excludes the 'mcp' folder
47+
services.AddSingleton(_ => new DocumentationService(["mcp"]));
48+
4549
return services;
4650
}
4751

src/Tools/McpServer/Microsoft.FluentUI.AspNetCore.McpServer.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@
7979

8080
<!-- Embed the pre-generated JSON documentation as a resource -->
8181

82+
<!-- Include Documentation markdown files as embedded resources -->
83+
<ItemGroup>
84+
<EmbeddedResource Include="..\..\..\examples\Demo\FluentUI.Demo.Client\Documentation\GetStarted\**\*.md"
85+
Exclude="..\..\..\examples\Demo\FluentUI.Demo.Client\Documentation\GetStarted\mcp\**\*"
86+
Link="Documentation\GetStarted\%(RecursiveDir)%(Filename)%(Extension)" />
87+
</ItemGroup>
88+
8289
<!-- Code Analysis -->
8390
<ItemGroup>
8491
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers">
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// ------------------------------------------------------------------------
2+
// This file is licensed to you under the MIT License.
3+
// ------------------------------------------------------------------------
4+
5+
namespace Microsoft.FluentUI.AspNetCore.McpServer.Models;
6+
7+
/// <summary>
8+
/// Represents general information about a documentation page.
9+
/// </summary>
10+
public class GeneralInfo
11+
{
12+
/// <summary>
13+
/// Gets or sets the title of the documentation page.
14+
/// </summary>
15+
public string Title { get; set; } = string.Empty;
16+
17+
/// <summary>
18+
/// Gets or sets the order of the documentation page.
19+
/// </summary>
20+
public int Order { get; set; }
21+
22+
/// <summary>
23+
/// Gets or sets the category of the documentation page.
24+
/// </summary>
25+
public string Category { get; set; } = string.Empty;
26+
27+
/// <summary>
28+
/// Gets or sets the route of the documentation page.
29+
/// </summary>
30+
public string Route { get; set; } = string.Empty;
31+
32+
/// <summary>
33+
/// Gets or sets the icon of the documentation page.
34+
/// </summary>
35+
public string Icon { get; set; } = string.Empty;
36+
37+
/// <summary>
38+
/// Gets or sets the file name of the documentation page.
39+
/// </summary>
40+
public string FileName { get; set; } = string.Empty;
41+
42+
/// <summary>
43+
/// Gets or sets whether the documentation page is hidden.
44+
/// </summary>
45+
public bool Hidden { get; set; }
46+
47+
/// <summary>
48+
/// Gets or sets the content of the documentation page (markdown).
49+
/// </summary>
50+
public string Content { get; set; } = string.Empty;
51+
52+
/// <summary>
53+
/// Gets or sets the summary (first paragraph) of the documentation page.
54+
/// </summary>
55+
public string Summary { get; set; } = string.Empty;
56+
}

src/Tools/McpServer/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ Tools are invoked automatically by the LLM for dynamic queries.
183183
| `SearchComponents` | Searches components by name or description | `searchTerm` |
184184
| `GetEnumValues` | Gets enum type values | `enumName`, `filter` (optional) |
185185
| `GetComponentEnums` | Lists enums used by a component | `componentName` |
186+
| `ListDocumentationTopics` | Lists all documentation topics | - |
187+
| `GetDocumentationTopic` | Gets detailed documentation for a documentation topic | `topicName` |
188+
| `SearchDocumentation` | Searches documentation by keyword | `searchTerm` |
189+
| `GetMigrationGuide` | Gets migration guide for upgrading to v5 | - |
186190

187191
### Resources (User-controlled)
188192

@@ -196,6 +200,9 @@ Resources provide static documentation that users can attach to conversations.
196200
| `fluentui://component/{name}` | Detailed documentation for a specific component |
197201
| `fluentui://category/{name}` | List of components in a specific category |
198202
| `fluentui://enum/{name}` | Detailed information about a specific enum type |
203+
| `fluentui://documentation` | Complete list of all documentation topics |
204+
| `fluentui://documentation/{topic}` | Documentation for a specific documentation topic (e.g., installation, localization, styles) |
205+
| `fluentui://documentation/migration` | Complete migration guide for upgrading to v5 |
199206

200207
## Usage Examples
201208

@@ -213,8 +220,22 @@ SearchComponents(searchTerm: "input")
213220
GetEnumValues(enumName: "Appearance")
214221
```
215222

223+
# List all documentation topics
224+
ListDocumentation()
225+
226+
# Get the installation guide
227+
GetDocumentationTopic(topicName: "Installation")
228+
229+
# Search for migration-related documentation
230+
SearchDocumentation(searchTerm: "migrate")
231+
232+
# Get the complete migration guide to v5
233+
GetMigrationGuide()
234+
```
235+
216236
## Debugging
217237
238+
218239
### Visual Studio Code
219240
220241
1. Configure the MCP server in `.vscode/mcp.json`:
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// ------------------------------------------------------------------------
2+
// This file is licensed to you under the MIT License.
3+
// ------------------------------------------------------------------------
4+
5+
using System.ComponentModel;
6+
using System.Globalization;
7+
using System.Text;
8+
using Microsoft.FluentUI.AspNetCore.McpServer.Services;
9+
using ModelContextProtocol.Server;
10+
11+
namespace Microsoft.FluentUI.AspNetCore.McpServer.Resources;
12+
13+
/// <summary>
14+
/// MCP Resources providing static documentation content for Fluent UI Blazor.
15+
/// These resources are user-selected and provide context for the LLM.
16+
/// </summary>
17+
[McpServerResourceType]
18+
public class DocumentationResources
19+
{
20+
private readonly DocumentationService _documentationService;
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="DocumentationResources"/> class.
24+
/// </summary>
25+
public DocumentationResources(DocumentationService documentationService)
26+
{
27+
_documentationService = documentationService;
28+
}
29+
30+
/// <summary>
31+
/// Gets the complete list of all documentation topics.
32+
/// </summary>
33+
[McpServerResource(
34+
UriTemplate = "fluentui://documentation",
35+
Name = "documentation",
36+
Title = "Fluent UI Blazor - Documentation",
37+
MimeType = "text/markdown")]
38+
[Description("Complete list of all documentation topics including installation, configuration, migration, and styling guides.")]
39+
public string GetAllTopics()
40+
{
41+
var docs = _documentationService.GetAllDocumentation();
42+
43+
var sb = new StringBuilder();
44+
sb.AppendLine("# Fluent UI Blazor - Documentation");
45+
sb.AppendLine();
46+
sb.AppendLine(CultureInfo.InvariantCulture, $"Total: {docs.Count} documentation topics");
47+
sb.AppendLine();
48+
sb.AppendLine("Available topics (use `fluentui://documentation/{topic}` to access):");
49+
sb.AppendLine();
50+
51+
foreach (var doc in docs)
52+
{
53+
sb.AppendLine(CultureInfo.InvariantCulture, $"## {doc.Title}");
54+
sb.AppendLine(CultureInfo.InvariantCulture, $"**URI:** `fluentui://documentation/{doc.FileName.ToLowerInvariant()}`");
55+
56+
if (!string.IsNullOrEmpty(doc.Route))
57+
{
58+
sb.AppendLine(CultureInfo.InvariantCulture, $"**Route:** {doc.Route}");
59+
}
60+
61+
sb.AppendLine();
62+
sb.AppendLine(doc.Summary);
63+
sb.AppendLine();
64+
}
65+
66+
return sb.ToString();
67+
}
68+
69+
/// <summary>
70+
/// Gets documentation for a specific documentation topic by name.
71+
/// </summary>
72+
/// <param name="topic">The topic name (e.g., 'installation', 'localization', 'styles', 'migrationversion5', 'defaultvalues').</param>
73+
[McpServerResource(
74+
UriTemplate = "fluentui://documentation/{topic}",
75+
Name = "documentation-topic",
76+
Title = "Topic Documentation",
77+
MimeType = "text/markdown")]
78+
[Description("Detailed documentation for a specific documentation topic. Use topic names like 'installation', 'localization', 'styles', 'migrationversion5', 'defaultvalues'.")]
79+
public string GetTopic(string topic)
80+
{
81+
var doc = _documentationService.GetDocumentation(topic);
82+
83+
if (doc == null)
84+
{
85+
var availableTopics = _documentationService.GetTopics();
86+
var topicList = string.Join(", ", availableTopics.Take(10).Select(t => $"'{t}'"));
87+
88+
return $"# Topic Not Found\n\nTopic '{topic}' was not found.\n\n" +
89+
$"Available topics include: {topicList}\n\n" +
90+
"Use `fluentui://documentation` to see all available topics.";
91+
}
92+
93+
return doc.Content;
94+
}
95+
96+
/// <summary>
97+
/// Gets the complete migration guide documentation.
98+
/// </summary>
99+
[McpServerResource(
100+
UriTemplate = "fluentui://documentation/migration",
101+
Name = "migration",
102+
Title = "Fluent UI Blazor - Migration Guide to v5",
103+
MimeType = "text/markdown")]
104+
[Description("Complete migration guide for upgrading to Fluent UI Blazor v5, including all breaking changes and component updates.")]
105+
public string GetMigrationGuide()
106+
{
107+
var migrationDocs = _documentationService.GetMigrationDocumentation();
108+
109+
var sb = new StringBuilder();
110+
sb.AppendLine("# Fluent UI Blazor - Migration Guide to v5");
111+
sb.AppendLine();
112+
113+
// Get the main migration document first
114+
var mainDoc = _documentationService.GetDocumentation("Migrating to v5") ??
115+
_documentationService.GetDocumentation("MigrationVersion5");
116+
117+
if (mainDoc != null)
118+
{
119+
sb.AppendLine(mainDoc.Content);
120+
sb.AppendLine();
121+
}
122+
123+
// Add component-specific migration info
124+
var componentMigrations = migrationDocs
125+
.Where(d => d.FileName.StartsWith("Migration", StringComparison.OrdinalIgnoreCase) &&
126+
!d.FileName.Equals("MigrationVersion5", StringComparison.OrdinalIgnoreCase))
127+
.ToList();
128+
129+
if (componentMigrations.Count > 0)
130+
{
131+
sb.AppendLine("## Component-Specific Migrations");
132+
sb.AppendLine();
133+
134+
foreach (var doc in componentMigrations)
135+
{
136+
sb.AppendLine(CultureInfo.InvariantCulture, $"### {doc.Title}");
137+
sb.AppendLine();
138+
sb.AppendLine(doc.Content);
139+
sb.AppendLine();
140+
}
141+
}
142+
143+
return sb.ToString();
144+
}
145+
}

0 commit comments

Comments
 (0)