Add Description property to Implementation type per MCP spec (#966)

* Initial plan

* Add Description property to Implementation type

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>

* Add test to validate client Description from server perspective

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
This commit is contained in:
Copilot 2025-11-17 10:42:40 -05:00 • committed by GitHub
commit 00bb5b2678
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 0 deletions

View file

@ -37,6 +37,22 @@ public sealed class Implementation : IBaseMetadata
[JsonPropertyName("version")]
public required string Version { get; set; }
/// <summary>
/// Gets or sets an optional description of the implementation.
/// </summary>
/// <remarks>
/// <para>
/// This description helps users and developers understand what the implementation provides
/// and its purpose. It should clearly explain the functionality and capabilities offered.
/// </para>
/// <para>
/// The description is typically used in documentation, UI displays, and for providing context
/// to users about the server or client they are interacting with.
/// </para>
/// </remarks>
[JsonPropertyName("description")]
public string? Description { get; set; }
/// <summary>
/// Gets or sets an optional list of icons for this implementation.
/// </summary>

View file

@ -34,6 +34,7 @@ public class McpClientTests : ClientServerTestBase
{
Name = "test-server",
Version = "1.0.0",
Description = "A test server for unit testing",
WebsiteUrl = "https://example.com",
Icons =
[
@ -52,6 +53,7 @@ public class McpClientTests : ClientServerTestBase
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 class McpClientTests : ClientServerTestBase
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)]

View file

@ -14,6 +14,7 @@ public static class ImplementationTests
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 class ImplementationTests
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 class ImplementationTests
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 class ImplementationTests
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 class ImplementationTests
Assert.Contains("\"name\":", json);
Assert.Contains("\"title\":", json);
Assert.Contains("\"version\":", json);
Assert.Contains("\"description\":", json);
Assert.Contains("\"icons\":", json);
Assert.Contains("\"websiteUrl\":", json);
}