diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncListFilter.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncListFilter.java index d6b1858bf..6a72a97f7 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncListFilter.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncListFilter.java @@ -52,7 +52,10 @@ public interface McpAsyncListFilter { static McpAsyncListFilter fromSync(McpSyncListFilter filter, boolean immediateExecution) { Assert.notNull(filter, "filter must not be null"); return (transportContext, primitive) -> { - var visible = Mono.fromCallable(() -> filter.isVisible(transportContext, primitive)); + // Not fromCallable: subscribeOn would fuse it into MonoSubscribeOnCallable, + // which can interrupt the worker thread after a downstream all() cancelled it + // from that thread, e.g. while that thread writes the HTTP response + var visible = Mono.defer(() -> Mono.just(filter.isVisible(transportContext, primitive))); return immediateExecution ? visible : visible.subscribeOn(Schedulers.boundedElastic()); }; }