diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java index 8362ca22..4a570aea 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java +++ b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java @@ -11,6 +11,9 @@ import java.util.List; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -21,11 +24,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import io.modelcontextprotocol.spec.McpSchema.CallToolResult; -import io.modelcontextprotocol.spec.McpSchema.TextContent; import io.modelcontextprotocol.util.Assert; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Based on the JSON-RPC 2.0 @@ -202,254 +201,345 @@ public sealed interface JSONRPCMessage permits JSONRPCRequest, JSONRPCNotificati } + /** + * A request that expects a response. + * + * @param jsonrpc The JSON-RPC version (must be "2.0") + * @param method The name of the method to be invoked + * @param id A unique identifier for the request + * @param params Parameters for the method call + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) // TODO: batching support // @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) public record JSONRPCRequest( // @formatter:off - @JsonProperty("jsonrpc") String jsonrpc, - @JsonProperty("method") String method, - @JsonProperty("id") Object id, - @JsonProperty("params") Object params) implements JSONRPCMessage { - } // @formatter:on + @JsonProperty("jsonrpc") String jsonrpc, + @JsonProperty("method") String method, + @JsonProperty("id") Object id, + @JsonProperty("params") Object params) implements JSONRPCMessage { // @formatter:on + } + /** + * A notification which does not expect a response. + * + * @param jsonrpc The JSON-RPC version (must be "2.0") + * @param method The name of the method being notified + * @param params Parameters for the notification + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) // TODO: batching support // @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) public record JSONRPCNotification( // @formatter:off - @JsonProperty("jsonrpc") String jsonrpc, - @JsonProperty("method") String method, - @JsonProperty("params") Object params) implements JSONRPCMessage { - } // @formatter:on + @JsonProperty("jsonrpc") String jsonrpc, + @JsonProperty("method") String method, + @JsonProperty("params") Object params) implements JSONRPCMessage { // @formatter:on + } + /** + * A successful (non-error) response to a request. + * + * @param jsonrpc The JSON-RPC version (must be "2.0") + * @param id The request identifier that this response corresponds to + * @param result The result of the successful request + * @param error Error information if the request failed + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) // TODO: batching support // @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) public record JSONRPCResponse( // @formatter:off - @JsonProperty("jsonrpc") String jsonrpc, - @JsonProperty("id") Object id, - @JsonProperty("result") Object result, - @JsonProperty("error") JSONRPCError error) implements JSONRPCMessage { - - @JsonInclude(JsonInclude.Include.NON_ABSENT) - @JsonIgnoreProperties(ignoreUnknown = true) - public record JSONRPCError( - @JsonProperty("code") int code, - @JsonProperty("message") String message, - @JsonProperty("data") Object data) { - } - }// @formatter:on + @JsonProperty("jsonrpc") String jsonrpc, + @JsonProperty("id") Object id, + @JsonProperty("result") Object result, + @JsonProperty("error") JSONRPCError error) implements JSONRPCMessage { // @formatter:on + + /** + * A response to a request that indicates an error occurred. + * + * @param code The error type that occurred + * @param message A short description of the error. The message SHOULD be limited + * to a concise single sentence + * @param data Additional information about the error. The value of this member is + * defined by the sender (e.g. detailed error information, nested errors etc.) + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + @JsonIgnoreProperties(ignoreUnknown = true) + public record JSONRPCError( // @formatter:off + @JsonProperty("code") int code, + @JsonProperty("message") String message, + @JsonProperty("data") Object data) { // @formatter:on + } + } // --------------------------- // Initialization // --------------------------- + /** + * This request is sent from the client to the server when it first connects, asking + * it to begin initialization. + * + * @param protocolVersion The latest version of the Model Context Protocol that the + * client supports. The client MAY decide to support older versions as well + * @param capabilities The capabilities that the client supports + * @param clientInfo Information about the client implementation + * @param meta See specification for notes on _meta usage + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record InitializeRequest( // @formatter:off - @JsonProperty("protocolVersion") String protocolVersion, - @JsonProperty("capabilities") ClientCapabilities capabilities, - @JsonProperty("clientInfo") Implementation clientInfo, - @JsonProperty("_meta") Map meta) implements Request { - - public InitializeRequest(String protocolVersion, ClientCapabilities capabilities, Implementation clientInfo) { - this(protocolVersion, capabilities, clientInfo, null); - } - } // @formatter:on + @JsonProperty("protocolVersion") String protocolVersion, + @JsonProperty("capabilities") ClientCapabilities capabilities, + @JsonProperty("clientInfo") Implementation clientInfo, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on + public InitializeRequest(String protocolVersion, ClientCapabilities capabilities, Implementation clientInfo) { + this(protocolVersion, capabilities, clientInfo, null); + } + } + + /** + * After receiving an initialize request from the client, the server sends this + * response. + * + * @param protocolVersion The version of the Model Context Protocol that the server + * wants to use. This may not match the version that the client requested. If the + * client cannot support this version, it MUST disconnect + * @param capabilities The capabilities that the server supports + * @param serverInfo Information about the server implementation + * @param instructions Instructions describing how to use the server and its features. + * This can be used by clients to improve the LLM's understanding of available tools, + * resources, etc. It can be thought of like a "hint" to the model. For example, this + * information MAY be added to the system prompt + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record InitializeResult( // @formatter:off - @JsonProperty("protocolVersion") String protocolVersion, - @JsonProperty("capabilities") ServerCapabilities capabilities, - @JsonProperty("serverInfo") Implementation serverInfo, - @JsonProperty("instructions") String instructions) { - } // @formatter:on + @JsonProperty("protocolVersion") String protocolVersion, + @JsonProperty("capabilities") ServerCapabilities capabilities, + @JsonProperty("serverInfo") Implementation serverInfo, + @JsonProperty("instructions") String instructions) { // @formatter:on + } /** - * Clients can implement additional features to enrich connected MCP servers with - * additional capabilities. These capabilities can be used to extend the functionality - * of the server, or to provide additional information to the server about the - * client's capabilities. - * - * @param experimental WIP - * @param roots define the boundaries of where servers can operate within the - * filesystem, allowing them to understand which directories and files they have - * access to. - * @param sampling Provides a standardized way for servers to request LLM sampling - * (“completions” or “generations”) from language models via clients. - * @param elicitation Provides a standardized way for servers to request additional - * information from users through the client during interactions. + * Capabilities a client may support. Known capabilities are defined here, in this + * schema, but this is not a closed set: any client can define its own, additional + * capabilities. * + * @param experimental Experimental, non-standard capabilities that the client + * supports + * @param roots Present if the client supports listing roots + * @param sampling Present if the client supports sampling from an LLM + * @param elicitation Present if the client supports elicitation from the server */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ClientCapabilities( // @formatter:off - @JsonProperty("experimental") Map experimental, - @JsonProperty("roots") RootCapabilities roots, - @JsonProperty("sampling") Sampling sampling, - @JsonProperty("elicitation") Elicitation elicitation) { - - /** - * Roots define the boundaries of where servers can operate within the filesystem, - * allowing them to understand which directories and files they have access to. - * Servers can request the list of roots from supporting clients and - * receive notifications when that list changes. - * - * @param listChanged Whether the client would send notification about roots - * has changed since the last time the server checked. - */ - @JsonInclude(JsonInclude.Include.NON_ABSENT) - @JsonIgnoreProperties(ignoreUnknown = true) - public record RootCapabilities( - @JsonProperty("listChanged") Boolean listChanged) { - } + @JsonProperty("experimental") Map experimental, + @JsonProperty("roots") RootCapabilities roots, + @JsonProperty("sampling") Sampling sampling, + @JsonProperty("elicitation") Elicitation elicitation) { // @formatter:on - /** - * Provides a standardized way for servers to request LLM - * sampling ("completions" or "generations") from language - * models via clients. This flow allows clients to maintain - * control over model access, selection, and permissions - * while enabling servers to leverage AI capabilities—with - * no server API keys necessary. Servers can request text or - * image-based interactions and optionally include context - * from MCP servers in their prompts. - */ - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record Sampling() { - } + /** + * Present if the client supports listing roots. + * + * @param listChanged Whether the client supports notifications for changes to the + * roots list + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + @JsonIgnoreProperties(ignoreUnknown = true) + public record RootCapabilities(@JsonProperty("listChanged") Boolean listChanged) { + } - /** - * Provides a standardized way for servers to request additional - * information from users through the client during interactions. - * This flow allows clients to maintain control over user - * interactions and data sharing while enabling servers to gather - * necessary information dynamically. Servers can request structured - * data from users with optional JSON schemas to validate responses. - */ - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record Elicitation() { - } + /** + * Provides a standardized way for servers to request LLM sampling ("completions" + * or "generations") from language models via clients. This flow allows clients to + * maintain control over model access, selection, and permissions while enabling + * servers to leverage AI capabilities—with no server API keys necessary. Servers + * can request text or image-based interactions and optionally include context + * from MCP servers in their prompts. + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record Sampling() { + } - public static Builder builder() { - return new Builder(); - } + /** + * Provides a standardized way for servers to request additional information from + * users through the client during interactions. This flow allows clients to + * maintain control over user interactions and data sharing while enabling servers + * to gather necessary information dynamically. Servers can request structured + * data from users with optional JSON schemas to validate responses. + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record Elicitation() { + } - public static class Builder { - private Map experimental; - private RootCapabilities roots; - private Sampling sampling; - private Elicitation elicitation; - - public Builder experimental(Map experimental) { - this.experimental = experimental; - return this; - } - - public Builder roots(Boolean listChanged) { - this.roots = new RootCapabilities(listChanged); - return this; - } - - public Builder sampling() { - this.sampling = new Sampling(); - return this; - } - - public Builder elicitation() { - this.elicitation = new Elicitation(); - return this; - } - - public ClientCapabilities build() { - return new ClientCapabilities(experimental, roots, sampling, elicitation); - } - } - }// @formatter:on + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private Map experimental; + + private RootCapabilities roots; + + private Sampling sampling; + + private Elicitation elicitation; + + public Builder experimental(Map experimental) { + this.experimental = experimental; + return this; + } + + public Builder roots(Boolean listChanged) { + this.roots = new RootCapabilities(listChanged); + return this; + } + + public Builder sampling() { + this.sampling = new Sampling(); + return this; + } + + public Builder elicitation() { + this.elicitation = new Elicitation(); + return this; + } + + public ClientCapabilities build() { + return new ClientCapabilities(experimental, roots, sampling, elicitation); + } + + } + } + /** + * Capabilities that a server may support. Known capabilities are defined here, in + * this schema, but this is not a closed set: any server can define its own, + * additional capabilities. + * + * @param completions Present if the server supports argument autocompletion + * suggestions + * @param experimental Experimental, non-standard capabilities that the server + * supports + * @param logging Present if the server supports sending log messages to the client + * @param prompts Present if the server offers any prompt templates + * @param resources Present if the server offers any resources to read + * @param tools Present if the server offers any tools to call + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ServerCapabilities( // @formatter:off - @JsonProperty("completions") CompletionCapabilities completions, - @JsonProperty("experimental") Map experimental, - @JsonProperty("logging") LoggingCapabilities logging, - @JsonProperty("prompts") PromptCapabilities prompts, - @JsonProperty("resources") ResourceCapabilities resources, - @JsonProperty("tools") ToolCapabilities tools) { - - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record CompletionCapabilities() { - } + @JsonProperty("completions") CompletionCapabilities completions, + @JsonProperty("experimental") Map experimental, + @JsonProperty("logging") LoggingCapabilities logging, + @JsonProperty("prompts") PromptCapabilities prompts, + @JsonProperty("resources") ResourceCapabilities resources, + @JsonProperty("tools") ToolCapabilities tools) { // @formatter:on - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record LoggingCapabilities() { - } + /** + * Present if the server supports argument autocompletion suggestions. + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record CompletionCapabilities() { + } - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record PromptCapabilities( - @JsonProperty("listChanged") Boolean listChanged) { - } + /** + * Present if the server supports sending log messages to the client. + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record LoggingCapabilities() { + } - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record ResourceCapabilities( - @JsonProperty("subscribe") Boolean subscribe, - @JsonProperty("listChanged") Boolean listChanged) { - } + /** + * Present if the server offers any prompt templates. + * + * @param listChanged Whether this server supports notifications for changes to + * the prompt list + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record PromptCapabilities(@JsonProperty("listChanged") Boolean listChanged) { + } - @JsonInclude(JsonInclude.Include.NON_ABSENT) - public record ToolCapabilities( - @JsonProperty("listChanged") Boolean listChanged) { - } + /** + * Present if the server offers any resources to read. + * + * @param subscribe Whether this server supports subscribing to resource updates + * @param listChanged Whether this server supports notifications for changes to + * the resource list + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record ResourceCapabilities(@JsonProperty("subscribe") Boolean subscribe, + @JsonProperty("listChanged") Boolean listChanged) { + } - public static Builder builder() { - return new Builder(); - } + /** + * Present if the server offers any tools to call. + * + * @param listChanged Whether this server supports notifications for changes to + * the tool list + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + public record ToolCapabilities(@JsonProperty("listChanged") Boolean listChanged) { + } - public static class Builder { - - private CompletionCapabilities completions; - private Map experimental; - private LoggingCapabilities logging = new LoggingCapabilities(); - private PromptCapabilities prompts; - private ResourceCapabilities resources; - private ToolCapabilities tools; - - public Builder completions() { - this.completions = new CompletionCapabilities(); - return this; - } - - public Builder experimental(Map experimental) { - this.experimental = experimental; - return this; - } - - public Builder logging() { - this.logging = new LoggingCapabilities(); - return this; - } - - public Builder prompts(Boolean listChanged) { - this.prompts = new PromptCapabilities(listChanged); - return this; - } - - public Builder resources(Boolean subscribe, Boolean listChanged) { - this.resources = new ResourceCapabilities(subscribe, listChanged); - return this; - } - - public Builder tools(Boolean listChanged) { - this.tools = new ToolCapabilities(listChanged); - return this; - } - - public ServerCapabilities build() { - return new ServerCapabilities(completions, experimental, logging, prompts, resources, tools); - } - } - } // @formatter:on + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private CompletionCapabilities completions; + + private Map experimental; + + private LoggingCapabilities logging = new LoggingCapabilities(); + + private PromptCapabilities prompts; + + private ResourceCapabilities resources; + + private ToolCapabilities tools; + + public Builder completions() { + this.completions = new CompletionCapabilities(); + return this; + } + + public Builder experimental(Map experimental) { + this.experimental = experimental; + return this; + } + + public Builder logging() { + this.logging = new LoggingCapabilities(); + return this; + } + + public Builder prompts(Boolean listChanged) { + this.prompts = new PromptCapabilities(listChanged); + return this; + } + + public Builder resources(Boolean subscribe, Boolean listChanged) { + this.resources = new ResourceCapabilities(subscribe, listChanged); + return this; + } + + public Builder tools(Boolean listChanged) { + this.tools = new ToolCapabilities(listChanged); + return this; + } + + public ServerCapabilities build() { + return new ServerCapabilities(completions, experimental, logging, prompts, resources, tools); + } + + } + } /** * Describes the name and version of an MCP implementation, with an optional title for @@ -462,10 +552,10 @@ public ServerCapabilities build() { */ @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 BaseMetadata {// @formatter:on + public record Implementation( // @formatter:off + @JsonProperty("name") String name, + @JsonProperty("title") String title, + @JsonProperty("version") String version) implements BaseMetadata { // @formatter:on public Implementation(String name, String version) { this(name, null, version); @@ -473,11 +563,12 @@ public Implementation(String name, String version) { } // Existing Enums and Base Types (from previous implementation) - public enum Role {// @formatter:off + public enum Role { - @JsonProperty("user") USER, - @JsonProperty("assistant") ASSISTANT - }// @formatter:on + // @formatter:off + @JsonProperty("user") USER, + @JsonProperty("assistant") ASSISTANT + } // @formatter:on // --------------------------- // Resource Interfaces @@ -507,9 +598,9 @@ public interface Annotated { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record Annotations( // @formatter:off - @JsonProperty("audience") List audience, - @JsonProperty("priority") Double priority) { - } // @formatter:on + @JsonProperty("audience") List audience, + @JsonProperty("priority") Double priority) { // @formatter:on + } /** * A common interface for resource content, which includes metadata about the resource @@ -573,13 +664,13 @@ public interface BaseMetadata { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record Resource( // @formatter:off - @JsonProperty("uri") String uri, - @JsonProperty("name") String name, - @JsonProperty("title") String title, - @JsonProperty("description") String description, - @JsonProperty("mimeType") String mimeType, - @JsonProperty("size") Long size, - @JsonProperty("annotations") Annotations annotations) implements Annotated, ResourceContent {// @formatter:on + @JsonProperty("uri") String uri, + @JsonProperty("name") String name, + @JsonProperty("title") String title, + @JsonProperty("description") String description, + @JsonProperty("mimeType") String mimeType, + @JsonProperty("size") Long size, + @JsonProperty("annotations") Annotations annotations) implements Annotated, ResourceContent { // @formatter:on /** * @deprecated Only exists for backwards-compatibility purposes. Use @@ -685,12 +776,12 @@ public Resource build() { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ResourceTemplate( // @formatter:off - @JsonProperty("uriTemplate") String uriTemplate, - @JsonProperty("name") String name, - @JsonProperty("title") String title, - @JsonProperty("description") String description, - @JsonProperty("mimeType") String mimeType, - @JsonProperty("annotations") Annotations annotations) implements Annotated, BaseMetadata {// @formatter:on + @JsonProperty("uriTemplate") String uriTemplate, + @JsonProperty("name") String name, + @JsonProperty("title") String title, + @JsonProperty("description") String description, + @JsonProperty("mimeType") String mimeType, + @JsonProperty("annotations") Annotations annotations) implements Annotated, BaseMetadata { // @formatter:on public ResourceTemplate(String uriTemplate, String name, String description, String mimeType, Annotations annotations) { @@ -698,36 +789,61 @@ public ResourceTemplate(String uriTemplate, String name, String description, Str } } + /** + * The server's response to a resources/list request from the client. + * + * @param resources A list of resources that the server provides + * @param nextCursor An opaque token representing the pagination position after the + * last returned result. If present, there may be more results available + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ListResourcesResult( // @formatter:off - @JsonProperty("resources") List resources, - @JsonProperty("nextCursor") String nextCursor) { - } // @formatter:on + @JsonProperty("resources") List resources, + @JsonProperty("nextCursor") String nextCursor) { // @formatter:on + } + /** + * The server's response to a resources/templates/list request from the client. + * + * @param resourceTemplates A list of resource templates that the server provides + * @param nextCursor An opaque token representing the pagination position after the + * last returned result. If present, there may be more results available + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ListResourceTemplatesResult( // @formatter:off - @JsonProperty("resourceTemplates") List resourceTemplates, - @JsonProperty("nextCursor") String nextCursor) { - } // @formatter:on + @JsonProperty("resourceTemplates") List resourceTemplates, + @JsonProperty("nextCursor") String nextCursor) { // @formatter:on + } + /** + * Sent from the client to the server, to read a specific resource URI. + * + * @param uri The URI of the resource to read. The URI can use any protocol; it is up + * to the server how to interpret it + * @param meta See specification for notes on _meta usage + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ReadResourceRequest( // @formatter:off - @JsonProperty("uri") String uri, - @JsonProperty("_meta") Map meta) implements Request {// @formatter:on + @JsonProperty("uri") String uri, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on public ReadResourceRequest(String uri) { this(uri, null); } } + /** + * The server's response to a resources/read request from the client. + * + * @param contents The contents of the resource + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record ReadResourceResult( // @formatter:off - @JsonProperty("contents") List contents){ - } // @formatter:on + public record ReadResourceResult(@JsonProperty("contents") List contents) { + } /** * Sent from the client to request resources/updated notifications from the server @@ -738,15 +854,19 @@ public record ReadResourceResult( // @formatter:off */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record SubscribeRequest( // @formatter:off - @JsonProperty("uri") String uri){ - } // @formatter:on + public record SubscribeRequest(@JsonProperty("uri") String uri) { + } + /** + * Sent from the client to request cancellation of resources/updated notifications + * from the server. This should follow a previous resources/subscribe request. + * + * @param uri The URI of the resource to unsubscribe from + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record UnsubscribeRequest( // @formatter:off - @JsonProperty("uri") String uri){ - } // @formatter:on + public record UnsubscribeRequest(@JsonProperty("uri") String uri) { + } /** * The contents of a specific resource or sub-resource. @@ -781,10 +901,10 @@ public sealed interface ResourceContents permits TextResourceContents, BlobResou @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record TextResourceContents( // @formatter:off - @JsonProperty("uri") String uri, - @JsonProperty("mimeType") String mimeType, - @JsonProperty("text") String text) implements ResourceContents { - } // @formatter:on + @JsonProperty("uri") String uri, + @JsonProperty("mimeType") String mimeType, + @JsonProperty("text") String text) implements ResourceContents { // @formatter:on + } /** * Binary contents of a resource. @@ -798,10 +918,10 @@ public record TextResourceContents( // @formatter:off @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record BlobResourceContents( // @formatter:off - @JsonProperty("uri") String uri, - @JsonProperty("mimeType") String mimeType, - @JsonProperty("blob") String blob) implements ResourceContents { - } // @formatter:on + @JsonProperty("uri") String uri, + @JsonProperty("mimeType") String mimeType, + @JsonProperty("blob") String blob) implements ResourceContents { // @formatter:on + } // --------------------------- // Prompt Interfaces @@ -817,10 +937,10 @@ public record BlobResourceContents( // @formatter:off @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record Prompt( // @formatter:off - @JsonProperty("name") String name, - @JsonProperty("title") String title, - @JsonProperty("description") String description, - @JsonProperty("arguments") List arguments) implements BaseMetadata { // @formatter:on + @JsonProperty("name") String name, + @JsonProperty("title") String title, + @JsonProperty("description") String description, + @JsonProperty("arguments") List arguments) implements BaseMetadata { // @formatter:on public Prompt(String name, String description, List arguments) { this(name, null, description, arguments != null ? arguments : new ArrayList<>()); @@ -838,10 +958,10 @@ public Prompt(String name, String description, List arguments) { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record PromptArgument( // @formatter:off - @JsonProperty("name") String name, - @JsonProperty("title") String title, - @JsonProperty("description") String description, - @JsonProperty("required") Boolean required) implements BaseMetadata {// @formatter:on + @JsonProperty("name") String name, + @JsonProperty("title") String title, + @JsonProperty("description") String description, + @JsonProperty("required") Boolean required) implements BaseMetadata { // @formatter:on public PromptArgument(String name, String description, Boolean required) { this(name, null, description, required); @@ -860,9 +980,9 @@ public PromptArgument(String name, String description, Boolean required) { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record PromptMessage( // @formatter:off - @JsonProperty("role") Role role, - @JsonProperty("content") Content content) { - } // @formatter:on + @JsonProperty("role") Role role, + @JsonProperty("content") Content content) { // @formatter:on + } /** * The server's response to a prompts/list request from the client. @@ -874,9 +994,9 @@ public record PromptMessage( // @formatter:off @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ListPromptsResult( // @formatter:off - @JsonProperty("prompts") List prompts, - @JsonProperty("nextCursor") String nextCursor) { - }// @formatter:on + @JsonProperty("prompts") List prompts, + @JsonProperty("nextCursor") String nextCursor) { // @formatter:on + } /** * Used by the client to get a prompt provided by the server. @@ -886,28 +1006,28 @@ public record ListPromptsResult( // @formatter:off */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record GetPromptRequest(// @formatter:off - @JsonProperty("name") String name, - @JsonProperty("arguments") Map arguments, - @JsonProperty("_meta") Map meta) implements Request { + public record GetPromptRequest( // @formatter:off + @JsonProperty("name") String name, + @JsonProperty("arguments") Map arguments, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on - public GetPromptRequest(String name, Map arguments) { - this(name, arguments, null); - } - }// @formatter:off + public GetPromptRequest(String name, Map arguments) { + this(name, arguments, null); + } + } - /** - * The server's response to a prompts/get request from the client. - * - * @param description An optional description for the prompt. - * @param messages A list of messages to display as part of the prompt. - */ - @JsonInclude(JsonInclude.Include.NON_ABSENT) - @JsonIgnoreProperties(ignoreUnknown = true) - public record GetPromptResult( // @formatter:off - @JsonProperty("description") String description, - @JsonProperty("messages") List messages) { - } // @formatter:on + /** + * The server's response to a prompts/get request from the client. + * + * @param description An optional description for the prompt. + * @param messages A list of messages to display as part of the prompt. + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + @JsonIgnoreProperties(ignoreUnknown = true) + public record GetPromptResult( // @formatter:off + @JsonProperty("description") String description, + @JsonProperty("messages") List messages) { // @formatter:on + } // --------------------------- // Tool Interfaces @@ -922,20 +1042,30 @@ public record GetPromptResult( // @formatter:off @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ListToolsResult( // @formatter:off - @JsonProperty("tools") List tools, - @JsonProperty("nextCursor") String nextCursor) { - }// @formatter:on + @JsonProperty("tools") List tools, + @JsonProperty("nextCursor") String nextCursor) { // @formatter:on + } + /** + * A JSON Schema object that describes the expected structure of arguments or output. + * + * @param type The type of the schema (e.g., "object") + * @param properties The properties of the schema object + * @param required List of required property names + * @param additionalProperties Whether additional properties are allowed + * @param defs Schema definitions using the newer $defs keyword + * @param definitions Schema definitions using the legacy definitions keyword + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record JsonSchema( // @formatter:off - @JsonProperty("type") String type, - @JsonProperty("properties") Map properties, - @JsonProperty("required") List required, - @JsonProperty("additionalProperties") Boolean additionalProperties, - @JsonProperty("$defs") Map defs, - @JsonProperty("definitions") Map definitions) { - } // @formatter:on + @JsonProperty("type") String type, + @JsonProperty("properties") Map properties, + @JsonProperty("required") List required, + @JsonProperty("additionalProperties") Boolean additionalProperties, + @JsonProperty("$defs") Map defs, + @JsonProperty("definitions") Map definitions) { // @formatter:on + } /** * Additional properties describing a Tool to clients. @@ -955,8 +1085,8 @@ public record ToolAnnotations( // @formatter:off @JsonProperty("destructiveHint") Boolean destructiveHint, @JsonProperty("idempotentHint") Boolean idempotentHint, @JsonProperty("openWorldHint") Boolean openWorldHint, - @JsonProperty("returnDirect") Boolean returnDirect) { - } // @formatter:on + @JsonProperty("returnDirect") Boolean returnDirect) { // @formatter:on + } /** * Represents a tool that the server provides. Tools enable servers to expose @@ -982,7 +1112,7 @@ public record Tool( // @formatter:off @JsonProperty("description") String description, @JsonProperty("inputSchema") JsonSchema inputSchema, @JsonProperty("outputSchema") Map outputSchema, - @JsonProperty("annotations") ToolAnnotations annotations) {// @formatter:on + @JsonProperty("annotations") ToolAnnotations annotations) { // @formatter:on /** * @deprecated Only exists for backwards-compatibility purposes. Use @@ -1115,96 +1245,102 @@ private static JsonSchema parseSchema(String schema) { */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record CallToolRequest(// @formatter:off - @JsonProperty("name") String name, - @JsonProperty("arguments") Map arguments, - @JsonProperty("_meta") Map meta) implements Request {// @formatter:off + public record CallToolRequest( // @formatter:off + @JsonProperty("name") String name, + @JsonProperty("arguments") Map arguments, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on - public CallToolRequest(String name, String jsonArguments) { - this(name, parseJsonArguments(jsonArguments), null); - } - public CallToolRequest(String name, Map arguments) { - this(name, arguments, null); - } + public CallToolRequest(String name, String jsonArguments) { + this(name, parseJsonArguments(jsonArguments), null); + } - private static Map parseJsonArguments(String jsonArguments) { - try { - return OBJECT_MAPPER.readValue(jsonArguments, MAP_TYPE_REF); - } - catch (IOException e) { - throw new IllegalArgumentException("Invalid arguments: " + jsonArguments, e); - } - } + public CallToolRequest(String name, Map arguments) { + this(name, arguments, null); + } - public static Builder builder() { - return new Builder(); - } + private static Map parseJsonArguments(String jsonArguments) { + try { + return OBJECT_MAPPER.readValue(jsonArguments, MAP_TYPE_REF); + } + catch (IOException e) { + throw new IllegalArgumentException("Invalid arguments: " + jsonArguments, e); + } + } - public static class Builder { - private String name; - private Map arguments; - private Map meta; - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder arguments(Map arguments) { - this.arguments = arguments; - return this; - } - - public Builder arguments(String jsonArguments) { - this.arguments = parseJsonArguments(jsonArguments); - return this; - } - - public Builder meta(Map meta) { - this.meta = meta; - return this; - } - - public Builder progressToken(String progressToken) { - if (this.meta == null) { - this.meta = new HashMap<>(); - } - this.meta.put("progressToken", progressToken); - return this; - } - - public CallToolRequest build() { - Assert.hasText(name, "name must not be empty"); - return new CallToolRequest(name, arguments, meta); - } - } + public static Builder builder() { + return new Builder(); } - /** - * The server's response to a tools/call request from the client. - * - * @param content A list of content items representing the tool's output. Each item can be text, an image, - * or an embedded resource. - * @param isError If true, indicates that the tool execution failed and the content contains error information. - * If false or absent, indicates successful execution. - * @param structuredContent An optional JSON object that represents the structured result of the tool call. - */ - @JsonInclude(JsonInclude.Include.NON_ABSENT) - @JsonIgnoreProperties(ignoreUnknown = true) - public record CallToolResult( // @formatter:off - @JsonProperty("content") List content, - @JsonProperty("isError") Boolean isError, - @JsonProperty("structuredContent") Map structuredContent) {// @formatter:on + public static class Builder { - // backwards compatibility constructor - public CallToolResult(List content, Boolean isError) { - this(content, isError, null); - } + private String name; - /** - * Creates a new instance of {@link CallToolResult} with a string containing the - * tool result. - * @param content The content of the tool result. This will be mapped to a + private Map arguments; + + private Map meta; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder arguments(Map arguments) { + this.arguments = arguments; + return this; + } + + public Builder arguments(String jsonArguments) { + this.arguments = parseJsonArguments(jsonArguments); + return this; + } + + public Builder meta(Map meta) { + this.meta = meta; + return this; + } + + public Builder progressToken(String progressToken) { + if (this.meta == null) { + this.meta = new HashMap<>(); + } + this.meta.put("progressToken", progressToken); + return this; + } + + public CallToolRequest build() { + Assert.hasText(name, "name must not be empty"); + return new CallToolRequest(name, arguments, meta); + } + + } + } + + /** + * The server's response to a tools/call request from the client. + * + * @param content A list of content items representing the tool's output. Each item + * can be text, an image, or an embedded resource. + * @param isError If true, indicates that the tool execution failed and the content + * contains error information. If false or absent, indicates successful execution. + * @param structuredContent An optional JSON object that represents the structured + * result of the tool call. + */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) + @JsonIgnoreProperties(ignoreUnknown = true) + public record CallToolResult( // @formatter:off + @JsonProperty("content") List content, + @JsonProperty("isError") Boolean isError, + @JsonProperty("structuredContent") Map structuredContent) { // @formatter:on + + // backwards compatibility constructor + public CallToolResult(List content, Boolean isError) { + this(content, isError, null); + } + + /** + * Creates a new instance of {@link CallToolResult} with a string containing the + * tool result. + * @param content The content of the tool result. This will be mapped to a * one-sized list with a {@link TextContent} element. * @param isError If true, indicates that the tool execution failed and the * content contains error information. If false or absent, indicates successful @@ -1322,58 +1458,91 @@ public CallToolResult build() { // --------------------------- // Sampling Interfaces // --------------------------- + /** + * The server's preferences for model selection, requested of the client during + * sampling. + * + * @param hints Optional hints to use for model selection. If multiple hints are + * specified, the client MUST evaluate them in order (such that the first match is + * taken). The client SHOULD prioritize these hints over the numeric priorities, but + * MAY still use the priorities to select from ambiguous matches + * @param costPriority How much to prioritize cost when selecting a model. A value of + * 0 means cost is not important, while a value of 1 means cost is the most important + * factor + * @param speedPriority How much to prioritize sampling speed (latency) when selecting + * a model. A value of 0 means speed is not important, while a value of 1 means speed + * is the most important factor + * @param intelligencePriority How much to prioritize intelligence and capabilities + * when selecting a model. A value of 0 means intelligence is not important, while a + * value of 1 means intelligence is the most important factor + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record ModelPreferences(// @formatter:off + public record ModelPreferences( // @formatter:off @JsonProperty("hints") List hints, @JsonProperty("costPriority") Double costPriority, @JsonProperty("speedPriority") Double speedPriority, - @JsonProperty("intelligencePriority") Double intelligencePriority) { + @JsonProperty("intelligencePriority") Double intelligencePriority) { // @formatter:on public static Builder builder() { - return new Builder(); + return new Builder(); } public static class Builder { - private List hints; - private Double costPriority; - private Double speedPriority; - private Double intelligencePriority; - - public Builder hints(List hints) { - this.hints = hints; - return this; - } - public Builder addHint(String name) { - if (this.hints == null) { - this.hints = new ArrayList<>(); - } - this.hints.add(new ModelHint(name)); - return this; - } + private List hints; - public Builder costPriority(Double costPriority) { - this.costPriority = costPriority; - return this; - } + private Double costPriority; - public Builder speedPriority(Double speedPriority) { - this.speedPriority = speedPriority; - return this; - } + private Double speedPriority; - public Builder intelligencePriority(Double intelligencePriority) { - this.intelligencePriority = intelligencePriority; - return this; - } + private Double intelligencePriority; + + public Builder hints(List hints) { + this.hints = hints; + return this; + } - public ModelPreferences build() { - return new ModelPreferences(hints, costPriority, speedPriority, intelligencePriority); + public Builder addHint(String name) { + if (this.hints == null) { + this.hints = new ArrayList<>(); } + this.hints.add(new ModelHint(name)); + return this; + } + + public Builder costPriority(Double costPriority) { + this.costPriority = costPriority; + return this; + } + + public Builder speedPriority(Double speedPriority) { + this.speedPriority = speedPriority; + return this; + } + + public Builder intelligencePriority(Double intelligencePriority) { + this.intelligencePriority = intelligencePriority; + return this; + } + + public ModelPreferences build() { + return new ModelPreferences(hints, costPriority, speedPriority, intelligencePriority); + } + } - } // @formatter:on + } + /** + * Hints to use for model selection. + * + * @param name A hint for a model name. The client SHOULD treat this as a substring of + * a model name; for example: `claude-3-5-sonnet` should match + * `claude-3-5-sonnet-20241022`, `sonnet` should match `claude-3-5-sonnet-20241022`, + * `claude-3-sonnet-20240229`, etc., `claude` should match any Claude model. The + * client MAY also map the string to a different provider's model name or a different + * model family, as long as it fills a similar niche + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ModelHint(@JsonProperty("name") String name) { @@ -1382,289 +1551,374 @@ public static ModelHint of(String name) { } } + /** + * Describes a message issued to or received from an LLM API. + * + * @param role The sender or recipient of messages and data in a conversation + * @param content The content of the message + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record SamplingMessage(// @formatter:off - @JsonProperty("role") Role role, - @JsonProperty("content") Content content) { - } // @formatter:on + public record SamplingMessage( // @formatter:off + @JsonProperty("role") Role role, + @JsonProperty("content") Content content) { // @formatter:on + } - // Sampling and Message Creation + /** + * A request from the server to sample an LLM via the client. The client has full + * discretion over which model to select. The client should also inform the user + * before beginning sampling, to allow them to inspect the request (human in the loop) + * and decide whether to approve it. + * + * @param messages The conversation messages to send to the LLM + * @param modelPreferences The server's preferences for which model to select. The + * client MAY ignore these preferences + * @param systemPrompt An optional system prompt the server wants to use for sampling. + * The client MAY modify or omit this prompt + * @param includeContext A request to include context from one or more MCP servers + * (including the caller), to be attached to the prompt. The client MAY ignore this + * request + * @param temperature Optional temperature parameter for sampling + * @param maxTokens The maximum number of tokens to sample, as requested by the + * server. The client MAY choose to sample fewer tokens than requested + * @param stopSequences Optional stop sequences for sampling + * @param metadata Optional metadata to pass through to the LLM provider. The format + * of this metadata is provider-specific + * @param meta See specification for notes on _meta usage + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record CreateMessageRequest(// @formatter:off - @JsonProperty("messages") List messages, - @JsonProperty("modelPreferences") ModelPreferences modelPreferences, - @JsonProperty("systemPrompt") String systemPrompt, - @JsonProperty("includeContext") ContextInclusionStrategy includeContext, - @JsonProperty("temperature") Double temperature, - @JsonProperty("maxTokens") int maxTokens, - @JsonProperty("stopSequences") List stopSequences, - @JsonProperty("metadata") Map metadata, - @JsonProperty("_meta") Map meta) implements Request { - - - // backwards compatibility constructor - public CreateMessageRequest(List messages, ModelPreferences modelPreferences, - String systemPrompt, ContextInclusionStrategy includeContext, - Double temperature, int maxTokens, List stopSequences, - Map metadata) { - this(messages, modelPreferences, systemPrompt, includeContext, temperature, maxTokens, - stopSequences, metadata, null); - } + public record CreateMessageRequest( // @formatter:off + @JsonProperty("messages") List messages, + @JsonProperty("modelPreferences") ModelPreferences modelPreferences, + @JsonProperty("systemPrompt") String systemPrompt, + @JsonProperty("includeContext") ContextInclusionStrategy includeContext, + @JsonProperty("temperature") Double temperature, + @JsonProperty("maxTokens") int maxTokens, + @JsonProperty("stopSequences") List stopSequences, + @JsonProperty("metadata") Map metadata, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on - public enum ContextInclusionStrategy { - @JsonProperty("none") NONE, - @JsonProperty("thisServer") THIS_SERVER, - @JsonProperty("allServers") ALL_SERVERS - } + // backwards compatibility constructor + public CreateMessageRequest(List messages, ModelPreferences modelPreferences, + String systemPrompt, ContextInclusionStrategy includeContext, Double temperature, int maxTokens, + List stopSequences, Map metadata) { + this(messages, modelPreferences, systemPrompt, includeContext, temperature, maxTokens, stopSequences, + metadata, null); + } - public static Builder builder() { - return new Builder(); - } + public enum ContextInclusionStrategy { + + // @formatter:off + @JsonProperty("none") NONE, + @JsonProperty("thisServer") THIS_SERVER, + @JsonProperty("allServers")ALL_SERVERS + } // @formatter:on + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private List messages; + + private ModelPreferences modelPreferences; + + private String systemPrompt; + + private ContextInclusionStrategy includeContext; + + private Double temperature; + + private int maxTokens; + + private List stopSequences; + + private Map metadata; + + private Map meta; + + public Builder messages(List messages) { + this.messages = messages; + return this; + } + + public Builder modelPreferences(ModelPreferences modelPreferences) { + this.modelPreferences = modelPreferences; + return this; + } - public static class Builder { - private List messages; - private ModelPreferences modelPreferences; - private String systemPrompt; - private ContextInclusionStrategy includeContext; - private Double temperature; - private int maxTokens; - private List stopSequences; - private Map metadata; - private Map meta; - - public Builder messages(List messages) { - this.messages = messages; - return this; - } - - public Builder modelPreferences(ModelPreferences modelPreferences) { - this.modelPreferences = modelPreferences; - return this; - } - - public Builder systemPrompt(String systemPrompt) { - this.systemPrompt = systemPrompt; - return this; - } - - public Builder includeContext(ContextInclusionStrategy includeContext) { - this.includeContext = includeContext; - return this; - } - - public Builder temperature(Double temperature) { - this.temperature = temperature; - return this; - } - - public Builder maxTokens(int maxTokens) { - this.maxTokens = maxTokens; - return this; - } - - public Builder stopSequences(List stopSequences) { - this.stopSequences = stopSequences; - return this; - } - - public Builder metadata(Map metadata) { - this.metadata = metadata; - return this; - } - - public Builder meta(Map meta) { - this.meta = meta; - return this; - } - - public Builder progressToken(String progressToken) { - if (this.meta == null) { - this.meta = new HashMap<>(); - } - this.meta.put("progressToken", progressToken); - return this; - } - - public CreateMessageRequest build() { - return new CreateMessageRequest(messages, modelPreferences, systemPrompt, - includeContext, temperature, maxTokens, stopSequences, metadata, meta); - } + public Builder systemPrompt(String systemPrompt) { + this.systemPrompt = systemPrompt; + return this; + } + + public Builder includeContext(ContextInclusionStrategy includeContext) { + this.includeContext = includeContext; + return this; + } + + public Builder temperature(Double temperature) { + this.temperature = temperature; + return this; + } + + public Builder maxTokens(int maxTokens) { + this.maxTokens = maxTokens; + return this; + } + + public Builder stopSequences(List stopSequences) { + this.stopSequences = stopSequences; + return this; + } + + public Builder metadata(Map metadata) { + this.metadata = metadata; + return this; + } + + public Builder meta(Map meta) { + this.meta = meta; + return this; + } + + public Builder progressToken(String progressToken) { + if (this.meta == null) { + this.meta = new HashMap<>(); } - }// @formatter:on + this.meta.put("progressToken", progressToken); + return this; + } + + public CreateMessageRequest build() { + return new CreateMessageRequest(messages, modelPreferences, systemPrompt, includeContext, temperature, + maxTokens, stopSequences, metadata, meta); + } + + } + } + /** + * The client's response to a sampling/create_message request from the server. The + * client should inform the user before returning the sampled message, to allow them + * to inspect the response (human in the loop) and decide whether to allow the server + * to see it. + * + * @param role The role of the message sender (typically assistant) + * @param content The content of the sampled message + * @param model The name of the model that generated the message + * @param stopReason The reason why sampling stopped, if known + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record CreateMessageResult(// @formatter:off - @JsonProperty("role") Role role, - @JsonProperty("content") Content content, - @JsonProperty("model") String model, - @JsonProperty("stopReason") StopReason stopReason) { - - public enum StopReason { - @JsonProperty("endTurn") END_TURN("endTurn"), - @JsonProperty("stopSequence") STOP_SEQUENCE("stopSequence"), - @JsonProperty("maxTokens") MAX_TOKENS("maxTokens"), - @JsonProperty("unknown") UNKNOWN("unknown"); - - private final String value; - - StopReason(String value) { - this.value = value; - } - - @JsonCreator - private static StopReason of(String value) { - return Arrays.stream(StopReason.values()) - .filter(stopReason -> stopReason.value.equals(value)) - .findFirst() - .orElse(StopReason.UNKNOWN); - } - } + public record CreateMessageResult( // @formatter:off + @JsonProperty("role") Role role, + @JsonProperty("content") Content content, + @JsonProperty("model") String model, + @JsonProperty("stopReason") StopReason stopReason) { // @formatter:on - public static Builder builder() { - return new Builder(); - } + public enum StopReason { - public static class Builder { - private Role role = Role.ASSISTANT; - private Content content; - private String model; - private StopReason stopReason = StopReason.END_TURN; - - public Builder role(Role role) { - this.role = role; - return this; - } - - public Builder content(Content content) { - this.content = content; - return this; - } - - public Builder model(String model) { - this.model = model; - return this; - } - - public Builder stopReason(StopReason stopReason) { - this.stopReason = stopReason; - return this; - } - - public Builder message(String message) { - this.content = new TextContent(message); - return this; - } - - public CreateMessageResult build() { - return new CreateMessageResult(role, content, model, stopReason); - } - } - }// @formatter:on + // @formatter:off + @JsonProperty("endTurn") END_TURN("endTurn"), + @JsonProperty("stopSequence") STOP_SEQUENCE("stopSequence"), + @JsonProperty("maxTokens") MAX_TOKENS("maxTokens"), + @JsonProperty("unknown") UNKNOWN("unknown"); + // @formatter:on + + private final String value; + + StopReason(String value) { + this.value = value; + } + + @JsonCreator + private static StopReason of(String value) { + return Arrays.stream(StopReason.values()) + .filter(stopReason -> stopReason.value.equals(value)) + .findFirst() + .orElse(StopReason.UNKNOWN); + } + + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private Role role = Role.ASSISTANT; + + private Content content; + + private String model; + + private StopReason stopReason = StopReason.END_TURN; + + public Builder role(Role role) { + this.role = role; + return this; + } + + public Builder content(Content content) { + this.content = content; + return this; + } + + public Builder model(String model) { + this.model = model; + return this; + } + + public Builder stopReason(StopReason stopReason) { + this.stopReason = stopReason; + return this; + } + + public Builder message(String message) { + this.content = new TextContent(message); + return this; + } + + public CreateMessageResult build() { + return new CreateMessageResult(role, content, model, stopReason); + } + + } + } // Elicitation /** - * Used by the server to send an elicitation to the client. + * A request from the server to elicit additional information from the user via the + * client. * - * @param errorMessage The body of the elicitation message. - * @param requestedSchema The elicitation response schema that must be satisfied. + * @param message The message to present to the user + * @param requestedSchema A restricted subset of JSON Schema. Only top-level + * properties are allowed, without nesting + * @param meta See specification for notes on _meta usage */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record ElicitRequest(// @formatter:off - @JsonProperty("message") String message, - @JsonProperty("requestedSchema") Map requestedSchema, - @JsonProperty("_meta") Map meta) implements Request { - - // backwards compatibility constructor - public ElicitRequest(String message, Map requestedSchema) { - this(message, requestedSchema, null); - } + public record ElicitRequest( // @formatter:off + @JsonProperty("message") String message, + @JsonProperty("requestedSchema") Map requestedSchema, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on - public static Builder builder() { - return new Builder(); - } + // backwards compatibility constructor + public ElicitRequest(String message, Map requestedSchema) { + this(message, requestedSchema, null); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String message; + + private Map requestedSchema; + + private Map meta; - public static class Builder { - private String message; - private Map requestedSchema; - private Map meta; - - public Builder message(String message) { - this.message = message; - return this; - } - - public Builder requestedSchema(Map requestedSchema) { - this.requestedSchema = requestedSchema; - return this; - } - - public Builder meta(Map meta) { - this.meta = meta; - return this; - } - - public Builder progressToken(String progressToken) { - if (this.meta == null) { - this.meta = new HashMap<>(); - } - this.meta.put("progressToken", progressToken); - return this; - } - - public ElicitRequest build() { - return new ElicitRequest(message, requestedSchema, meta); - } + public Builder message(String message) { + this.message = message; + return this; + } + + public Builder requestedSchema(Map requestedSchema) { + this.requestedSchema = requestedSchema; + return this; + } + + public Builder meta(Map meta) { + this.meta = meta; + return this; + } + + public Builder progressToken(String progressToken) { + if (this.meta == null) { + this.meta = new HashMap<>(); } - }// @formatter:on + this.meta.put("progressToken", progressToken); + return this; + } + + public ElicitRequest build() { + return new ElicitRequest(message, requestedSchema, meta); + } + } + } + + /** + * The client's response to an elicitation request. + * + * @param action The user action in response to the elicitation. "accept": User + * submitted the form/confirmed the action, "decline": User explicitly declined the + * action, "cancel": User dismissed without making an explicit choice + * @param content The submitted form data, only present when action is "accept". + * Contains values matching the requested schema + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record ElicitResult(// @formatter:off - @JsonProperty("action") Action action, - @JsonProperty("content") Map content) { - - public enum Action { - @JsonProperty("accept") ACCEPT, - @JsonProperty("decline") DECLINE, - @JsonProperty("cancel") CANCEL - } + public record ElicitResult( // @formatter:off + @JsonProperty("action") Action action, + @JsonProperty("content") Map content) { // @formatter:on - public static Builder builder() { - return new Builder(); - } + public enum Action { - public static class Builder { - private Action action; - private Map content; + // @formatter:off + @JsonProperty("accept") ACCEPT, + @JsonProperty("decline") DECLINE, + @JsonProperty("cancel") CANCEL + } // @formatter:on - public Builder message(Action action) { - this.action = action; - return this; - } + public static Builder builder() { + return new Builder(); + } - public Builder content(Map content) { - this.content = content; - return this; - } + public static class Builder { - public ElicitResult build() { - return new ElicitResult(action, content); - } - } - }// @formatter:on + private Action action; + + private Map content; + + public Builder message(Action action) { + this.action = action; + return this; + } + + public Builder content(Map content) { + this.content = content; + return this; + } + + public ElicitResult build() { + return new ElicitResult(action, content); + } + + } + } // --------------------------- // Pagination Interfaces // --------------------------- + /** + * A request that supports pagination using cursors. + * + * @param cursor An opaque token representing the current pagination position. If + * provided, the server should return results starting after this cursor + * @param meta See specification for notes on _meta usage + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record PaginatedRequest(// @formatter:off - @JsonProperty("cursor") String cursor, - @JsonProperty("_meta") Map meta) implements Request { // @formatter:on + public record PaginatedRequest( // @formatter:off + @JsonProperty("cursor") String cursor, + @JsonProperty("_meta") Map meta) implements Request { // @formatter:on public PaginatedRequest(String cursor) { this(cursor, null); @@ -1678,6 +1932,13 @@ public PaginatedRequest() { } } + /** + * An opaque token representing the pagination position after the last returned + * result. If present, there may be more results available. + * + * @param nextCursor An opaque token representing the pagination position after the + * last returned result. If present, there may be more results available + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record PaginatedResult(@JsonProperty("nextCursor") String nextCursor) { @@ -1699,12 +1960,12 @@ public record PaginatedResult(@JsonProperty("nextCursor") String nextCursor) { */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record ProgressNotification(// @formatter:off - @JsonProperty("progressToken") String progressToken, - @JsonProperty("progress") Double progress, - @JsonProperty("total") Double total, - @JsonProperty("message") String message) { - }// @formatter:on + public record ProgressNotification( // @formatter:off + @JsonProperty("progressToken") String progressToken, + @JsonProperty("progress") Double progress, + @JsonProperty("total") Double total, + @JsonProperty("message") String message) { // @formatter:on + } /** * The Model Context Protocol (MCP) provides a standardized way for servers to send @@ -1713,9 +1974,8 @@ public record ProgressNotification(// @formatter:off * @param uri The updated resource uri. */ @JsonIgnoreProperties(ignoreUnknown = true) - public record ResourcesUpdatedNotification(// @formatter:off - @JsonProperty("uri") String uri) { - }// @formatter:on + public record ResourcesUpdatedNotification(@JsonProperty("uri") String uri) { + } /** * The Model Context Protocol (MCP) provides a standardized way for servers to send @@ -1728,63 +1988,77 @@ public record ResourcesUpdatedNotification(// @formatter:off * @param data JSON-serializable logging data. */ @JsonIgnoreProperties(ignoreUnknown = true) - public record LoggingMessageNotification(// @formatter:off - @JsonProperty("level") LoggingLevel level, - @JsonProperty("logger") String logger, - @JsonProperty("data") String data) { + public record LoggingMessageNotification( // @formatter:off + @JsonProperty("level") LoggingLevel level, + @JsonProperty("logger") String logger, + @JsonProperty("data") String data) { // @formatter:on - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static class Builder { - private LoggingLevel level = LoggingLevel.INFO; - private String logger = "server"; - private String data; - - public Builder level(LoggingLevel level) { - this.level = level; - return this; - } - - public Builder logger(String logger) { - this.logger = logger; - return this; - } - - public Builder data(String data) { - this.data = data; - return this; - } - - public LoggingMessageNotification build() { - return new LoggingMessageNotification(level, logger, data); - } - } - }// @formatter:on - - public enum LoggingLevel {// @formatter:off - @JsonProperty("debug") DEBUG(0), - @JsonProperty("info") INFO(1), - @JsonProperty("notice") NOTICE(2), - @JsonProperty("warning") WARNING(3), - @JsonProperty("error") ERROR(4), - @JsonProperty("critical") CRITICAL(5), - @JsonProperty("alert") ALERT(6), - @JsonProperty("emergency") EMERGENCY(7); - - private final int level; - - LoggingLevel(int level) { - this.level = level; - } + public static class Builder { - public int level() { - return level; - } + private LoggingLevel level = LoggingLevel.INFO; - } // @formatter:on + private String logger = "server"; + + private String data; + + public Builder level(LoggingLevel level) { + this.level = level; + return this; + } + + public Builder logger(String logger) { + this.logger = logger; + return this; + } + + public Builder data(String data) { + this.data = data; + return this; + } + + public LoggingMessageNotification build() { + return new LoggingMessageNotification(level, logger, data); + } + + } + } + + public enum LoggingLevel { + + // @formatter:off + @JsonProperty("debug") DEBUG(0), + @JsonProperty("info") INFO(1), + @JsonProperty("notice") NOTICE(2), + @JsonProperty("warning") WARNING(3), + @JsonProperty("error") ERROR(4), + @JsonProperty("critical") CRITICAL(5), + @JsonProperty("alert") ALERT(6), + @JsonProperty("emergency") EMERGENCY(7); + // @formatter:on + + private final int level; + + LoggingLevel(int level) { + this.level = level; + } + public int level() { + return level; + } + + } + + /** + * A request from the client to the server, to enable or adjust logging. + * + * @param level The level of logging that the client wants to receive from the server. + * The server should send all logs at this level and higher (i.e., more severe) to the + * client as notifications/message + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record SetLevelRequest(@JsonProperty("level") LoggingLevel level) { @@ -1801,12 +2075,19 @@ public sealed interface CompleteReference permits PromptReference, ResourceRefer } + /** + * Identifies a prompt for completion requests. + * + * @param type The reference type identifier (typically "ref/prompt") + * @param name The name of the prompt + * @param title An optional title for the prompt + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record PromptReference(// @formatter:off - @JsonProperty("type") String type, - @JsonProperty("name") String name, - @JsonProperty("title") String title ) implements McpSchema.CompleteReference, BaseMetadata { // @formatter:on + public record PromptReference( // @formatter:off + @JsonProperty("type") String type, + @JsonProperty("name") String name, + @JsonProperty("title") String title ) implements McpSchema.CompleteReference, BaseMetadata { // @formatter:on public PromptReference(String type, String name) { this(type, name, null); @@ -1822,29 +2103,43 @@ public String identifier() { } } + /** + * A reference to a resource or resource template definition for completion requests. + * + * @param type The reference type identifier (typically "ref/resource") + * @param uri The URI or URI template of the resource + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record ResourceReference(// @formatter:off - @JsonProperty("type") String type, - @JsonProperty("uri") String uri) implements McpSchema.CompleteReference { + public record ResourceReference( // @formatter:off + @JsonProperty("type") String type, + @JsonProperty("uri") String uri) implements McpSchema.CompleteReference { // @formatter:on - public ResourceReference(String uri) { - this("ref/resource", uri); - } + public ResourceReference(String uri) { + this("ref/resource", uri); + } - @Override - public String identifier() { - return uri(); - } - }// @formatter:on + @Override + public String identifier() { + return uri(); + } + } + /** + * A request from the client to the server, to ask for completion options. + * + * @param ref A reference to a prompt or resource template definition + * @param argument The argument's information for completion requests + * @param meta See specification for notes on _meta usage + * @param context Additional, optional context for completions + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record CompleteRequest(// @formatter:off + public record CompleteRequest( // @formatter:off @JsonProperty("ref") McpSchema.CompleteReference ref, @JsonProperty("argument") CompleteArgument argument, @JsonProperty("_meta") Map meta, - @JsonProperty("context") CompleteContext context) implements Request { + @JsonProperty("context") CompleteContext context) implements Request { // @formatter:on public CompleteRequest(McpSchema.CompleteReference ref, CompleteArgument argument, Map meta) { this(ref, argument, meta, null); @@ -1857,26 +2152,48 @@ public CompleteRequest(McpSchema.CompleteReference ref, CompleteArgument argumen public CompleteRequest(McpSchema.CompleteReference ref, CompleteArgument argument) { this(ref, argument, null, null); } - - public record CompleteArgument( - @JsonProperty("name") String name, - @JsonProperty("value") String value) { + + /** + * The argument's information for completion requests. + * + * @param name The name of the argument + * @param value The value of the argument to use for completion matching + */ + public record CompleteArgument(@JsonProperty("name") String name, @JsonProperty("value") String value) { } - public record CompleteContext( - @JsonProperty("arguments") Map arguments) { - }// @formatter:on + /** + * Additional, optional context for completions. + * + * @param arguments Previously-resolved variables in a URI template or prompt + */ + public record CompleteContext(@JsonProperty("arguments") Map arguments) { + } } + /** + * The server's response to a completion/complete request. + * + * @param completion The completion information containing values and metadata + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) - public record CompleteResult(@JsonProperty("completion") CompleteCompletion completion) { // @formatter:off + public record CompleteResult(@JsonProperty("completion") CompleteCompletion completion) { - public record CompleteCompletion( - @JsonProperty("values") List values, - @JsonProperty("total") Integer total, - @JsonProperty("hasMore") Boolean hasMore) { - }// @formatter:on + /** + * The server's response to a completion/complete request + * + * @param values An array of completion values. Must not exceed 100 items + * @param total The total number of completion options available. This can exceed + * the number of values actually sent in the response + * @param hasMore Indicates whether there are additional completion options beyond + * those provided in the current response, even if the exact total is unknown + */ + public record CompleteCompletion( // @formatter:off + @JsonProperty("values") List values, + @JsonProperty("total") Integer total, + @JsonProperty("hasMore") Boolean hasMore) { // @formatter:on + } } // --------------------------- @@ -1911,11 +2228,17 @@ else if (this instanceof ResourceLink) { } + /** + * Text provided to or from an LLM. + * + * @param annotations Optional annotations for the client + * @param text The text content of the message + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record TextContent( // @formatter:off - @JsonProperty("annotations") Annotations annotations, - @JsonProperty("text") String text) implements Annotated, Content { // @formatter:on + @JsonProperty("annotations") Annotations annotations, + @JsonProperty("text") String text) implements Annotated, Content { // @formatter:on public TextContent(String content) { this(null, content); @@ -1946,12 +2269,20 @@ public Double priority() { } } + /** + * An image provided to or from an LLM. + * + * @param annotations Optional annotations for the client + * @param data The base64-encoded image data + * @param mimeType The MIME type of the image. Different providers may support + * different image types + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ImageContent( // @formatter:off - @JsonProperty("annotations") Annotations annotations, - @JsonProperty("data") String data, - @JsonProperty("mimeType") String mimeType) implements Annotated, Content { // @formatter:on + @JsonProperty("annotations") Annotations annotations, + @JsonProperty("data") String data, + @JsonProperty("mimeType") String mimeType) implements Annotated, Content { // @formatter:on /** * @deprecated Only exists for backwards-compatibility purposes. Use @@ -1978,19 +2309,36 @@ public Double priority() { } } + /** + * Audio provided to or from an LLM. + * + * @param annotations Optional annotations for the client + * @param data The base64-encoded audio data + * @param mimeType The MIME type of the audio. Different providers may support + * different audio types + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record AudioContent( // @formatter:off - @JsonProperty("annotations") Annotations annotations, - @JsonProperty("data") String data, - @JsonProperty("mimeType") String mimeType) implements Annotated, Content { // @formatter:on + @JsonProperty("annotations") Annotations annotations, + @JsonProperty("data") String data, + @JsonProperty("mimeType") String mimeType) implements Annotated, Content { // @formatter:on } + /** + * The contents of a resource, embedded into a prompt or tool call result. + * + * It is up to the client how best to render embedded resources for the benefit of the + * LLM and/or the user. + * + * @param annotations Optional annotations for the client + * @param resource The resource contents that are embedded + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record EmbeddedResource( // @formatter:off - @JsonProperty("annotations") Annotations annotations, - @JsonProperty("resource") ResourceContents resource) implements Annotated, Content { // @formatter:on + @JsonProperty("annotations") Annotations annotations, + @JsonProperty("resource") ResourceContents resource) implements Annotated, Content { // @formatter:on /** * @deprecated Only exists for backwards-compatibility purposes. Use @@ -2038,13 +2386,13 @@ public Double priority() { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ResourceLink( // @formatter:off - @JsonProperty("name") String name, - @JsonProperty("title") String title, - @JsonProperty("uri") String uri, - @JsonProperty("description") String description, - @JsonProperty("mimeType") String mimeType, - @JsonProperty("size") Long size, - @JsonProperty("annotations") Annotations annotations) implements Annotated, Content, ResourceContent { // @formatter:on + @JsonProperty("name") String name, + @JsonProperty("title") String title, + @JsonProperty("uri") String uri, + @JsonProperty("description") String description, + @JsonProperty("mimeType") String mimeType, + @JsonProperty("size") Long size, + @JsonProperty("annotations") Annotations annotations) implements Annotated, Content, ResourceContent { // @formatter:on /** * @deprecated Only exists for backwards-compatibility purposes. Use @@ -2138,9 +2486,9 @@ public ResourceLink build() { @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record Root( // @formatter:off - @JsonProperty("uri") String uri, - @JsonProperty("name") String name) { - } // @formatter:on + @JsonProperty("uri") String uri, + @JsonProperty("name") String name) { // @formatter:on + } /** * The client's response to a roots/list request from the server. This result contains @@ -2156,12 +2504,12 @@ public record Root( // @formatter:off @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record ListRootsResult( // @formatter:off - @JsonProperty("roots") List roots, - @JsonProperty("nextCursor") String nextCursor) { + @JsonProperty("roots") List roots, + @JsonProperty("nextCursor") String nextCursor) { // @formatter:on - public ListRootsResult(List roots) { - this(roots, null); - } - } // @formatter:on + public ListRootsResult(List roots) { + this(roots, null); + } + } }