From 3c87155b9ac11ab3f72dfc01d2238510537de69a Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Mon, 23 Feb 2026 10:16:53 +0100 Subject: [PATCH 1/9] Release version 1.0.0 Signed-off-by: Christian Tzolov --- .../client-jdk-http-client/pom.xml | 4 +- conformance-tests/pom.xml | 2 +- conformance-tests/server-servlet/pom.xml | 4 +- docs/blog/.authors.yml | 5 -- docs/blog/index.md | 1 - .../posts/mcp-server-performance-benchmark.md | 72 ------------------- mcp-bom/pom.xml | 2 +- mcp-core/pom.xml | 2 +- mcp-json-jackson2/pom.xml | 4 +- mcp-json-jackson3/pom.xml | 4 +- mcp-test/pom.xml | 8 +-- mcp/pom.xml | 6 +- mkdocs.yml | 5 +- pom.xml | 2 +- 14 files changed, 20 insertions(+), 101 deletions(-) delete mode 100644 docs/blog/.authors.yml delete mode 100644 docs/blog/index.md delete mode 100644 docs/blog/posts/mcp-server-performance-benchmark.md diff --git a/conformance-tests/client-jdk-http-client/pom.xml b/conformance-tests/client-jdk-http-client/pom.xml index 0e6291ac9..1051f0dda 100644 --- a/conformance-tests/client-jdk-http-client/pom.xml +++ b/conformance-tests/client-jdk-http-client/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.0-SNAPSHOT + 1.0.0 client-jdk-http-client jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.0-SNAPSHOT + 1.0.0 diff --git a/conformance-tests/pom.xml b/conformance-tests/pom.xml index 37a66b496..f459166bb 100644 --- a/conformance-tests/pom.xml +++ b/conformance-tests/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 conformance-tests pom diff --git a/conformance-tests/server-servlet/pom.xml b/conformance-tests/server-servlet/pom.xml index eeb8485ae..9c24c265b 100644 --- a/conformance-tests/server-servlet/pom.xml +++ b/conformance-tests/server-servlet/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.0-SNAPSHOT + 1.0.0 server-servlet jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.0-SNAPSHOT + 1.0.0 diff --git a/docs/blog/.authors.yml b/docs/blog/.authors.yml deleted file mode 100644 index 7b255c403..000000000 --- a/docs/blog/.authors.yml +++ /dev/null @@ -1,5 +0,0 @@ -authors: - mcp-team: - name: MCP Java SDK Team - description: Maintainers of the MCP Java SDK - avatar: https://github.com/modelcontextprotocol.png diff --git a/docs/blog/index.md b/docs/blog/index.md deleted file mode 100644 index e61459078..000000000 --- a/docs/blog/index.md +++ /dev/null @@ -1 +0,0 @@ -# News diff --git a/docs/blog/posts/mcp-server-performance-benchmark.md b/docs/blog/posts/mcp-server-performance-benchmark.md deleted file mode 100644 index a08b807b6..000000000 --- a/docs/blog/posts/mcp-server-performance-benchmark.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -date: 2026-02-15 -authors: - - mcp-team -categories: - - Performance - - Benchmarks ---- - -# Java Leads MCP Server Performance Benchmarks with Sub-Millisecond Latency - -A comprehensive independent benchmark of MCP server implementations across four major languages puts Java at the top of the performance charts — delivering sub-millisecond latency, the highest throughput, and the best CPU efficiency of all tested platforms. - - - -## The Benchmark - -[TM Dev Lab](https://www.tmdevlab.com/mcp-server-performance-benchmark.html) published a rigorous performance comparison of MCP server implementations spanning **3.9 million total requests** across three independent test rounds. The benchmark evaluated four implementations under identical conditions: - -- **Java** — Spring Boot 4.0.0 + Spring AI 2.0.0-M2 on Java 21 -- **Go** — Official MCP SDK v1.2.0 -- **Node.js** — @modelcontextprotocol/sdk v1.26.0 -- **Python** — FastMCP 2.12.0+ with FastAPI 0.109.0+ - -Each server was tested with 50 concurrent virtual users over 5-minute sustained runs in Docker containers (1-core CPU, 1GB memory) on Ubuntu 24.04.3 LTS. Four standardized benchmark tools measured CPU-intensive, I/O-intensive, data transformation, and latency-handling scenarios — all with a **0% error rate** across every implementation. - -## Java's Performance Highlights - -The results speak for themselves: - -| Server | Avg Latency | Throughput (RPS) | CPU Efficiency (RPS/CPU%) | -|------------|-------------|------------------|---------------------------| -| **Java** | **0.835 ms** | **1,624** | **57.2** | -| Go | 0.855 ms | 1,624 | 50.4 | -| Node.js | 10.66 ms | 559 | 5.7 | -| Python | 26.45 ms | 292 | 3.2 | - -```mermaid ---- -config: - xyChart: - width: 700 - height: 400 - themeVariables: - xyChart: - backgroundColor: transparent ---- -xychart-beta - title "Average Latency Comparison (milliseconds)" - x-axis [Java, Go, "Node.js", Python] - y-axis "Latency (ms)" 0 --> 30 - bar [0.84, 0.86, 10.66, 26.45] -``` - -Java achieved the **lowest average latency** at 0.835 ms — edging out Go's 0.855 ms — while matching its throughput at 1,624 requests per second. Where Java truly stands out is **CPU efficiency**: at 57.2 RPS per CPU%, it extracts more performance per compute cycle than any other implementation, including Go (50.4). - -In CPU-bound workloads like Fibonacci calculation, Java excelled with a **0.369 ms** response time, showcasing the JVM's highly optimized just-in-time compilation. - -## A Clear Performance Tier - -The benchmark reveals two distinct performance tiers: - -- **High-performance tier**: Java and Go deliver sub-millisecond latencies and 1,600+ RPS -- **Standard tier**: Node.js (12x slower) and Python (31x slower) trail significantly - -Java's throughput is **2.9x higher than Node.js** and **5.6x higher than Python**. For latency-sensitive MCP deployments, the difference is even more pronounced — Java responds **12.8x faster than Node.js** and **31.7x faster than Python**. - -## What This Means for MCP Developers - -For teams building production MCP servers that need to handle high concurrency and low-latency tool interactions, Java with Spring Boot and Spring AI provides a battle-tested, high-performance foundation. The JVM's mature ecosystem, strong typing, and proven scalability make it an excellent choice for enterprise MCP deployments where performance and reliability are paramount. - -The full benchmark details, methodology, and raw data are available at [TM Dev Lab](https://www.tmdevlab.com/mcp-server-performance-benchmark.html). diff --git a/mcp-bom/pom.xml b/mcp-bom/pom.xml index b43b703fa..15aff632a 100644 --- a/mcp-bom/pom.xml +++ b/mcp-bom/pom.xml @@ -7,7 +7,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 mcp-bom diff --git a/mcp-core/pom.xml b/mcp-core/pom.xml index 67ed015bd..dadd84a86 100644 --- a/mcp-core/pom.xml +++ b/mcp-core/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 mcp-core jar diff --git a/mcp-json-jackson2/pom.xml b/mcp-json-jackson2/pom.xml index 7220318c5..dc5691b5a 100644 --- a/mcp-json-jackson2/pom.xml +++ b/mcp-json-jackson2/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 mcp-json-jackson2 jar @@ -70,7 +70,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.0-SNAPSHOT + 1.0.0 com.networknt diff --git a/mcp-json-jackson3/pom.xml b/mcp-json-jackson3/pom.xml index 55db3417f..6e21660d8 100644 --- a/mcp-json-jackson3/pom.xml +++ b/mcp-json-jackson3/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 mcp-json-jackson3 jar @@ -64,7 +64,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.0-SNAPSHOT + 1.0.0 tools.jackson.core diff --git a/mcp-test/pom.xml b/mcp-test/pom.xml index f08ccc883..70c607744 100644 --- a/mcp-test/pom.xml +++ b/mcp-test/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 mcp-test jar @@ -24,7 +24,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.0-SNAPSHOT + 1.0.0 @@ -159,7 +159,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.0-SNAPSHOT + 1.0.0 test @@ -170,7 +170,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson2 - 1.0.0-SNAPSHOT + 1.0.0 test diff --git a/mcp/pom.xml b/mcp/pom.xml index 2db79f87b..24c0c6241 100644 --- a/mcp/pom.xml +++ b/mcp/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 mcp jar @@ -25,13 +25,13 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.0-SNAPSHOT + 1.0.0 io.modelcontextprotocol.sdk mcp-core - 1.0.0-SNAPSHOT + 1.0.0 diff --git a/mkdocs.yml b/mkdocs.yml index 3e27c3fb5..5c71d8f54 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -48,9 +48,7 @@ nav: - Contributing: - Contributing Guide: contribute.md - Documentation: development.md - - API Reference: https://javadoc.io/doc/io.modelcontextprotocol.sdk/mcp-core/latest - - News: - - blog/index.md + - API Reference: https://www.javadocs.dev/io.modelcontextprotocol.sdk/mcp-core/1.0.0/index.html markdown_extensions: - admonition @@ -94,4 +92,3 @@ extra: plugins: - search - - blog diff --git a/pom.xml b/pom.xml index 13b456d8f..8de38748e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0-SNAPSHOT + 1.0.0 pom https://github.com/modelcontextprotocol/java-sdk From 9d34216162ef30d0008fe44d2382bdec05513941 Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Mon, 23 Feb 2026 10:17:15 +0100 Subject: [PATCH 2/9] Next development version Signed-off-by: Christian Tzolov --- conformance-tests/client-jdk-http-client/pom.xml | 4 ++-- conformance-tests/pom.xml | 2 +- conformance-tests/server-servlet/pom.xml | 4 ++-- mcp-bom/pom.xml | 2 +- mcp-core/pom.xml | 2 +- mcp-json-jackson2/pom.xml | 4 ++-- mcp-json-jackson3/pom.xml | 4 ++-- mcp-test/pom.xml | 8 ++++---- mcp/pom.xml | 6 +++--- pom.xml | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/conformance-tests/client-jdk-http-client/pom.xml b/conformance-tests/client-jdk-http-client/pom.xml index 1051f0dda..c4eb9e54a 100644 --- a/conformance-tests/client-jdk-http-client/pom.xml +++ b/conformance-tests/client-jdk-http-client/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.0 + 1.0.1-SNAPSHOT client-jdk-http-client jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.0 + 1.0.1-SNAPSHOT diff --git a/conformance-tests/pom.xml b/conformance-tests/pom.xml index f459166bb..60e5cc857 100644 --- a/conformance-tests/pom.xml +++ b/conformance-tests/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT conformance-tests pom diff --git a/conformance-tests/server-servlet/pom.xml b/conformance-tests/server-servlet/pom.xml index 9c24c265b..35b3c981d 100644 --- a/conformance-tests/server-servlet/pom.xml +++ b/conformance-tests/server-servlet/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.0 + 1.0.1-SNAPSHOT server-servlet jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.0 + 1.0.1-SNAPSHOT diff --git a/mcp-bom/pom.xml b/mcp-bom/pom.xml index 15aff632a..422462e05 100644 --- a/mcp-bom/pom.xml +++ b/mcp-bom/pom.xml @@ -7,7 +7,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT mcp-bom diff --git a/mcp-core/pom.xml b/mcp-core/pom.xml index dadd84a86..e540074f9 100644 --- a/mcp-core/pom.xml +++ b/mcp-core/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT mcp-core jar diff --git a/mcp-json-jackson2/pom.xml b/mcp-json-jackson2/pom.xml index dc5691b5a..a2af272c0 100644 --- a/mcp-json-jackson2/pom.xml +++ b/mcp-json-jackson2/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT mcp-json-jackson2 jar @@ -70,7 +70,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.0 + 1.0.1-SNAPSHOT com.networknt diff --git a/mcp-json-jackson3/pom.xml b/mcp-json-jackson3/pom.xml index 6e21660d8..77ac06ff1 100644 --- a/mcp-json-jackson3/pom.xml +++ b/mcp-json-jackson3/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT mcp-json-jackson3 jar @@ -64,7 +64,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.0 + 1.0.1-SNAPSHOT tools.jackson.core diff --git a/mcp-test/pom.xml b/mcp-test/pom.xml index 70c607744..f27b741c0 100644 --- a/mcp-test/pom.xml +++ b/mcp-test/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT mcp-test jar @@ -24,7 +24,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.0 + 1.0.1-SNAPSHOT @@ -159,7 +159,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.0 + 1.0.1-SNAPSHOT test @@ -170,7 +170,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson2 - 1.0.0 + 1.0.1-SNAPSHOT test diff --git a/mcp/pom.xml b/mcp/pom.xml index 24c0c6241..576ab0ce8 100644 --- a/mcp/pom.xml +++ b/mcp/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT mcp jar @@ -25,13 +25,13 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.0 + 1.0.1-SNAPSHOT io.modelcontextprotocol.sdk mcp-core - 1.0.0 + 1.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 8de38748e..a854e5e73 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.0 + 1.0.1-SNAPSHOT pom https://github.com/modelcontextprotocol/java-sdk From 5a06a37b04b6de1450bf60e42a5480ca5901e23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20J=C4=99drzejczyk?= Date: Mon, 23 Feb 2026 11:34:27 +0100 Subject: [PATCH 3/9] Use dynamic jar discovery for conformance tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dariusz Jędrzejczyk --- .github/workflows/conformance.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 2e655d6ce..efd06938f 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -57,7 +57,7 @@ jobs: uses: modelcontextprotocol/conformance@v0.1.11 with: mode: client - command: 'java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.0.0-SNAPSHOT.jar' + command: 'java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-*-SNAPSHOT.jar' scenario: ${{ matrix.scenario }} expected-failures: ./conformance-tests/conformance-baseline.yml @@ -99,6 +99,6 @@ jobs: with: node-version: '22' # see https://github.com/modelcontextprotocol/conformance/pull/162 mode: client - command: 'java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.0.0-SNAPSHOT.jar' + command: 'java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-*-SNAPSHOT.jar' scenario: ${{ matrix.scenario }} expected-failures: ./conformance-tests/conformance-baseline.yml \ No newline at end of file From 5b9c2fb414895815fdf0b0502e502d5abc30540b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=ED=98=95=EC=A4=80?= Date: Tue, 3 Mar 2026 00:57:08 +0900 Subject: [PATCH 4/9] Use explicit UTF-8 charset in StdioServerTransportProvider (#826) Also add a test simulating a different locale in an isolated process. Resolves #295 --- .../StdioServerTransportProvider.java | 2 +- .../StdioServerTransportProviderTests.java | 38 +++++++++ .../server/transport/StdioUtf8TestServer.java | 82 +++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioUtf8TestServer.java diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransportProvider.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransportProvider.java index d288ea3d6..3a01193a3 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransportProvider.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/StdioServerTransportProvider.java @@ -200,7 +200,7 @@ private void startInboundProcessing() { inboundReady.tryEmitValue(null); BufferedReader reader = null; try { - reader = new BufferedReader(new InputStreamReader(inputStream)); + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); while (!isClosing.get()) { try { String line = reader.readLine(); diff --git a/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioServerTransportProviderTests.java b/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioServerTransportProviderTests.java index 5390cc4c2..6c2cc2bf4 100644 --- a/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioServerTransportProviderTests.java +++ b/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioServerTransportProviderTests.java @@ -4,9 +4,11 @@ package io.modelcontextprotocol.server.transport; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.util.Map; @@ -135,6 +137,42 @@ void shouldHandleIncomingMessages() throws Exception { }).verifyComplete(); } + @Test + void shouldHandleUtf8MessagesWithNonUtf8DefaultCharset() throws Exception { + String utf8Content = "한글 漢字 café 🎉"; + String jsonMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"test\"," + "\"params\":{\"message\":\"" + utf8Content + + "\"},\"id\":1}\n"; + + // Start a subprocess with non-UTF-8 default charset + String javaHome = System.getProperty("java.home"); + String classpath = System.getProperty("java.class.path"); + ProcessBuilder pb = new ProcessBuilder(javaHome + "/bin/java", "-Dfile.encoding=ISO-8859-1", "-cp", classpath, + StdioUtf8TestServer.class.getName()); + pb.redirectErrorStream(false); + Process process = pb.start(); + + try { + // Write UTF-8 encoded JSON-RPC message to the subprocess stdin + process.getOutputStream().write(jsonMessage.getBytes(StandardCharsets.UTF_8)); + process.getOutputStream().flush(); + process.getOutputStream().close(); + + // Read the echoed message from subprocess stdout + String result; + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { + result = reader.readLine(); + } + + // Verify that multi-byte UTF-8 characters survived the round trip + assertThat(result).isEqualTo(utf8Content); + } + finally { + process.destroyForcibly(); + process.waitFor(10, TimeUnit.SECONDS); + } + } + @Test void shouldNotifyClients() { // Set session factory diff --git a/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioUtf8TestServer.java b/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioUtf8TestServer.java new file mode 100644 index 000000000..3fc3a716d --- /dev/null +++ b/mcp-test/src/test/java/io/modelcontextprotocol/server/transport/StdioUtf8TestServer.java @@ -0,0 +1,82 @@ +/* + * Copyright 2024-2024 the original author or authors. + */ + +package io.modelcontextprotocol.server.transport; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import io.modelcontextprotocol.json.McpJsonDefaults; +import io.modelcontextprotocol.spec.McpSchema; +import io.modelcontextprotocol.spec.McpServerSession; +import reactor.core.publisher.Mono; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Minimal STDIO server process for testing UTF-8 encoding behavior. + * + *

