Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions mcp-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,6 @@
<version>${project.version}</version>
</dependency>

<!-- MCP JSON -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-json</artifactId>
<version>${project.version}</version>
</dependency>

<!-- MCP JSON Jackson -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
Expand Down
20 changes: 7 additions & 13 deletions mcp-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
Automatic-Module-Name: ${project.groupId}.${project.artifactId}
Import-Package: jakarta.*;resolution:=optional, \
*;
Service-Component: OSGI-INF/io.modelcontextprotocol.json.McpJsonDefaults.xml
Export-Package: io.modelcontextprotocol.*;version="${version}";-noimport:=true
-noimportjava: true;
-nouses: true;
Expand All @@ -65,11 +66,6 @@
</build>

<dependencies>
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-json</artifactId>
<version>0.18.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
Expand Down Expand Up @@ -97,21 +93,19 @@
<scope>provided</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp-json-jackson3</artifactId>
<version>0.18.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson3.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.projectreactor.netty</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.modelcontextprotocol.client;

import io.modelcontextprotocol.common.McpTransportContext;
import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
Expand Down Expand Up @@ -491,9 +492,12 @@ public McpSyncClient build() {

McpClientFeatures.Async asyncFeatures = McpClientFeatures.Async.fromSync(syncFeatures);

return new McpSyncClient(new McpAsyncClient(transport, this.requestTimeout, this.initializationTimeout,
jsonSchemaValidator != null ? jsonSchemaValidator : JsonSchemaValidator.getDefault(),
asyncFeatures), this.contextProvider);
return new McpSyncClient(
new McpAsyncClient(transport, this.requestTimeout, this.initializationTimeout,
jsonSchemaValidator != null ? jsonSchemaValidator
: McpJsonDefaults.getDefaultJsonSchemaValidator(),
asyncFeatures),
this.contextProvider);
}

}
Expand Down Expand Up @@ -826,7 +830,7 @@ public AsyncSpec enableCallToolSchemaCaching(boolean enableCallToolSchemaCaching
*/
public McpAsyncClient build() {
var jsonSchemaValidator = (this.jsonSchemaValidator != null) ? this.jsonSchemaValidator
: JsonSchemaValidator.getDefault();
: McpJsonDefaults.getDefaultJsonSchemaValidator();
return new McpAsyncClient(this.transport, this.requestTimeout, this.initializationTimeout,
jsonSchemaValidator,
new McpClientFeatures.Async(this.clientInfo, this.capabilities, this.roots,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.modelcontextprotocol.client.transport.customizer.McpAsyncHttpClientRequestCustomizer;
import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer;
import io.modelcontextprotocol.common.McpTransportContext;
import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.json.McpJsonMapper;
import io.modelcontextprotocol.json.TypeRef;
import io.modelcontextprotocol.spec.HttpHeaders;
Expand Down Expand Up @@ -327,7 +328,7 @@ public Builder connectTimeout(Duration connectTimeout) {
public HttpClientSseClientTransport build() {
HttpClient httpClient = this.clientBuilder.connectTimeout(this.connectTimeout).build();
return new HttpClientSseClientTransport(httpClient, requestBuilder, baseUri, sseEndpoint,
jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper, httpRequestCustomizer);
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, httpRequestCustomizer);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.modelcontextprotocol.client.transport.customizer.McpAsyncHttpClientRequestCustomizer;
import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer;
import io.modelcontextprotocol.common.McpTransportContext;
import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.json.McpJsonMapper;
import io.modelcontextprotocol.json.TypeRef;
import io.modelcontextprotocol.spec.ClosedMcpTransportSession;
Expand Down Expand Up @@ -822,9 +823,10 @@ public Builder supportedProtocolVersions(List<String> supportedProtocolVersions)
*/
public HttpClientStreamableHttpTransport build() {
HttpClient httpClient = this.clientBuilder.connectTimeout(this.connectTimeout).build();
return new HttpClientStreamableHttpTransport(jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper,
httpClient, requestBuilder, baseUri, endpoint, resumableStreams, openConnectionOnStartup,
httpRequestCustomizer, supportedProtocolVersions);
return new HttpClientStreamableHttpTransport(
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, httpClient,
requestBuilder, baseUri, endpoint, resumableStreams, openConnectionOnStartup, httpRequestCustomizer,
supportedProtocolVersions);
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* Copyright 2026 - 2026 the original author or authors.
*/
package io.modelcontextprotocol.json;

import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
import io.modelcontextprotocol.json.schema.JsonSchemaValidatorSupplier;
import io.modelcontextprotocol.util.McpServiceLoader;

/**
* This class is to be used to provide access to the default McpJsonMapper and to the
* default JsonSchemaValidator instances via the static methods: getDefaultMcpJsonMapper
* and getDefaultJsonSchemaValidator.
* <p>
* </p>
* The initialization of (singleton) instances of this class is different in non-OSGi
* environments and OSGi environments. Specifically, in non-OSGi environments The
* McpJsonDefaults class will be loaded by whatever classloader is used to call one of the
* existing static get methods for the first time. For servers, this will usually be in
* response to the creation of the first McpServer instance. At that first time, the
* mcpMapperServiceLoader and mcpValidatorServiceLoader will be null, and the
* McpJsonDefaults constructor will be called, creating/initializing the
* mcpMapperServiceLoader and the mcpValidatorServiceLoader...which will then be used to
* call the ServiceLoader.load method.
* <p>
* </p>
* In OSGi environments, upon bundle activation SCR will create a new (singleton) instance
* of McpJsonDefaults (via the constructor), and then inject suppliers via the
* setMcpJsonMapperSupplier and setJsonSchemaValidatorSupplier methods with the
* SCR-discovered instances of those services. This does depend upon the jars/bundles
* providing those suppliers to be started/activated. This SCR behavior is dictated by xml
* files in OSGi-INF directory of mcp-core (this project/jar/bundle), and the jsonmapper
* and jsonschemvalidator provider jars/bundles (e.g. mcp-json-jackson2, 3, or others).
*
* <p>
* </p>
*
*/
public class McpJsonDefaults {

protected static McpServiceLoader<McpJsonMapperSupplier, McpJsonMapper> mcpMapperServiceLoader;

protected static McpServiceLoader<JsonSchemaValidatorSupplier, JsonSchemaValidator> mcpValidatorServiceLoader;

public McpJsonDefaults() {
mcpMapperServiceLoader = new McpServiceLoader<McpJsonMapperSupplier, McpJsonMapper>(
McpJsonMapperSupplier.class);
mcpValidatorServiceLoader = new McpServiceLoader<JsonSchemaValidatorSupplier, JsonSchemaValidator>(
JsonSchemaValidatorSupplier.class);
}

void setMcpJsonMapperSupplier(McpJsonMapperSupplier supplier) {
mcpMapperServiceLoader.setSupplier(supplier);
}

void unsetMcpJsonMapperSupplier(McpJsonMapperSupplier supplier) {
mcpMapperServiceLoader.unsetSupplier(supplier);
}

public synchronized static McpJsonMapper getDefaultMcpJsonMapper() {
if (mcpMapperServiceLoader == null) {
new McpJsonDefaults();
}
return mcpMapperServiceLoader.getDefault();
}

void setJsonSchemaValidatorSupplier(JsonSchemaValidatorSupplier supplier) {
mcpValidatorServiceLoader.setSupplier(supplier);
}

void unsetJsonSchemaValidatorSupplier(JsonSchemaValidatorSupplier supplier) {
mcpValidatorServiceLoader.unsetSupplier(supplier);
}

public synchronized static JsonSchemaValidator getDefaultJsonSchemaValidator() {
if (mcpValidatorServiceLoader == null) {
new McpJsonDefaults();
}
return mcpValidatorServiceLoader.getDefault();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,4 @@ public interface McpJsonMapper {
*/
byte[] writeValueAsBytes(Object value) throws IOException;

/**
* Returns the default {@link McpJsonMapper}.
* @return The default {@link McpJsonMapper}
* @throws IllegalStateException If no {@link McpJsonMapper} implementation exists on
* the classpath.
*/
static McpJsonMapper getDefault() {
return McpJsonInternal.getDefaultMapper();
}

/**
* Creates a new default {@link McpJsonMapper}.
* @return The default {@link McpJsonMapper}
* @throws IllegalStateException If no {@link McpJsonMapper} implementation exists on
* the classpath.
*/
static McpJsonMapper createDefault() {
return McpJsonInternal.createDefaultMapper();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

/**
* Captures generic type information at runtime for parameterized JSON (de)serialization.
* Usage: TypeRef&lt;List&lt;Foo&gt;&gt; ref = new TypeRef&lt;&gt;(){};
* Usage: TypeRef<List<Foo>> ref = new TypeRef<>(){};
*/
public abstract class TypeRef<T> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,4 @@ public static ValidationResponse asInvalid(String message) {
*/
ValidationResponse validate(Map<String, Object> schema, Object structuredContent);

/**
* Creates the default {@link JsonSchemaValidator}.
* @return The default {@link JsonSchemaValidator}
* @throws IllegalStateException If no {@link JsonSchemaValidator} implementation
* exists on the classpath.
*/
static JsonSchemaValidator createDefault() {
return JsonSchemaInternal.createDefaultValidator();
}

/**
* Returns the default {@link JsonSchemaValidator}.
* @return The default {@link JsonSchemaValidator}
* @throws IllegalStateException If no {@link JsonSchemaValidator} implementation
* exists on the classpath.
*/
static JsonSchemaValidator getDefault() {
return JsonSchemaInternal.getDefaultValidator();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.json.McpJsonMapper;

import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
Expand Down Expand Up @@ -240,10 +241,11 @@ public McpAsyncServer build() {
this.instructions);

var jsonSchemaValidator = (this.jsonSchemaValidator != null) ? this.jsonSchemaValidator
: JsonSchemaValidator.getDefault();
: McpJsonDefaults.getDefaultJsonSchemaValidator();

return new McpAsyncServer(transportProvider, jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper,
features, requestTimeout, uriTemplateManagerFactory, jsonSchemaValidator);
return new McpAsyncServer(transportProvider,
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, features,
requestTimeout, uriTemplateManagerFactory, jsonSchemaValidator);
}

}
Expand All @@ -267,9 +269,10 @@ public McpAsyncServer build() {
this.resources, this.resourceTemplates, this.prompts, this.completions, this.rootsChangeHandlers,
this.instructions);
var jsonSchemaValidator = this.jsonSchemaValidator != null ? this.jsonSchemaValidator
: JsonSchemaValidator.getDefault();
return new McpAsyncServer(transportProvider, jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper,
features, requestTimeout, uriTemplateManagerFactory, jsonSchemaValidator);
: McpJsonDefaults.getDefaultJsonSchemaValidator();
return new McpAsyncServer(transportProvider,
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, features,
requestTimeout, uriTemplateManagerFactory, jsonSchemaValidator);
}

}
Expand Down Expand Up @@ -834,9 +837,9 @@ public McpSyncServer build() {
this.immediateExecution);

var asyncServer = new McpAsyncServer(transportProvider,
jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper, asyncFeatures, requestTimeout,
uriTemplateManagerFactory,
jsonSchemaValidator != null ? jsonSchemaValidator : JsonSchemaValidator.getDefault());
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, asyncFeatures,
requestTimeout, uriTemplateManagerFactory, jsonSchemaValidator != null ? jsonSchemaValidator
: McpJsonDefaults.getDefaultJsonSchemaValidator());
return new McpSyncServer(asyncServer, this.immediateExecution);
}

Expand Down Expand Up @@ -864,10 +867,10 @@ public McpSyncServer build() {
McpServerFeatures.Async asyncFeatures = McpServerFeatures.Async.fromSync(syncFeatures,
this.immediateExecution);
var jsonSchemaValidator = this.jsonSchemaValidator != null ? this.jsonSchemaValidator
: JsonSchemaValidator.getDefault();
: McpJsonDefaults.getDefaultJsonSchemaValidator();
var asyncServer = new McpAsyncServer(transportProvider,
jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper, asyncFeatures, this.requestTimeout,
this.uriTemplateManagerFactory, jsonSchemaValidator);
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, asyncFeatures,
this.requestTimeout, this.uriTemplateManagerFactory, jsonSchemaValidator);
return new McpSyncServer(asyncServer, this.immediateExecution);
}

Expand Down Expand Up @@ -1871,9 +1874,10 @@ public StatelessAsyncSpecification jsonSchemaValidator(JsonSchemaValidator jsonS
public McpStatelessAsyncServer build() {
var features = new McpStatelessServerFeatures.Async(this.serverInfo, this.serverCapabilities, this.tools,
this.resources, this.resourceTemplates, this.prompts, this.completions, this.instructions);
return new McpStatelessAsyncServer(transport, jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper,
features, requestTimeout, uriTemplateManagerFactory,
jsonSchemaValidator != null ? jsonSchemaValidator : JsonSchemaValidator.getDefault());
return new McpStatelessAsyncServer(transport,
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, features,
requestTimeout, uriTemplateManagerFactory, jsonSchemaValidator != null ? jsonSchemaValidator
: McpJsonDefaults.getDefaultJsonSchemaValidator());
}

}
Expand Down Expand Up @@ -2351,9 +2355,9 @@ public McpStatelessSyncServer build() {
this.resources, this.resourceTemplates, this.prompts, this.completions, this.instructions);
var asyncFeatures = McpStatelessServerFeatures.Async.fromSync(syncFeatures, this.immediateExecution);
var asyncServer = new McpStatelessAsyncServer(transport,
jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper, asyncFeatures, requestTimeout,
uriTemplateManagerFactory,
this.jsonSchemaValidator != null ? this.jsonSchemaValidator : JsonSchemaValidator.getDefault());
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, asyncFeatures,
requestTimeout, uriTemplateManagerFactory, this.jsonSchemaValidator != null
? this.jsonSchemaValidator : McpJsonDefaults.getDefaultJsonSchemaValidator());
return new McpStatelessSyncServer(asyncServer, this.immediateExecution);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.concurrent.atomic.AtomicBoolean;

import io.modelcontextprotocol.common.McpTransportContext;
import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.json.McpJsonMapper;
import io.modelcontextprotocol.json.TypeRef;
import io.modelcontextprotocol.server.McpTransportContextExtractor;
Expand Down Expand Up @@ -632,8 +633,8 @@ public HttpServletSseServerTransportProvider build() {
throw new IllegalStateException("MessageEndpoint must be set");
}
return new HttpServletSseServerTransportProvider(
jsonMapper == null ? McpJsonMapper.getDefault() : jsonMapper, baseUrl, messageEndpoint, sseEndpoint,
keepAliveInterval, contextExtractor);
jsonMapper == null ? McpJsonDefaults.getDefaultMcpJsonMapper() : jsonMapper, baseUrl,
messageEndpoint, sseEndpoint, keepAliveInterval, contextExtractor);
}

}
Expand Down
Loading