Expose resourcesUpdateConsumer() in sync client (#735)

`resourcesUpdateConsumer()` was missing from the sync client. Add it.
This commit is contained in:
Jordan Zimmerman 2026-01-08 19:29:05 +00:00 • committed by GitHub
commit b518393cfd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 12 deletions

View file

@ -4,17 +4,8 @@
package io.modelcontextprotocol.client;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
import io.modelcontextprotocol.common.McpTransportContext;
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpSchema.ClientCapabilities;
@ -28,6 +19,15 @@ import io.modelcontextprotocol.spec.McpTransport;
import io.modelcontextprotocol.util.Assert;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Factory class for creating Model Context Protocol (MCP) clients. MCP is a protocol that
* enables AI models to interact with external tools and resources through a standardized
@ -75,6 +75,7 @@ import reactor.core.publisher.Mono;
* .resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> System.out.println("Resources updated: " + resources)))
* .promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> System.out.println("Prompts updated: " + prompts)))
* .loggingConsumer(message -> Mono.fromRunnable(() -> System.out.println("Log message: " + message)))
* .resourcesUpdateConsumer(resourceContents -> Mono.fromRunnable(() -> System.out.println("Resources contents updated: " + resourceContents)))
* .build();
* }</pre>
*
@ -346,6 +347,22 @@ public interface McpClient {
return this;
}
/**
* Adds a consumer to be notified when a specific resource is updated. This allows
* the client to react to changes in individual resources, such as updates to
* their content or metadata.
* @param resourcesUpdateConsumer A consumer function that processes the updated
* resource and returns a Mono indicating the completion of the processing. Must
* not be null.
* @return This builder instance for method chaining.
* @throws IllegalArgumentException If the resourcesUpdateConsumer is null.
*/
public SyncSpec resourcesUpdateConsumer(Consumer<List<McpSchema.ResourceContents>> resourcesUpdateConsumer) {
Assert.notNull(resourcesUpdateConsumer, "Resources update consumer must not be null");
this.resourcesUpdateConsumers.add(resourcesUpdateConsumer);
return this;
}
/**
* Adds a consumer to be notified when the available prompts change. This allows
* the client to react to changes in the server's prompt templates, such as new

View file

@ -536,11 +536,13 @@ public abstract class AbstractMcpSyncClientTests {
AtomicBoolean toolsNotificationReceived = new AtomicBoolean(false);
AtomicBoolean resourcesNotificationReceived = new AtomicBoolean(false);
AtomicBoolean promptsNotificationReceived = new AtomicBoolean(false);
AtomicBoolean resourcesUpdatedNotificationReceived = new AtomicBoolean(false);
withClient(createMcpTransport(),
builder -> builder.toolsChangeConsumer(tools -> toolsNotificationReceived.set(true))
.resourcesChangeConsumer(resources -> resourcesNotificationReceived.set(true))
.promptsChangeConsumer(prompts -> promptsNotificationReceived.set(true)),
.promptsChangeConsumer(prompts -> promptsNotificationReceived.set(true))
.resourcesUpdateConsumer(resources -> resourcesUpdatedNotificationReceived.set(true)),
client -> {
assertThatCode(() -> {

View file

@ -535,11 +535,13 @@ public abstract class AbstractMcpSyncClientTests {
AtomicBoolean toolsNotificationReceived = new AtomicBoolean(false);
AtomicBoolean resourcesNotificationReceived = new AtomicBoolean(false);
AtomicBoolean promptsNotificationReceived = new AtomicBoolean(false);
AtomicBoolean resourcesUpdatedNotificationReceived = new AtomicBoolean(false);
withClient(createMcpTransport(),
builder -> builder.toolsChangeConsumer(tools -> toolsNotificationReceived.set(true))
.resourcesChangeConsumer(resources -> resourcesNotificationReceived.set(true))
.promptsChangeConsumer(prompts -> promptsNotificationReceived.set(true)),
.promptsChangeConsumer(prompts -> promptsNotificationReceived.set(true))
.resourcesUpdateConsumer(resources -> resourcesUpdatedNotificationReceived.set(true)),
client -> {
assertThatCode(() -> {