+ * This class is spawned as a subprocess with {@code -Dfile.encoding=ISO-8859-1} to + * simulate a non-UTF-8 default charset environment. It uses + * {@link StdioServerTransportProvider} to read a JSON-RPC message from stdin and echoes + * the received {@code params.message} value back to stdout, allowing the parent test to + * verify that multi-byte UTF-8 characters are preserved regardless of the JVM default + * charset. + * + * @see StdioServerTransportProviderTests#shouldHandleUtf8MessagesWithNonUtf8DefaultCharset + */ +public class StdioUtf8TestServer { + + @SuppressWarnings("unchecked") + public static void main(String[] args) throws Exception { + // Capture the original stdout for echoing the result later + PrintStream originalOut = System.out; + + // Redirect System.out to stderr so that logger output does not + // interfere with the test result written to stdout + System.setOut(new PrintStream(System.err, true)); + + CountDownLatch messageLatch = new CountDownLatch(1); + StringBuilder receivedMessage = new StringBuilder(); + + StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(McpJsonDefaults.getMapper(), + System.in, OutputStream.nullOutputStream()); + + McpServerSession.Factory sessionFactory = transport -> { + McpServerSession session = mock(McpServerSession.class); + when(session.handle(any())).thenAnswer(invocation -> { + McpSchema.JSONRPCMessage msg = invocation.getArgument(0); + if (msg instanceof McpSchema.JSONRPCRequest request) { + Map params = (Map) request.params(); + receivedMessage.append(params.get("message")); + } + messageLatch.countDown(); + return Mono.empty(); + }); + when(session.closeGracefully()).thenReturn(Mono.empty()); + return session; + }; + + // Start processing stdin + transportProvider.setSessionFactory(sessionFactory); + + // Wait for the message to be processed + if (messageLatch.await(10, TimeUnit.SECONDS)) { + // Write the received message to the original stdout in UTF-8 + originalOut.write(receivedMessage.toString().getBytes(StandardCharsets.UTF_8)); + originalOut.write('\n'); + originalOut.flush(); + } + + transportProvider.closeGracefully().block(java.time.Duration.ofSeconds(5)); + } + +} From 03c5b8d0ecab592690314723f1dacb4db36cc37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20J=C4=99drzejczyk?= Date: Thu, 5 Mar 2026 09:53:37 +0100 Subject: [PATCH 5/9] Fix elicitation and resource subscription tests that deadlock on a single CPU (#854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dariusz Jędrzejczyk --- ...stractMcpClientServerIntegrationTests.java | 18 +++++++++------- .../client/AbstractMcpAsyncClientTests.java | 21 +++++++------------ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java index 270bc4308..7d0784c9c 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java @@ -53,7 +53,6 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; @@ -404,6 +403,8 @@ void testCreateElicitationSuccess(String clientType) { .addContent(new McpSchema.TextContent("CALL RESPONSE")) .build(); + AtomicReference elicitResultRef = new AtomicReference<>(); + McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) .callHandler((exchange, request) -> { @@ -414,13 +415,9 @@ void testCreateElicitationSuccess(String clientType) { Map.of("type", "object", "properties", Map.of("message", Map.of("type", "string")))) .build(); - StepVerifier.create(exchange.createElicitation(elicitationRequest)).consumeNextWith(result -> { - assertThat(result).isNotNull(); - assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT); - assertThat(result.content().get("message")).isEqualTo("Test message"); - }).verifyComplete(); - - return Mono.just(callResponse); + return exchange.createElicitation(elicitationRequest) + .doOnNext(elicitResultRef::set) + .thenReturn(callResponse); }) .build(); @@ -438,6 +435,11 @@ void testCreateElicitationSuccess(String clientType) { assertThat(response).isNotNull(); assertThat(response).isEqualTo(callResponse); + assertWith(elicitResultRef.get(), result -> { + assertThat(result).isNotNull(); + assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT); + assertThat(result.content().get("message")).isEqualTo("Test message"); + }); } finally { mcpServer.closeGracefully().block(); diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/client/AbstractMcpAsyncClientTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/client/AbstractMcpAsyncClientTests.java index bee8f4f16..2ef45a1e0 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/client/AbstractMcpAsyncClientTests.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/client/AbstractMcpAsyncClientTests.java @@ -610,22 +610,17 @@ void testListAllResourceTemplatesReturnsImmutableList() { }); } - // @Test + @Test void testResourceSubscription() { withClient(createMcpTransport(), mcpAsyncClient -> { - StepVerifier.create(mcpAsyncClient.listResources()).consumeNextWith(resources -> { - if (!resources.resources().isEmpty()) { - Resource firstResource = resources.resources().get(0); - - // Test subscribe - StepVerifier.create(mcpAsyncClient.subscribeResource(new SubscribeRequest(firstResource.uri()))) - .verifyComplete(); - - // Test unsubscribe - StepVerifier.create(mcpAsyncClient.unsubscribeResource(new UnsubscribeRequest(firstResource.uri()))) - .verifyComplete(); + StepVerifier.create(mcpAsyncClient.listResources().flatMap(resources -> { + if (resources.resources().isEmpty()) { + return Mono.empty(); } - }).verifyComplete(); + Resource firstResource = resources.resources().get(0); + return mcpAsyncClient.subscribeResource(new SubscribeRequest(firstResource.uri())) + .then(mcpAsyncClient.unsubscribeResource(new UnsubscribeRequest(firstResource.uri()))); + })).verifyComplete(); }); } From ef9a621e460a84e4590129994dd0fcd19620bf07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20J=C4=99drzejczyk?= Date: Thu, 5 Mar 2026 10:12:46 +0100 Subject: [PATCH 6/9] chore: Publish 1.0.x snapshots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dariusz Jędrzejczyk --- .github/workflows/publish-snapshot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 1a61d336c..7bf426659 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -2,7 +2,7 @@ name: Publish Snapshot on: push: - branches: [ "main" ] + branches: [ "1.0.x" ] jobs: build: From 007604a870338132a2eafad0ae63b6e89636f8d4 Mon Sep 17 00:00:00 2001 From: Daniel Garnier-Moiroux Date: Fri, 27 Mar 2026 19:19:47 +0100 Subject: [PATCH 7/9] Merge commit from fork --- .../server/transport/HttpServletSseServerTransportProvider.java | 1 - .../transport/HttpServletStreamableServerTransportProvider.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProvider.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProvider.java index 7037ff293..e520e4288 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProvider.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProvider.java @@ -267,7 +267,6 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) response.setCharacterEncoding(UTF_8); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); - response.setHeader("Access-Control-Allow-Origin", "*"); String sessionId = UUID.randomUUID().toString(); AsyncContext asyncContext = request.startAsync(); diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletStreamableServerTransportProvider.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletStreamableServerTransportProvider.java index d7561188c..f4feaf52d 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletStreamableServerTransportProvider.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/transport/HttpServletStreamableServerTransportProvider.java @@ -303,7 +303,6 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) response.setCharacterEncoding(UTF_8); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); - response.setHeader("Access-Control-Allow-Origin", "*"); AsyncContext asyncContext = request.startAsync(); asyncContext.setTimeout(0); @@ -510,7 +509,6 @@ else if (message instanceof McpSchema.JSONRPCRequest jsonrpcRequest) { response.setCharacterEncoding(UTF_8); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); - response.setHeader("Access-Control-Allow-Origin", "*"); AsyncContext asyncContext = request.startAsync(); asyncContext.setTimeout(0); From d187d09dd58ae9349380a57a23c3636dd78e29e1 Mon Sep 17 00:00:00 2001 From: Daniel Garnier-Moiroux Date: Fri, 27 Mar 2026 20:56:02 +0100 Subject: [PATCH 8/9] Release version 1.0.1 Signed-off-by: Daniel Garnier-Moiroux --- conformance-tests/client-jdk-http-client/pom.xml | 4 ++-- conformance-tests/pom.xml | 2 +- conformance-tests/server-servlet/pom.xml | 4 ++-- mcp-bom/pom.xml | 2 +- mcp-core/pom.xml | 2 +- mcp-json-jackson2/pom.xml | 4 ++-- mcp-json-jackson3/pom.xml | 4 ++-- mcp-test/pom.xml | 8 ++++---- mcp/pom.xml | 6 +++--- pom.xml | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/conformance-tests/client-jdk-http-client/pom.xml b/conformance-tests/client-jdk-http-client/pom.xml index c4eb9e54a..637aeea16 100644 --- a/conformance-tests/client-jdk-http-client/pom.xml +++ b/conformance-tests/client-jdk-http-client/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.1-SNAPSHOT + 1.0.1 client-jdk-http-client jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.1-SNAPSHOT + 1.0.1 diff --git a/conformance-tests/pom.xml b/conformance-tests/pom.xml index 60e5cc857..9390c559e 100644 --- a/conformance-tests/pom.xml +++ b/conformance-tests/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 conformance-tests pom diff --git a/conformance-tests/server-servlet/pom.xml b/conformance-tests/server-servlet/pom.xml index 35b3c981d..e7e7a13c4 100644 --- a/conformance-tests/server-servlet/pom.xml +++ b/conformance-tests/server-servlet/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.1-SNAPSHOT + 1.0.1 server-servlet jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.1-SNAPSHOT + 1.0.1 diff --git a/mcp-bom/pom.xml b/mcp-bom/pom.xml index 422462e05..337b00038 100644 --- a/mcp-bom/pom.xml +++ b/mcp-bom/pom.xml @@ -7,7 +7,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 mcp-bom diff --git a/mcp-core/pom.xml b/mcp-core/pom.xml index e540074f9..b55ccaaca 100644 --- a/mcp-core/pom.xml +++ b/mcp-core/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 mcp-core jar diff --git a/mcp-json-jackson2/pom.xml b/mcp-json-jackson2/pom.xml index a2af272c0..ef458d87d 100644 --- a/mcp-json-jackson2/pom.xml +++ b/mcp-json-jackson2/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 mcp-json-jackson2 jar @@ -70,7 +70,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.1-SNAPSHOT + 1.0.1 com.networknt diff --git a/mcp-json-jackson3/pom.xml b/mcp-json-jackson3/pom.xml index 77ac06ff1..d5318ccae 100644 --- a/mcp-json-jackson3/pom.xml +++ b/mcp-json-jackson3/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 mcp-json-jackson3 jar @@ -64,7 +64,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.1-SNAPSHOT + 1.0.1 tools.jackson.core diff --git a/mcp-test/pom.xml b/mcp-test/pom.xml index f27b741c0..c8e0bdb6f 100644 --- a/mcp-test/pom.xml +++ b/mcp-test/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 mcp-test jar @@ -24,7 +24,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.1-SNAPSHOT + 1.0.1 @@ -159,7 +159,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.1-SNAPSHOT + 1.0.1 test @@ -170,7 +170,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson2 - 1.0.1-SNAPSHOT + 1.0.1 test diff --git a/mcp/pom.xml b/mcp/pom.xml index 576ab0ce8..b61f7b6ee 100644 --- a/mcp/pom.xml +++ b/mcp/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 mcp jar @@ -25,13 +25,13 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.1-SNAPSHOT + 1.0.1 io.modelcontextprotocol.sdk mcp-core - 1.0.1-SNAPSHOT + 1.0.1 diff --git a/pom.xml b/pom.xml index a854e5e73..414accb93 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1-SNAPSHOT + 1.0.1 pom https://github.com/modelcontextprotocol/java-sdk From b6718fd17a1112556149adcf7c8a39d28be3f3b8 Mon Sep 17 00:00:00 2001 From: Daniel Garnier-Moiroux Date: Fri, 27 Mar 2026 20:57:07 +0100 Subject: [PATCH 9/9] Next development version Signed-off-by: Daniel Garnier-Moiroux --- conformance-tests/client-jdk-http-client/pom.xml | 4 ++-- conformance-tests/pom.xml | 2 +- conformance-tests/server-servlet/pom.xml | 4 ++-- mcp-bom/pom.xml | 2 +- mcp-core/pom.xml | 2 +- mcp-json-jackson2/pom.xml | 4 ++-- mcp-json-jackson3/pom.xml | 4 ++-- mcp-test/pom.xml | 8 ++++---- mcp/pom.xml | 6 +++--- pom.xml | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/conformance-tests/client-jdk-http-client/pom.xml b/conformance-tests/client-jdk-http-client/pom.xml index 637aeea16..dfd9c7d93 100644 --- a/conformance-tests/client-jdk-http-client/pom.xml +++ b/conformance-tests/client-jdk-http-client/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.1 + 1.0.2-SNAPSHOT client-jdk-http-client jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.1 + 1.0.2-SNAPSHOT diff --git a/conformance-tests/pom.xml b/conformance-tests/pom.xml index 9390c559e..87b342bad 100644 --- a/conformance-tests/pom.xml +++ b/conformance-tests/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT conformance-tests pom diff --git a/conformance-tests/server-servlet/pom.xml b/conformance-tests/server-servlet/pom.xml index e7e7a13c4..a40c976fd 100644 --- a/conformance-tests/server-servlet/pom.xml +++ b/conformance-tests/server-servlet/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk conformance-tests - 1.0.1 + 1.0.2-SNAPSHOT server-servlet jar @@ -28,7 +28,7 @@ io.modelcontextprotocol.sdk mcp - 1.0.1 + 1.0.2-SNAPSHOT diff --git a/mcp-bom/pom.xml b/mcp-bom/pom.xml index 337b00038..bc368eaf7 100644 --- a/mcp-bom/pom.xml +++ b/mcp-bom/pom.xml @@ -7,7 +7,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT mcp-bom diff --git a/mcp-core/pom.xml b/mcp-core/pom.xml index b55ccaaca..de151b8aa 100644 --- a/mcp-core/pom.xml +++ b/mcp-core/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT mcp-core jar diff --git a/mcp-json-jackson2/pom.xml b/mcp-json-jackson2/pom.xml index ef458d87d..497ba4945 100644 --- a/mcp-json-jackson2/pom.xml +++ b/mcp-json-jackson2/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT mcp-json-jackson2 jar @@ -70,7 +70,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.1 + 1.0.2-SNAPSHOT com.networknt diff --git a/mcp-json-jackson3/pom.xml b/mcp-json-jackson3/pom.xml index d5318ccae..0ed736a96 100644 --- a/mcp-json-jackson3/pom.xml +++ b/mcp-json-jackson3/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT mcp-json-jackson3 jar @@ -64,7 +64,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.1 + 1.0.2-SNAPSHOT tools.jackson.core diff --git a/mcp-test/pom.xml b/mcp-test/pom.xml index c8e0bdb6f..9f7e8b41a 100644 --- a/mcp-test/pom.xml +++ b/mcp-test/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT mcp-test jar @@ -24,7 +24,7 @@ io.modelcontextprotocol.sdk mcp-core - 1.0.1 + 1.0.2-SNAPSHOT @@ -159,7 +159,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.1 + 1.0.2-SNAPSHOT test @@ -170,7 +170,7 @@ io.modelcontextprotocol.sdk mcp-json-jackson2 - 1.0.1 + 1.0.2-SNAPSHOT test diff --git a/mcp/pom.xml b/mcp/pom.xml index b61f7b6ee..9928f5d7b 100644 --- a/mcp/pom.xml +++ b/mcp/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT mcp jar @@ -25,13 +25,13 @@ io.modelcontextprotocol.sdk mcp-json-jackson3 - 1.0.1 + 1.0.2-SNAPSHOT io.modelcontextprotocol.sdk mcp-core - 1.0.1 + 1.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 414accb93..2bc24bb7c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.modelcontextprotocol.sdk mcp-parent - 1.0.1 + 1.0.2-SNAPSHOT pom https://github.com/modelcontextprotocol/java-sdk