Fix javadoc issues

This commit is contained in:
Christian Tzolov 2024-12-29 21:05:57 +01:00
commit 2de1d637c0
7 changed files with 111 additions and 41 deletions

View file

@ -84,8 +84,8 @@ public class McpAsyncClient {
private final ConcurrentHashMap<String, Root> roots; private final ConcurrentHashMap<String, Root> roots;
/** /**
* MCP provides a standardized way for servers to request LLM sampling (“completions” * MCP provides a standardized way for servers to request LLM sampling ("completions"
* or “generations”) from language models via clients. This flow allows clients to * or "generations") from language models via clients. This flow allows clients to
* maintain control over model access, selection, and permissions while enabling * maintain control over model access, selection, and permissions while enabling
* servers to leverage AI capabilities—with no server API keys necessary. Servers can * 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 * request text or image-based interactions and optionally include context from MCP
@ -108,10 +108,13 @@ public class McpAsyncClient {
* timeout. * timeout.
* @param transport the transport to use. * @param transport the transport to use.
* @param requestTimeout the session request-response timeout. * @param requestTimeout the session request-response timeout.
* @param rootsListProviders the list of suppliers that provide the list of roots * @param clientInfo the client implementation information.
* backing the roots list request. * @param clientCapabilities the client capabilities.
* @param rootsListChangedNotification whether the client supports roots/list_changed * @param roots the roots.
* notification. * @param toolsChangeConsumers the tools change consumers.
* @param resourcesChangeConsumers the resources change consumers.
* @param promptsChangeConsumers the prompts change consumers.
* @param samplingHandler the sampling handler.
*/ */
public McpAsyncClient(McpTransport transport, Duration requestTimeout, Implementation clientInfo, public McpAsyncClient(McpTransport transport, Duration requestTimeout, Implementation clientInfo,
ClientCapabilities clientCapabilities, Map<String, Root> roots, ClientCapabilities clientCapabilities, Map<String, Root> roots,
@ -239,10 +242,17 @@ public class McpAsyncClient {
}); });
} }
/**
* Closes the client connection immediately.
*/
public void close() { public void close() {
this.mcpSession.close(); this.mcpSession.close();
} }
/**
* Gracefully closes the client connection.
* @return A Mono that completes when the connection is closed
*/
public Mono<Void> closeGracefully() { public Mono<Void> closeGracefully() {
return this.mcpSession.closeGracefully(); return this.mcpSession.closeGracefully();
} }
@ -252,7 +262,8 @@ public class McpAsyncClient {
// -------------------------- // --------------------------
/** /**
* Send a synchronous ping request. * Sends a ping request to the server.
* @return A Mono that completes with the server's ping response
*/ */
public Mono<Object> ping() { public Mono<Object> ping() {
return this.mcpSession.sendRequest("ping", null, new TypeReference<Object>() { return this.mcpSession.sendRequest("ping", null, new TypeReference<Object>() {
@ -262,6 +273,11 @@ public class McpAsyncClient {
// -------------------------- // --------------------------
// Roots // Roots
// -------------------------- // --------------------------
/**
* Adds a new root to the client's root list.
* @param root The root to add
* @return A Mono that completes when the root is added and notifications are sent
*/
public Mono<Void> addRoot(Root root) { public Mono<Void> addRoot(Root root) {
if (root == null) { if (root == null) {
@ -286,6 +302,11 @@ public class McpAsyncClient {
return Mono.empty(); return Mono.empty();
} }
/**
* Removes a root from the client's root list.
* @param rootUri The URI of the root to remove
* @return A Mono that completes when the root is removed and notifications are sent
*/
public Mono<Void> removeRoot(String rootUri) { public Mono<Void> removeRoot(String rootUri) {
if (rootUri == null) { if (rootUri == null) {
@ -309,8 +330,9 @@ public class McpAsyncClient {
} }
/** /**
* Manually, send a roots/list_changed notification. The addRoot and removeRoot * Manually sends a roots/list_changed notification. The addRoot and removeRoot
* methods automatically send the roots/list_changed notification. * methods automatically send the roots/list_changed notification.
* @return A Mono that completes when the notification is sent
*/ */
public Mono<Void> rootsListChangedNotification() { public Mono<Void> rootsListChangedNotification() {
return this.mcpSession.sendNotification("notifications/roots/list_changed"); return this.mcpSession.sendNotification("notifications/roots/list_changed");
@ -436,7 +458,7 @@ public class McpAsyncClient {
/** /**
* Send a resources/list request. * Send a resources/list request.
* @return the list of resources result. * @return A Mono that completes with the list of resources result
*/ */
public Mono<McpSchema.ListResourcesResult> listResources() { public Mono<McpSchema.ListResourcesResult> listResources() {
return this.listResources(null); return this.listResources(null);
@ -444,8 +466,8 @@ public class McpAsyncClient {
/** /**
* Send a resources/list request. * Send a resources/list request.
* @param cursor the cursor * @param cursor the cursor for pagination
* @return the list of resources result. * @return A Mono that completes with the list of resources result
*/ */
public Mono<McpSchema.ListResourcesResult> listResources(String cursor) { public Mono<McpSchema.ListResourcesResult> listResources(String cursor) {
return this.mcpSession.sendRequest("resources/list", new McpSchema.PaginatedRequest(cursor), return this.mcpSession.sendRequest("resources/list", new McpSchema.PaginatedRequest(cursor),
@ -455,7 +477,7 @@ public class McpAsyncClient {
/** /**
* Send a resources/read request. * Send a resources/read request.
* @param resource the resource to read * @param resource the resource to read
* @return the resource content. * @return A Mono that completes with the resource content
*/ */
public Mono<McpSchema.ReadResourceResult> readResource(McpSchema.Resource resource) { public Mono<McpSchema.ReadResourceResult> readResource(McpSchema.Resource resource) {
return this.readResource(new McpSchema.ReadResourceRequest(resource.uri())); return this.readResource(new McpSchema.ReadResourceRequest(resource.uri()));
@ -463,8 +485,8 @@ public class McpAsyncClient {
/** /**
* Send a resources/read request. * Send a resources/read request.
* @param readResourceRequest the read resource request. * @param readResourceRequest the read resource request
* @return the resource content. * @return A Mono that completes with the resource content
*/ */
public Mono<McpSchema.ReadResourceResult> readResource(McpSchema.ReadResourceRequest readResourceRequest) { public Mono<McpSchema.ReadResourceResult> readResource(McpSchema.ReadResourceRequest readResourceRequest) {
return this.mcpSession.sendRequest("resources/read", readResourceRequest, READ_RESOURCE_RESULT_TYPE_REF); return this.mcpSession.sendRequest("resources/read", readResourceRequest, READ_RESOURCE_RESULT_TYPE_REF);
@ -475,7 +497,7 @@ public class McpAsyncClient {
* templates. Arguments may be auto-completed through the completion API. * templates. Arguments may be auto-completed through the completion API.
* *
* Request a list of resource templates the server has. * Request a list of resource templates the server has.
* @return the list of resource templates result. * @return A Mono that completes with the list of resource templates result
*/ */
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates() { public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates() {
return this.listResourceTemplates(null); return this.listResourceTemplates(null);
@ -486,8 +508,8 @@ public class McpAsyncClient {
* templates. Arguments may be auto-completed through the completion API. * templates. Arguments may be auto-completed through the completion API.
* *
* Request a list of resource templates the server has. * Request a list of resource templates the server has.
* @param cursor the cursor * @param cursor the cursor for pagination
* @return the list of resource templates result. * @return A Mono that completes with the list of resource templates result
*/ */
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor) { public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor) {
return this.mcpSession.sendRequest("resources/templates/list", new McpSchema.PaginatedRequest(cursor), return this.mcpSession.sendRequest("resources/templates/list", new McpSchema.PaginatedRequest(cursor),
@ -496,7 +518,8 @@ public class McpAsyncClient {
/** /**
* List Changed Notification. When the list of available resources changes, servers * List Changed Notification. When the list of available resources changes, servers
* that declared the listChanged capability SHOULD send a notification: * that declared the listChanged capability SHOULD send a notification.
* @return A Mono that completes when the notification is sent
*/ */
public Mono<Void> sendResourcesListChanged() { public Mono<Void> sendResourcesListChanged() {
return this.mcpSession.sendNotification("notifications/resources/list_changed"); return this.mcpSession.sendNotification("notifications/resources/list_changed");
@ -509,7 +532,8 @@ public class McpAsyncClient {
* *
* Send a resources/subscribe request. * Send a resources/subscribe request.
* @param subscribeRequest the subscribe request contains the uri of the resource to * @param subscribeRequest the subscribe request contains the uri of the resource to
* subscribe to. * subscribe to
* @return A Mono that completes when the subscription is complete
*/ */
public Mono<Void> subscribeResource(McpSchema.SubscribeRequest subscribeRequest) { public Mono<Void> subscribeResource(McpSchema.SubscribeRequest subscribeRequest) {
return this.mcpSession.sendRequest("resources/subscribe", subscribeRequest, VOID_TYPE_REFERENCE); return this.mcpSession.sendRequest("resources/subscribe", subscribeRequest, VOID_TYPE_REFERENCE);
@ -518,7 +542,8 @@ public class McpAsyncClient {
/** /**
* Send a resources/unsubscribe request. * Send a resources/unsubscribe request.
* @param unsubscribeRequest the unsubscribe request contains the uri of the resource * @param unsubscribeRequest the unsubscribe request contains the uri of the resource
* to unsubscribe from. * to unsubscribe from
* @return A Mono that completes when the unsubscription is complete
*/ */
public Mono<Void> unsubscribeResource(McpSchema.UnsubscribeRequest unsubscribeRequest) { public Mono<Void> unsubscribeResource(McpSchema.UnsubscribeRequest unsubscribeRequest) {
return this.mcpSession.sendRequest("resources/unsubscribe", unsubscribeRequest, VOID_TYPE_REFERENCE); return this.mcpSession.sendRequest("resources/unsubscribe", unsubscribeRequest, VOID_TYPE_REFERENCE);
@ -554,7 +579,7 @@ public class McpAsyncClient {
/** /**
* List all available prompts. * List all available prompts.
* @return the list of prompts result. * @return A Mono that completes with the list of prompts result
*/ */
public Mono<ListPromptsResult> listPrompts() { public Mono<ListPromptsResult> listPrompts() {
return this.listPrompts(null); return this.listPrompts(null);
@ -562,8 +587,8 @@ public class McpAsyncClient {
/** /**
* List all available prompts. * List all available prompts.
* @param cursor the cursor * @param cursor the cursor for pagination
* @return the list of prompts result. * @return A Mono that completes with the list of prompts result
*/ */
public Mono<ListPromptsResult> listPrompts(String cursor) { public Mono<ListPromptsResult> listPrompts(String cursor) {
return this.mcpSession.sendRequest("prompts/list", new PaginatedRequest(cursor), LIST_PROMPTS_RESULT_TYPE_REF); return this.mcpSession.sendRequest("prompts/list", new PaginatedRequest(cursor), LIST_PROMPTS_RESULT_TYPE_REF);
@ -571,8 +596,8 @@ public class McpAsyncClient {
/** /**
* Get a prompt by its id. * Get a prompt by its id.
* @param getPromptRequest the get prompt request. * @param getPromptRequest the get prompt request
* @return the get prompt result. * @return A Mono that completes with the get prompt result
*/ */
public Mono<GetPromptResult> getPrompt(GetPromptRequest getPromptRequest) { public Mono<GetPromptResult> getPrompt(GetPromptRequest getPromptRequest) {
return this.mcpSession.sendRequest("prompts/get", getPromptRequest, GET_PROMPT_RESULT_TYPE_REF); return this.mcpSession.sendRequest("prompts/get", getPromptRequest, GET_PROMPT_RESULT_TYPE_REF);
@ -582,6 +607,7 @@ public class McpAsyncClient {
* (Server) An optional notification from the server to the client, informing it that * (Server) An optional notification from the server to the client, informing it that
* the list of prompts it offers has changed. This may be issued by servers without * the list of prompts it offers has changed. This may be issued by servers without
* any previous subscription from the client. * any previous subscription from the client.
* @return A Mono that completes when the notification is sent
*/ */
public Mono<Void> promptListChangedNotification() { public Mono<Void> promptListChangedNotification() {
return this.mcpSession.sendNotification("notifications/prompts/list_changed"); return this.mcpSession.sendNotification("notifications/prompts/list_changed");

View file

@ -28,6 +28,8 @@ import org.springframework.ai.mcp.spec.McpSchema.ListPromptsResult;
import org.springframework.ai.mcp.util.Assert; import org.springframework.ai.mcp.util.Assert;
/** /**
* A synchronous client for the Model Context Protocol (MCP).
*
* @author Dariusz Jędrzejczyk * @author Dariusz Jędrzejczyk
* @author Christian Tzolov * @author Christian Tzolov
*/ */

View file

@ -60,8 +60,8 @@ import org.springframework.web.reactive.function.client.WebClient;
* <ol> * <ol>
* <li>The client establishes an SSE connection to the server's /sse endpoint</li> * <li>The client establishes an SSE connection to the server's /sse endpoint</li>
* <li>The server sends an 'endpoint' event containing the URI for sending messages</li> * <li>The server sends an 'endpoint' event containing the URI for sending messages</li>
* </ol>
* *
* <p>
* This implementation handles automatic reconnection for transient failures and provides * This implementation handles automatic reconnection for transient failures and provides
* graceful shutdown capabilities. It uses {@link WebClient} for HTTP communications and * graceful shutdown capabilities. It uses {@link WebClient} for HTTP communications and
* supports JSON serialization/deserialization of messages. * supports JSON serialization/deserialization of messages.

View file

@ -61,10 +61,13 @@ public class McpAsyncServer {
/** /**
* Create a new McpAsyncServer with the given transport and capabilities. * Create a new McpAsyncServer with the given transport and capabilities.
* @param transport The transport to use for communication * @param mcpTransport The transport layer implementation for MCP communication
* @param tools List of tool registrations * @param serverInfo The server implementation details
* @param resources Map of resource registrations * @param serverCapabilities The server capabilities
* @param prompts Map of prompt registrations * @param tools The list of tool registrations
* @param resources The map of resource registrations
* @param resourceTemplates The list of resource templates
* @param prompts The map of prompt registrations
*/ */
public McpAsyncServer(McpTransport mcpTransport, McpSchema.Implementation serverInfo, public McpAsyncServer(McpTransport mcpTransport, McpSchema.Implementation serverInfo,
McpSchema.ServerCapabilities serverCapabilities, List<ToolRegistration> tools, McpSchema.ServerCapabilities serverCapabilities, List<ToolRegistration> tools,
@ -407,28 +410,32 @@ public class McpAsyncServer {
} }
/** /**
* Notify clients that the list of available tools has changed. * Notifies clients that the list of available tools has changed.
* @return A Mono that completes when all clients have been notified
*/ */
public Mono<Void> notifyToolsListChanged() { public Mono<Void> notifyToolsListChanged() {
return this.mcpSession.sendNotification("notifications/tools/list_changed", null); return this.mcpSession.sendNotification("notifications/tools/list_changed", null);
} }
/** /**
* Notify clients that the list of available resources has changed. * Notifies clients that the list of available resources has changed.
* @return A Mono that completes when all clients have been notified
*/ */
public Mono<Void> notifyResourcesListChanged() { public Mono<Void> notifyResourcesListChanged() {
return this.mcpSession.sendNotification("notifications/resources/list_changed", null); return this.mcpSession.sendNotification("notifications/resources/list_changed", null);
} }
/** /**
* Notify clients that the list of available prompts has changed. * Notifies clients that the list of available prompts has changed.
* @return A Mono that completes when all clients have been notified
*/ */
public Mono<Void> notifyPromptsListChanged() { public Mono<Void> notifyPromptsListChanged() {
return this.mcpSession.sendNotification("notifications/prompts/list_changed", null); return this.mcpSession.sendNotification("notifications/prompts/list_changed", null);
} }
/** /**
* Close the server gracefully. * Gracefully closes the server, allowing any in-progress operations to complete.
* @return A Mono that completes when the server has been closed
*/ */
public Mono<Void> closeGracefully() { public Mono<Void> closeGracefully() {
return this.mcpSession.closeGracefully(); return this.mcpSession.closeGracefully();

View file

@ -32,7 +32,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
/** /**
* Based on the <a href="http://www.jsonrpc.org/specification">JSON-RPC 2.0 * Based on the <a href="http://www.jsonrpc.org/specification">JSON-RPC 2.0
* specification<a/> and the <a href= * specification</a> and the <a href=
* "https://github.com/modelcontextprotocol/specification/blob/main/schema/schema.ts">Model * "https://github.com/modelcontextprotocol/specification/blob/main/schema/schema.ts">Model
* Context Protocol Schema</a>. * Context Protocol Schema</a>.
* *
@ -47,16 +47,34 @@ public class McpSchema {
// --------------------------- // ---------------------------
// JSON-RPC Error Codes // JSON-RPC Error Codes
// --------------------------- // ---------------------------
/**
* Standard error codes used in MCP JSON-RPC responses.
*/
public final class ErrorCodes { public final class ErrorCodes {
/**
* Invalid JSON was received by the server.
*/
public static final int PARSE_ERROR = -32700; public static final int PARSE_ERROR = -32700;
/**
* The JSON sent is not a valid Request object.
*/
public static final int INVALID_REQUEST = -32600; public static final int INVALID_REQUEST = -32600;
/**
* The method does not exist / is not available.
*/
public static final int METHOD_NOT_FOUND = -32601; public static final int METHOD_NOT_FOUND = -32601;
/**
* Invalid method parameter(s).
*/
public static final int INVALID_PARAMS = -32602; public static final int INVALID_PARAMS = -32602;
/**
* Internal JSON-RPC error.
*/
public static final int INTERNAL_ERROR = -32603; public static final int INTERNAL_ERROR = -32603;
} }
@ -340,6 +358,9 @@ public class McpSchema {
} }
/** /**
* Optional annotations for the client. The client can use annotations to inform how
* objects are used or displayed.
*
* @param audience Describes who the intended customer of this object or data is. It * @param audience Describes who the intended customer of this object or data is. It
* can include multiple entries to indicate content useful for multiple audiences * can include multiple entries to indicate content useful for multiple audiences
* (e.g., `["user", "assistant"]`). * (e.g., `["user", "assistant"]`).
@ -544,6 +565,10 @@ public class McpSchema {
/** /**
* The server's response to a prompts/list request from the client. * The server's response to a prompts/list request from the client.
*
* @param prompts A list of prompts that the server provides.
* @param nextCursor An optional cursor for pagination. If present, indicates there
* are more prompts available.
*/ */
@JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonInclude(JsonInclude.Include.NON_ABSENT)
public record ListPromptsResult( // @formatter:off public record ListPromptsResult( // @formatter:off
@ -856,6 +881,9 @@ public class McpSchema {
* The client's response to a roots/list request from the server. This result contains * The client's response to a roots/list request from the server. This result contains
* an array of Root objects, each representing a root directory or file that the * an array of Root objects, each representing a root directory or file that the
* server can operate on. * server can operate on.
*
* @param roots An array of Root objects, each representing a root directory or file
* that the server can operate on.
*/ */
@JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonInclude(JsonInclude.Include.NON_ABSENT)
public record ListRootsResult( // @formatter:off public record ListRootsResult( // @formatter:off

View file

@ -19,10 +19,15 @@ package org.springframework.ai.mcp.util;
import reactor.util.annotation.Nullable; import reactor.util.annotation.Nullable;
/** /**
* Assertion utility class that assists in validating arguments.
*
* @author Christian Tzolov * @author Christian Tzolov
*/ */
public class Assert { /**
* Utility class providing assertion methods for parameter validation.
*/
public final class Assert {
/** /**
* Assert that an object is not {@code null}. * Assert that an object is not {@code null}.

View file

@ -24,10 +24,12 @@ import reactor.util.annotation.Nullable;
import org.springframework.lang.Contract; import org.springframework.lang.Contract;
/** /**
* Miscellaneous utility methods.
*
* @author Christian Tzolov * @author Christian Tzolov
*/ */
public class Utils { public final class Utils {
/** /**
* Check whether the given {@code String} contains actual <em>text</em>. * Check whether the given {@code String} contains actual <em>text</em>.