-
Notifications
You must be signed in to change notification settings - Fork 803
Description
Bug description
In the stateless server path (DefaultMcpStatelessServerHandler), when a request is received for a method that does not have a registered handler, the server currently throws an McpError exception instead of returning a JSON-RPC response with an error code. This is inconsistent with the stateful/session server implementations (McpServerSession, etc.), which respond with the standard JSON-RPC error -32601 (Method not found).
Environment
ModelContextProtocol Java SDK, stateless/server mode.
Steps to reproduce
- Start a stateless MCP server instance (e.g., without advertising or registering a resources or prompts capability).
- Send a request with method: "resources/list" (or another method for which the handler is not registered).
- Exception is thrown instead of returning a JSON-RPC response with a "Method not found" error
Expected behavior
Stateless server should respond to any unknown/unregistered method with the standard JSON-RPC -32601 "Method not found" error, to be consistent with other server implementations in the SDK and with JSON-RPC specification.
Minimal Complete Reproducible example
Minimal Spring AI reproducer:
package com.example.demo;
import org.springaicommunity.mcp.annotation.McpTool;
import org.springaicommunity.mcp.annotation.McpToolParam;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Component
public static class DemoTools {
@McpTool
public String hello(@McpToolParam String name) {
return "Hello, " + name;
}
}
}spring:
ai:
mcp:
server:
enabled: true
type: sync
protocol: stateless
annotation-scanner:
enabled: true
streamable-http:
mcp-endpoint: /mcp
capabilities:
completion: false
prompt: false
resource: false
tool: true<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<spring-ai.version>2.0.0-M2</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-bom</artifactId>
<version>0.17.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>Running a resources/list command against this server returns a JSON stack trace instead of a JSON-RPC response:
$ curl -H "Accept: application/json, text/event-stream" -H "Content-Type: application/json" -X POST http://localhost:8080/mcp -d '{"jsonrpc": "2.0", "method": "resources/list", "id": 1}' | jq
{
"cause": null,
"jsonRpcError": null,
"localizedMessage": "Failed to handle request: Missing handler for request type: resources/list",
"message": "Failed to handle request: Missing handler for request type: resources/list",
"stackTrace": [
{
"classLoaderName": "app",
"className": "io.modelcontextprotocol.server.transport.WebMvcStatelessServerTransport",
"fileName": "WebMvcStatelessServerTransport.java",
"lineNumber": 126,
"methodName": "handlePost",
"moduleName": null,
"moduleVersion": null,
"nativeMethod": false
},
{
"classLoaderName": "app",
"className": "org.springframework.web.servlet.function.support.HandlerFunctionAdapter",
"fileName": "HandlerFunctionAdapter.java",
// ...
},
// ...
],
"suppressed": []
}