Class ModernMethodSupport
java.lang.Object
org.springframework.ai.mcp.annotation.common.ModernMethodSupport
Parameter handling shared by the method callbacks of a 2026-07-28 ("modern") MCP
server.
A modern method may declare McpModernSyncRequestContext, the SDK
McpRequestContext, McpSyncNotifier and McpTransportContext next
to the primitive's own parameters. The legacy exchange and request context types are
rejected because there is no session to back them.
- Since:
- 2.1.0
- Author:
- Christian Tzolov
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidcheckClientCapabilities(io.modelcontextprotocol.modern.server.McpRequestContext ctx, @Nullable Object outcome, Method method, AtomicBoolean warned) Enforces the 2026-07-28 rule that a server must not request input the client did not declare a capability for.A provider filter that skips, with a warning naming the modern server and the replacement type, any method declaring a legacy exchange or request context parameter.static voidinjectContextArguments(Object[] args, Parameter[] parameters, io.modelcontextprotocol.modern.server.McpRequestContext context, @Nullable Map<String, Object> inputResponses, @Nullable String requestState, @Nullable io.modelcontextprotocol.modern.server.McpSyncNotifier notifier) Fills the modern context parameters andMcpTransportContextinto the argument array, leaving every other slot untouched.static voidinjectContextArguments(Object[] args, Parameter[] parameters, io.modelcontextprotocol.modern.server.McpRequestContext context, @Nullable Map<String, Object> inputResponses, @Nullable String requestState, @Nullable io.modelcontextprotocol.modern.server.McpSyncNotifier notifier, @Nullable io.modelcontextprotocol.json.McpJsonMapper jsonMapper) Fills the modern context parameters andMcpTransportContextinto the argument array, leaving every other slot untouched.static booleanisContextParameter(Class<?> parameterType) Whether a parameter of this type is a modern context parameter, injected by the callback rather than bound from the request.static booleanisInfrastructureParameter(Class<?> parameterType, Class<?> modernRequestType) Whether a parameter of this type is injected by a modern callback rather than bound from the request: a modern context parameter or the primitive's modern request type.static booleanisStreamingParameter(Class<?> parameterType) Whether a parameter of this type makes the invocation a streaming response, so that notifications can be pushed before the result.static voidrejectLegacyContextParameter(Class<?> parameterType, Method method) Rejects the session-bound legacy parameter types with an explanation of what to use instead.static io.modelcontextprotocol.modern.McpSchema.ClientCapabilitiesrequiredCapabilities(Method method, McpClientCapability[] required) Converts therequiredCapabilitiesattribute of a primitive annotation into the SDK form that the server checks before the method runs.static io.modelcontextprotocol.modern.McpExceptionTranslates a failure of the method invocation into the protocol error the modern server reports: modern exceptions pass through, legacy protocol errors are converted and anything else is logged and reported as an internal error, as the SDK does, so that its message stays server-side.
-
Method Details
-
isStreamingParameter
Whether a parameter of this type makes the invocation a streaming response, so that notifications can be pushed before the result. Only the SDK notifier does; the response shape is the method's explicit choice, as it is for a handler written against the SDK, and declaringMcpModernSyncRequestContextalone leaves the response a plain result. -
isContextParameter
Whether a parameter of this type is a modern context parameter, injected by the callback rather than bound from the request. -
isInfrastructureParameter
Whether a parameter of this type is injected by a modern callback rather than bound from the request: a modern context parameter or the primitive's modern request type.- Parameters:
modernRequestType- the modern request record of the primitive, for exampleio.modelcontextprotocol.modern.McpSchema.CallToolRequest
-
rejectLegacyContextParameter
Rejects the session-bound legacy parameter types with an explanation of what to use instead.- Throws:
IllegalArgumentException- if the type is a legacy exchange or request context
-
requiredCapabilities
public static io.modelcontextprotocol.modern.McpSchema.ClientCapabilities requiredCapabilities(Method method, McpClientCapability[] required) Converts therequiredCapabilitiesattribute of a primitive annotation into the SDK form that the server checks before the method runs. Warns when the method declares capabilities but its return type cannot carry anInputRequiredResult, the only way a modern method can use them.- Parameters:
method- the annotated methodrequired- the annotation'srequiredCapabilities- Returns:
- the required capabilities, or
McpSchema.ClientCapabilities.NONEwhen none are declared - Since:
- 2.1.0
-
checkClientCapabilities
public static void checkClientCapabilities(io.modelcontextprotocol.modern.server.McpRequestContext ctx, @Nullable Object outcome, Method method, AtomicBoolean warned) Enforces the 2026-07-28 rule that a server must not request input the client did not declare a capability for. Whenoutcomeis anInputRequiredResult, every input request is checked againstctx.clientCapabilities(); the missing capabilities are reported as JSON-RPC error-32021whose data names them. Any other outcome passes through untouched.This is the safety net for a method that requests input without checking the client's capabilities first. The first time it fires for a method, it logs a warning recommending the
requiredCapabilitiesattribute, which refuses the call before the method runs.- Parameters:
ctx- the request context carrying the client's declared capabilitiesoutcome- the handler's resultmethod- the method that produced the resultwarned- whether the warning has been logged for this method; owned by the callback, so that nothing outlives it- Throws:
io.modelcontextprotocol.modern.McpException--32021 Missing required client capability- Since:
- 2.1.0
-
filterLegacyContextMethods
A provider filter that skips, with a warning naming the modern server and the replacement type, any method declaring a legacy exchange or request context parameter. The callbacks reject such methods outright; the providers skip them so that one unconverted method does not prevent the application from starting. -
injectContextArguments
public static void injectContextArguments(Object[] args, Parameter[] parameters, io.modelcontextprotocol.modern.server.McpRequestContext context, @Nullable Map<String, Object> inputResponses, @Nullable String requestState, @Nullable io.modelcontextprotocol.modern.server.McpSyncNotifier notifier) Fills the modern context parameters andMcpTransportContextinto the argument array, leaving every other slot untouched.- Parameters:
inputResponses- the request's MRTR input responses, if anyrequestState- the request's unsealed MRTR state, if anynotifier- the notifier of a streaming response, or null for a plain result
-
injectContextArguments
public static void injectContextArguments(Object[] args, Parameter[] parameters, io.modelcontextprotocol.modern.server.McpRequestContext context, @Nullable Map<String, Object> inputResponses, @Nullable String requestState, @Nullable io.modelcontextprotocol.modern.server.McpSyncNotifier notifier, @Nullable io.modelcontextprotocol.json.McpJsonMapper jsonMapper) Fills the modern context parameters andMcpTransportContextinto the argument array, leaving every other slot untouched.- Parameters:
inputResponses- the request's MRTR input responses, if anyrequestState- the request's unsealed MRTR state, if anynotifier- the notifier of a streaming response, or null for a plain resultjsonMapper- the mapper thatinputResponse(key, type)converts with, normally the server's, or null for the SDK default
-
translate
public static io.modelcontextprotocol.modern.McpException translate(Throwable failure, String primitive, Method method, Object bean) Translates a failure of the method invocation into the protocol error the modern server reports: modern exceptions pass through, legacy protocol errors are converted and anything else is logged and reported as an internal error, as the SDK does, so that its message stays server-side.
-