Skip to content
Open
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
107 changes: 98 additions & 9 deletions mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -610,16 +610,38 @@ public ServerCapabilities build() {
* past specs or fallback (if title isn't present).
* @param title Intended for UI and end-user contexts
* @param version The version of the implementation.
* @param icons Optional list of icons that can be used to visually represent this
* implementation in client UIs. Multiple icons can be provided for different sizes
* and formats.
* @param websiteUrl Optional URL to the website or documentation for this
* implementation.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Implementation( // @formatter:off
@JsonProperty("name") String name,
@JsonProperty("title") String title,
@JsonProperty("version") String version) implements Identifier { // @formatter:on
@JsonProperty("version") String version,
@JsonProperty("icons") List<Icon> icons,
@JsonProperty("websiteUrl") String websiteUrl) implements Identifier { // @formatter:on

/**
* Creates an Implementation with just name and version.
* @param name The implementation name
* @param version The implementation version
*/
public Implementation(String name, String version) {
this(name, null, version);
this(name, null, version, null, null);
}

/**
* Creates an Implementation with name, title, and version.
* @param name The implementation name
* @param title The display title
* @param version The implementation version
*/
public Implementation(String name, String title, String version) {
this(name, title, version, null, null);
}
}

Expand Down Expand Up @@ -713,6 +735,50 @@ public interface Identifier {

}

/**
* Represents an icon that can be used to visually identify servers, tools, resources,
* or prompts in client UIs.
*
* <p>
* Icons can be provided as HTTP/HTTPS URLs or as data URIs containing base64-encoded
* image data. Clients should display icons at appropriate sizes based on their UI
* context.
*
* @param src The URI of the icon. Can be an HTTP/HTTPS URL or a data URI (e.g.,
* "data:image/png;base64,...").
* @param mimeType Optional MIME type of the icon (e.g., "image/png",
* "image/svg+xml"). If not provided, clients should infer the type from the URI or
* content.
* @param sizes Optional size specification following Web Manifest format. Can be a
* single size (e.g., "48x48"), multiple sizes separated by spaces (e.g., "48x48
* 96x96"), or "any" for scalable formats like SVG.
* @see <a href=
* "https://spec.modelcontextprotocol.io/specification/2025-06-18/base-protocol/#icons">MCP
* Icons Specification</a>
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Icon( // @formatter:off
@JsonProperty("src") String src,
@JsonProperty("mimeType") String mimeType,
@JsonProperty("sizes") String sizes) { // @formatter:on

/**
* Creates an Icon with just a source URL.
* @param src The URI of the icon
*/
public Icon(String src) {
this(src, null, null);
}

/**
* Canonical constructor with validation.
*/
public Icon {
Assert.hasText(src, "Icon src must not be null or empty");
}
}

/**
* A known resource that the server is capable of reading.
*
Expand All @@ -729,6 +795,8 @@ public interface Identifier {
* sizes and estimate context window usage.
* @param annotations Optional annotations for the client. The client can use
* annotations to inform how objects are used or displayed.
* @param icons Optional list of icons that can be used to visually represent this
* resource in client UIs.
* @param meta See specification for notes on _meta usage
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
Expand All @@ -741,6 +809,7 @@ public record Resource( // @formatter:off
@JsonProperty("mimeType") String mimeType,
@JsonProperty("size") Long size,
@JsonProperty("annotations") Annotations annotations,
@JsonProperty("icons") List<Icon> icons,
@JsonProperty("_meta") Map<String, Object> meta) implements ResourceContent { // @formatter:on

/**
Expand All @@ -750,7 +819,7 @@ public record Resource( // @formatter:off
@Deprecated
public Resource(String uri, String name, String title, String description, String mimeType, Long size,
Annotations annotations) {
this(uri, name, title, description, mimeType, size, annotations, null);
this(uri, name, title, description, mimeType, size, annotations, null, null);
}

/**
Expand All @@ -760,7 +829,7 @@ public Resource(String uri, String name, String title, String description, Strin
@Deprecated
public Resource(String uri, String name, String description, String mimeType, Long size,
Annotations annotations) {
this(uri, name, null, description, mimeType, size, annotations, null);
this(uri, name, null, description, mimeType, size, annotations, null, null);
}

/**
Expand All @@ -769,7 +838,7 @@ public Resource(String uri, String name, String description, String mimeType, Lo
*/
@Deprecated
public Resource(String uri, String name, String description, String mimeType, Annotations annotations) {
this(uri, name, null, description, mimeType, null, annotations, null);
this(uri, name, null, description, mimeType, null, annotations, null, null);
}

public static Builder builder() {
Expand All @@ -792,6 +861,8 @@ public static class Builder {

private Annotations annotations;

private List<Icon> icons;

private Map<String, Object> meta;

public Builder uri(String uri) {
Expand Down Expand Up @@ -829,6 +900,11 @@ public Builder annotations(Annotations annotations) {
return this;
}

public Builder icons(List<Icon> icons) {
this.icons = icons;
return this;
}

public Builder meta(Map<String, Object> meta) {
this.meta = meta;
return this;
Expand All @@ -838,7 +914,7 @@ public Resource build() {
Assert.hasText(uri, "uri must not be empty");
Assert.hasText(name, "name must not be empty");

return new Resource(uri, name, title, description, mimeType, size, annotations, meta);
return new Resource(uri, name, title, description, mimeType, size, annotations, icons, meta);
}

}
Expand Down Expand Up @@ -1137,6 +1213,8 @@ public BlobResourceContents(String uri, String mimeType, String blob) {
* @param title An optional title for the prompt.
* @param description An optional description of what this prompt provides.
* @param arguments A list of arguments to use for templating the prompt.
* @param icons Optional list of icons that can be used to visually represent this
* prompt in client UIs.
* @param meta See specification for notes on _meta usage
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
Expand All @@ -1146,14 +1224,15 @@ public record Prompt( // @formatter:off
@JsonProperty("title") String title,
@JsonProperty("description") String description,
@JsonProperty("arguments") List<PromptArgument> arguments,
@JsonProperty("icons") List<Icon> icons,
@JsonProperty("_meta") Map<String, Object> meta) implements Identifier { // @formatter:on

public Prompt(String name, String description, List<PromptArgument> arguments) {
this(name, null, description, arguments != null ? arguments : new ArrayList<>());
this(name, null, description, arguments != null ? arguments : new ArrayList<>(), null, null);
}

public Prompt(String name, String title, String description, List<PromptArgument> arguments) {
this(name, title, description, arguments != null ? arguments : new ArrayList<>(), null);
this(name, title, description, arguments != null ? arguments : new ArrayList<>(), null, null);
}
}

Expand Down Expand Up @@ -1332,6 +1411,8 @@ public record ToolAnnotations( // @formatter:off
* @param outputSchema An optional JSON Schema object defining the structure of the
* tool's output returned in the structuredContent field of a CallToolResult.
* @param annotations Optional additional tool information.
* @param icons Optional list of icons that can be used to visually represent this
* tool in client UIs.
* @param meta See specification for notes on _meta usage
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
Expand All @@ -1343,6 +1424,7 @@ public record Tool( // @formatter:off
@JsonProperty("inputSchema") JsonSchema inputSchema,
@JsonProperty("outputSchema") Map<String, Object> outputSchema,
@JsonProperty("annotations") ToolAnnotations annotations,
@JsonProperty("icons") List<Icon> icons,
@JsonProperty("_meta") Map<String, Object> meta) { // @formatter:on

public static Builder builder() {
Expand All @@ -1363,6 +1445,8 @@ public static class Builder {

private ToolAnnotations annotations;

private List<Icon> icons;

private Map<String, Object> meta;

public Builder name(String name) {
Expand Down Expand Up @@ -1405,14 +1489,19 @@ public Builder annotations(ToolAnnotations annotations) {
return this;
}

public Builder icons(List<Icon> icons) {
this.icons = icons;
return this;
}

public Builder meta(Map<String, Object> meta) {
this.meta = meta;
return this;
}

public Tool build() {
Assert.hasText(name, "name must not be empty");
return new Tool(name, title, description, inputSchema, outputSchema, annotations, meta);
return new Tool(name, title, description, inputSchema, outputSchema, annotations, icons, meta);
}

}
Expand Down