diff --git a/src/ModelContextProtocol.Core/Protocol/Implementation.cs b/src/ModelContextProtocol.Core/Protocol/Implementation.cs index 4bf9d5a1..a1242cd5 100644 --- a/src/ModelContextProtocol.Core/Protocol/Implementation.cs +++ b/src/ModelContextProtocol.Core/Protocol/Implementation.cs @@ -37,6 +37,22 @@ public sealed class Implementation : IBaseMetadata [JsonPropertyName("version")] public required string Version { get; set; } + /// + /// Gets or sets an optional description of the implementation. + /// + /// + /// + /// This description helps users and developers understand what the implementation provides + /// and its purpose. It should clearly explain the functionality and capabilities offered. + /// + /// + /// The description is typically used in documentation, UI displays, and for providing context + /// to users about the server or client they are interacting with. + /// + /// + [JsonPropertyName("description")] + public string? Description { get; set; } + /// /// Gets or sets an optional list of icons for this implementation. /// diff --git a/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs b/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs index 2d748468..09be7385 100644 --- a/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs +++ b/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs @@ -34,6 +34,7 @@ protected override void ConfigureServices(ServiceCollection services, IMcpServer { Name = "test-server", Version = "1.0.0", + Description = "A test server for unit testing", WebsiteUrl = "https://example.com", Icons = [ @@ -52,6 +53,7 @@ public async Task CanReadServerInfo() var serverInfo = client.ServerInfo; Assert.Equal("test-server", serverInfo.Name); Assert.Equal("1.0.0", serverInfo.Version); + Assert.Equal("A test server for unit testing", serverInfo.Description); Assert.Equal("https://example.com", serverInfo.WebsiteUrl); Assert.NotNull(serverInfo.Icons); Assert.Equal(2, serverInfo.Icons.Count); @@ -69,6 +71,29 @@ public async Task CanReadServerInfo() Assert.Equal("dark", icon1.Theme); } + [Fact] + public async Task ServerCanReadClientInfo() + { + var clientOptions = new McpClientOptions + { + ClientInfo = new Implementation + { + Name = "test-client", + Version = "2.0.0", + Description = "A test client for validating client-server communication" + } + }; + + await using McpClient client = await CreateMcpClientForServer(clientOptions); + + // Verify the server received the client info with description + var clientInfo = Server.ClientInfo; + Assert.NotNull(clientInfo); + Assert.Equal("test-client", clientInfo.Name); + Assert.Equal("2.0.0", clientInfo.Version); + Assert.Equal("A test client for validating client-server communication", clientInfo.Description); + } + [Theory] [InlineData(null, 10)] [InlineData(0.7f, 50)] diff --git a/tests/ModelContextProtocol.Tests/Protocol/ImplementationTests.cs b/tests/ModelContextProtocol.Tests/Protocol/ImplementationTests.cs index e3fae24f..854ba272 100644 --- a/tests/ModelContextProtocol.Tests/Protocol/ImplementationTests.cs +++ b/tests/ModelContextProtocol.Tests/Protocol/ImplementationTests.cs @@ -14,6 +14,7 @@ public static void Implementation_SerializationRoundTrip_PreservesAllProperties( Name = "test-server", Title = "Test MCP Server", Version = "1.0.0", + Description = "A test MCP server implementation for demonstration purposes", Icons = [ new() { Source = "https://example.com/icon.png", MimeType = "image/png", Sizes = ["48x48"] }, @@ -33,6 +34,7 @@ public static void Implementation_SerializationRoundTrip_PreservesAllProperties( Assert.Equal(original.Name, deserialized.Name); Assert.Equal(original.Title, deserialized.Title); Assert.Equal(original.Version, deserialized.Version); + Assert.Equal(original.Description, deserialized.Description); Assert.Equal(original.WebsiteUrl, deserialized.WebsiteUrl); Assert.NotNull(deserialized.Icons); Assert.Equal(original.Icons.Count, deserialized.Icons.Count); @@ -66,6 +68,7 @@ public static void Implementation_SerializationRoundTrip_WithoutOptionalProperti Assert.Equal(original.Name, deserialized.Name); Assert.Equal(original.Title, deserialized.Title); Assert.Equal(original.Version, deserialized.Version); + Assert.Equal(original.Description, deserialized.Description); Assert.Equal(original.Icons, deserialized.Icons); Assert.Equal(original.WebsiteUrl, deserialized.WebsiteUrl); } @@ -78,6 +81,7 @@ public static void Implementation_HasCorrectJsonPropertyNames() Name = "test-server", Title = "Test Server", Version = "1.0.0", + Description = "Test description", Icons = [new() { Source = "https://example.com/icon.png" }], WebsiteUrl = "https://example.com" }; @@ -87,6 +91,7 @@ public static void Implementation_HasCorrectJsonPropertyNames() Assert.Contains("\"name\":", json); Assert.Contains("\"title\":", json); Assert.Contains("\"version\":", json); + Assert.Contains("\"description\":", json); Assert.Contains("\"icons\":", json); Assert.Contains("\"websiteUrl\":", json); }