feat: add pagination support for listRoots operation (#336)
- Add nextCursor field to ListRootsResult for cursor-based pagination - Implement automatic pagination in McpAsyncServerExchange.listRoots() - Automatically fetches and combines all pages into single result - Refactor McpAsyncServerExchange.listRoots() to return Collections.unmodifiableList - Update tests to verify pagination functionality - Add test suite for McpAsyncServerExchange covering: - listRoots() pagination scenarios and edge cases - Logging notification with level filtering - Elicitation creation with various capabilities - Message creation with sampling capabilities - Error handling and validation scenarios - Verify sendNotification calls in logging notification tests - Verify sendRequest is never called when capabilities are missing Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
parent
5bd64c2beb
commit
1cbace3353
2 changed files with 770 additions and 4 deletions
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
package io.modelcontextprotocol.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.modelcontextprotocol.spec.McpError;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
|
|
@ -126,7 +129,19 @@ public class McpAsyncServerExchange {
|
|||
* @return A Mono that emits the list of roots result.
|
||||
*/
|
||||
public Mono<McpSchema.ListRootsResult> listRoots() {
|
||||
return this.listRoots(null);
|
||||
|
||||
// @formatter:off
|
||||
return this.listRoots(McpSchema.FIRST_PAGE)
|
||||
.expand(result -> (result.nextCursor() != null) ?
|
||||
this.listRoots(result.nextCursor()) : Mono.empty())
|
||||
.reduce(new McpSchema.ListRootsResult(new ArrayList<>(), null),
|
||||
(allRootsResult, result) -> {
|
||||
allRootsResult.roots().addAll(result.roots());
|
||||
return allRootsResult;
|
||||
})
|
||||
.map(result -> new McpSchema.ListRootsResult(Collections.unmodifiableList(result.roots()),
|
||||
result.nextCursor()));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1628,11 +1628,19 @@ public final class McpSchema {
|
|||
*
|
||||
* @param roots An array of Root objects, each representing a root directory or file
|
||||
* that the server can operate on.
|
||||
* @param nextCursor An optional cursor for pagination. If present, indicates there
|
||||
* are more roots available. The client can use this cursor to request the next page
|
||||
* of results by sending a roots/list request with the cursor parameter set to this
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record ListRootsResult( // @formatter:off
|
||||
@JsonProperty("roots") List<Root> roots) {
|
||||
@JsonProperty("roots") List<Root> roots,
|
||||
@JsonProperty("nextCursor") String nextCursor) {
|
||||
|
||||
public ListRootsResult(List<Root> roots) {
|
||||
this(roots, null);
|
||||
}
|
||||
} // @formatter:on
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue