Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9e1a2f34d | ||
|
|
141063c99c | ||
|
|
92bb47b67c | ||
|
|
9ead4d154e | ||
|
|
8e1c5d0cd4 | ||
|
|
7e4c179b77 | ||
|
|
3c27d8e3f8 | ||
|
|
5968078106 | ||
|
|
d69501fd28 |
||
|
|
c9b936835f | ||
|
|
d4d8072693 |
27 changed files with 455 additions and 113 deletions
|
|
@ -27,7 +27,7 @@ Once we catch up on the most recent MCP specification revision we aim to fully s
|
||||||
|
|
||||||
### v1.x Development
|
### v1.x Development
|
||||||
|
|
||||||
The Java SDK is currently in active development as v1.x, following a recent stable 1.0.0 release. The SDK provides:
|
The Java SDK is currently in active development as v1.x, following a recent stable 1.1.0 release. The SDK provides:
|
||||||
|
|
||||||
- MCP protocol implementation
|
- MCP protocol implementation
|
||||||
- Synchronous and asynchronous programming models
|
- Synchronous and asynchronous programming models
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ cd conformance-tests/client-jdk-http-client
|
||||||
# Run all scenarios
|
# Run all scenarios
|
||||||
for scenario in initialize tools_call elicitation-sep1034-client-defaults sse-retry; do
|
for scenario in initialize tools_call elicitation-sep1034-client-defaults sse-retry; do
|
||||||
npx @modelcontextprotocol/conformance client \
|
npx @modelcontextprotocol/conformance client \
|
||||||
--command "java -jar target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar target/client-jdk-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario $scenario
|
--scenario $scenario
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
@ -104,7 +104,7 @@ cd conformance-tests/client-spring-http-client
|
||||||
# Run auth suite
|
# Run auth suite
|
||||||
npx @modelcontextprotocol/conformance@0.1.15 client \
|
npx @modelcontextprotocol/conformance@0.1.15 client \
|
||||||
--spec-version 2025-11-25 \
|
--spec-version 2025-11-25 \
|
||||||
--command "java -jar target/client-spring-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar target/client-spring-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--suite auth
|
--suite auth
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ cd conformance-tests/client-jdk-http-client
|
||||||
|
|
||||||
This creates an executable JAR at:
|
This creates an executable JAR at:
|
||||||
```
|
```
|
||||||
target/client-jdk-http-client-1.1.0-SNAPSHOT.jar
|
target/client-jdk-http-client-1.1.1-SNAPSHOT.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running Tests
|
## Running Tests
|
||||||
|
|
@ -65,19 +65,19 @@ Run a single scenario:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx @modelcontextprotocol/conformance client \
|
npx @modelcontextprotocol/conformance client \
|
||||||
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario initialize
|
--scenario initialize
|
||||||
|
|
||||||
npx @modelcontextprotocol/conformance client \
|
npx @modelcontextprotocol/conformance client \
|
||||||
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario tools_call
|
--scenario tools_call
|
||||||
|
|
||||||
npx @modelcontextprotocol/conformance client \
|
npx @modelcontextprotocol/conformance client \
|
||||||
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario elicitation-sep1034-client-defaults
|
--scenario elicitation-sep1034-client-defaults
|
||||||
|
|
||||||
npx @modelcontextprotocol/conformance client \
|
npx @modelcontextprotocol/conformance client \
|
||||||
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario sse-retry
|
--scenario sse-retry
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ Run with verbose output:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx @modelcontextprotocol/conformance client \
|
npx @modelcontextprotocol/conformance client \
|
||||||
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario initialize \
|
--scenario initialize \
|
||||||
--verbose
|
--verbose
|
||||||
```
|
```
|
||||||
|
|
@ -96,7 +96,7 @@ You can also run the client manually if you have a test server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export MCP_CONFORMANCE_SCENARIO=initialize
|
export MCP_CONFORMANCE_SCENARIO=initialize
|
||||||
java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar http://localhost:3000/mcp
|
java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.1-SNAPSHOT.jar http://localhost:3000/mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test Results
|
## Test Results
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>conformance-tests</artifactId>
|
<artifactId>conformance-tests</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>client-jdk-http-client</artifactId>
|
<artifactId>client-jdk-http-client</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp</artifactId>
|
<artifactId>mcp</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Logging -->
|
<!-- Logging -->
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ cd conformance-tests/client-spring-http-client
|
||||||
|
|
||||||
This creates an executable JAR at:
|
This creates an executable JAR at:
|
||||||
```
|
```
|
||||||
target/client-spring-http-client-1.1.0-SNAPSHOT.jar
|
target/client-spring-http-client-1.1.1-SNAPSHOT.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running Tests
|
## Running Tests
|
||||||
|
|
@ -79,7 +79,7 @@ Run the full auth suite:
|
||||||
```bash
|
```bash
|
||||||
npx @modelcontextprotocol/conformance@0.1.15 client \
|
npx @modelcontextprotocol/conformance@0.1.15 client \
|
||||||
--spec-version 2025-11-25 \
|
--spec-version 2025-11-25 \
|
||||||
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--suite auth
|
--suite auth
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ Run a single scenario:
|
||||||
```bash
|
```bash
|
||||||
npx @modelcontextprotocol/conformance@0.1.15 client \
|
npx @modelcontextprotocol/conformance@0.1.15 client \
|
||||||
--spec-version 2025-11-25 \
|
--spec-version 2025-11-25 \
|
||||||
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario auth/metadata-default
|
--scenario auth/metadata-default
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ Run with verbose output:
|
||||||
```bash
|
```bash
|
||||||
npx @modelcontextprotocol/conformance@0.1.15 client \
|
npx @modelcontextprotocol/conformance@0.1.15 client \
|
||||||
--spec-version 2025-11-25 \
|
--spec-version 2025-11-25 \
|
||||||
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.0-SNAPSHOT.jar" \
|
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.1-SNAPSHOT.jar" \
|
||||||
--scenario auth/metadata-default \
|
--scenario auth/metadata-default \
|
||||||
--verbose
|
--verbose
|
||||||
```
|
```
|
||||||
|
|
@ -108,7 +108,7 @@ You can also run the client manually if you have a test server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export MCP_CONFORMANCE_SCENARIO=auth/metadata-default
|
export MCP_CONFORMANCE_SCENARIO=auth/metadata-default
|
||||||
java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.0-SNAPSHOT.jar http://localhost:3000/mcp
|
java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-1.1.1-SNAPSHOT.jar http://localhost:3000/mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>conformance-tests</artifactId>
|
<artifactId>conformance-tests</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>client-spring-http-client</artifactId>
|
<artifactId>client-spring-http-client</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-parent</artifactId>
|
<artifactId>mcp-parent</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>conformance-tests</artifactId>
|
<artifactId>conformance-tests</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>conformance-tests</artifactId>
|
<artifactId>conformance-tests</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>server-servlet</artifactId>
|
<artifactId>server-servlet</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp</artifactId>
|
<artifactId>mcp</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ Add the BOM to your project:
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-bom</artifactId>
|
<artifactId>mcp-bom</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
@ -135,7 +135,7 @@ Add the BOM to your project:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation platform("io.modelcontextprotocol.sdk:mcp-bom:1.0.0")
|
implementation platform("io.modelcontextprotocol.sdk:mcp-bom:1.1.0")
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-parent</artifactId>
|
<artifactId>mcp-parent</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mcp-bom</artifactId>
|
<artifactId>mcp-bom</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-parent</artifactId>
|
<artifactId>mcp-parent</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>mcp-core</artifactId>
|
<artifactId>mcp-core</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ public class McpAsyncClient {
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.listToolsInternal(init, McpSchema.FIRST_PAGE).doOnNext(listToolsResult -> {
|
return this.listToolsInternal(init, McpSchema.FIRST_PAGE, null).doOnNext(listToolsResult -> {
|
||||||
listToolsResult.tools()
|
listToolsResult.tools()
|
||||||
.forEach(tool -> logger.debug("Tool {} schema: {}", tool.name(), tool.outputSchema()));
|
.forEach(tool -> logger.debug("Tool {} schema: {}", tool.name(), tool.outputSchema()));
|
||||||
if (enableCallToolSchemaCaching && listToolsResult.tools() != null) {
|
if (enableCallToolSchemaCaching && listToolsResult.tools() != null) {
|
||||||
|
|
@ -645,16 +645,27 @@ public class McpAsyncClient {
|
||||||
* @return A Mono that emits the list of tools result
|
* @return A Mono that emits the list of tools result
|
||||||
*/
|
*/
|
||||||
public Mono<McpSchema.ListToolsResult> listTools(String cursor) {
|
public Mono<McpSchema.ListToolsResult> listTools(String cursor) {
|
||||||
return this.initializer.withInitialization("listing tools", init -> this.listToolsInternal(init, cursor));
|
return this.initializer.withInitialization("listing tools", init -> this.listToolsInternal(init, cursor, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<McpSchema.ListToolsResult> listToolsInternal(Initialization init, String cursor) {
|
/**
|
||||||
|
* Retrieves a paginated list of tools with optional metadata.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return A Mono that emits the list of tools result
|
||||||
|
*/
|
||||||
|
public Mono<McpSchema.ListToolsResult> listTools(String cursor, Map<String, Object> meta) {
|
||||||
|
return this.initializer.withInitialization("listing tools", init -> this.listToolsInternal(init, cursor, meta));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<McpSchema.ListToolsResult> listToolsInternal(Initialization init, String cursor,
|
||||||
|
Map<String, Object> meta) {
|
||||||
|
|
||||||
if (init.initializeResult().capabilities().tools() == null) {
|
if (init.initializeResult().capabilities().tools() == null) {
|
||||||
return Mono.error(new IllegalStateException("Server does not provide tools capability"));
|
return Mono.error(new IllegalStateException("Server does not provide tools capability"));
|
||||||
}
|
}
|
||||||
return init.mcpSession()
|
return init.mcpSession()
|
||||||
.sendRequest(McpSchema.METHOD_TOOLS_LIST, new McpSchema.PaginatedRequest(cursor),
|
.sendRequest(McpSchema.METHOD_TOOLS_LIST, new McpSchema.PaginatedRequest(cursor, meta),
|
||||||
LIST_TOOLS_RESULT_TYPE_REF)
|
LIST_TOOLS_RESULT_TYPE_REF)
|
||||||
.doOnNext(result -> {
|
.doOnNext(result -> {
|
||||||
// Validate tool names (warn only)
|
// Validate tool names (warn only)
|
||||||
|
|
@ -725,12 +736,30 @@ public class McpAsyncClient {
|
||||||
* @see #readResource(McpSchema.Resource)
|
* @see #readResource(McpSchema.Resource)
|
||||||
*/
|
*/
|
||||||
public Mono<McpSchema.ListResourcesResult> listResources(String cursor) {
|
public Mono<McpSchema.ListResourcesResult> listResources(String cursor) {
|
||||||
|
return this.listResourcesInternal(cursor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of resources provided by the server. Resources represent
|
||||||
|
* any kind of UTF-8 encoded data that an MCP server makes available to clients, such
|
||||||
|
* as database records, API responses, log files, and more.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return A Mono that completes with the list of resources result.
|
||||||
|
* @see McpSchema.ListResourcesResult
|
||||||
|
* @see #readResource(McpSchema.Resource)
|
||||||
|
*/
|
||||||
|
public Mono<McpSchema.ListResourcesResult> listResources(String cursor, Map<String, Object> meta) {
|
||||||
|
return this.listResourcesInternal(cursor, meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<McpSchema.ListResourcesResult> listResourcesInternal(String cursor, Map<String, Object> meta) {
|
||||||
return this.initializer.withInitialization("listing resources", init -> {
|
return this.initializer.withInitialization("listing resources", init -> {
|
||||||
if (init.initializeResult().capabilities().resources() == null) {
|
if (init.initializeResult().capabilities().resources() == null) {
|
||||||
return Mono.error(new IllegalStateException("Server does not provide the resources capability"));
|
return Mono.error(new IllegalStateException("Server does not provide the resources capability"));
|
||||||
}
|
}
|
||||||
return init.mcpSession()
|
return init.mcpSession()
|
||||||
.sendRequest(McpSchema.METHOD_RESOURCES_LIST, new McpSchema.PaginatedRequest(cursor),
|
.sendRequest(McpSchema.METHOD_RESOURCES_LIST, new McpSchema.PaginatedRequest(cursor, meta),
|
||||||
LIST_RESOURCES_RESULT_TYPE_REF);
|
LIST_RESOURCES_RESULT_TYPE_REF);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -795,12 +824,30 @@ public class McpAsyncClient {
|
||||||
* @see McpSchema.ListResourceTemplatesResult
|
* @see McpSchema.ListResourceTemplatesResult
|
||||||
*/
|
*/
|
||||||
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor) {
|
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor) {
|
||||||
|
return this.listResourceTemplatesInternal(cursor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of resource templates provided by the server. Resource
|
||||||
|
* templates allow servers to expose parameterized resources using URI templates,
|
||||||
|
* enabling dynamic resource access based on variable parameters.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return A Mono that completes with the list of resource templates result.
|
||||||
|
* @see McpSchema.ListResourceTemplatesResult
|
||||||
|
*/
|
||||||
|
public Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplates(String cursor, Map<String, Object> meta) {
|
||||||
|
return this.listResourceTemplatesInternal(cursor, meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<McpSchema.ListResourceTemplatesResult> listResourceTemplatesInternal(String cursor,
|
||||||
|
Map<String, Object> meta) {
|
||||||
return this.initializer.withInitialization("listing resource templates", init -> {
|
return this.initializer.withInitialization("listing resource templates", init -> {
|
||||||
if (init.initializeResult().capabilities().resources() == null) {
|
if (init.initializeResult().capabilities().resources() == null) {
|
||||||
return Mono.error(new IllegalStateException("Server does not provide the resources capability"));
|
return Mono.error(new IllegalStateException("Server does not provide the resources capability"));
|
||||||
}
|
}
|
||||||
return init.mcpSession()
|
return init.mcpSession()
|
||||||
.sendRequest(McpSchema.METHOD_RESOURCES_TEMPLATES_LIST, new McpSchema.PaginatedRequest(cursor),
|
.sendRequest(McpSchema.METHOD_RESOURCES_TEMPLATES_LIST, new McpSchema.PaginatedRequest(cursor, meta),
|
||||||
LIST_RESOURCE_TEMPLATES_RESULT_TYPE_REF);
|
LIST_RESOURCE_TEMPLATES_RESULT_TYPE_REF);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -895,8 +942,26 @@ public class McpAsyncClient {
|
||||||
* @see #getPrompt(GetPromptRequest)
|
* @see #getPrompt(GetPromptRequest)
|
||||||
*/
|
*/
|
||||||
public Mono<ListPromptsResult> listPrompts(String cursor) {
|
public Mono<ListPromptsResult> listPrompts(String cursor) {
|
||||||
return this.initializer.withInitialization("listing prompts", init -> init.mcpSession()
|
return this.listPromptsInternal(cursor, null);
|
||||||
.sendRequest(McpSchema.METHOD_PROMPT_LIST, new PaginatedRequest(cursor), LIST_PROMPTS_RESULT_TYPE_REF));
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of prompts with optional metadata.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return A Mono that completes with the list of prompts result.
|
||||||
|
* @see McpSchema.ListPromptsResult
|
||||||
|
* @see #getPrompt(GetPromptRequest)
|
||||||
|
*/
|
||||||
|
public Mono<ListPromptsResult> listPrompts(String cursor, Map<String, Object> meta) {
|
||||||
|
return this.listPromptsInternal(cursor, meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<ListPromptsResult> listPromptsInternal(String cursor, Map<String, Object> meta) {
|
||||||
|
return this.initializer.withInitialization("listing prompts",
|
||||||
|
init -> init.mcpSession()
|
||||||
|
.sendRequest(McpSchema.METHOD_PROMPT_LIST, new PaginatedRequest(cursor, meta),
|
||||||
|
LIST_PROMPTS_RESULT_TYPE_REF));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package io.modelcontextprotocol.client;
|
package io.modelcontextprotocol.client;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -259,6 +260,18 @@ public class McpSyncClient implements AutoCloseable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of tools provided by the server.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return The list of tools result containing: - tools: List of available tools, each
|
||||||
|
* with a name, description, and input schema - nextCursor: Optional cursor for
|
||||||
|
* pagination if more tools are available
|
||||||
|
*/
|
||||||
|
public McpSchema.ListToolsResult listTools(String cursor, Map<String, Object> meta) {
|
||||||
|
return withProvidedContext(this.delegate.listTools(cursor, meta)).block();
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// Resources
|
// Resources
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
|
@ -282,6 +295,17 @@ public class McpSyncClient implements AutoCloseable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of resources with optional metadata.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return The list of resources result
|
||||||
|
*/
|
||||||
|
public McpSchema.ListResourcesResult listResources(String cursor, Map<String, Object> meta) {
|
||||||
|
return withProvidedContext(this.delegate.listResources(cursor, meta)).block();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a resources/read request.
|
* Send a resources/read request.
|
||||||
* @param resource the resource to read
|
* @param resource the resource to read
|
||||||
|
|
@ -324,6 +348,20 @@ public class McpSyncClient implements AutoCloseable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource templates allow servers to expose parameterized resources using URI
|
||||||
|
* templates. Arguments may be auto-completed through the completion API.
|
||||||
|
*
|
||||||
|
* Retrieves a paginated list of resource templates provided by the server.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return The list of resource templates result.
|
||||||
|
*/
|
||||||
|
public McpSchema.ListResourceTemplatesResult listResourceTemplates(String cursor, Map<String, Object> meta) {
|
||||||
|
return withProvidedContext(this.delegate.listResourceTemplates(cursor, meta)).block();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscriptions. The protocol supports optional subscriptions to resource changes.
|
* Subscriptions. The protocol supports optional subscriptions to resource changes.
|
||||||
* Clients can subscribe to specific resources and receive notifications when they
|
* Clients can subscribe to specific resources and receive notifications when they
|
||||||
|
|
@ -370,6 +408,17 @@ public class McpSyncClient implements AutoCloseable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of prompts provided by the server.
|
||||||
|
* @param cursor Optional pagination cursor from a previous list request
|
||||||
|
* @param meta Optional metadata to include in the request (_meta field)
|
||||||
|
* @return The list of prompts result.
|
||||||
|
*/
|
||||||
|
public ListPromptsResult listPrompts(String cursor, Map<String, Object> meta) {
|
||||||
|
return withProvidedContext(this.delegate.listPrompts(cursor, meta)).block();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public GetPromptResult getPrompt(GetPromptRequest getPromptRequest) {
|
public GetPromptResult getPrompt(GetPromptRequest getPromptRequest) {
|
||||||
return withProvidedContext(this.delegate.getPrompt(getPromptRequest)).block();
|
return withProvidedContext(this.delegate.getPrompt(getPromptRequest)).block();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -241,10 +241,17 @@ public class HttpClientSseClientTransport implements McpClientTransport {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customizes the HTTP client builder.
|
* Applies the given consumer to the shared {@link HttpRequest.Builder} <b>once,
|
||||||
|
* at build time</b>. Any headers set here are frozen into the template and
|
||||||
|
* <b>cannot be updated</b> after the transport is built.
|
||||||
* @param requestCustomizer the consumer to customize the HTTP request builder
|
* @param requestCustomizer the consumer to customize the HTTP request builder
|
||||||
* @return this builder
|
* @return this builder
|
||||||
|
* @deprecated Use {@link #requestBuilder(HttpRequest.Builder)} for stable
|
||||||
|
* headers, or {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)}
|
||||||
|
* / {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for
|
||||||
|
* dynamic per-request customization.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder customizeRequest(final Consumer<HttpRequest.Builder> requestCustomizer) {
|
public Builder customizeRequest(final Consumer<HttpRequest.Builder> requestCustomizer) {
|
||||||
Assert.notNull(requestCustomizer, "requestCustomizer must not be null");
|
Assert.notNull(requestCustomizer, "requestCustomizer must not be null");
|
||||||
requestCustomizer.accept(requestBuilder);
|
requestCustomizer.accept(requestBuilder);
|
||||||
|
|
@ -456,7 +463,7 @@ public class HttpClientSseClientTransport implements McpClientTransport {
|
||||||
return Mono.deferContextual(ctx -> {
|
return Mono.deferContextual(ctx -> {
|
||||||
var builder = this.requestBuilder.copy()
|
var builder = this.requestBuilder.copy()
|
||||||
.uri(requestUri)
|
.uri(requestUri)
|
||||||
.header(HttpHeaders.CONTENT_TYPE, "application/json")
|
.header(HttpHeaders.CONTENT_TYPE, "application/json; charset=utf-8")
|
||||||
.header(MCP_PROTOCOL_VERSION_HEADER_NAME, MCP_PROTOCOL_VERSION)
|
.header(MCP_PROTOCOL_VERSION_HEADER_NAME, MCP_PROTOCOL_VERSION)
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(body));
|
.POST(HttpRequest.BodyPublishers.ofString(body));
|
||||||
var transportContext = ctx.getOrDefault(McpTransportContext.KEY, McpTransportContext.EMPTY);
|
var transportContext = ctx.getOrDefault(McpTransportContext.KEY, McpTransportContext.EMPTY);
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,8 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
||||||
|
|
||||||
private static final String APPLICATION_JSON = "application/json";
|
private static final String APPLICATION_JSON = "application/json";
|
||||||
|
|
||||||
|
private static final String APPLICATION_JSON_UTF8 = "application/json; charset=utf-8";
|
||||||
|
|
||||||
private static final String TEXT_EVENT_STREAM = "text/event-stream";
|
private static final String TEXT_EVENT_STREAM = "text/event-stream";
|
||||||
|
|
||||||
public static int NOT_FOUND = 404;
|
public static int NOT_FOUND = 404;
|
||||||
|
|
@ -298,6 +300,10 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
||||||
"Authorization error connecting to SSE stream",
|
"Authorization error connecting to SSE stream",
|
||||||
responseEvent.responseInfo()));
|
responseEvent.responseInfo()));
|
||||||
}
|
}
|
||||||
|
else if (statusCode == METHOD_NOT_ALLOWED) {
|
||||||
|
logger.debug("The server does not support SSE streams, using request-response mode.");
|
||||||
|
return Flux.empty();
|
||||||
|
}
|
||||||
|
|
||||||
if (!(responseEvent instanceof ResponseSubscribers.SseResponseEvent sseResponseEvent)) {
|
if (!(responseEvent instanceof ResponseSubscribers.SseResponseEvent sseResponseEvent)) {
|
||||||
return Flux.<McpSchema.JSONRPCMessage>error(new McpTransportException(
|
return Flux.<McpSchema.JSONRPCMessage>error(new McpTransportException(
|
||||||
|
|
@ -344,10 +350,6 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
||||||
return Flux.empty();
|
return Flux.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (statusCode == METHOD_NOT_ALLOWED) { // NotAllowed
|
|
||||||
logger.debug("The server does not support SSE streams, using request-response mode.");
|
|
||||||
return Flux.empty();
|
|
||||||
}
|
|
||||||
else if (statusCode == NOT_FOUND) {
|
else if (statusCode == NOT_FOUND) {
|
||||||
|
|
||||||
if (transportSession != null && transportSession.sessionId().isPresent()) {
|
if (transportSession != null && transportSession.sessionId().isPresent()) {
|
||||||
|
|
@ -477,7 +479,7 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
||||||
|
|
||||||
var builder = requestBuilder.uri(uri)
|
var builder = requestBuilder.uri(uri)
|
||||||
.header(HttpHeaders.ACCEPT, APPLICATION_JSON + ", " + TEXT_EVENT_STREAM)
|
.header(HttpHeaders.ACCEPT, APPLICATION_JSON + ", " + TEXT_EVENT_STREAM)
|
||||||
.header(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON)
|
.header(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON_UTF8)
|
||||||
.header(HttpHeaders.CACHE_CONTROL, "no-cache")
|
.header(HttpHeaders.CACHE_CONTROL, "no-cache")
|
||||||
.header(HttpHeaders.PROTOCOL_VERSION,
|
.header(HttpHeaders.PROTOCOL_VERSION,
|
||||||
ctx.getOrDefault(McpAsyncClient.NEGOTIATED_PROTOCOL_VERSION,
|
ctx.getOrDefault(McpAsyncClient.NEGOTIATED_PROTOCOL_VERSION,
|
||||||
|
|
@ -738,10 +740,17 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customizes the HTTP client builder.
|
* Applies the given consumer to the shared {@link HttpRequest.Builder} <b>once,
|
||||||
|
* at build time</b>. Any headers set here are frozen into the template and
|
||||||
|
* <b>cannot be updated</b> after the transport is built.
|
||||||
* @param requestCustomizer the consumer to customize the HTTP request builder
|
* @param requestCustomizer the consumer to customize the HTTP request builder
|
||||||
* @return this builder
|
* @return this builder
|
||||||
|
* @deprecated Use {@link #requestBuilder(HttpRequest.Builder)} for stable
|
||||||
|
* headers, or {@link #httpRequestCustomizer(McpSyncHttpClientRequestCustomizer)}
|
||||||
|
* / {@link #asyncHttpRequestCustomizer(McpAsyncHttpClientRequestCustomizer)} for
|
||||||
|
* dynamic per-request customization.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder customizeRequest(final Consumer<HttpRequest.Builder> requestCustomizer) {
|
public Builder customizeRequest(final Consumer<HttpRequest.Builder> requestCustomizer) {
|
||||||
Assert.notNull(requestCustomizer, "requestCustomizer must not be null");
|
Assert.notNull(requestCustomizer, "requestCustomizer must not be null");
|
||||||
requestCustomizer.accept(requestBuilder);
|
requestCustomizer.accept(requestBuilder);
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,6 @@ public class HttpServletSseServerTransportProvider extends HttpServlet implement
|
||||||
response.setCharacterEncoding(UTF_8);
|
response.setCharacterEncoding(UTF_8);
|
||||||
response.setHeader("Cache-Control", "no-cache");
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
response.setHeader("Connection", "keep-alive");
|
response.setHeader("Connection", "keep-alive");
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
|
|
||||||
String sessionId = UUID.randomUUID().toString();
|
String sessionId = UUID.randomUUID().toString();
|
||||||
AsyncContext asyncContext = request.startAsync();
|
AsyncContext asyncContext = request.startAsync();
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,6 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
|
||||||
response.setCharacterEncoding(UTF_8);
|
response.setCharacterEncoding(UTF_8);
|
||||||
response.setHeader("Cache-Control", "no-cache");
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
response.setHeader("Connection", "keep-alive");
|
response.setHeader("Connection", "keep-alive");
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
|
|
||||||
AsyncContext asyncContext = request.startAsync();
|
AsyncContext asyncContext = request.startAsync();
|
||||||
asyncContext.setTimeout(0);
|
asyncContext.setTimeout(0);
|
||||||
|
|
@ -522,7 +521,6 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
|
||||||
response.setCharacterEncoding(UTF_8);
|
response.setCharacterEncoding(UTF_8);
|
||||||
response.setHeader("Cache-Control", "no-cache");
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
response.setHeader("Connection", "keep-alive");
|
response.setHeader("Connection", "keep-alive");
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
|
|
||||||
AsyncContext asyncContext = request.startAsync();
|
AsyncContext asyncContext = request.startAsync();
|
||||||
asyncContext.setTimeout(0);
|
asyncContext.setTimeout(0);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-parent</artifactId>
|
<artifactId>mcp-parent</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>mcp-json-jackson2</artifactId>
|
<artifactId>mcp-json-jackson2</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-core</artifactId>
|
<artifactId>mcp-core</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.networknt</groupId>
|
<groupId>com.networknt</groupId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-parent</artifactId>
|
<artifactId>mcp-parent</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>mcp-json-jackson3</artifactId>
|
<artifactId>mcp-json-jackson3</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-core</artifactId>
|
<artifactId>mcp-core</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>tools.jackson.core</groupId>
|
<groupId>tools.jackson.core</groupId>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-parent</artifactId>
|
<artifactId>mcp-parent</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>mcp-test</artifactId>
|
<artifactId>mcp-test</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-core</artifactId>
|
<artifactId>mcp-core</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
@ -159,7 +159,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-json-jackson3</artifactId>
|
<artifactId>mcp-json-jackson3</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
@ -170,7 +170,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.modelcontextprotocol.sdk</groupId>
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
<artifactId>mcp-json-jackson2</artifactId>
|
<artifactId>mcp-json-jackson2</artifactId>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue