java-sdk/spring/src/main/java/spring/ai/mcp/client/McpSyncClient.java
Christian Tzolov 6a90fdce49 bal
2024-12-09 16:06:28 +01:00

180 lines
5.1 KiB
Java

package spring.ai.mcp.client;
import java.time.Duration;
import spring.ai.mcp.spec.McpSchema;
import org.springframework.util.Assert;
public class McpSyncClient implements AutoCloseable {
// TODO: Consider providing a client config to set this properly
// this is currently a concern only because AutoCloseable is used - perhaps it is
// not a requirement?
private static final long DEFAULT_CLOSE_TIMEOUT_MS = 10_000L;
McpAsyncClient delegate;
public McpSyncClient(McpAsyncClient delegate) {
Assert.notNull(delegate, "McpAsyncClient must not be null");
this.delegate = delegate;
}
@Override
public void close() {
delegate.closeGracefully(Duration.ofMillis(DEFAULT_CLOSE_TIMEOUT_MS)).block();
}
/**
* The initialization phase MUST be the first interaction between client and server.
* During this phase, the client and server:
* <ul>
* <li>Establish protocol version compatibility</li>
* <li>Exchange and negotiate capabilities</li>
* <li>Share implementation details</li>
* </ul>
* <br/>
* The client MUST initiate this phase by sending an initialize request containing:
* <ul>
* <li>The protocol version the client supports</li>
* <li>The client's capabilities</li>
* <li>Client implementation information</li>
* </ul>
*
* The server MUST respond with its own capabilities and information:
* {@link McpSchema.ServerCapabilities}. <br/>
* After successful initialization, the client MUST send an initialized notification
* to indicate it is ready to begin normal operations.
*
* <br/>
*
* <a href=
* "https://github.com/modelcontextprotocol/specification/blob/main/docs/specification/basic/lifecycle.md#initialization">Initialization
* Spec</a>
* @return the initialize result.
*/
public McpSchema.InitializeResult initialize() {
// TODO: block takes no argument here as we assume the async client is
// configured with a requestTimeout at all times
return delegate.initialize()
.block();
}
/**
* Send a roots/list_changed notification.
*/
public void sendRootsListChanged() {
delegate.sendRootsListChanged()
.block();
}
/**
* Send a synchronous ping request.
*/
public void ping() {
delegate.ping()
.block();
}
// --------------------------
// Tools
// --------------------------
/**
* Send a tools/call request.
* @param callToolRequest the call tool request.
* @return the call tool result.
*/
public McpSchema.CallToolResult callTool(McpSchema.CallToolRequest callToolRequest) {
return delegate.callTool(callToolRequest)
.block();
}
/**
* Send a tools/list request.
* @return the list of tools result.
*/
public McpSchema.ListToolsResult listTools(String cursor) {
return delegate.listTools(cursor)
.block();
}
// --------------------------
// Resources
// --------------------------
/**
* Send a resources/list request.
* @param cursor the cursor
* @return the list of resources result.
*/
public McpSchema.ListResourcesResult listResources(String cursor) {
return delegate.listResources(cursor)
.block();
}
/**
* Send a resources/read request.
* @param resource the resource to read
* @return the resource content.
*/
public McpSchema.ReadResourceResult readResource(McpSchema.Resource resource) {
return delegate.readResource(resource)
.block();
}
/**
* Send a resources/read request.
* @param readResourceRequest the read resource request.
* @return the resource content.
*/
public McpSchema.ReadResourceResult readResource(McpSchema.ReadResourceRequest readResourceRequest) {
return delegate.readResource(readResourceRequest)
.block();
}
/**
* Resource templates allow servers to expose parameterized resources using URI
* templates. Arguments may be auto-completed through the completion API.
*
* Request a list of resource templates the server has.
* @param cursor the cursor
* @return the list of resource templates result.
*/
public McpSchema.ListResourceTemplatesResult listResourceTemplates(String cursor) {
return delegate.listResourceTemplates(cursor)
.block();
}
/**
* List Changed Notification. When the list of available resources changes, servers
* that declared the listChanged capability SHOULD send a notification:
*/
public void sendResourcesListChanged() {
delegate.sendResourcesListChanged()
.block();
}
/**
* Subscriptions. The protocol supports optional subscriptions to resource changes.
* Clients can subscribe to specific resources and receive notifications when they
* change.
*
* Send a resources/subscribe request.
* @param subscribeRequest the subscribe request contains the uri of the resource to
* subscribe to.
*/
public void subscribeResource(McpSchema.SubscribeRequest subscribeRequest) {
delegate.subscribeResource(subscribeRequest)
.block();
}
/**
* Send a resources/unsubscribe request.
* @param unsubscribeRequest the unsubscribe request contains the uri of the resource
* to unsubscribe from.
*/
public void unsubscribeResource(McpSchema.UnsubscribeRequest unsubscribeRequest) {
delegate.unsubscribeResource(unsubscribeRequest)
.block();
}
}