feat: Improve pagination support on client side (#306)
This change enhances the client API by providing both paginated access for fine-grained control and convenience methods for retrieving complete result sets automatically. - Implement "list all" methods that automatically handle pagination using expand/reduce operations - Replace null parameters with McpSchema.FIRST_PAGE constant for better readability - Add tests for both paginated and "list all" functionality - Update method javadocs to clarify pagination behavior - Maintain backward compatibility Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
parent
aff24fdf2f
commit
d4a1bfa58f
3 changed files with 403 additions and 94 deletions
|
|
@ -13,7 +13,11 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpClientSession;
|
||||
import io.modelcontextprotocol.spec.McpClientSession.NotificationHandler;
|
||||
import io.modelcontextprotocol.spec.McpClientSession.RequestHandler;
|
||||
|
|
@ -35,8 +39,6 @@ import io.modelcontextprotocol.spec.McpSchema.Root;
|
|||
import io.modelcontextprotocol.spec.McpTransportSessionNotFoundException;
|
||||
import io.modelcontextprotocol.util.Assert;
|
||||
import io.modelcontextprotocol.util.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.publisher.Sinks;
|
||||
|
|
@ -657,10 +659,18 @@ public class McpAsyncClient {
|
|||
|
||||
/**
|
||||
* Retrieves the list of all tools provided by the server.
|
||||
* @return A Mono that emits the list of tools result.
|
||||
* @return A Mono that emits the list of all tools result
|
||||
*/
|
||||
public Mono<McpSchema.ListToolsResult> listTools() {
|
||||
return this.listTools(null);
|
||||
return this.listTools(McpSchema.FIRST_PAGE).expand(result -> {
|
||||
if (result.nextCursor() != null) {
|
||||
return this.listTools(result.nextCursor());
|
||||
}
|
||||
return Mono.empty();
|
||||
}).reduce(new McpSchema.ListToolsResult(new ArrayList<>(), null), (allToolsResult, result) -> {
|
||||
allToolsResult.tools().addAll(result.tools());
|
||||
return allToolsResult;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -709,12 +719,20 @@ public class McpAsyncClient {
|
|||
* Retrieves the list of all resources provided by the server. Resources represent any
|
||||
* kind of UTF-8 encoded data that an MCP server makes available to clients, such as
|
||||
* database records, API responses, log files, and more.
|
||||
* @return A Mono that completes with the list of resources result.
|
||||
* @return A Mono that completes with the list of all resources result
|
||||
* @see McpSchema.ListResourcesResult
|
||||
* @see #readResource(McpSchema.Resource)
|
||||
*/
|
||||
public Mono<McpSchema.ListResourcesResult> listResources() {
|
||||
return this.listResources(null);
|
||||
return this.listResources(McpSchema.FIRST_PAGE).expand(result -> {
|
||||
if (result.nextCursor() != null) {
|
||||
return this.listResources(result.nextCursor());
|
||||
}
|
||||
return Mono.empty();
|
||||
}).reduce(new McpSchema.ListResourcesResult(new ArrayList<>(), null), (allResourcesResult, result) -> {
|
||||
allResourcesResult.resources().addAll(result.resources());
|
||||
return allResourcesResult;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -772,11 +790,21 @@ public class McpAsyncClient {
|
|||
* Retrieves the list of all resource templates provided by the server. Resource
|
||||
* templates allow servers to expose parameterized resources using URI templates,
|
||||
* enabling dynamic resource access based on variable parameters.
|
||||
* @return A Mono that completes with the list of resource templates result.
|
||||
* @return A Mono that completes with the list of all resource templates result
|
||||
* @see McpSchema.ListResourceTemplatesResult
|
||||
*/
|
||||
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates() {
|
||||
return this.listResourceTemplates(null);
|
||||
return this.listResourceTemplates(McpSchema.FIRST_PAGE).expand(result -> {
|
||||
if (result.nextCursor() != null) {
|
||||
return this.listResourceTemplates(result.nextCursor());
|
||||
}
|
||||
return Mono.empty();
|
||||
})
|
||||
.reduce(new McpSchema.ListResourceTemplatesResult(new ArrayList<>(), null),
|
||||
(allResourceTemplatesResult, result) -> {
|
||||
allResourceTemplatesResult.resourceTemplates().addAll(result.resourceTemplates());
|
||||
return allResourceTemplatesResult;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -848,12 +876,20 @@ public class McpAsyncClient {
|
|||
|
||||
/**
|
||||
* Retrieves the list of all prompts provided by the server.
|
||||
* @return A Mono that completes with the list of prompts result.
|
||||
* @return A Mono that completes with the list of all prompts result.
|
||||
* @see McpSchema.ListPromptsResult
|
||||
* @see #getPrompt(GetPromptRequest)
|
||||
*/
|
||||
public Mono<ListPromptsResult> listPrompts() {
|
||||
return this.listPrompts(null);
|
||||
return this.listPrompts(McpSchema.FIRST_PAGE).expand(result -> {
|
||||
if (result.nextCursor() != null) {
|
||||
return this.listPrompts(result.nextCursor());
|
||||
}
|
||||
return Mono.empty();
|
||||
}).reduce(new ListPromptsResult(new ArrayList<>(), null), (allPromptsResult, result) -> {
|
||||
allPromptsResult.prompts().addAll(result.prompts());
|
||||
return allPromptsResult;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
package io.modelcontextprotocol.client;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import io.modelcontextprotocol.spec.McpSchema.ClientCapabilities;
|
||||
|
|
@ -12,8 +16,6 @@ import io.modelcontextprotocol.spec.McpSchema.GetPromptRequest;
|
|||
import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
|
||||
import io.modelcontextprotocol.spec.McpSchema.ListPromptsResult;
|
||||
import io.modelcontextprotocol.util.Assert;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A synchronous client implementation for the Model Context Protocol (MCP) that wraps an
|
||||
|
|
@ -220,8 +222,8 @@ public class McpSyncClient implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Retrieves the list of all tools provided by the server.
|
||||
* @return The list of tools result containing: - tools: List of available tools, each
|
||||
* with a name, description, and input schema - nextCursor: Optional cursor for
|
||||
* @return The list of all tools result containing: - tools: List of available tools,
|
||||
* each with a name, description, and input schema - nextCursor: Optional cursor for
|
||||
* pagination if more tools are available
|
||||
*/
|
||||
public McpSchema.ListToolsResult listTools() {
|
||||
|
|
@ -244,22 +246,22 @@ public class McpSyncClient implements AutoCloseable {
|
|||
// --------------------------
|
||||
|
||||
/**
|
||||
* Send a resources/list request.
|
||||
* @param cursor the cursor
|
||||
* @return the list of resources result.
|
||||
*/
|
||||
public McpSchema.ListResourcesResult listResources(String cursor) {
|
||||
return this.delegate.listResources(cursor).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a resources/list request.
|
||||
* @return the list of resources result.
|
||||
* Retrieves the list of all resources provided by the server.
|
||||
* @return The list of all resources result
|
||||
*/
|
||||
public McpSchema.ListResourcesResult listResources() {
|
||||
return this.delegate.listResources().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a paginated list of resources provided by the server.
|
||||
* @param cursor Optional pagination cursor from a previous list request
|
||||
* @return The list of resources result
|
||||
*/
|
||||
public McpSchema.ListResourcesResult listResources(String cursor) {
|
||||
return this.delegate.listResources(cursor).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a resources/read request.
|
||||
* @param resource the resource to read
|
||||
|
|
@ -279,25 +281,25 @@ public class McpSyncClient implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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 this.delegate.listResourceTemplates(cursor).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a list of resource templates the server has.
|
||||
* @return the list of resource templates result.
|
||||
* Retrieves the list of all resource templates provided by the server.
|
||||
* @return The list of all resource templates result.
|
||||
*/
|
||||
public McpSchema.ListResourceTemplatesResult listResourceTemplates() {
|
||||
return this.delegate.listResourceTemplates().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource templates allow servers to expose parameterized resources using URI
|
||||
* templates. Arguments may be auto-completed through the completion API.
|
||||
*
|
||||
* Retrieves a paginated list of resource templates provided by the server.
|
||||
* @param cursor Optional pagination cursor from a previous list request
|
||||
* @return The list of resource templates result.
|
||||
*/
|
||||
public McpSchema.ListResourceTemplatesResult listResourceTemplates(String cursor) {
|
||||
return this.delegate.listResourceTemplates(cursor).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscriptions. The protocol supports optional subscriptions to resource changes.
|
||||
* Clients can subscribe to specific resources and receive notifications when they
|
||||
|
|
@ -323,14 +325,24 @@ public class McpSyncClient implements AutoCloseable {
|
|||
// --------------------------
|
||||
// Prompts
|
||||
// --------------------------
|
||||
public ListPromptsResult listPrompts(String cursor) {
|
||||
return this.delegate.listPrompts(cursor).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of all prompts provided by the server.
|
||||
* @return The list of all prompts result.
|
||||
*/
|
||||
public ListPromptsResult listPrompts() {
|
||||
return this.delegate.listPrompts().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a paginated list of prompts provided by the server.
|
||||
* @param cursor Optional pagination cursor from a previous list request
|
||||
* @return The list of prompts result.
|
||||
*/
|
||||
public ListPromptsResult listPrompts(String cursor) {
|
||||
return this.delegate.listPrompts(cursor).block();
|
||||
}
|
||||
|
||||
public GetPromptResult getPrompt(GetPromptRequest getPromptRequest) {
|
||||
return this.delegate.getPrompt(getPromptRequest).block();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ public final class McpSchema {
|
|||
|
||||
public static final String JSONRPC_VERSION = "2.0";
|
||||
|
||||
public static final String FIRST_PAGE = null;
|
||||
|
||||
// ---------------------------
|
||||
// Method Names
|
||||
// ---------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue