Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/ModelContextProtocol.Core/Protocol/Implementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
25 changes: 25 additions & 0 deletions tests/ModelContextProtocol.Tests/Client/McpClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
[
Expand All @@ -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);
Expand All @@ -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)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"] },
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand All @@ -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"
};
Expand All @@ -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);
}
Expand Down
Loading