Class ModernMethodSupport

java.lang.Object
org.springframework.ai.mcp.annotation.common.ModernMethodSupport

public final class ModernMethodSupport extends Object
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 Type
    Method
    Description
    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.
    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 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 and McpTransportContext into the argument array, leaving every other slot untouched.
    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 and McpTransportContext into the argument array, leaving every other slot untouched.
    static boolean
    isContextParameter(Class<?> parameterType)
    Whether a parameter of this type is a modern context parameter, injected by the callback rather than bound from the request.
    static boolean
    isInfrastructureParameter(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 boolean
    isStreamingParameter(Class<?> parameterType)
    Whether a parameter of this type makes the invocation a streaming response, so that notifications can be pushed before the result.
    static void
    rejectLegacyContextParameter(Class<?> parameterType, Method method)
    Rejects the session-bound legacy parameter types with an explanation of what to use instead.
    static io.modelcontextprotocol.modern.McpSchema.ClientCapabilities
    Converts the requiredCapabilities attribute of a primitive annotation into the SDK form that the server checks before the method runs.
    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.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • isStreamingParameter

      public static boolean isStreamingParameter(Class<?> parameterType)
      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 declaring McpModernSyncRequestContext alone leaves the response a plain result.
    • isContextParameter

      public static boolean isContextParameter(Class<?> parameterType)
      Whether a parameter of this type is a modern context parameter, injected by the callback rather than bound from the request.
    • isInfrastructureParameter

      public static boolean isInfrastructureParameter(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.
      Parameters:
      modernRequestType - the modern request record of the primitive, for example io.modelcontextprotocol.modern.McpSchema.CallToolRequest
    • rejectLegacyContextParameter

      public static void rejectLegacyContextParameter(Class<?> parameterType, Method method)
      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 the requiredCapabilities attribute 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 an InputRequiredResult, the only way a modern method can use them.
      Parameters:
      method - the annotated method
      required - the annotation's requiredCapabilities
      Returns:
      the required capabilities, or McpSchema.ClientCapabilities.NONE when 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. When outcome is an InputRequiredResult, every input request is checked against ctx.clientCapabilities(); the missing capabilities are reported as JSON-RPC error -32021 whose 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 requiredCapabilities attribute, which refuses the call before the method runs.

      Parameters:
      ctx - the request context carrying the client's declared capabilities
      outcome - the handler's result
      method - the method that produced the result
      warned - 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

      public static Predicate<Method> 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 and McpTransportContext into the argument array, leaving every other slot untouched.
      Parameters:
      inputResponses - the request's MRTR input responses, if any
      requestState - the request's unsealed MRTR state, if any
      notifier - 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 and McpTransportContext into the argument array, leaving every other slot untouched.
      Parameters:
      inputResponses - the request's MRTR input responses, if any
      requestState - the request's unsealed MRTR state, if any
      notifier - the notifier of a streaming response, or null for a plain result
      jsonMapper - the mapper that inputResponse(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.