Implement SEP-973: Icons and metadata support for Implementations, Resources, Tools, and Prompts (#802)
* Initial plan * Initial plan for SEP-973 implementation Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Implement SEP-973: Add Icon class and icon support to Implementation, Resource, Tool, and Prompt Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Complete SEP-973 implementation with documentation and fix property consistency Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Address code review feedback: improve tests, remove docs, split test files Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Fix tests to use S.T.J. source generator * Styling fixes * Simplify Icons property documentation as suggested in code review Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Rename Icon.Src property to Icon.Source for more .NET-y naming Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Add icon support to McpServerTool infrastructure and attributes Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Cleanup * Refactor icon tests to use Delegate overload instead of MethodInfo pattern Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Change Icon.Sizes property from string to IList<string> per spec update Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Add icon support to Prompts and Resources (CreateOptions and Attributes) Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Add client-server integration tests for Icons and WebsiteUrl Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> * Fix nullability warnings * Revert "Add client-server integration tests for Icons and WebsiteUrl" This reverts commit f37de15569e54e86a0709121c9bdf80c5045511c. * More nullability fixes * Add more tests * Address code review feedback: add Theme property, fix docs, improve test patterns Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Update Icon tests to exercise Theme property Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Add Theme property assertions to client-server integration tests Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> * Fix nullability --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com> Co-authored-by: jozkee <16040868+jozkee@users.noreply.github.com> Co-authored-by: David Cantú <dacantu@microsoft.com>
This commit is contained in:
parent
a0049c7a3c
commit
f28639119b
9 changed files with 982 additions and 8 deletions
|
|
@ -135,6 +135,7 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
|||
Title = options?.Title,
|
||||
Description = options?.Description ?? function.Description,
|
||||
Arguments = args,
|
||||
Icons = options?.Icons,
|
||||
};
|
||||
|
||||
return new AIFunctionMcpServerPrompt(function, prompt, options?.Metadata ?? []);
|
||||
|
|
@ -148,6 +149,12 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
|||
{
|
||||
newOptions.Name ??= promptAttr.Name;
|
||||
newOptions.Title ??= promptAttr.Title;
|
||||
|
||||
// Handle icon from attribute if not already specified in options
|
||||
if (newOptions.Icons is null && promptAttr.IconSource is { Length: > 0 } iconSource)
|
||||
{
|
||||
newOptions.Icons = [new() { Source = iconSource }];
|
||||
}
|
||||
}
|
||||
|
||||
if (method.GetCustomAttribute<DescriptionAttribute>() is { } descAttr)
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
|
|||
Title = options?.Title,
|
||||
Description = options?.Description,
|
||||
MimeType = options?.MimeType ?? "application/octet-stream",
|
||||
Icons = options?.Icons,
|
||||
};
|
||||
|
||||
return new AIFunctionMcpServerResource(function, resource, options?.Metadata ?? []);
|
||||
|
|
@ -233,6 +234,12 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
|
|||
newOptions.Name ??= resourceAttr.Name;
|
||||
newOptions.Title ??= resourceAttr.Title;
|
||||
newOptions.MimeType ??= resourceAttr.MimeType;
|
||||
|
||||
// Handle icon from attribute if not already specified in options
|
||||
if (newOptions.Icons is null && resourceAttr.IconSource is { Length: > 0 } iconSource)
|
||||
{
|
||||
newOptions.Icons = [new() { Source = iconSource }];
|
||||
}
|
||||
}
|
||||
|
||||
if (member.GetCustomAttribute<DescriptionAttribute>() is { } descAttr)
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ internal sealed partial class AIFunctionMcpServerTool : McpServerTool
|
|||
Description = options?.Description ?? function.Description,
|
||||
InputSchema = function.JsonSchema,
|
||||
OutputSchema = CreateOutputSchema(function, options, out bool structuredOutputRequiresWrapping),
|
||||
Icons = options?.Icons,
|
||||
};
|
||||
|
||||
if (options is not null)
|
||||
|
|
@ -176,6 +177,11 @@ internal sealed partial class AIFunctionMcpServerTool : McpServerTool
|
|||
newOptions.ReadOnly ??= readOnly;
|
||||
}
|
||||
|
||||
if (newOptions.Icons is null && toolAttr.IconSource is { Length: > 0 } iconSource)
|
||||
{
|
||||
newOptions.Icons = [new() { Source = iconSource }];
|
||||
}
|
||||
|
||||
newOptions.UseStructuredContent = toolAttr.UseStructuredContent;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,4 +120,19 @@ public sealed class McpServerPromptAttribute : Attribute
|
|||
|
||||
/// <summary>Gets or sets the title of the prompt.</summary>
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the source URI for the prompt's icon.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This can be an HTTP/HTTPS URL pointing to an image file or a data URI with base64-encoded image data.
|
||||
/// When specified, a single icon will be added to the prompt.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For more advanced icon configuration (multiple icons, MIME type specification, size characteristics),
|
||||
/// use <see cref="McpServerPromptCreateOptions.Icons"/> when creating the prompt programmatically.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public string? IconSource { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.Extensions.AI;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json;
|
||||
|
||||
|
|
@ -77,6 +78,14 @@ public sealed class McpServerPromptCreateOptions
|
|||
/// </remarks>
|
||||
public IReadOnlyList<object>? Metadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icons for this prompt.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be used by clients to display the prompt's icon in a user interface.
|
||||
/// </remarks>
|
||||
public IList<Icon>? Icons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow clone of the current <see cref="McpServerPromptCreateOptions"/> instance.
|
||||
/// </summary>
|
||||
|
|
@ -90,5 +99,6 @@ public sealed class McpServerPromptCreateOptions
|
|||
SerializerOptions = SerializerOptions,
|
||||
SchemaCreateOptions = SchemaCreateOptions,
|
||||
Metadata = Metadata,
|
||||
Icons = Icons,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,4 +135,19 @@ public sealed class McpServerResourceAttribute : Attribute
|
|||
|
||||
/// <summary>Gets or sets the MIME (media) type of the resource.</summary>
|
||||
public string? MimeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the source URI for the resource's icon.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This can be an HTTP/HTTPS URL pointing to an image file or a data URI with base64-encoded image data.
|
||||
/// When specified, a single icon will be added to the resource.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For more advanced icon configuration (multiple icons, MIME type specification, size characteristics),
|
||||
/// use <see cref="McpServerResourceCreateOptions.Icons"/> when creating the resource programmatically.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public string? IconSource { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.Extensions.AI;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json;
|
||||
|
||||
|
|
@ -92,6 +93,14 @@ public sealed class McpServerResourceCreateOptions
|
|||
/// </remarks>
|
||||
public IReadOnlyList<object>? Metadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icons for this resource.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be used by clients to display the resource's icon in a user interface.
|
||||
/// </remarks>
|
||||
public IList<Icon>? Icons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow clone of the current <see cref="McpServerResourceCreateOptions"/> instance.
|
||||
/// </summary>
|
||||
|
|
@ -107,5 +116,6 @@ public sealed class McpServerResourceCreateOptions
|
|||
SerializerOptions = SerializerOptions,
|
||||
SchemaCreateOptions = SchemaCreateOptions,
|
||||
Metadata = Metadata,
|
||||
Icons = Icons,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,4 +254,19 @@ public sealed class McpServerToolAttribute : Attribute
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public bool UseStructuredContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the source URI for the tool's icon.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This can be an HTTP/HTTPS URL pointing to an image file or a data URI with base64-encoded image data.
|
||||
/// When specified, a single icon will be added to the tool.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For more advanced icon configuration (multiple icons, MIME type specification, size characteristics),
|
||||
/// use <see cref="McpServerToolCreateOptions.Icons"/> when creating the tool programmatically.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public string? IconSource { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,14 @@ public sealed class McpServerToolCreateOptions
|
|||
/// </remarks>
|
||||
public IReadOnlyList<object>? Metadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icons for this tool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be used by clients to display the tool's icon in a user interface.
|
||||
/// </remarks>
|
||||
public IList<Icon>? Icons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow clone of the current <see cref="McpServerToolCreateOptions"/> instance.
|
||||
/// </summary>
|
||||
|
|
@ -182,5 +190,6 @@ public sealed class McpServerToolCreateOptions
|
|||
SerializerOptions = SerializerOptions,
|
||||
SchemaCreateOptions = SchemaCreateOptions,
|
||||
Metadata = Metadata,
|
||||
Icons = Icons,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue