diff --git a/src/ModelContextProtocol.Core/Protocol/Icon.cs b/src/ModelContextProtocol.Core/Protocol/Icon.cs
new file mode 100644
index 00000000..b87272ec
--- /dev/null
+++ b/src/ModelContextProtocol.Core/Protocol/Icon.cs
@@ -0,0 +1,75 @@
+using System.Text.Json.Serialization;
+
+namespace ModelContextProtocol.Protocol;
+
+///
+/// Represents an icon that can be used to visually identify an implementation, resource, tool, or prompt.
+///
+///
+///
+/// Icons enhance user interfaces by providing visual context and improving the discoverability of available functionality.
+/// Each icon includes a source URI pointing to the icon resource, and optional MIME type and size information.
+///
+///
+/// Clients that support rendering icons MUST support at least the following MIME types:
+///
+///
+/// image/png - PNG images (safe, universal compatibility)
+/// image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)
+///
+///
+/// Clients that support rendering icons SHOULD also support:
+///
+///
+/// image/svg+xml - SVG images (scalable but requires security precautions)
+/// image/webp - WebP images (modern, efficient format)
+///
+///
+/// See the schema for details.
+///
+///
+public sealed class Icon
+{
+ ///
+ /// Gets or sets the URI pointing to the icon resource.
+ ///
+ ///
+ ///
+ /// This can be an HTTP/HTTPS URL pointing to an image file or a data URI with base64-encoded image data.
+ ///
+ ///
+ /// Consumers SHOULD take steps to ensure URLs serving icons are from the same domain as the client/server
+ /// or a trusted domain.
+ ///
+ ///
+ /// Consumers SHOULD take appropriate precautions when consuming SVGs as they can contain executable JavaScript.
+ ///
+ ///
+ [JsonPropertyName("src")]
+ public required string Source { get; init; }
+
+ ///
+ /// Gets or sets the optional MIME type of the icon.
+ ///
+ ///
+ /// This can be used to override the server's MIME type if it's missing or generic.
+ /// Common values include "image/png", "image/jpeg", "image/svg+xml", and "image/webp".
+ ///
+ [JsonPropertyName("mimeType")]
+ public string? MimeType { get; init; }
+
+ ///
+ /// Gets or sets the optional size specification for the icon.
+ ///
+ ///
+ ///
+ /// This can specify one or more sizes at which the icon file can be used.
+ /// Examples include "48x48", "any" for scalable formats like SVG, or "48x48 96x96" for multiple sizes.
+ ///
+ ///
+ /// If not provided, clients should assume that the icon can be used at any size.
+ ///
+ ///
+ [JsonPropertyName("sizes")]
+ public string? Sizes { get; init; }
+}
\ No newline at end of file
diff --git a/src/ModelContextProtocol.Core/Protocol/Implementation.cs b/src/ModelContextProtocol.Core/Protocol/Implementation.cs
index af177000..76f323b2 100644
--- a/src/ModelContextProtocol.Core/Protocol/Implementation.cs
+++ b/src/ModelContextProtocol.Core/Protocol/Implementation.cs
@@ -36,4 +36,28 @@ public sealed class Implementation : IBaseMetadata
///
[JsonPropertyName("version")]
public required string Version { get; set; }
+
+ ///
+ /// Gets or sets an optional list of icons for this implementation.
+ ///
+ ///
+ /// This can be used by clients to display the implementation in a user interface.
+ ///
+ [JsonPropertyName("icons")]
+ public IList? Icons { get; set; }
+
+ ///
+ /// Gets or sets an optional URL of the website for this implementation.
+ ///
+ ///
+ ///
+ /// This URL can be used by clients to link to documentation or more information about the implementation.
+ ///
+ ///
+ /// Consumers SHOULD take steps to ensure URLs are from the same domain as the client/server
+ /// or a trusted domain to prevent security issues.
+ ///
+ ///
+ [JsonPropertyName("websiteUrl")]
+ public string? WebsiteUrl { get; set; }
}
\ No newline at end of file
diff --git a/src/ModelContextProtocol.Core/Protocol/Prompt.cs b/src/ModelContextProtocol.Core/Protocol/Prompt.cs
index fcd3053f..35c4c470 100644
--- a/src/ModelContextProtocol.Core/Protocol/Prompt.cs
+++ b/src/ModelContextProtocol.Core/Protocol/Prompt.cs
@@ -52,6 +52,15 @@ public sealed class Prompt : IBaseMetadata
[JsonPropertyName("arguments")]
public IList? Arguments { get; set; }
+ ///
+ /// Gets or sets an optional list of icons for this prompt.
+ ///
+ ///
+ /// This can be used by clients to display the prompt's icon in a user interface.
+ ///
+ [JsonPropertyName("icons")]
+ public IList? Icons { get; set; }
+
///
/// Gets or sets metadata reserved by MCP for protocol-level metadata.
///
diff --git a/src/ModelContextProtocol.Core/Protocol/Resource.cs b/src/ModelContextProtocol.Core/Protocol/Resource.cs
index 1b8a0e9c..d8441488 100644
--- a/src/ModelContextProtocol.Core/Protocol/Resource.cs
+++ b/src/ModelContextProtocol.Core/Protocol/Resource.cs
@@ -80,6 +80,15 @@ public sealed class Resource : IBaseMetadata
[JsonPropertyName("size")]
public long? Size { get; init; }
+ ///
+ /// Gets or sets an optional list of icons for this resource.
+ ///
+ ///
+ /// This can be used by clients to display the resource's icon in a user interface.
+ ///
+ [JsonPropertyName("icons")]
+ public IList? Icons { get; set; }
+
///
/// Gets or sets metadata reserved by MCP for protocol-level metadata.
///
diff --git a/src/ModelContextProtocol.Core/Protocol/Tool.cs b/src/ModelContextProtocol.Core/Protocol/Tool.cs
index 1c471669..9365a85a 100644
--- a/src/ModelContextProtocol.Core/Protocol/Tool.cs
+++ b/src/ModelContextProtocol.Core/Protocol/Tool.cs
@@ -107,6 +107,15 @@ public JsonElement? OutputSchema
[JsonPropertyName("annotations")]
public ToolAnnotations? Annotations { get; set; }
+ ///
+ /// Gets or sets an optional list of icons for this tool.
+ ///
+ ///
+ /// This can be used by clients to display the tool's icon in a user interface.
+ ///
+ [JsonPropertyName("icons")]
+ public IList? Icons { get; set; }
+
///
/// Gets or sets metadata reserved by MCP for protocol-level metadata.
///
diff --git a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs
index cb475848..3c75e6f5 100644
--- a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs
+++ b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs
@@ -121,6 +121,7 @@ private static AIFunctionFactoryOptions CreateAIFunctionFactoryOptions(
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 @@ private static McpServerToolCreateOptions DeriveOptions(MethodInfo method, McpSe
newOptions.ReadOnly ??= readOnly;
}
+ if (toolAttr.IconSource is { Length: > 0 } iconSource)
+ {
+ newOptions.Icons ??= [new() { Source = iconSource }];
+ }
+
newOptions.UseStructuredContent = toolAttr.UseStructuredContent;
}
diff --git a/src/ModelContextProtocol.Core/Server/McpServerToolAttribute.cs b/src/ModelContextProtocol.Core/Server/McpServerToolAttribute.cs
index 7d5bf488..9e71e0ea 100644
--- a/src/ModelContextProtocol.Core/Server/McpServerToolAttribute.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServerToolAttribute.cs
@@ -254,4 +254,19 @@ public bool ReadOnly
///
///
public bool UseStructuredContent { get; set; }
+
+ ///
+ /// Gets or sets the source URI for the tool's icon.
+ ///
+ ///
+ ///
+ /// 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.
+ ///
+ ///
+ /// For more advanced icon configuration (multiple icons, MIME type specification, size characteristics),
+ /// use when creating the tool programmatically.
+ ///
+ ///
+ public string? IconSource { get; set; }
}
diff --git a/src/ModelContextProtocol.Core/Server/McpServerToolCreateOptions.cs b/src/ModelContextProtocol.Core/Server/McpServerToolCreateOptions.cs
index d18af8c0..cb4205be 100644
--- a/src/ModelContextProtocol.Core/Server/McpServerToolCreateOptions.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServerToolCreateOptions.cs
@@ -164,6 +164,14 @@ public sealed class McpServerToolCreateOptions
///
public IReadOnlyList