Skip to content

Commit eaa0c69

Browse files
smohite04SHEETAL MOHITE
andauthored
feat: add support for meta parameter in client paginated list queries (#906)
* feat: add support for meta parameter in client paginated list queries# - resources/list - resources/templates/list - prompts/list - tools/list paginated list operations extended in this review: - listResources(String cursor, Map<String, Object> meta) - listResourceTemplates(String cursor, Map<String, Object> meta) - listPrompts(String cursor, Map<String, Object> meta) Closes #907 Co-authored-by: SHEETAL MOHITE <mohishee@amazon.com> Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
1 parent 8fd9903 commit eaa0c69

File tree

4 files changed

+733
-8
lines changed

4 files changed

+733
-8
lines changed

mcp-core/src/main/java/io/modelcontextprotocol/client/McpAsyncClient.java

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public class McpAsyncClient {
303303
return Mono.empty();
304304
}
305305

306-
return this.listToolsInternal(init, McpSchema.FIRST_PAGE).doOnNext(listToolsResult -> {
306+
return this.listToolsInternal(init, McpSchema.FIRST_PAGE, null).doOnNext(listToolsResult -> {
307307
listToolsResult.tools()
308308
.forEach(tool -> logger.debug("Tool {} schema: {}", tool.name(), tool.outputSchema()));
309309
if (enableCallToolSchemaCaching && listToolsResult.tools() != null) {
@@ -645,16 +645,27 @@ public Mono<McpSchema.ListToolsResult> listTools() {
645645
* @return A Mono that emits the list of tools result
646646
*/
647647
public Mono<McpSchema.ListToolsResult> listTools(String cursor) {
648-
return this.initializer.withInitialization("listing tools", init -> this.listToolsInternal(init, cursor));
648+
return this.initializer.withInitialization("listing tools", init -> this.listToolsInternal(init, cursor, null));
649649
}
650650

651-
private Mono<McpSchema.ListToolsResult> listToolsInternal(Initialization init, String cursor) {
651+
/**
652+
* Retrieves a paginated list of tools with optional metadata.
653+
* @param cursor Optional pagination cursor from a previous list request
654+
* @param meta Optional metadata to include in the request (_meta field)
655+
* @return A Mono that emits the list of tools result
656+
*/
657+
public Mono<McpSchema.ListToolsResult> listTools(String cursor, java.util.Map<String, Object> meta) {
658+
return this.initializer.withInitialization("listing tools", init -> this.listToolsInternal(init, cursor, meta));
659+
}
660+
661+
private Mono<McpSchema.ListToolsResult> listToolsInternal(Initialization init, String cursor,
662+
java.util.Map<String, Object> meta) {
652663

653664
if (init.initializeResult().capabilities().tools() == null) {
654665
return Mono.error(new IllegalStateException("Server does not provide tools capability"));
655666
}
656667
return init.mcpSession()
657-
.sendRequest(McpSchema.METHOD_TOOLS_LIST, new McpSchema.PaginatedRequest(cursor),
668+
.sendRequest(McpSchema.METHOD_TOOLS_LIST, new McpSchema.PaginatedRequest(cursor, meta),
658669
LIST_TOOLS_RESULT_TYPE_REF)
659670
.doOnNext(result -> {
660671
// Validate tool names (warn only)
@@ -725,12 +736,31 @@ public Mono<McpSchema.ListResourcesResult> listResources() {
725736
* @see #readResource(McpSchema.Resource)
726737
*/
727738
public Mono<McpSchema.ListResourcesResult> listResources(String cursor) {
739+
return this.listResourcesInternal(cursor, null);
740+
}
741+
742+
/**
743+
* Retrieves a paginated list of resources provided by the server. Resources represent
744+
* any kind of UTF-8 encoded data that an MCP server makes available to clients, such
745+
* as database records, API responses, log files, and more.
746+
* @param cursor Optional pagination cursor from a previous list request
747+
* @param meta Optional metadata to include in the request (_meta field)
748+
* @return A Mono that completes with the list of resources result.
749+
* @see McpSchema.ListResourcesResult
750+
* @see #readResource(McpSchema.Resource)
751+
*/
752+
public Mono<McpSchema.ListResourcesResult> listResources(String cursor, java.util.Map<String, Object> meta) {
753+
return this.listResourcesInternal(cursor, meta);
754+
}
755+
756+
private Mono<McpSchema.ListResourcesResult> listResourcesInternal(String cursor,
757+
java.util.Map<String, Object> meta) {
728758
return this.initializer.withInitialization("listing resources", init -> {
729759
if (init.initializeResult().capabilities().resources() == null) {
730760
return Mono.error(new IllegalStateException("Server does not provide the resources capability"));
731761
}
732762
return init.mcpSession()
733-
.sendRequest(McpSchema.METHOD_RESOURCES_LIST, new McpSchema.PaginatedRequest(cursor),
763+
.sendRequest(McpSchema.METHOD_RESOURCES_LIST, new McpSchema.PaginatedRequest(cursor, meta),
734764
LIST_RESOURCES_RESULT_TYPE_REF);
735765
});
736766
}
@@ -795,12 +825,31 @@ public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates() {
795825
* @see McpSchema.ListResourceTemplatesResult
796826
*/
797827
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor) {
828+
return this.listResourceTemplatesInternal(cursor, null);
829+
}
830+
831+
/**
832+
* Retrieves a paginated list of resource templates provided by the server. Resource
833+
* templates allow servers to expose parameterized resources using URI templates,
834+
* enabling dynamic resource access based on variable parameters.
835+
* @param cursor Optional pagination cursor from a previous list request
836+
* @param meta Optional metadata to include in the request (_meta field)
837+
* @return A Mono that completes with the list of resource templates result.
838+
* @see McpSchema.ListResourceTemplatesResult
839+
*/
840+
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor,
841+
java.util.Map<String, Object> meta) {
842+
return this.listResourceTemplatesInternal(cursor, meta);
843+
}
844+
845+
private Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplatesInternal(String cursor,
846+
java.util.Map<String, Object> meta) {
798847
return this.initializer.withInitialization("listing resource templates", init -> {
799848
if (init.initializeResult().capabilities().resources() == null) {
800849
return Mono.error(new IllegalStateException("Server does not provide the resources capability"));
801850
}
802851
return init.mcpSession()
803-
.sendRequest(McpSchema.METHOD_RESOURCES_TEMPLATES_LIST, new McpSchema.PaginatedRequest(cursor),
852+
.sendRequest(McpSchema.METHOD_RESOURCES_TEMPLATES_LIST, new McpSchema.PaginatedRequest(cursor, meta),
804853
LIST_RESOURCE_TEMPLATES_RESULT_TYPE_REF);
805854
});
806855
}
@@ -895,8 +944,26 @@ public Mono<ListPromptsResult> listPrompts() {
895944
* @see #getPrompt(GetPromptRequest)
896945
*/
897946
public Mono<ListPromptsResult> listPrompts(String cursor) {
898-
return this.initializer.withInitialization("listing prompts", init -> init.mcpSession()
899-
.sendRequest(McpSchema.METHOD_PROMPT_LIST, new PaginatedRequest(cursor), LIST_PROMPTS_RESULT_TYPE_REF));
947+
return this.listPromptsInternal(cursor, null);
948+
}
949+
950+
/**
951+
* Retrieves a paginated list of prompts with optional metadata.
952+
* @param cursor Optional pagination cursor from a previous list request
953+
* @param meta Optional metadata to include in the request (_meta field)
954+
* @return A Mono that completes with the list of prompts result.
955+
* @see McpSchema.ListPromptsResult
956+
* @see #getPrompt(GetPromptRequest)
957+
*/
958+
public Mono<ListPromptsResult> listPrompts(String cursor, java.util.Map<String, Object> meta) {
959+
return this.listPromptsInternal(cursor, meta);
960+
}
961+
962+
private Mono<ListPromptsResult> listPromptsInternal(String cursor, java.util.Map<String, Object> meta) {
963+
return this.initializer.withInitialization("listing prompts",
964+
init -> init.mcpSession()
965+
.sendRequest(McpSchema.METHOD_PROMPT_LIST, new PaginatedRequest(cursor, meta),
966+
LIST_PROMPTS_RESULT_TYPE_REF));
900967
}
901968

902969
/**

mcp-core/src/main/java/io/modelcontextprotocol/client/McpSyncClient.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,18 @@ public McpSchema.ListToolsResult listTools(String cursor) {
259259

260260
}
261261

262+
/**
263+
* Retrieves a paginated list of tools provided by the server.
264+
* @param cursor Optional pagination cursor from a previous list request
265+
* @param meta Optional metadata to include in the request (_meta field)
266+
* @return The list of tools result containing: - tools: List of available tools, each
267+
* with a name, description, and input schema - nextCursor: Optional cursor for
268+
* pagination if more tools are available
269+
*/
270+
public McpSchema.ListToolsResult listTools(String cursor, java.util.Map<String, Object> meta) {
271+
return withProvidedContext(this.delegate.listTools(cursor, meta)).block();
272+
}
273+
262274
// --------------------------
263275
// Resources
264276
// --------------------------
@@ -282,6 +294,17 @@ public McpSchema.ListResourcesResult listResources(String cursor) {
282294

283295
}
284296

297+
/**
298+
* Retrieves a paginated list of resources with optional metadata.
299+
* @param cursor Optional pagination cursor from a previous list request
300+
* @param meta Optional metadata to include in the request (_meta field)
301+
* @return The list of resources result
302+
*/
303+
public McpSchema.ListResourcesResult listResources(String cursor, java.util.Map<String, Object> meta) {
304+
return withProvidedContext(this.delegate.listResources(cursor, meta)).block();
305+
306+
}
307+
285308
/**
286309
* Send a resources/read request.
287310
* @param resource the resource to read
@@ -324,6 +347,21 @@ public McpSchema.ListResourceTemplatesResult listResourceTemplates(String cursor
324347

325348
}
326349

350+
/**
351+
* Resource templates allow servers to expose parameterized resources using URI
352+
* templates. Arguments may be auto-completed through the completion API.
353+
*
354+
* Retrieves a paginated list of resource templates provided by the server.
355+
* @param cursor Optional pagination cursor from a previous list request
356+
* @param meta Optional metadata to include in the request (_meta field)
357+
* @return The list of resource templates result.
358+
*/
359+
public McpSchema.ListResourceTemplatesResult listResourceTemplates(String cursor,
360+
java.util.Map<String, Object> meta) {
361+
return withProvidedContext(this.delegate.listResourceTemplates(cursor, meta)).block();
362+
363+
}
364+
327365
/**
328366
* Subscriptions. The protocol supports optional subscriptions to resource changes.
329367
* Clients can subscribe to specific resources and receive notifications when they
@@ -370,6 +408,17 @@ public ListPromptsResult listPrompts(String cursor) {
370408

371409
}
372410

411+
/**
412+
* Retrieves a paginated list of prompts provided by the server.
413+
* @param cursor Optional pagination cursor from a previous list request
414+
* @param meta Optional metadata to include in the request (_meta field)
415+
* @return The list of prompts result.
416+
*/
417+
public ListPromptsResult listPrompts(String cursor, java.util.Map<String, Object> meta) {
418+
return withProvidedContext(this.delegate.listPrompts(cursor, meta)).block();
419+
420+
}
421+
373422
public GetPromptResult getPrompt(GetPromptRequest getPromptRequest) {
374423
return withProvidedContext(this.delegate.getPrompt(getPromptRequest)).block();
375424
}

mcp-test/src/main/java/io/modelcontextprotocol/client/AbstractMcpSyncClientTests.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,19 @@ void testListTools() {
154154
});
155155
}
156156

157+
@Test
158+
void testListToolsWithMeta() {
159+
withClient(createMcpTransport(), mcpSyncClient -> {
160+
mcpSyncClient.initialize();
161+
java.util.Map<String, Object> meta = java.util.Map.of("requestId", "test-123");
162+
ListToolsResult tools = mcpSyncClient.listTools(McpSchema.FIRST_PAGE, meta);
163+
164+
assertThat(tools).isNotNull().satisfies(result -> {
165+
assertThat(result.tools()).isNotNull().isNotEmpty();
166+
});
167+
});
168+
}
169+
157170
@Test
158171
void testListAllTools() {
159172
withClient(createMcpTransport(), mcpSyncClient -> {
@@ -678,4 +691,43 @@ void testProgressConsumer() {
678691
});
679692
}
680693

694+
@Test
695+
void testListResourcesWithMeta() {
696+
withClient(createMcpTransport(), mcpSyncClient -> {
697+
mcpSyncClient.initialize();
698+
java.util.Map<String, Object> meta = java.util.Map.of("requestId", "test-123");
699+
ListResourcesResult resources = mcpSyncClient.listResources(McpSchema.FIRST_PAGE, meta);
700+
701+
assertThat(resources).isNotNull().satisfies(result -> {
702+
assertThat(result.resources()).isNotNull();
703+
});
704+
});
705+
}
706+
707+
@Test
708+
void testListResourceTemplatesWithMeta() {
709+
withClient(createMcpTransport(), mcpSyncClient -> {
710+
mcpSyncClient.initialize();
711+
java.util.Map<String, Object> meta = java.util.Map.of("requestId", "test-123");
712+
ListResourceTemplatesResult result = mcpSyncClient.listResourceTemplates(McpSchema.FIRST_PAGE, meta);
713+
714+
assertThat(result).isNotNull().satisfies(r -> {
715+
assertThat(r.resourceTemplates()).isNotNull();
716+
});
717+
});
718+
}
719+
720+
@Test
721+
void testListPromptsWithMeta() {
722+
withClient(createMcpTransport(), mcpSyncClient -> {
723+
mcpSyncClient.initialize();
724+
java.util.Map<String, Object> meta = java.util.Map.of("requestId", "test-123");
725+
McpSchema.ListPromptsResult result = mcpSyncClient.listPrompts(McpSchema.FIRST_PAGE, meta);
726+
727+
assertThat(result).isNotNull().satisfies(r -> {
728+
assertThat(r.prompts()).isNotNull();
729+
});
730+
});
731+
}
732+
681733
}

0 commit comments

Comments
 (0)