diff --git a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/FluxToolSpecificationPostProcessor.java b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/FluxToolSpecificationPostProcessor.java
new file mode 100644
index 00000000000..f4bb20742da
--- /dev/null
+++ b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/FluxToolSpecificationPostProcessor.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2025-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ai.mcp.server.common.autoconfigure.annotations;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.modelcontextprotocol.common.McpTransportContext;
+import io.modelcontextprotocol.server.McpStatelessServerFeatures;
+import io.modelcontextprotocol.spec.McpSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import org.springframework.util.ReflectionUtils;
+
+/**
+ * Post-processor that wraps AsyncToolSpecifications to handle Flux return types properly
+ * by collecting all elements before serialization.
+ *
+ * 
+ * Background:  This class fixes Issue #4542 where Flux-returning @McpTool
+ * methods only return the first element. The root cause is in the external {@code
+ * org.springaicommunity.mcp.provider.tool.AsyncStatelessMcpToolProvider} library, which
+ * treats Flux as a single-value Publisher and only takes the first element.
+ *
+ * 
+ * Solution:  This post-processor intercepts tool specifications and wraps
+ * their call handlers. When a method returns a Flux, it collects all elements into a list
+ * before passing the result to the MCP serialization layer.
+ *
+ * 
+ * Note:  Users can also work around this issue by returning {@code
+ * Mono>} instead of {@code Flux} from their {@code @McpTool} methods.
+ *
+ * @author liugddx
+ * @since 1.1.0
+ * @see Issue #4542 
+ */
+public final class FluxToolSpecificationPostProcessor {
+
+	private static final Logger logger = LoggerFactory.getLogger(FluxToolSpecificationPostProcessor.class);
+
+	private static final ObjectMapper objectMapper = new ObjectMapper();
+
+	private FluxToolSpecificationPostProcessor() {
+		// Utility class - no instances allowed
+	}
+
+	/**
+	 * Wraps tool specifications to properly handle Flux return types by collecting all
+	 * elements into a list.
+	 * @param originalSpecs the original tool specifications from the annotation provider
+	 * @param toolBeans the bean objects containing @McpTool annotated methods
+	 * @return wrapped tool specifications that properly collect Flux elements
+	 */
+	public static List processToolSpecifications(
+			List originalSpecs, List toolBeans) {
+
+		List processedSpecs = new ArrayList<>();
+
+		for (McpStatelessServerFeatures.AsyncToolSpecification spec : originalSpecs) {
+			ToolMethodInfo methodInfo = findToolMethod(toolBeans, spec.tool().name());
+			if (methodInfo != null && methodInfo.returnsFlux()) {
+				logger.info("Detected Flux return type for MCP tool '{}', applying collection wrapper",
+						spec.tool().name());
+				McpStatelessServerFeatures.AsyncToolSpecification wrappedSpec = wrapToolSpecificationForFlux(spec,
+						methodInfo);
+				processedSpecs.add(wrappedSpec);
+			}
+			else {
+				processedSpecs.add(spec);
+			}
+		}
+
+		return processedSpecs;
+	}
+
+	/**
+	 * Finds the method annotated with @McpTool that matches the given tool name.
+	 * @param toolBeans the bean objects containing @McpTool annotated methods
+	 * @param toolName the name of the tool to find
+	 * @return the ToolMethodInfo object, or null if not found
+	 */
+	private static ToolMethodInfo findToolMethod(List toolBeans, String toolName) {
+		for (Object bean : toolBeans) {
+			Class> clazz = bean.getClass();
+			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
+			for (Method method : methods) {
+				McpTool annotation = method.getAnnotation(McpTool.class);
+				if (annotation != null && annotation.name().equals(toolName)) {
+					return new ToolMethodInfo(bean, method);
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Wraps a tool specification to collect all Flux elements before serialization.
+	 * @param original the original tool specification
+	 * @param methodInfo the method information including bean and method
+	 * @return the wrapped tool specification
+	 */
+	private static McpStatelessServerFeatures.AsyncToolSpecification wrapToolSpecificationForFlux(
+			McpStatelessServerFeatures.AsyncToolSpecification original, ToolMethodInfo methodInfo) {
+
+		BiFunction> originalHandler = original
+			.callHandler();
+
+		BiFunction> wrappedHandler = (
+				context, request) -> {
+			try {
+				// Invoke the method directly to get access to the Flux
+				Object[] args = buildMethodArguments(methodInfo.method(), request.arguments());
+				Object result = ReflectionUtils.invokeMethod(methodInfo.method(), methodInfo.bean(), args);
+
+				if (result instanceof Flux) {
+					// Collect all Flux elements into a list
+					Flux> flux = (Flux>) result;
+					return flux.collectList().flatMap(list -> {
+						// Serialize the list to JSON
+						try {
+							String jsonContent = objectMapper.writeValueAsString(list);
+							return Mono.just(new McpSchema.CallToolResult(
+									List.of(new McpSchema.TextContent(jsonContent)), false));
+						}
+						catch (Exception e) {
+							logger.error("Failed to serialize Flux result for tool '{}'", original.tool().name(), e);
+							return Mono.just(new McpSchema.CallToolResult(
+									List.of(new McpSchema.TextContent("Error: " + e.getMessage())), true));
+						}
+					});
+				}
+				else {
+					// Fall back to original handler for non-Flux results
+					return originalHandler.apply(context, request);
+				}
+			}
+			catch (Exception e) {
+				logger.error("Failed to invoke tool method '{}'", original.tool().name(), e);
+				return Mono.just(new McpSchema.CallToolResult(
+						List.of(new McpSchema.TextContent("Error: " + e.getMessage())), true));
+			}
+		};
+
+		return new McpStatelessServerFeatures.AsyncToolSpecification(original.tool(), wrappedHandler);
+	}
+
+	/**
+	 * Builds method arguments from the request arguments map.
+	 * @param method the method to invoke
+	 * @param requestArgs the arguments from the CallToolRequest
+	 * @return array of method arguments
+	 */
+	private static Object[] buildMethodArguments(Method method, Map requestArgs) {
+		java.lang.reflect.Parameter[] parameters = method.getParameters();
+		Object[] args = new Object[parameters.length];
+
+		for (int i = 0; i < parameters.length; i++) {
+			java.lang.reflect.Parameter param = parameters[i];
+			McpToolParam paramAnnotation = param.getAnnotation(McpToolParam.class);
+
+			if (paramAnnotation != null) {
+				String paramName = paramAnnotation.name().isEmpty() ? param.getName() : paramAnnotation.name();
+				Object value = requestArgs.get(paramName);
+
+				// Type conversion if needed
+				if (value != null) {
+					args[i] = objectMapper.convertValue(value, param.getType());
+				}
+				else if (!paramAnnotation.required()) {
+					args[i] = null;
+				}
+				else {
+					throw new IllegalArgumentException("Required parameter '" + paramName + "' is missing");
+				}
+			}
+			else {
+				// Try to match by parameter name
+				Object value = requestArgs.get(param.getName());
+				if (value != null) {
+					args[i] = objectMapper.convertValue(value, param.getType());
+				}
+				else {
+					args[i] = null;
+				}
+			}
+		}
+
+		return args;
+	}
+
+	/**
+	 * Holds information about a tool method.
+	 */
+	private static class ToolMethodInfo {
+
+		private final Object bean;
+
+		private final Method method;
+
+		ToolMethodInfo(Object bean, Method method) {
+			this.bean = bean;
+			this.method = method;
+			ReflectionUtils.makeAccessible(method);
+		}
+
+		Object bean() {
+			return this.bean;
+		}
+
+		Method method() {
+			return this.method;
+		}
+
+		boolean returnsFlux() {
+			return Flux.class.isAssignableFrom(this.method.getReturnType());
+		}
+
+	}
+
+}
diff --git a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/StatelessServerSpecificationFactoryAutoConfiguration.java b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/StatelessServerSpecificationFactoryAutoConfiguration.java
index 97d01f82280..8f9430a55f8 100644
--- a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/StatelessServerSpecificationFactoryAutoConfiguration.java
+++ b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/main/java/org/springframework/ai/mcp/server/common/autoconfigure/annotations/StatelessServerSpecificationFactoryAutoConfiguration.java
@@ -127,8 +127,12 @@ public List completionS
 		@Bean
 		public List toolSpecs(
 				ServerMcpAnnotatedBeans beansWithMcpMethodAnnotations) {
-			return AsyncMcpAnnotationProviders
-				.statelessToolSpecifications(beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class));
+			List toolBeans = beansWithMcpMethodAnnotations.getBeansByAnnotation(McpTool.class);
+			List originalSpecs = AsyncMcpAnnotationProviders
+				.statelessToolSpecifications(toolBeans);
+
+			// Apply post-processing to handle Flux return types (Issue #4542)
+			return FluxToolSpecificationPostProcessor.processToolSpecifications(originalSpecs, toolBeans);
 		}
 
 	}
diff --git a/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/test/java/org/springframework/ai/mcp/server/common/autoconfigure/FluxReturnTypeIT.java b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/test/java/org/springframework/ai/mcp/server/common/autoconfigure/FluxReturnTypeIT.java
new file mode 100644
index 00000000000..670164c4b66
--- /dev/null
+++ b/auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common/src/test/java/org/springframework/ai/mcp/server/common/autoconfigure/FluxReturnTypeIT.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2025-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ai.mcp.server.common.autoconfigure;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.modelcontextprotocol.common.McpTransportContext;
+import io.modelcontextprotocol.server.McpStatelessServerFeatures;
+import io.modelcontextprotocol.spec.McpSchema;
+import org.junit.jupiter.api.Test;
+import org.springaicommunity.mcp.annotation.McpTool;
+import org.springaicommunity.mcp.annotation.McpToolParam;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import org.springframework.ai.mcp.server.common.autoconfigure.annotations.McpServerAnnotationScannerAutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration test to verify the fix for Issue #4542: Stateless Async MCP Server with
+ * streamable-http returns only the first element from tools with a Flux return type.
+ *
+ * @author liugddx
+ */
+public class FluxReturnTypeIT {
+
+	private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+		.withConfiguration(AutoConfigurations.of(McpServerStatelessAutoConfiguration.class,
+				McpServerAnnotationScannerAutoConfiguration.class,
+				StatelessToolCallbackConverterAutoConfiguration.class));
+
+	private final ObjectMapper objectMapper = new ObjectMapper();
+
+	/**
+	 * This test verifies that @McpTool methods returning Flux now properly return all
+	 * elements after the fix.
+	 */
+	@Test
+	void testFluxReturnTypeReturnsAllElements() {
+		this.contextRunner.withUserConfiguration(FluxToolConfiguration.class)
+			.withPropertyValues("spring.ai.mcp.server.type=ASYNC", "spring.ai.mcp.server.protocol=STATELESS",
+					"spring.ai.mcp.server.annotation.enabled=true")
+			.run(context -> {
+				assertThat(context).hasBean("fluxTestTools");
+
+				// Get the tool specifications
+				List toolSpecs = context.getBean("toolSpecs",
+						List.class);
+				assertThat(toolSpecs).isNotEmpty();
+
+				// Find the flux-test tool
+				McpStatelessServerFeatures.AsyncToolSpecification fluxTestTool = toolSpecs.stream()
+					.filter(spec -> spec.tool().name().equals("flux-test"))
+					.findFirst()
+					.orElseThrow(() -> new AssertionError("flux-test tool not found"));
+
+				// Call the tool with count=3
+				McpSchema.CallToolRequest request = McpSchema.CallToolRequest.builder()
+					.name("flux-test")
+					.arguments(Map.of("count", 3))
+					.build();
+
+				McpSchema.CallToolResult result = fluxTestTool.callHandler()
+					.apply(new McpTransportContext(Map.of()), request)
+					.block();
+
+				assertThat(result).isNotNull();
+				assertThat(result.isError()).isFalse();
+				assertThat(result.content()).hasSize(1);
+
+				// Verify all three elements are present in the result
+				String content = ((McpSchema.TextContent) result.content().get(0)).text();
+				List items = this.objectMapper.readValue(content, List.class);
+
+				assertThat(items).containsExactly("item-1", "item-2", "item-3");
+			});
+	}
+
+	/**
+	 * This test verifies that @McpTool methods returning Flux with complex
+	 * objects properly return all elements.
+	 */
+	@Test
+	void testFluxReturnTypeWithComplexObjects() {
+		this.contextRunner.withUserConfiguration(FluxToolConfiguration.class)
+			.withPropertyValues("spring.ai.mcp.server.type=ASYNC", "spring.ai.mcp.server.protocol=STATELESS",
+					"spring.ai.mcp.server.annotation.enabled=true")
+			.run(context -> {
+				assertThat(context).hasBean("fluxTestTools");
+
+				List toolSpecs = context.getBean("toolSpecs",
+						List.class);
+
+				McpStatelessServerFeatures.AsyncToolSpecification fluxDataTool = toolSpecs.stream()
+					.filter(spec -> spec.tool().name().equals("flux-data-stream"))
+					.findFirst()
+					.orElseThrow(() -> new AssertionError("flux-data-stream tool not found"));
+
+				McpSchema.CallToolRequest request = McpSchema.CallToolRequest.builder()
+					.name("flux-data-stream")
+					.arguments(Map.of("category", "test"))
+					.build();
+
+				McpSchema.CallToolResult result = fluxDataTool.callHandler()
+					.apply(new McpTransportContext(Map.of()), request)
+					.block();
+
+				assertThat(result).isNotNull();
+				assertThat(result.isError()).isFalse();
+
+				String content = ((McpSchema.TextContent) result.content().get(0)).text();
+				List> items = this.objectMapper.readValue(content, List.class);
+
+				assertThat(items).hasSize(3);
+				assertThat(items.get(0)).containsEntry("id", "id1");
+				assertThat(items.get(1)).containsEntry("id", "id2");
+				assertThat(items.get(2)).containsEntry("id", "id3");
+			});
+	}
+
+	/**
+	 * This test demonstrates that the workaround using Mono> continues to work
+	 * properly.
+	 */
+	@Test
+	void testMonoListWorkaround() {
+		this.contextRunner.withUserConfiguration(MonoListToolConfiguration.class)
+			.withPropertyValues("spring.ai.mcp.server.type=ASYNC", "spring.ai.mcp.server.protocol=STATELESS",
+					"spring.ai.mcp.server.annotation.enabled=true")
+			.run(context -> {
+				assertThat(context).hasBean("monoListTestTools");
+
+				List toolSpecs = context.getBean("toolSpecs",
+						List.class);
+
+				McpStatelessServerFeatures.AsyncToolSpecification monoListTool = toolSpecs.stream()
+					.filter(spec -> spec.tool().name().equals("mono-list-test"))
+					.findFirst()
+					.orElseThrow(() -> new AssertionError("mono-list-test tool not found"));
+
+				McpSchema.CallToolRequest request = McpSchema.CallToolRequest.builder()
+					.name("mono-list-test")
+					.arguments(Map.of("count", 3))
+					.build();
+
+				McpSchema.CallToolResult result = monoListTool.callHandler()
+					.apply(new McpTransportContext(Map.of()), request)
+					.block();
+
+				assertThat(result).isNotNull();
+				assertThat(result.isError()).isFalse();
+
+				// The workaround should also return all three elements
+				String content = ((McpSchema.TextContent) result.content().get(0)).text();
+				List items = this.objectMapper.readValue(content, List.class);
+
+				assertThat(items).containsExactly("item-1", "item-2", "item-3");
+			});
+	}
+
+	@Configuration
+	static class FluxToolConfiguration {
+
+		@Bean
+		FluxTestTools fluxTestTools() {
+			return new FluxTestTools();
+		}
+
+	}
+
+	@Component
+	static class FluxTestTools {
+
+		/**
+		 * This method demonstrates the bug: it returns Flux but only the first
+		 * element is returned to the client.
+		 */
+		@McpTool(name = "flux-test", description = "Test Flux return type - BUGGY")
+		public Flux getMultipleItems(
+				@McpToolParam(description = "Number of items to return", required = true) int count) {
+			return Flux.range(1, count).map(i -> "item-" + i);
+		}
+
+		/**
+		 * This method also demonstrates the bug with a more realistic streaming scenario.
+		 */
+		@McpTool(name = "flux-data-stream", description = "Stream data items - BUGGY")
+		public Flux streamDataItems(
+				@McpToolParam(description = "Category to filter", required = false) String category) {
+			return Flux.just(new DataItem("id1", "Item 1", category), new DataItem("id2", "Item 2", category),
+					new DataItem("id3", "Item 3", category));
+		}
+
+	}
+
+	@Configuration
+	static class MonoListToolConfiguration {
+
+		@Bean
+		MonoListTestTools monoListTestTools() {
+			return new MonoListTestTools();
+		}
+
+	}
+
+	@Component
+	static class MonoListTestTools {
+
+		/**
+		 * WORKAROUND: Use Mono> instead of Flux to return all elements.
+		 */
+		@McpTool(name = "mono-list-test", description = "Test Mono workaround")
+		public Mono> getMultipleItems(
+				@McpToolParam(description = "Number of items to return", required = true) int count) {
+			return Flux.range(1, count).map(i -> "item-" + i).collectList();
+		}
+
+		/**
+		 * WORKAROUND: Collect Flux elements into a list before returning.
+		 */
+		@McpTool(name = "mono-list-data-stream", description = "Get data items as list")
+		public Mono> getDataItems(
+				@McpToolParam(description = "Category to filter", required = false) String category) {
+			return Flux
+				.just(new DataItem("id1", "Item 1", category), new DataItem("id2", "Item 2", category),
+						new DataItem("id3", "Item 3", category))
+				.collectList();
+		}
+
+	}
+
+	record DataItem(String id, String name, String category) {
+	}
+
+}