diff --git a/src/Tools/McpServer/README.md b/src/Tools/McpServer/README.md index ce1fd6186e..016b9b3b85 100644 --- a/src/Tools/McpServer/README.md +++ b/src/Tools/McpServer/README.md @@ -185,11 +185,13 @@ Tools are invoked automatically by the LLM for dynamic queries. | Tool | Description | Parameters | |------|-------------|------------| | `ListComponents` | Lists all available components | `category` (optional) | +| `ListCategories` | Lists all available component categories | - | | `GetComponentDetails` | Gets detailed documentation for a component | `componentName` | | `SearchComponents` | Searches components by name or description | `searchTerm` | | `GetEnumValues` | Gets enum type values | `enumName`, `filter` (optional) | | `GetComponentEnums` | Lists enums used by a component | `componentName` | -| `ListDocumentationTopics` | Lists all documentation topics | - | +| `ListEnums` | Lists all available enum types | - | +| `ListDocumentation` | Lists all documentation topics | - | | `GetDocumentationTopic` | Gets detailed documentation for a documentation topic | `topicName` | | `SearchDocumentation` | Searches documentation by keyword | `searchTerm` | | `GetMigrationGuide` | Gets migration guide for upgrading to v5 | - | diff --git a/src/Tools/McpServer/Tools/ComponentListTools.cs b/src/Tools/McpServer/Tools/ComponentListTools.cs index 6836f823f8..adaff4ea5c 100644 --- a/src/Tools/McpServer/Tools/ComponentListTools.cs +++ b/src/Tools/McpServer/Tools/ComponentListTools.cs @@ -159,4 +159,41 @@ public string SearchComponents( // Sort the combined results by name for stable output return [.. components.Concat(additionalComponents).OrderBy(c => c.Name, StringComparer.OrdinalIgnoreCase)]; } + + /// + /// Lists all available component categories in the Fluent UI Blazor library. + /// Use this to discover valid category names for filtering . + /// + /// + /// A formatted string listing all component categories with the number of components in each. + /// + [McpServerTool] + [Description("Lists all available component categories in Fluent UI Blazor. Use this to find valid category names for filtering ListComponents(category: ...).")] + public string ListCategories() + { + var components = _documentationService.GetAllComponents(); + + var groups = components + .GroupBy(c => c.Category, StringComparer.OrdinalIgnoreCase) + .OrderBy(g => g.Key, StringComparer.OrdinalIgnoreCase) + .ToList(); + + if (groups.Count == 0) + { + return "No component categories found."; + } + var sb = new StringBuilder(); + sb.AppendLine(CultureInfo.InvariantCulture, $"# Fluent UI Blazor - Component Categories ({groups.Count} categories)"); + sb.AppendLine(); + + foreach (var group in groups) + { + sb.AppendLine(CultureInfo.InvariantCulture, $"- **{group.Key}** ({group.Count()} components)"); + } + + sb.AppendLine(); + sb.AppendLine("Use `ListComponents(category: \"\")` to list components in a specific category."); + + return sb.ToString(); + } } diff --git a/src/Tools/McpServer/Tools/EnumTools.cs b/src/Tools/McpServer/Tools/EnumTools.cs index 6117e9fc81..64d9cbaaa8 100644 --- a/src/Tools/McpServer/Tools/EnumTools.cs +++ b/src/Tools/McpServer/Tools/EnumTools.cs @@ -157,4 +157,37 @@ public string GetComponentEnums( return sb.ToString(); } + + /// + /// Lists all enum types available in the Fluent UI Blazor library. + /// Use this to discover valid enum names for . + /// + /// + /// A formatted string listing all enum types with their descriptions. + /// + [McpServerTool] + [Description("Lists all enum types available in the Fluent UI Blazor library. Use this to discover valid enum names for GetEnumValues(enumName: ...).")] + public string ListEnums() + { + var enums = _documentationService.GetAllEnums(); + + if (enums.Count == 0) + { + return "No enums found."; + } + var sb = new StringBuilder(); + sb.AppendLine(CultureInfo.InvariantCulture, $"# Fluent UI Blazor - Enum Types ({enums.Count} enums)"); + sb.AppendLine(); + + foreach (var enumInfo in enums) + { + var description = string.IsNullOrEmpty(enumInfo.Description) ? string.Empty : $" — {enumInfo.Description}"; + sb.AppendLine(CultureInfo.InvariantCulture, $"- **{enumInfo.Name}**{description}"); + } + + sb.AppendLine(); + sb.AppendLine("Use `GetEnumValues(enumName: \"EnumName\")` to see all values for a specific enum."); + + return sb.ToString(); + } } diff --git a/tests/Tools/McpServer.Tests/Tools/ComponentListToolsTests.cs b/tests/Tools/McpServer.Tests/Tools/ComponentListToolsTests.cs index bd59a616e1..65575e566e 100644 --- a/tests/Tools/McpServer.Tests/Tools/ComponentListToolsTests.cs +++ b/tests/Tools/McpServer.Tests/Tools/ComponentListToolsTests.cs @@ -287,4 +287,69 @@ public void Constructor_ShouldInitializeCorrectly() } #endregion + + #region ListCategories Tests + + [Fact] + public void ListCategories_ShouldReturnCategories() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListCategories(); + + // Assert + Assert.False(string.IsNullOrEmpty(result)); + Assert.Contains("# Fluent UI Blazor - Component Categories", result, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ListCategories_ShouldIncludeComponentCounts() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListCategories(); + + // Assert + Assert.Contains("components)", result, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ListCategories_ShouldIncludeUsageHint() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListCategories(); + + // Assert + Assert.Contains("ListComponents", result, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ListCategories_ShouldContainKnownCategory() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListCategories(); + + // Assert + Assert.Contains("Button", result, StringComparison.OrdinalIgnoreCase); + } + + #endregion } diff --git a/tests/Tools/McpServer.Tests/Tools/EnumToolsTests.cs b/tests/Tools/McpServer.Tests/Tools/EnumToolsTests.cs index 8a912a745d..1212df6032 100644 --- a/tests/Tools/McpServer.Tests/Tools/EnumToolsTests.cs +++ b/tests/Tools/McpServer.Tests/Tools/EnumToolsTests.cs @@ -332,4 +332,69 @@ public void Constructor_ShouldInitializeCorrectly() } #endregion + + #region ListEnums Tests + + [Fact] + public void ListEnums_ShouldReturnEnumNames() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListEnums(); + + // Assert + Assert.False(string.IsNullOrEmpty(result)); + Assert.Contains("Appearance", result, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ListEnums_ShouldReturnHeader() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListEnums(); + + // Assert + Assert.Contains("# Fluent UI Blazor - Enum Types", result, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ListEnums_ShouldIncludeUsageHint() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListEnums(); + + // Assert + Assert.Contains("GetEnumValues", result, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void ListEnums_ShouldIncludeCount() + { + Skip.IfNot(_jsonFileExists, "JSON documentation file not found"); + + // Arrange + var tools = CreateTools(); + + // Act + var result = tools.ListEnums(); + + // Assert + Assert.Contains("enums)", result, StringComparison.OrdinalIgnoreCase); + } + + #endregion }