Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Sep 19, 2025

SEP-973: Icons and metadata support implementation

This PR implements SEP-973 which adds support for icons and additional metadata for Implementations, Resources, Tools, and Prompts.

Implementation Plan

  • Review and understand SEP-973 specification requirements
  • Understand current codebase structure and build system
  • Create Icon class with Source, MimeType, Sizes, and Theme properties
  • Add Icons property to Implementation class
  • Add WebsiteUrl property to Implementation class
  • Add Icons property to Resource class
  • Add Icons property to Tool class
  • Add Icons property to Prompt class
  • Create comprehensive tests for Icon validation and serialization
  • Create tests for all updated classes with icon support
  • Fix property accessor consistency across classes
  • Address code review feedback and improve test patterns
  • Simplify XML documentation for Icons properties
  • Rename Icon.Src to Icon.Source for .NET naming conventions
  • Add icon support to server tooling infrastructure (Tools, Prompts, and Resources)
  • Refactor tests to use established patterns
  • Update Icon.Sizes to IList per spec update
  • Add Theme property to Icon per spec update (PR #1584)
  • Consolidate duplicate tests and improve test patterns
  • Add client-server integration tests for Icons and WebsiteUrl
  • Update existing Icon tests to exercise Theme property
  • Add Theme property assertions to all client-server integration tests

Recent Changes (Addressing Latest Code Review Feedback)

  • Added Theme property: Added optional Theme property to Icon class per specification update (PR #1584)
  • Fixed documentation consistency: Updated XML documentation for Icons properties across Implementation, Resource, ResourceTemplate, Tool, and Prompt
  • Improved test assertions: Changed from multi-line assertions to Assert.Single() pattern for cleaner, more idiomatic tests
  • Consolidated icon handling: Made AIFunctionMcpServerTool icon handling consistent with Prompt and Resource patterns
  • Merged duplicate tests: Consolidated TitleAttributeProperty_PropagatedToTitle and IconSourceAttributeProperty_PropagatedToIcons tests into single AttributeProperties_Propagated tests
  • Updated tests for Theme: Modified existing Icon tests to exercise the new Theme property in serialization, deserialization, and JSON property name validation
  • Enhanced integration tests: Added Theme property assertions to client-server tests for Implementation, Tool, Prompt, Resource, and ResourceTemplate

Key Changes Implemented

1. New Icon Class (Icon.cs)

  • Required: Source property for URI pointing to icon resource (serialized as "src" in JSON)
  • Optional: MimeType, Sizes, and Theme properties
  • Sizes: IList<string>? to support multiple size specifications (e.g., ["48x48", "96x96"])
  • Theme: string? to specify UI theme ("light", "dark", or custom identifiers)
  • Supports HTTP/HTTPS URLs and data URIs
  • Comprehensive security documentation per SEP-973
  • Uses init-only properties for immutability
  • Follows .NET naming conventions with Source property

2. Enhanced Classes with Icon Support

  • Implementation: Added Icons and WebsiteUrl properties
  • Resource: Added Icons property
  • ResourceTemplate: Added Icons property
  • Tool: Added Icons property
  • Prompt: Added Icons property

3. Server-Side Tooling Integration

Tools:

  • McpServerToolCreateOptions: Added Icons property for programmatic multi-icon configuration
  • McpServerToolAttribute: Added IconSource property for simple attribute-based single-icon configuration
  • AIFunctionMcpServerTool: Enhanced to handle icon properties from both options and attributes with proper precedence

Prompts:

  • McpServerPromptCreateOptions: Added Icons property for programmatic multi-icon configuration
  • McpServerPromptAttribute: Added IconSource property for simple attribute-based single-icon configuration
  • AIFunctionMcpServerPrompt: Enhanced to handle icon properties from both options and attributes with proper precedence

Resources:

  • McpServerResourceCreateOptions: Added Icons property for programmatic multi-icon configuration
  • McpServerResourceAttribute: Added IconSource property for simple attribute-based single-icon configuration
  • AIFunctionMcpServerResource: Enhanced to handle icon properties from both options and attributes with proper precedence

Common Features:

  • Flexible Configuration: Attributes provide basic support; options provide full multi-icon capabilities
  • Precedence Rules: CreateOptions.Icons takes precedence over attribute IconSource for maximum control across all entity types
  • Consistent patterns: All three types (Tools, Prompts, Resources) follow the same implementation pattern

4. Specification Compliance

✅ Matches TypeScript schema exactly
✅ Correct JSON property names (icons, websiteUrl, src, mimeType, sizes, theme)
✅ All new properties are optional for backward compatibility
✅ Supports multiple icons per entity
✅ Supports multiple size specifications per icon (as string array)
✅ Supports theme specification per icon (light, dark, or custom)
✅ Documents required (PNG, JPEG) and recommended (SVG, WebP) MIME types
✅ Includes security considerations for SVG and URI validation
✅ Uses .NET naming conventions while preserving JSON compatibility

5. Comprehensive Test Coverage

  • IconTests.cs: Icon serialization, round-trip validation, JsonException tests, and Theme property validation
  • ImplementationTests.cs: Full Implementation testing with required property validation
  • ToolTests.cs: Tool functionality testing including new icon support
  • ResourceTests.cs: Resource serialization and property validation
  • PromptTests.cs: Prompt functionality testing
  • McpServerToolTests.cs: Server-side Tool icon support using idiomatic test patterns
  • McpServerPromptTests.cs: Server-side Prompt icon support via options and attributes
  • McpServerResourceTests.cs: Server-side Resource icon support via options and attributes
  • Configuration integration tests (all include Theme assertions):
    • McpServerBuilderExtensionsToolsTests: Client-server test verifying tool icons retrieval and attribute propagation
    • McpServerBuilderExtensionsPromptsTests: Client-server test verifying prompt icons retrieval and attribute propagation
    • McpServerBuilderExtensionsResourcesTests: Client-server test verifying resource and resource template icons retrieval and attribute propagation
    • McpClientTests: Verifies server Implementation icons with Theme values and WebsiteUrl
  • All tests follow existing repository patterns with idiomatic assertions
  • Tests use Assert.Single() pattern for cleaner assertions
  • Tests validate JsonException behavior for invalid JSON
  • Tests cover all properties including Theme across all entity types
  • Consolidated tests reduce duplication and improve maintainability

Usage Examples

Simple Attribute-Based Icon Configuration:

For Tools:

McpServerTool.Create([McpServerTool(IconSource = "https://example.com/icon.png")] () => "result");

For Prompts:

McpServerPrompt.Create([McpServerPrompt(IconSource = "https://example.com/icon.png")] () => "prompt result");

For Resources:

McpServerResource.Create([McpServerResource(UriTemplate = "resource://example", IconSource = "https://example.com/icon.png")] () => "resource content");

Advanced Multi-Icon Configuration with Theme:

var tool = McpServerTool.Create(() => "result", new McpServerToolCreateOptions
{
    Icons = new List<Icon>
    {
        new() { Source = "https://example.com/icon-light.png", MimeType = "image/png", Sizes = new List<string> { "48x48", "96x96" }, Theme = "light" },
        new() { Source = "https://example.com/icon-dark.svg", MimeType = "image/svg+xml", Sizes = new List<string> { "any" }, Theme = "dark" }
    }
});

Server Implementation with Icons and WebsiteUrl:

services.AddMcpServer(options =>
{
    options.ServerInfo = new Implementation
    {
        Name = "my-server",
        Version = "1.0.0",
        Icons = new List<Icon>
        {
            new() { Source = "https://example.com/icon.png", MimeType = "image/png", Sizes = new List<string> { "64x64" }, Theme = "light" }
        },
        WebsiteUrl = "https://example.com/docs"
    };
});

Technical Details

  • Uses IList<Icon>? for consistency with existing collection patterns
  • Uses IList<string>? for Icon.Sizes to support multiple size specifications per the updated spec
  • Uses string? for Icon.Theme to support theme identifiers
  • Proper JSON serialization with JsonPropertyName attributes
  • Follows existing codebase conventions and patterns
  • All optional properties use nullable types
  • Test classes follow established naming and structure patterns
  • Concise XML documentation that focuses on essential information
  • .NET-style property naming with JSON compatibility via attributes
  • Server tooling integration maintains existing patterns and precedence rules for Tools, Prompts, and Resources
  • Tests use idiomatic patterns (Assert.Single, consolidated tests)
  • Integration tests verify end-to-end functionality from client to server
  • All existing tests updated to exercise Theme property across all entity types

Security Features

Implementation includes documentation for:

  • URI validation and trusted domain requirements
  • SVG security precautions (executable JavaScript content)
  • Resource exhaustion protection recommendations
  • MIME type validation guidelines

Note: Build validation requires .NET 9 SDK. The implementation follows established patterns and should compile correctly with the appropriate SDK version.

Fixes #753.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copy link
Contributor Author

Copilot AI commented Sep 19, 2025

@MackinnonBuck 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

@Copilot Copilot AI changed the title [WIP] Implement SEP-973: Icons and metadata support Implement SEP-973: Icons and metadata support for Implementations, Resources, Tools, and Prompts Sep 19, 2025
@Copilot Copilot AI requested a review from MackinnonBuck September 19, 2025 21:31
Copilot finished work on behalf of MackinnonBuck September 19, 2025 21:31
@Copilot Copilot AI requested a review from MackinnonBuck September 19, 2025 22:22
Copilot finished work on behalf of MackinnonBuck September 19, 2025 22:22
@MackinnonBuck MackinnonBuck marked this pull request as ready for review September 19, 2025 23:24
@Copilot Copilot AI requested a review from MackinnonBuck September 23, 2025 17:00
Copilot finished work on behalf of MackinnonBuck September 23, 2025 17:00
Copilot finished work on behalf of MackinnonBuck October 1, 2025 18:26
Copilot finished work on behalf of jozkee October 7, 2025 20:48
@Copilot Copilot AI requested a review from jozkee October 7, 2025 20:48
Copilot finished work on behalf of jozkee October 7, 2025 20:50
Copilot finished work on behalf of jozkee October 7, 2025 21:02
Copilot finished work on behalf of jozkee October 7, 2025 21:17
@jozkee
Copy link
Collaborator

jozkee commented Oct 8, 2025

The test failure seems unrelated and non-deterministic since it only failed in macOS release:

Failed ModelContextProtocol.AspNetCore.Tests.MapMcpStatelessTests.StreamableHttpClient_SendsMcpProtocolVersionHeader_AfterInitialization [460 ms]
  Error Message:
   Assert.Equal() Failure: Values differ
Expected: 3
Actual:   2
  Stack Trace:
     at ModelContextProtocol.AspNetCore.Tests.MapMcpStreamableHttpTests.StreamableHttpClient_SendsMcpProtocolVersionHeader_AfterInitialization() in /_/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs:line 186
   at ModelContextProtocol.AspNetCore.Tests.MapMcpStreamableHttpTests.StreamableHttpClient_SendsMcpProtocolVersionHeader_AfterInitialization() in /_/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs:line 187
   at ModelContextProtocol.AspNetCore.Tests.MapMcpStreamableHttpTests.StreamableHttpClient_SendsMcpProtocolVersionHeader_AfterInitialization() in /_/tests/ModelContextProtocol.AspNetCore.Tests/MapMcpStreamableHttpTests.cs:line 187

@halter73 maybe related to #760?

@MackinnonBuck MackinnonBuck merged commit f286391 into main Oct 8, 2025
16 of 17 checks passed
@MackinnonBuck MackinnonBuck deleted the copilot/fix-753 branch October 8, 2025 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement SEP-973: Icons and metadata support

4 participants