Remove deprecated APIs and modules for 1.0.0 release (#807)

- Remove mcp-json-jackson module (JacksonMcpJsonMapper, DefaultJsonSchemaValidator)
- Remove deprecated session interfaces (McpServerSession, McpClientSession methods)
- Remove deprecated server methods (loggingNotification, McpAsyncServerExchange constructor)
- Remove deprecated schema definitions and constructors (McpSchema, McpError, tool/content classes)
- Replace generic McpError with appropriate exception types (IllegalStateException, IllegalArgumentException)
- Update all tests to use current APIs

---------

Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
This commit is contained in:
Dariusz Jędrzejczyk 2026-02-20 17:32:40 +01:00 • committed by GitHub
commit 4c1c3d8d5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 261 additions and 1940 deletions

View file

@ -185,19 +185,6 @@ public class HttpClientSseClientTransport implements McpClientTransport {
// Default constructor
}
/**
* Creates a new builder with the specified base URI.
* @param baseUri the base URI of the MCP server
* @deprecated Use {@link HttpClientSseClientTransport#builder(String)} instead.
* This constructor is deprecated and will be removed or made {@code protected} or
* {@code private} in a future release.
*/
@Deprecated(forRemoval = true)
public Builder(String baseUri) {
Assert.hasText(baseUri, "baseUri must not be empty");
this.baseUri = baseUri;
}
/**
* Sets the base URI.
* @param baseUri the base URI

View file

@ -32,7 +32,9 @@ class DefaultMcpStatelessServerHandler implements McpStatelessServerHandler {
McpSchema.JSONRPCRequest request) {
McpStatelessRequestHandler<?> requestHandler = this.requestHandlers.get(request.method());
if (requestHandler == null) {
return Mono.error(new McpError("Missing handler for request type: " + request.method()));
return Mono.error(McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND)
.message("Missing handler for request type: " + request.method())
.build());
}
return requestHandler.handle(transportContext, request.params())
.map(result -> new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION, request.id(), result, null))

View file

@ -326,7 +326,7 @@ public class McpAsyncServer {
if (toolSpecification.tool() == null) {
return Mono.error(new IllegalArgumentException("Tool must not be null"));
}
if (toolSpecification.call() == null && toolSpecification.callHandler() == null) {
if (toolSpecification.callHandler() == null) {
return Mono.error(new IllegalArgumentException("Tool call handler must not be null"));
}
if (this.serverCapabilities.tools() == null) {
@ -869,32 +869,6 @@ public class McpAsyncServer {
// Logging Management
// ---------------------------------------
/**
* This implementation would, incorrectly, broadcast the logging message to all
* connected clients, using a single minLoggingLevel for all of them. Similar to the
* sampling and roots, the logging level should be set per client session and use the
* ServerExchange to send the logging message to the right client.
* @param loggingMessageNotification The logging message to send
* @return A Mono that completes when the notification has been sent
* @deprecated Use
* {@link McpAsyncServerExchange#loggingNotification(LoggingMessageNotification)}
* instead.
*/
@Deprecated
public Mono<Void> loggingNotification(LoggingMessageNotification loggingMessageNotification) {
if (loggingMessageNotification == null) {
return Mono.error(new McpError("Logging message must not be null"));
}
if (loggingMessageNotification.level().level() < minLoggingLevel.level()) {
return Mono.empty();
}
return this.mcpTransportProvider.notifyClients(McpSchema.METHOD_NOTIFICATION_MESSAGE,
loggingMessageNotification);
}
private McpRequestHandler<Object> setLoggerRequestHandler() {
return (exchange, params) -> {
return Mono.defer(() -> {

View file

@ -49,28 +49,6 @@ public class McpAsyncServerExchange {
public static final TypeRef<Object> OBJECT_TYPE_REF = new TypeRef<>() {
};
/**
* Create a new asynchronous exchange with the client.
* @param session The server session representing a 1-1 interaction.
* @param clientCapabilities The client capabilities that define the supported
* features and functionality.
* @param clientInfo The client implementation information.
* @deprecated Use
* {@link #McpAsyncServerExchange(String, McpLoggableSession, McpSchema.ClientCapabilities, McpSchema.Implementation, McpTransportContext)}
*/
@Deprecated
public McpAsyncServerExchange(McpSession session, McpSchema.ClientCapabilities clientCapabilities,
McpSchema.Implementation clientInfo) {
this.sessionId = null;
if (!(session instanceof McpLoggableSession)) {
throw new IllegalArgumentException("Expecting session to be a McpLoggableSession instance");
}
this.session = (McpLoggableSession) session;
this.clientCapabilities = clientCapabilities;
this.clientInfo = clientInfo;
this.transportContext = McpTransportContext.EMPTY;
}
/**
* Create a new asynchronous exchange with the client.
* @param session The server session representing a 1-1 interaction.
@ -142,10 +120,11 @@ public class McpAsyncServerExchange {
*/
public Mono<McpSchema.CreateMessageResult> createMessage(McpSchema.CreateMessageRequest createMessageRequest) {
if (this.clientCapabilities == null) {
return Mono.error(new McpError("Client must be initialized. Call the initialize method first!"));
return Mono
.error(new IllegalStateException("Client must be initialized. Call the initialize method first!"));
}
if (this.clientCapabilities.sampling() == null) {
return Mono.error(new McpError("Client must be configured with sampling capabilities"));
return Mono.error(new IllegalStateException("Client must be configured with sampling capabilities"));
}
return this.session.sendRequest(McpSchema.METHOD_SAMPLING_CREATE_MESSAGE, createMessageRequest,
CREATE_MESSAGE_RESULT_TYPE_REF);
@ -167,10 +146,11 @@ public class McpAsyncServerExchange {
*/
public Mono<McpSchema.ElicitResult> createElicitation(McpSchema.ElicitRequest elicitRequest) {
if (this.clientCapabilities == null) {
return Mono.error(new McpError("Client must be initialized. Call the initialize method first!"));
return Mono
.error(new IllegalStateException("Client must be initialized. Call the initialize method first!"));
}
if (this.clientCapabilities.elicitation() == null) {
return Mono.error(new McpError("Client must be configured with elicitation capabilities"));
return Mono.error(new IllegalStateException("Client must be configured with elicitation capabilities"));
}
return this.session.sendRequest(McpSchema.METHOD_ELICITATION_CREATE, elicitRequest,
ELICITATION_RESULT_TYPE_REF);
@ -215,7 +195,7 @@ public class McpAsyncServerExchange {
public Mono<Void> loggingNotification(LoggingMessageNotification loggingMessageNotification) {
if (loggingMessageNotification == null) {
return Mono.error(new McpError("Logging message must not be null"));
return Mono.error(new IllegalStateException("Logging message must not be null"));
}
return Mono.defer(() -> {
@ -234,7 +214,7 @@ public class McpAsyncServerExchange {
*/
public Mono<Void> progressNotification(McpSchema.ProgressNotification progressNotification) {
if (progressNotification == null) {
return Mono.error(new McpError("Progress notification must not be null"));
return Mono.error(new IllegalStateException("Progress notification must not be null"));
}
return this.session.sendNotification(McpSchema.METHOD_NOTIFICATION_PROGRESS, progressNotification);
}

View file

@ -66,9 +66,9 @@ import reactor.core.publisher.Mono;
* Example of creating a basic synchronous server: <pre>{@code
* McpServer.sync(transportProvider)
* .serverInfo("my-server", "1.0.0")
* .tool(Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(),
* (exchange, args) -> CallToolResult.builder()
* .content(List.of(new McpSchema.TextContent("Result: " + calculate(args))))
* .toolCall(Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(),
* (exchange, request) -> CallToolResult.builder()
* .content(List.of(new McpSchema.TextContent("Result: " + calculate(request.arguments()))))
* .isError(false)
* .build())
* .build();
@ -77,8 +77,8 @@ import reactor.core.publisher.Mono;
* Example of creating a basic asynchronous server: <pre>{@code
* McpServer.async(transportProvider)
* .serverInfo("my-server", "1.0.0")
* .tool(Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(),
* (exchange, args) -> Mono.fromSupplier(() -> calculate(args))
* .toolCall(Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(),
* (exchange, request) -> Mono.fromSupplier(() -> calculate(request.arguments()))
* .map(result -> CallToolResult.builder()
* .content(List.of(new McpSchema.TextContent("Result: " + result)))
* .isError(false)
@ -441,46 +441,6 @@ public interface McpServer {
return this;
}
/**
* Adds a single tool with its implementation handler to the server. This is a
* convenience method for registering individual tools without creating a
* {@link McpServerFeatures.AsyncToolSpecification} explicitly.
*
* <p>
* Example usage: <pre>{@code
* .tool(
* Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(),
* (exchange, args) -> Mono.fromSupplier(() -> calculate(args))
* .map(result -> CallToolResult.builder()
* .content(List.of(new McpSchema.TextContent("Result: " + result)))
* .isError(false)
* .build()))
* )
* }</pre>
* @param tool The tool definition including name, description, and schema. Must
* not be null.
* @param handler The function that implements the tool's logic. Must not be null.
* The function's first argument is an {@link McpAsyncServerExchange} upon which
* the server can interact with the connected client. The second argument is the
* map of arguments passed to the tool.
* @return This builder instance for method chaining
* @throws IllegalArgumentException if tool or handler is null
* @deprecated Use {@link #toolCall(McpSchema.Tool, BiFunction)} instead for tool
* calls that require a request object.
*/
@Deprecated
public AsyncSpecification<S> tool(McpSchema.Tool tool,
BiFunction<McpAsyncServerExchange, Map<String, Object>, Mono<CallToolResult>> handler) {
Assert.notNull(tool, "Tool must not be null");
Assert.notNull(handler, "Handler must not be null");
validateToolName(tool.name());
assertNoDuplicateTool(tool.name());
this.tools.add(new McpServerFeatures.AsyncToolSpecification(tool, handler));
return this;
}
/**
* Adds a single tool with its implementation handler to the server. This is a
* convenience method for registering individual tools without creating a
@ -1064,45 +1024,6 @@ public interface McpServer {
return this;
}
/**
* Adds a single tool with its implementation handler to the server. This is a
* convenience method for registering individual tools without creating a
* {@link McpServerFeatures.SyncToolSpecification} explicitly.
*
* <p>
* Example usage: <pre>{@code
* .tool(
* Tool.builder().name("calculator").title("Performs calculations".inputSchema(schema).build(),
* (exchange, args) -> CallToolResult.builder()
* .content(List.of(new McpSchema.TextContent("Result: " + calculate(args))))
* .isError(false)
* .build())
* )
* }</pre>
* @param tool The tool definition including name, description, and schema. Must
* not be null.
* @param handler The function that implements the tool's logic. Must not be null.
* The function's first argument is an {@link McpSyncServerExchange} upon which
* the server can interact with the connected client. The second argument is the
* list of arguments passed to the tool.
* @return This builder instance for method chaining
* @throws IllegalArgumentException if tool or handler is null
* @deprecated Use {@link #toolCall(McpSchema.Tool, BiFunction)} instead for tool
* calls that require a request object.
*/
@Deprecated
public SyncSpecification<S> tool(McpSchema.Tool tool,
BiFunction<McpSyncServerExchange, Map<String, Object>, McpSchema.CallToolResult> handler) {
Assert.notNull(tool, "Tool must not be null");
Assert.notNull(handler, "Handler must not be null");
validateToolName(tool.name());
assertNoDuplicateTool(tool.name());
this.tools.add(new McpServerFeatures.SyncToolSpecification(tool, handler));
return this;
}
/**
* Adds a single tool with its implementation handler to the server. This is a
* convenience method for registering individual tools without creating a
@ -1123,7 +1044,7 @@ public interface McpServer {
validateToolName(tool.name());
assertNoDuplicateTool(tool.name());
this.tools.add(new McpServerFeatures.SyncToolSpecification(tool, null, handler));
this.tools.add(new McpServerFeatures.SyncToolSpecification(tool, handler));
return this;
}

View file

@ -223,19 +223,8 @@ public class McpServerFeatures {
* map of tool arguments.
*/
public record AsyncToolSpecification(McpSchema.Tool tool,
@Deprecated BiFunction<McpAsyncServerExchange, Map<String, Object>, Mono<McpSchema.CallToolResult>> call,
BiFunction<McpAsyncServerExchange, McpSchema.CallToolRequest, Mono<McpSchema.CallToolResult>> callHandler) {
/**
* @deprecated Use {@link AsyncToolSpecification(McpSchema.Tool, null,
* BiFunction)} instead.
**/
@Deprecated
public AsyncToolSpecification(McpSchema.Tool tool,
BiFunction<McpAsyncServerExchange, Map<String, Object>, Mono<McpSchema.CallToolResult>> call) {
this(tool, call, (exchange, toolReq) -> call.apply(exchange, toolReq.arguments()));
}
static AsyncToolSpecification fromSync(SyncToolSpecification syncToolSpec) {
return fromSync(syncToolSpec, false);
}
@ -247,13 +236,6 @@ public class McpServerFeatures {
return null;
}
BiFunction<McpAsyncServerExchange, Map<String, Object>, Mono<McpSchema.CallToolResult>> deprecatedCall = (syncToolSpec
.call() != null) ? (exchange, map) -> {
var toolResult = Mono
.fromCallable(() -> syncToolSpec.call().apply(new McpSyncServerExchange(exchange), map));
return immediate ? toolResult : toolResult.subscribeOn(Schedulers.boundedElastic());
} : null;
BiFunction<McpAsyncServerExchange, McpSchema.CallToolRequest, Mono<McpSchema.CallToolResult>> callHandler = (
exchange, req) -> {
var toolResult = Mono
@ -261,7 +243,7 @@ public class McpServerFeatures {
return immediate ? toolResult : toolResult.subscribeOn(Schedulers.boundedElastic());
};
return new AsyncToolSpecification(syncToolSpec.tool(), deprecatedCall, callHandler);
return new AsyncToolSpecification(syncToolSpec.tool(), callHandler);
}
/**
@ -304,7 +286,7 @@ public class McpServerFeatures {
Assert.notNull(tool, "Tool must not be null");
Assert.notNull(callHandler, "Call handler function must not be null");
return new AsyncToolSpecification(tool, null, callHandler);
return new AsyncToolSpecification(tool, callHandler);
}
}
@ -523,26 +505,16 @@ public class McpServerFeatures {
* }</pre>
*
* @param tool The tool definition including name, description, and parameter schema
* @param call (Deprected) The function that implements the tool's logic, receiving
* arguments and returning results. The function's first argument is an
* {@link McpSyncServerExchange} upon which the server can interact with the connected
* @param callHandler The function that implements the tool's logic, receiving a
* {@link McpSyncServerExchange} and a
* {@link io.modelcontextprotocol.spec.McpSchema.CallToolRequest} and returning
* results. The function's first argument is an {@link McpSyncServerExchange} upon
* which the server can interact with the client. The second arguments is a map of
* arguments passed to the tool.
* which the server can interact with the client. The second argument is a request
* object containing the arguments passed to the tool.
*/
public record SyncToolSpecification(McpSchema.Tool tool,
@Deprecated BiFunction<McpSyncServerExchange, Map<String, Object>, McpSchema.CallToolResult> call,
BiFunction<McpSyncServerExchange, CallToolRequest, McpSchema.CallToolResult> callHandler) {
@Deprecated
public SyncToolSpecification(McpSchema.Tool tool,
BiFunction<McpSyncServerExchange, Map<String, Object>, McpSchema.CallToolResult> call) {
this(tool, call, (exchange, toolReq) -> call.apply(exchange, toolReq.arguments()));
}
/**
* Builder for creating SyncToolSpecification instances.
*/
@ -583,7 +555,7 @@ public class McpServerFeatures {
Assert.notNull(tool, "Tool must not be null");
Assert.notNull(callHandler, "CallTool function must not be null");
return new SyncToolSpecification(tool, null, callHandler);
return new SyncToolSpecification(tool, callHandler);
}
}

View file

@ -230,21 +230,6 @@ public class McpSyncServer {
this.asyncServer.notifyPromptsListChanged().block();
}
/**
* This implementation would, incorrectly, broadcast the logging message to all
* connected clients, using a single minLoggingLevel for all of them. Similar to the
* sampling and roots, the logging level should be set per client session and use the
* ServerExchange to send the logging message to the right client.
* @param loggingMessageNotification The logging message to send
* @deprecated Use
* {@link McpSyncServerExchange#loggingNotification(LoggingMessageNotification)}
* instead.
*/
@Deprecated
public void loggingNotification(LoggingMessageNotification loggingMessageNotification) {
this.asyncServer.loggingNotification(loggingMessageNotification).block();
}
/**
* Close the server gracefully.
*/

View file

@ -343,7 +343,9 @@ public class HttpServletSseServerTransportProvider extends HttpServlet implement
response.setContentType(APPLICATION_JSON);
response.setCharacterEncoding(UTF_8);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
String jsonError = jsonMapper.writeValueAsString(new McpError("Session ID missing in message endpoint"));
String jsonError = jsonMapper.writeValueAsString(McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND)
.message("Session ID missing in message endpoint")
.build());
PrintWriter writer = response.getWriter();
writer.write(jsonError);
writer.flush();
@ -356,7 +358,9 @@ public class HttpServletSseServerTransportProvider extends HttpServlet implement
response.setContentType(APPLICATION_JSON);
response.setCharacterEncoding(UTF_8);
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
String jsonError = jsonMapper.writeValueAsString(new McpError("Session not found: " + sessionId));
String jsonError = jsonMapper.writeValueAsString(McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Session not found: " + sessionId)
.build());
PrintWriter writer = response.getWriter();
writer.write(jsonError);
writer.flush();
@ -383,7 +387,9 @@ public class HttpServletSseServerTransportProvider extends HttpServlet implement
catch (Exception e) {
logger.error("Error processing message: {}", e.getMessage());
try {
McpError mcpError = new McpError(e.getMessage());
McpError mcpError = McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message(e.getMessage())
.build();
response.setContentType(APPLICATION_JSON);
response.setCharacterEncoding(UTF_8);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

View file

@ -147,7 +147,9 @@ public class HttpServletStatelessServerTransport extends HttpServlet implements
String accept = request.getHeader(ACCEPT);
if (accept == null || !(accept.contains(APPLICATION_JSON) && accept.contains(TEXT_EVENT_STREAM))) {
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
new McpError("Both application/json and text/event-stream required in Accept header"));
McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND)
.message("Both application/json and text/event-stream required in Accept header")
.build());
return;
}
@ -180,7 +182,9 @@ public class HttpServletStatelessServerTransport extends HttpServlet implements
catch (Exception e) {
logger.error("Failed to handle request: {}", e.getMessage());
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError("Failed to handle request: " + e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Failed to handle request: " + e.getMessage())
.build());
}
}
else if (message instanceof McpSchema.JSONRPCNotification jsonrpcNotification) {
@ -193,22 +197,29 @@ public class HttpServletStatelessServerTransport extends HttpServlet implements
catch (Exception e) {
logger.error("Failed to handle notification: {}", e.getMessage());
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError("Failed to handle notification: " + e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Failed to handle notification: " + e.getMessage())
.build());
}
}
else {
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
new McpError("The server accepts either requests or notifications"));
McpError.builder(McpSchema.ErrorCodes.INVALID_REQUEST)
.message("The server accepts either requests or notifications")
.build());
}
}
catch (IllegalArgumentException | IOException e) {
logger.error("Failed to deserialize message: {}", e.getMessage());
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST, new McpError("Invalid message format"));
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
McpError.builder(McpSchema.ErrorCodes.INVALID_REQUEST).message("Invalid message format").build());
}
catch (Exception e) {
logger.error("Unexpected error handling message: {}", e.getMessage());
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError("Unexpected error: " + e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Unexpected error: " + e.getMessage())
.build());
}
}

View file

@ -282,7 +282,8 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
if (!badRequestErrors.isEmpty()) {
String combinedMessage = String.join("; ", badRequestErrors);
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST, new McpError(combinedMessage));
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND).message(combinedMessage).build());
return;
}
@ -430,7 +431,8 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
&& jsonrpcRequest.method().equals(McpSchema.METHOD_INITIALIZE)) {
if (!badRequestErrors.isEmpty()) {
String combinedMessage = String.join("; ", badRequestErrors);
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST, new McpError(combinedMessage));
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND).message(combinedMessage).build());
return;
}
@ -460,7 +462,9 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
catch (Exception e) {
logger.error("Failed to initialize session: {}", e.getMessage());
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError("Failed to initialize session: " + e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Failed to initialize session: " + e.getMessage())
.build());
return;
}
}
@ -473,7 +477,8 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
if (!badRequestErrors.isEmpty()) {
String combinedMessage = String.join("; ", badRequestErrors);
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST, new McpError(combinedMessage));
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND).message(combinedMessage).build());
return;
}
@ -481,7 +486,9 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
if (session == null) {
this.responseError(response, HttpServletResponse.SC_NOT_FOUND,
new McpError("Session not found: " + sessionId));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Session not found: " + sessionId)
.build());
return;
}
@ -523,19 +530,23 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
}
else {
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError("Unknown message type"));
McpError.builder(McpSchema.ErrorCodes.INVALID_REQUEST).message("Unknown message type").build());
}
}
catch (IllegalArgumentException | IOException e) {
logger.error("Failed to deserialize message: {}", e.getMessage());
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
new McpError("Invalid message format: " + e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INVALID_REQUEST)
.message("Invalid message format: " + e.getMessage())
.build());
}
catch (Exception e) {
logger.error("Error handling message: {}", e.getMessage());
try {
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError("Error processing message: " + e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
.message("Error processing message: " + e.getMessage())
.build());
}
catch (IOException ex) {
logger.error(FAILED_TO_SEND_ERROR_RESPONSE, ex.getMessage());
@ -584,7 +595,9 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
if (request.getHeader(HttpHeaders.MCP_SESSION_ID) == null) {
this.responseError(response, HttpServletResponse.SC_BAD_REQUEST,
new McpError("Session ID required in mcp-session-id header"));
McpError.builder(McpSchema.ErrorCodes.METHOD_NOT_FOUND)
.message("Session ID required in mcp-session-id header")
.build());
return;
}
@ -605,7 +618,7 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
logger.error("Failed to delete session {}: {}", sessionId, e.getMessage());
try {
this.responseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
new McpError(e.getMessage()));
McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR).message(e.getMessage()).build());
}
catch (IOException ex) {
logger.error(FAILED_TO_SEND_ERROR_RESPONSE, ex.getMessage());

View file

@ -98,7 +98,7 @@ public class StdioServerTransportProvider implements McpServerTransportProvider
@Override
public Mono<Void> notifyClients(String method, Object params) {
if (this.session == null) {
return Mono.error(new McpError("No session to close"));
return Mono.error(new IllegalStateException("No session to close"));
}
return this.session.sendNotification(method, params)
.doOnError(e -> logger.error("Failed to send notification: {}", e.getMessage()));

View file

@ -96,21 +96,6 @@ public class McpClientSession implements McpSession {
}
/**
* Creates a new McpClientSession with the specified configuration and handlers.
* @param requestTimeout Duration to wait for responses
* @param transport Transport implementation for message exchange
* @param requestHandlers Map of method names to request handlers
* @param notificationHandlers Map of method names to notification handlers
* @deprecated Use
* {@link #McpClientSession(Duration, McpClientTransport, Map, Map, Function)}
*/
@Deprecated
public McpClientSession(Duration requestTimeout, McpClientTransport transport,
Map<String, RequestHandler<?>> requestHandlers, Map<String, NotificationHandler> notificationHandlers) {
this(requestTimeout, transport, requestHandlers, notificationHandlers, Function.identity());
}
/**
* Creates a new McpClientSession with the specified configuration and handlers.
* @param requestTimeout Duration to wait for responses

View file

@ -27,11 +27,6 @@ public class McpError extends RuntimeException {
this.jsonRpcError = jsonRpcError;
}
@Deprecated
public McpError(Object error) {
super(error.toString());
}
public JSONRPCError getJsonRpcError() {
return jsonRpcError;
}

View file

@ -41,9 +41,6 @@ public final class McpSchema {
private McpSchema() {
}
@Deprecated
public static final String LATEST_PROTOCOL_VERSION = ProtocolVersions.MCP_2025_11_25;
public static final String JSONRPC_VERSION = "2.0";
public static final String FIRST_PAGE = null;
@ -798,35 +795,6 @@ public final class McpSchema {
@JsonProperty("annotations") Annotations annotations,
@JsonProperty("_meta") Map<String, Object> meta) implements ResourceContent { // @formatter:on
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link Resource#builder()} instead.
*/
@Deprecated
public Resource(String uri, String name, String title, String description, String mimeType, Long size,
Annotations annotations) {
this(uri, name, title, description, mimeType, size, annotations, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link Resource#builder()} instead.
*/
@Deprecated
public Resource(String uri, String name, String description, String mimeType, Long size,
Annotations annotations) {
this(uri, name, null, description, mimeType, size, annotations, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link Resource#builder()} instead.
*/
@Deprecated
public Resource(String uri, String name, String description, String mimeType, Annotations annotations) {
this(uri, name, null, description, mimeType, null, annotations, null);
}
public static Builder builder() {
return new Builder();
}
@ -1592,36 +1560,6 @@ public final class McpSchema {
@JsonProperty("structuredContent") Object structuredContent,
@JsonProperty("_meta") Map<String, Object> meta) implements Result { // @formatter:on
/**
* @deprecated use the builder instead.
*/
@Deprecated
public CallToolResult(List<Content> content, Boolean isError) {
this(content, isError, (Object) null, null);
}
/**
* @deprecated use the builder instead.
*/
@Deprecated
public CallToolResult(List<Content> content, Boolean isError, Map<String, Object> structuredContent) {
this(content, isError, structuredContent, null);
}
/**
* Creates a new instance of {@link CallToolResult} with a string containing the
* tool result.
* @param content The content of the tool result. This will be mapped to a
* one-sized list with a {@link TextContent} element.
* @param isError If true, indicates that the tool execution failed and the
* content contains error information. If false or absent, indicates successful
* execution.
*/
@Deprecated
public CallToolResult(String content, Boolean isError) {
this(List.of(new TextContent(content)), isError, null);
}
/**
* Creates a builder for {@link CallToolResult}.
* @return a new builder instance
@ -2619,33 +2557,6 @@ public final class McpSchema {
public TextContent(String content) {
this(null, content, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link TextContent#TextContent(Annotations, String)} instead.
*/
@Deprecated
public TextContent(List<Role> audience, Double priority, String content) {
this(audience != null || priority != null ? new Annotations(audience, priority) : null, content, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link TextContent#annotations()} instead.
*/
@Deprecated
public List<Role> audience() {
return annotations == null ? null : annotations.audience();
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link TextContent#annotations()} instead.
*/
@Deprecated
public Double priority() {
return annotations == null ? null : annotations.priority();
}
}
/**
@ -2668,34 +2579,6 @@ public final class McpSchema {
public ImageContent(Annotations annotations, String data, String mimeType) {
this(annotations, data, mimeType, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link ImageContent#ImageContent(Annotations, String, String)} instead.
*/
@Deprecated
public ImageContent(List<Role> audience, Double priority, String data, String mimeType) {
this(audience != null || priority != null ? new Annotations(audience, priority) : null, data, mimeType,
null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link ImageContent#annotations()} instead.
*/
@Deprecated
public List<Role> audience() {
return annotations == null ? null : annotations.audience();
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link ImageContent#annotations()} instead.
*/
@Deprecated
public Double priority() {
return annotations == null ? null : annotations.priority();
}
}
/**
@ -2742,34 +2625,6 @@ public final class McpSchema {
public EmbeddedResource(Annotations annotations, ResourceContents resource) {
this(annotations, resource, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link EmbeddedResource#EmbeddedResource(Annotations, ResourceContents)}
* instead.
*/
@Deprecated
public EmbeddedResource(List<Role> audience, Double priority, ResourceContents resource) {
this(audience != null || priority != null ? new Annotations(audience, priority) : null, resource, null);
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link EmbeddedResource#annotations()} instead.
*/
@Deprecated
public List<Role> audience() {
return annotations == null ? null : annotations.audience();
}
/**
* @deprecated Only exists for backwards-compatibility purposes. Use
* {@link EmbeddedResource#annotations()} instead.
*/
@Deprecated
public Double priority() {
return annotations == null ? null : annotations.priority();
}
}
/**

View file

@ -86,34 +86,6 @@ public class McpServerSession implements McpLoggableSession {
this.notificationHandlers = notificationHandlers;
}
/**
* Creates a new server session with the given parameters and the transport to use.
* @param id session id
* @param transport the transport to use
* @param initHandler called when a
* {@link io.modelcontextprotocol.spec.McpSchema.InitializeRequest} is received by the
* server
* @param initNotificationHandler called when a
* {@link io.modelcontextprotocol.spec.McpSchema#METHOD_NOTIFICATION_INITIALIZED} is
* received.
* @param requestHandlers map of request handlers to use
* @param notificationHandlers map of notification handlers to use
* @deprecated Use
* {@link #McpServerSession(String, Duration, McpServerTransport, McpInitRequestHandler, Map, Map)}
*/
@Deprecated
public McpServerSession(String id, Duration requestTimeout, McpServerTransport transport,
McpInitRequestHandler initHandler, InitNotificationHandler initNotificationHandler,
Map<String, McpRequestHandler<?>> requestHandlers,
Map<String, McpNotificationHandler> notificationHandlers) {
this.id = id;
this.requestTimeout = requestTimeout;
this.transport = transport;
this.initRequestHandler = initHandler;
this.requestHandlers = requestHandlers;
this.notificationHandlers = notificationHandlers;
}
/**
* Retrieve the session id.
* @return session id
@ -355,23 +327,6 @@ public class McpServerSession implements McpLoggableSession {
this.transport.close();
}
/**
* Request handler for the initialization request.
*
* @deprecated Use {@link McpInitRequestHandler}
*/
@Deprecated
public interface InitRequestHandler {
/**
* Handles the initialization request.
* @param initializeRequest the initialization request by the client
* @return a Mono that will emit the result of the initialization
*/
Mono<McpSchema.InitializeResult> handle(McpSchema.InitializeRequest initializeRequest);
}
/**
* Notification handler for the initialization notification from the client.
*/
@ -385,46 +340,6 @@ public class McpServerSession implements McpLoggableSession {
}
/**
* A handler for client-initiated notifications.
*
* @deprecated Use {@link McpNotificationHandler}
*/
@Deprecated
public interface NotificationHandler {
/**
* Handles a notification from the client.
* @param exchange the exchange associated with the client that allows calling
* back to the connected client or inspecting its capabilities.
* @param params the parameters of the notification.
* @return a Mono that completes once the notification is handled.
*/
Mono<Void> handle(McpAsyncServerExchange exchange, Object params);
}
/**
* A handler for client-initiated requests.
*
* @param <T> the type of the response that is expected as a result of handling the
* request.
* @deprecated Use {@link McpRequestHandler}
*/
@Deprecated
public interface RequestHandler<T> {
/**
* Handles a request from the client.
* @param exchange the exchange associated with the client that allows calling
* back to the connected client or inspecting its capabilities.
* @param params the parameters of the request.
* @return a Mono that will emit the response to the request.
*/
Mono<T> handle(McpAsyncServerExchange exchange, Object params);
}
/**
* Factory for creating server sessions which delegate to a provided 1:1 transport
* with a connected client.