spring-projects/spring-ai · warning
Stateless servers doesn't support bidirectional parameters.
Error message
Stateless servers doesn't support bidirectional parameters. Skipping method <method> with bidirectional parameters
What it means
Stateless MCP servers cannot correlate the client callback that bidirectional parameters require. When a method on a stateless server declares parameters that support bidirectional communication (e.g. McpSyncRequestContext/McpAsyncRequestContext exchange with callbacks), the method is skipped and a warning is logged rather than thrown.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/common/McpPredicates.java:102
if (McpSyncRequestContext.class.isAssignableFrom(paramType)
|| McpAsyncRequestContext.class.isAssignableFrom(paramType)
|| McpSyncServerExchange.class.isAssignableFrom(paramType)
|| McpAsyncServerExchange.class.isAssignableFrom(paramType)) {
return true;
}
}
return false;
}
public static Predicate<Method> filterMethodWithBidirectionalParameters() {
return method -> {
if (!hasBidirectionalParameters(method)) {
return true;
}
if (logger.isWarnEnabled()) {
logger.warn("Stateless servers doesn't support bidirectional parameters. Skipping method " + method
+ " with bidirectional parameters");
}
return false;
};
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Use a stateful server builder (McpServer.async()/sync() stateful variant) so bidirectional parameters are supported
- Remove the bidirectional context parameter from the method, or restrict the method to stateless-safe operations (no sampling/elicitation/progress)
- Keep bidirectional methods in a separate service registered only with stateful servers
Example fix
// before (stateless server)
@McpTool(description = "Ask")
public String ask(McpSyncRequestContext ctx, String q) { return ctx.sample(s -> s.prompt("Think: " + q)).block(); }
// after (stateless-safe)
@McpTool(description = "Ask")
public String ask(String q) { return staticAnswer(q); } Defensive patterns
Strategy: validation
Validate before calling
boolean stateless = builder instanceof McpServer.StatelessSyncSpecification || builder instanceof McpServer.StatelessAsyncSpecification;
if (stateless) {
for (Method m : service.getClass().getDeclaredMethods()) {
for (Class<?> p : m.getParameterTypes()) {
if (McpSyncRequestContext.class == p || McpAsyncRequestContext.class == p) {
throw new IllegalStateException(m + " uses bidirectional context; needs a stateful server");
}
}
}
} Type guard
static boolean usesBidirectionalContext(Method m) {
return java.util.Arrays.stream(m.getParameterTypes())
.anyMatch(p -> p == McpSyncRequestContext.class || p == McpAsyncRequestContext.class);
} Prevention
- Match server statefulness to tool capabilities: stateful if sampling/elicitation/progress are used
- Document which services require bidirectional context parameters
- Check startup warnings about skipped methods with bidirectional parameters
When it happens
Trigger: Declaring a method parameter of type McpSyncRequestContext (or the async equivalent) that performs bidirectional operations like sampling or elicitation, then registering it with a STATELESS MCP server.
Common situations: Configuring a stateless (McpServer.StatelessAsyncSpecification/StatelessSyncSpecification) server while copying tool examples that use request contexts for sampling/progress; stateful-to-stateless migration.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- No complete methods found in the provided complete objects:
- Async complete methods should use McpAsyncRequestContext ins
- Sync complete methods should use McpSyncRequestContext inste
- Method cannot have more than one request context parameter:
- Sync complete methods should use McpSyncRequestContext inste
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/acdbfcc8ca617116.
Report an issue: GitHub.