|
| 1 | +// ------------------------------------------------------------------------ |
| 2 | +// This file is licensed to you under the MIT License. |
| 3 | +// ------------------------------------------------------------------------ |
| 4 | + |
| 5 | +using System.ComponentModel; |
| 6 | +using System.Text; |
| 7 | +using Microsoft.FluentUI.AspNetCore.Components.McpServer.Services; |
| 8 | +using Microsoft.Extensions.AI; |
| 9 | +using ModelContextProtocol.Server; |
| 10 | + |
| 11 | +namespace Microsoft.FluentUI.AspNetCore.Components.McpServer.Prompts; |
| 12 | + |
| 13 | +/// <summary> |
| 14 | +/// MCP Prompt for checking version compatibility between NuGet package and MCP Server. |
| 15 | +/// </summary> |
| 16 | +[McpServerPromptType] |
| 17 | +public class CheckVersionCompatibilityPrompt |
| 18 | +{ |
| 19 | + private readonly FluentUIDocumentationService _documentationService; |
| 20 | + |
| 21 | + /// <summary> |
| 22 | + /// Initializes a new instance of the <see cref="CheckVersionCompatibilityPrompt"/> class. |
| 23 | + /// </summary> |
| 24 | + public CheckVersionCompatibilityPrompt(FluentUIDocumentationService documentationService) |
| 25 | + { |
| 26 | + _documentationService = documentationService; |
| 27 | + } |
| 28 | + |
| 29 | + [McpServerPrompt(Name = "check_version_compatibility")] |
| 30 | + [Description("Check if the installed Fluent UI Blazor NuGet package version is compatible with this MCP Server.")] |
| 31 | + public ChatMessage CheckVersionCompatibility( |
| 32 | + [Description("The version of Microsoft.FluentUI.AspNetCore.Components currently installed in the project (e.g., '5.0.0', '4.10.3')")] string installedVersion) |
| 33 | + { |
| 34 | + var expectedVersion = _documentationService.ComponentsVersion; |
| 35 | + var mcpServerVersion = FluentUIDocumentationService.McpServerVersion; |
| 36 | + var generatedDate = _documentationService.DocumentationGeneratedDate; |
| 37 | + |
| 38 | + var sb = new StringBuilder(); |
| 39 | + sb.AppendLine("# Fluent UI Blazor Version Compatibility Check"); |
| 40 | + sb.AppendLine(); |
| 41 | + |
| 42 | + sb.AppendLine("## Version Information"); |
| 43 | + sb.AppendLine(); |
| 44 | + sb.AppendLine($"| Component | Version |"); |
| 45 | + sb.AppendLine($"|-----------|---------|"); |
| 46 | + sb.AppendLine($"| **MCP Server** | {mcpServerVersion} |"); |
| 47 | + sb.AppendLine($"| **Expected Components Version** | {expectedVersion} |"); |
| 48 | + sb.AppendLine($"| **Your Installed Version** | {installedVersion} |"); |
| 49 | + sb.AppendLine($"| **Documentation Generated** | {generatedDate} |"); |
| 50 | + sb.AppendLine(); |
| 51 | + |
| 52 | + // Parse versions for comparison |
| 53 | + _ = CheckVersionCompatibilityInternal(installedVersion, expectedVersion, out var compatibilityLevel); |
| 54 | + |
| 55 | + switch (compatibilityLevel) |
| 56 | + { |
| 57 | + case VersionCompatibility.Exact: |
| 58 | + sb.AppendLine("## ✅ Perfect Match"); |
| 59 | + sb.AppendLine(); |
| 60 | + sb.AppendLine("Your installed version matches exactly with this MCP Server's documentation."); |
| 61 | + sb.AppendLine("All component information, parameters, and examples will be accurate."); |
| 62 | + break; |
| 63 | + |
| 64 | + case VersionCompatibility.MinorDifference: |
| 65 | + sb.AppendLine("## ⚠️ Minor Version Difference"); |
| 66 | + sb.AppendLine(); |
| 67 | + sb.AppendLine("Your installed version has a different minor or patch version."); |
| 68 | + sb.AppendLine("Most documentation should be accurate, but some new features or changes may not be reflected."); |
| 69 | + sb.AppendLine(); |
| 70 | + sb.AppendLine("### Recommendations:"); |
| 71 | + sb.AppendLine($"- Consider upgrading to version **{expectedVersion}** for full compatibility"); |
| 72 | + sb.AppendLine("- Or update the MCP Server to match your installed version"); |
| 73 | + break; |
| 74 | + |
| 75 | + case VersionCompatibility.MajorDifference: |
| 76 | + sb.AppendLine("## ❌ Major Version Mismatch"); |
| 77 | + sb.AppendLine(); |
| 78 | + sb.AppendLine("**Warning**: Your installed version has a different major version."); |
| 79 | + sb.AppendLine("There may be significant breaking changes, removed components, or new APIs not covered by this documentation."); |
| 80 | + sb.AppendLine(); |
| 81 | + sb.AppendLine("### Required Actions:"); |
| 82 | + sb.AppendLine($"1. **Upgrade your NuGet package** to version **{expectedVersion}**:"); |
| 83 | + sb.AppendLine(" ```shell"); |
| 84 | + sb.AppendLine($" dotnet add package Microsoft.FluentUI.AspNetCore.Components --version {expectedVersion}"); |
| 85 | + sb.AppendLine(" ```"); |
| 86 | + sb.AppendLine(); |
| 87 | + sb.AppendLine("2. **Or update the MCP Server** to match your installed version:"); |
| 88 | + sb.AppendLine(" ```shell"); |
| 89 | + sb.AppendLine($" dotnet tool update --global Microsoft.FluentUI.AspNetCore.Components.McpServer --version {installedVersion}"); |
| 90 | + sb.AppendLine(" ```"); |
| 91 | + break; |
| 92 | + |
| 93 | + default: |
| 94 | + sb.AppendLine("## ⚠️ Unable to Determine Compatibility"); |
| 95 | + sb.AppendLine(); |
| 96 | + sb.AppendLine("Could not parse the version numbers for comparison."); |
| 97 | + sb.AppendLine($"Please verify you're using version **{expectedVersion}** of Microsoft.FluentUI.AspNetCore.Components."); |
| 98 | + break; |
| 99 | + } |
| 100 | + |
| 101 | + sb.AppendLine(); |
| 102 | + sb.AppendLine("## Task"); |
| 103 | + sb.AppendLine(); |
| 104 | + sb.AppendLine("Based on the version compatibility check above:"); |
| 105 | + sb.AppendLine($"1. Explain any potential issues with using version {installedVersion} when the MCP documentation is for version {expectedVersion}"); |
| 106 | + sb.AppendLine("2. If there are breaking changes between these versions, list them"); |
| 107 | + sb.AppendLine("3. Provide migration guidance if an upgrade is recommended"); |
| 108 | + sb.AppendLine("4. Suggest the best course of action for the user"); |
| 109 | + |
| 110 | + return new ChatMessage(ChatRole.User, sb.ToString()); |
| 111 | + } |
| 112 | + |
| 113 | + /// <summary> |
| 114 | + /// Checks version compatibility and returns the level of compatibility. |
| 115 | + /// </summary> |
| 116 | + private static bool CheckVersionCompatibilityInternal(string installedVersion, string expectedVersion, out VersionCompatibility level) |
| 117 | + { |
| 118 | + level = VersionCompatibility.Unknown; |
| 119 | + |
| 120 | + // Clean versions (remove any prerelease suffixes for comparison) |
| 121 | + var installedClean = CleanVersion(installedVersion); |
| 122 | + var expectedClean = CleanVersion(expectedVersion); |
| 123 | + |
| 124 | + if (!Version.TryParse(installedClean, out var installed) || |
| 125 | + !Version.TryParse(expectedClean, out var expected)) |
| 126 | + { |
| 127 | + return false; |
| 128 | + } |
| 129 | + |
| 130 | + // Exact match |
| 131 | + if (installed.Major == expected.Major && |
| 132 | + installed.Minor == expected.Minor && |
| 133 | + installed.Build == expected.Build) |
| 134 | + { |
| 135 | + level = VersionCompatibility.Exact; |
| 136 | + return true; |
| 137 | + } |
| 138 | + |
| 139 | + // Same major version |
| 140 | + if (installed.Major == expected.Major) |
| 141 | + { |
| 142 | + level = VersionCompatibility.MinorDifference; |
| 143 | + return true; |
| 144 | + } |
| 145 | + |
| 146 | + // Different major version |
| 147 | + level = VersionCompatibility.MajorDifference; |
| 148 | + return false; |
| 149 | + } |
| 150 | + |
| 151 | + /// <summary> |
| 152 | + /// Cleans a version string by removing prerelease suffixes. |
| 153 | + /// </summary> |
| 154 | + private static string CleanVersion(string version) |
| 155 | + { |
| 156 | + if (string.IsNullOrEmpty(version)) |
| 157 | + { |
| 158 | + return "0.0.0"; |
| 159 | + } |
| 160 | + |
| 161 | + // Remove prerelease suffix (e.g., "-preview.1", "-rc.2", "-beta") |
| 162 | + var dashIndex = version.IndexOf('-'); |
| 163 | + if (dashIndex > 0) |
| 164 | + { |
| 165 | + version = version[..dashIndex]; |
| 166 | + } |
| 167 | + |
| 168 | + // Ensure we have at least 3 parts |
| 169 | + var parts = version.Split('.'); |
| 170 | + if (parts.Length < 3) |
| 171 | + { |
| 172 | + version = string.Join(".", parts.Concat(Enumerable.Repeat("0", 3 - parts.Length))); |
| 173 | + } |
| 174 | + |
| 175 | + return version; |
| 176 | + } |
| 177 | + |
| 178 | + private enum VersionCompatibility |
| 179 | + { |
| 180 | + Unknown, |
| 181 | + Exact, |
| 182 | + MinorDifference, |
| 183 | + MajorDifference |
| 184 | + } |
| 185 | +} |
0 commit comments