docs Improve MCP readme
This commit is contained in:
parent
abd0facf4e
commit
347f86ff19
6 changed files with 270 additions and 203 deletions
336
mcp/README.md
336
mcp/README.md
|
|
@ -1,10 +1,6 @@
|
||||||
# Model Context Protocol (MCP) Java SDK
|
# Spring AI MCP SDK
|
||||||
|
|
||||||
A Java implementation of the [Model Context Protocol](https://modelcontextprotocol.org/docs/concepts/architecture) specification, providing both synchronous and asynchronous clients for MCP server interactions.
|
This SDK implements the Model Context Protocol, enabling seamless integration with language models and AI tools.
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This SDK implements the Model Context Protocol, enabling seamless integration with AI models and tools through a standardized interface. It supports both synchronous and asynchronous communication patterns, making it suitable for various use cases and integration scenarios.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
@ -46,11 +42,6 @@ The SDK follows a layered architecture with clear separation of concerns:
|
||||||
- **Session Layer (McpSession)**: Manages communication patterns and state using DefaultMcpSession implementation.
|
- **Session Layer (McpSession)**: Manages communication patterns and state using DefaultMcpSession implementation.
|
||||||
- **Client/Server Layer**: Both use McpSession for sync/async operations, with McpClient handling client-side protocol operations and McpServer managing server-side protocol operations.
|
- **Client/Server Layer**: Both use McpSession for sync/async operations, with McpClient handling client-side protocol operations and McpServer managing server-side protocol operations.
|
||||||
|
|
||||||
Following class diagram illustrates the layered architecture of the MCP SDK, showing the relationships between core interfaces (McpTransport, McpSession), their implementations, and the client/server components. It highlights how the transport layer connects to sessions, which in turn support both synchronous and asynchronous client/server implementations.
|
|
||||||
|
|
||||||
<img src="../docs/spring-ai-mcp-uml-classdiagram.svg" width="600"/>
|
|
||||||
|
|
||||||
|
|
||||||
### Key Interactions
|
### Key Interactions
|
||||||
|
|
||||||
- **Client/Server Initialization**: Transport setup, protocol compatibility check, capability negotiation, and implementation details exchange.
|
- **Client/Server Initialization**: Transport setup, protocol compatibility check, capability negotiation, and implementation details exchange.
|
||||||
|
|
@ -59,149 +50,183 @@ Following class diagram illustrates the layered architecture of the MCP SDK, sho
|
||||||
- **Prompt System**: Discovery, parameter-based retrieval, change notifications, and content management.
|
- **Prompt System**: Discovery, parameter-based retrieval, change notifications, and content management.
|
||||||
- **Tool Execution**: Discovery, parameter validation, timeout-aware execution, and result processing.
|
- **Tool Execution**: Discovery, parameter validation, timeout-aware execution, and result processing.
|
||||||
|
|
||||||
|
## Client Usage Examples
|
||||||
|
|
||||||
### [Reference Documentation](../docs/ref-index.md)
|
### MCP Client (Sync API)
|
||||||
Detailed reference documentation covering the Spring AI implementation of the Model Context Protocol (MCP) specification.
|
|
||||||
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### McpClient
|
|
||||||
|
|
||||||
Factory for creating `sync` and `async` variants MCP clients. Uses McpSession for communication and handles client-side protocol operations.
|
|
||||||
|
|
||||||
#### Sync MCP Client
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Create and initialize sync client
|
// Create a sync client with custom configuration
|
||||||
McpTransport mcpTransport = ...
|
McpSyncClient client = McpClient.using(transport)
|
||||||
|
.requestTimeout(Duration.ofSeconds(10))
|
||||||
|
.capabilities(ClientCapabilities.builder()
|
||||||
|
.roots(true) // Enable roots capability
|
||||||
|
.sampling() // Enable sampling capability
|
||||||
|
.build())
|
||||||
|
.sync();
|
||||||
|
|
||||||
try (McpSyncClient client = McpClient.using(mcpTransport).sync()) {
|
// Initialize connection
|
||||||
// Initialize connection with protocol version and capabilities
|
client.initialize();
|
||||||
InitializeResult initResult = client.initialize();
|
|
||||||
|
|
||||||
// List available tools
|
// List available tools
|
||||||
ListToolsResult tools = client.listTools();
|
ListToolsResult tools = client.listTools();
|
||||||
|
|
||||||
// Execute a tool
|
// Call a tool
|
||||||
CallToolResult result = client.callTool(
|
CallToolResult result = client.callTool(
|
||||||
new CallToolRequest("echo", Map.of("message", "Hello!"))
|
new CallToolRequest("calculator",
|
||||||
);
|
Map.of("operation", "add", "a", 2, "b", 3))
|
||||||
|
);
|
||||||
|
|
||||||
// Resource management
|
// List and read resources
|
||||||
ListResourcesResult resources = client.listResources();
|
ListResourcesResult resources = client.listResources();
|
||||||
ReadResourceResult resource = client.readResource(
|
ReadResourceResult resource = client.readResource(
|
||||||
new ReadResourceRequest("resource-uri")
|
new ReadResourceRequest("resource://uri")
|
||||||
);
|
);
|
||||||
|
|
||||||
// List and retrieve prompts
|
// List and use prompts
|
||||||
ListPromptsResult prompts = client.listPrompts();
|
ListPromptsResult prompts = client.listPrompts();
|
||||||
GetPromptResult prompt = client.getPrompt(
|
GetPromptResult prompt = client.getPrompt(
|
||||||
new GetPromptRequest("prompt-id", Map.of())
|
new GetPromptRequest("greeting", Map.of("name", "Spring"))
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
// Add/remove roots
|
||||||
|
client.addRoot(new Root("file:///path", "description"));
|
||||||
|
client.removeRoot("file:///path");
|
||||||
|
client.rootsListChangedNotification();
|
||||||
|
|
||||||
|
// Close client
|
||||||
|
client.closeGracefully();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Async MCP Client
|
### MCP Client (Async API)
|
||||||
|
|
||||||
```java
|
```java
|
||||||
McpTransport mcpTransport = ...
|
// Create an async client with custom configuration
|
||||||
|
McpAsyncClient client = McpClient.using(transport)
|
||||||
// Initialize async client with custom timeout
|
.requestTimeout(Duration.ofSeconds(10))
|
||||||
McpAsyncClient client = McpClient.using(mcpTransport)
|
.capabilities(ClientCapabilities.builder()
|
||||||
.requestTimeout(Duration.ofSeconds(30))
|
.roots(true) // Enable roots capability
|
||||||
|
.sampling() // Enable sampling capability
|
||||||
|
.build())
|
||||||
|
.toolsChangeConsumer(tools -> {
|
||||||
|
logger.info("Tools updated: {}", tools);
|
||||||
|
})
|
||||||
|
.resourcesChangeConsumer(resources -> {
|
||||||
|
logger.info("Resources updated: {}", resources);
|
||||||
|
})
|
||||||
|
.promptsChangeConsumer(prompts -> {
|
||||||
|
logger.info("Prompts updated: {}", prompts);
|
||||||
|
})
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
// Initialize connection and chain operations
|
// Initialize connection
|
||||||
var result = client.initialize()
|
client.initialize()
|
||||||
// Connection initialized with protocol version compatibility
|
.flatMap(initResult -> {
|
||||||
.flatMap(initResult -> client.listTools())
|
// List available tools
|
||||||
// Process available tools
|
return client.listTools();
|
||||||
.flatMap(tools -> client.callTool(
|
})
|
||||||
new CallToolRequest("echo", Map.of("message", "Hello MCP!"))))
|
.flatMap(tools -> {
|
||||||
// Handle tool execution result
|
// Call a tool
|
||||||
.flatMap(toolResult -> client.listPrompts())
|
return client.callTool(new CallToolRequest(
|
||||||
// Process available prompts
|
"calculator",
|
||||||
.flatMap(prompts -> client.getPrompt(new GetPromptRequest("prompt-id", Map.of()));
|
Map.of("operation", "add", "a", 2, "b", 3)
|
||||||
|
));
|
||||||
// Subscribe to resource changes
|
})
|
||||||
var subscription = client.listResources()
|
.flatMap(result -> {
|
||||||
.flatMap(resources -> client.subscribeResource(new SubscribeRequest("resource-uri")));
|
// List and read resources
|
||||||
|
return client.listResources()
|
||||||
// Handle results reactively or block if needed
|
.flatMap(resources ->
|
||||||
GetPromptResult promptResult = result.block();
|
client.readResource(new ReadResourceRequest("resource://uri"))
|
||||||
subscription.block();
|
);
|
||||||
|
})
|
||||||
// Cleanup
|
.flatMap(resource -> {
|
||||||
client.closeGracefully().block();
|
// List and use prompts
|
||||||
|
return client.listPrompts()
|
||||||
|
.flatMap(prompts ->
|
||||||
|
client.getPrompt(new GetPromptRequest(
|
||||||
|
"greeting",
|
||||||
|
Map.of("name", "Spring")
|
||||||
|
))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.flatMap(prompt -> {
|
||||||
|
// Add/remove roots
|
||||||
|
return client.addRoot(new Root("file:///path", "description"))
|
||||||
|
.then(client.removeRoot("file:///path"))
|
||||||
|
.then(client.rootsListChangedNotification());
|
||||||
|
})
|
||||||
|
.doFinally(signalType -> {
|
||||||
|
// Close client
|
||||||
|
client.closeGracefully().subscribe();
|
||||||
|
})
|
||||||
|
.subscribe();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Client Transports
|
### Client Transport Options
|
||||||
Clients can use the following transport options:
|
|
||||||
|
|
||||||
##### StdioClientTransport
|
|
||||||
Standard I/O based transport for process-based communication with MCP servers:
|
|
||||||
|
|
||||||
|
#### StdioClientTransport
|
||||||
```java
|
```java
|
||||||
|
// Create transport for process-based communication
|
||||||
ServerParameters params = ServerParameters.builder("npx")
|
ServerParameters params = ServerParameters.builder("npx")
|
||||||
.args("-y", "@modelcontextprotocol/server-everything", "dir")
|
.args("-y", "@modelcontextprotocol/server-everything", "dir")
|
||||||
.build();
|
.build();
|
||||||
McpTransport transport = new StdioClientTransport(params);
|
McpTransport transport = new StdioClientTransport(params);
|
||||||
```
|
```
|
||||||
|
|
||||||
##### SseClientTransport
|
#### SseClientTransport
|
||||||
Server-Sent Events (SSE) based transport following the MCP HTTP with SSE transport specification:
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
// Create transport for HTTP streaming
|
||||||
WebClient.Builder webClientBuilder = WebClient.builder()
|
WebClient.Builder webClientBuilder = WebClient.builder()
|
||||||
.baseUrl("http://your-mcp-server");
|
.baseUrl("http://your-mcp-server");
|
||||||
McpTransport transport = new SseClientTransport(webClientBuilder);
|
McpTransport transport = new SseClientTransport(webClientBuilder);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### MCP Server
|
## Server Usage Examples
|
||||||
|
|
||||||
Factory for creating `sync` and `async` variants MCP servers. Uses McpSession for communication and handles server-side protocol operations.
|
### MCP Server (Sync API)
|
||||||
|
|
||||||
#### MCP Sync Server
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Create a sync server with custom configuration
|
// Create a server with custom configuration
|
||||||
McpSyncServer syncServer = McpServer.using(transport)
|
McpSyncServer syncServer = McpServer.using(transport)
|
||||||
.serverInfo("my-server", "1.0.0")
|
.info("my-server", "1.0.0")
|
||||||
.serverCapabilities(new ServerCapabilities(...))
|
.capabilities(ServerCapabilities.builder()...build())
|
||||||
.addTool(new CalculatorTool())
|
.tools(new CalculatorTool())
|
||||||
.resourcesProvider(cursor -> resources)
|
.resources(resourceRegistration)
|
||||||
.promptsProvider(cursor -> prompts)
|
.prompts(promptRegistration)
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
// Add a tool handler at runtime
|
// Add a tool handler at runtime
|
||||||
syncServer.addTool(new CalculatorTool());
|
syncServer.addTool(new CalculatorTool());
|
||||||
logger.info("Tool added");
|
|
||||||
|
|
||||||
// Remove a tool handler
|
// Remove a tool handler at runtime
|
||||||
syncServer.removeTool("calculator");
|
syncServer.removeTool("calculator");
|
||||||
logger.info("Tool removed");
|
|
||||||
|
|
||||||
// Notify clients of changes
|
// Add a resource at runtime
|
||||||
syncServer.notifyToolsListChanged();
|
syncServer.addResource(resourceRegistration);
|
||||||
syncServer.notifyResourcesListChanged();
|
|
||||||
syncServer.notifyPromptsListChanged();
|
// Remove a resource at runtime
|
||||||
|
syncServer.removeResource(resourceUri);
|
||||||
|
|
||||||
|
// Add a prompt at runtime
|
||||||
|
syncServer.addPrompt(promptRegistration);
|
||||||
|
|
||||||
|
// Remove a prompt at runtime
|
||||||
|
syncServer.removePrompt(promptName);
|
||||||
|
|
||||||
// Graceful shutdown
|
// Graceful shutdown
|
||||||
syncServer.closeGracefully();
|
syncServer.closeGracefully();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### MCP Async Server
|
### MCP Server (Async API)
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Create an async server with custom configuration
|
// Create an async server with custom configuration
|
||||||
McpAsyncServer asyncServer = McpServer.using(transport)
|
McpAsyncServer asyncServer = McpServer.using(transport)
|
||||||
.serverInfo("my-server", "1.0.0")
|
.info("my-server", "1.0.0")
|
||||||
.serverCapabilities(new ServerCapabilities(...))
|
.capabilities(ServerCapabilities.builder()...build())
|
||||||
.addTool(new CalculatorTool())
|
.tools(new CalculatorTool())
|
||||||
.resourcesProvider(cursor -> resources)
|
.resources(resourceRegistration)
|
||||||
.promptsProvider(cursor -> prompts)
|
.prompts(promptRegistration)
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
// Add a tool handler at runtime
|
// Add a tool handler at runtime
|
||||||
|
|
@ -209,11 +234,31 @@ asyncServer.addTool(new CalculatorTool())
|
||||||
.doOnSuccess(v -> logger.info("Tool added"))
|
.doOnSuccess(v -> logger.info("Tool added"))
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
||||||
// Remove a tool handler
|
// Remove a tool handler at runtime
|
||||||
asyncServer.removeTool("calculator")
|
asyncServer.removeTool("calculator")
|
||||||
.doOnSuccess(v -> logger.info("Tool removed"))
|
.doOnSuccess(v -> logger.info("Tool removed"))
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
||||||
|
// Add a resource at runtime
|
||||||
|
asyncServer.addResource(resourceRegistration)
|
||||||
|
.doOnSuccess(v -> logger.info("Resource added"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Remove a resource at runtime
|
||||||
|
asyncServer.removeResource(resourceUri)
|
||||||
|
.doOnSuccess(v -> logger.info("Resource removed"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Add a prompt at runtime
|
||||||
|
asyncServer.addPrompt(promptRegistration)
|
||||||
|
.doOnSuccess(v -> logger.info("Prompt added"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Remove a prompt at runtime
|
||||||
|
asyncServer.removePrompt(promptName)
|
||||||
|
.doOnSuccess(v -> logger.info("Prompt removed"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
// Notify clients of changes
|
// Notify clients of changes
|
||||||
asyncServer.notifyToolsListChanged().subscribe();
|
asyncServer.notifyToolsListChanged().subscribe();
|
||||||
asyncServer.notifyResourcesListChanged().subscribe();
|
asyncServer.notifyResourcesListChanged().subscribe();
|
||||||
|
|
@ -223,12 +268,9 @@ asyncServer.notifyPromptsListChanged().subscribe();
|
||||||
asyncServer.closeGracefully().subscribe();
|
asyncServer.closeGracefully().subscribe();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Server Transports
|
### Server Transport Options
|
||||||
|
|
||||||
Servers can use the following transport options:
|
#### StdioServerTransport
|
||||||
|
|
||||||
##### StdioServerTransport
|
|
||||||
Standard I/O based transport for process-based communication:
|
|
||||||
```java
|
```java
|
||||||
// Create transport with custom ObjectMapper
|
// Create transport with custom ObjectMapper
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
@ -237,8 +279,7 @@ StdioServerTransport transport = new StdioServerTransport(mapper);
|
||||||
|
|
||||||
Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support.
|
Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support.
|
||||||
|
|
||||||
##### SseServerTransport
|
#### SseServerTransport
|
||||||
Server-Sent Events based transport for HTTP streaming:
|
|
||||||
```java
|
```java
|
||||||
// Create SSE transport
|
// Create SSE transport
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
@ -251,26 +292,65 @@ RouterFunction<?> router = transport.getRouterFunction();
|
||||||
|
|
||||||
Implements the MCP HTTP with SSE transport specification, providing concurrent client connections through SSE endpoints with message routing, session management, and graceful shutdown capabilities.
|
Implements the MCP HTTP with SSE transport specification, providing concurrent client connections through SSE endpoints with message routing, session management, and graceful shutdown capabilities.
|
||||||
|
|
||||||
|
|
||||||
|
### Server Capabilities
|
||||||
|
|
||||||
|
The server can be configured with various capabilities:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var capabilities = ServerCapabilities.builder()
|
||||||
|
.resources(false, true) // Resource support with list changes notifications
|
||||||
|
.tools(true) // Tool support with list changes notifications
|
||||||
|
.prompts(true) // Prompt support with list changes notifications
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tool Registration
|
||||||
|
|
||||||
|
```java
|
||||||
|
var toolRegistration = new ToolRegistration(
|
||||||
|
new Tool("calculator", "Basic calculator", Map.of(
|
||||||
|
"operation", "string",
|
||||||
|
"a", "number",
|
||||||
|
"b", "number"
|
||||||
|
)),
|
||||||
|
arguments -> {
|
||||||
|
// Tool implementation
|
||||||
|
return new CallToolResult(result, false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Registration
|
||||||
|
|
||||||
|
```java
|
||||||
|
var resourceRegistration = new ResourceRegistration(
|
||||||
|
new Resource("custom://resource", "name", "description", "mime-type", null),
|
||||||
|
request -> {
|
||||||
|
// Resource read implementation
|
||||||
|
return new ReadResourceResult(contents);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt Registration
|
||||||
|
|
||||||
|
```java
|
||||||
|
var promptRegistration = new PromptRegistration(
|
||||||
|
new Prompt("greeting", "description", List.of(
|
||||||
|
new PromptArgument("name", "description", true)
|
||||||
|
)),
|
||||||
|
request -> {
|
||||||
|
// Prompt implementation
|
||||||
|
return new GetPromptResult(description, messages);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.
|
The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
See [CONTRIBUTING.md](../CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Copyright 2024 - 2024 the original author or authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
|
||||||
|
|
@ -155,19 +155,6 @@ public interface McpServer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the server implementation information using name and version.
|
|
||||||
* @param name The server name
|
|
||||||
* @param version The server version
|
|
||||||
* @return This builder instance
|
|
||||||
*/
|
|
||||||
public Builder serverInfo(String name, String version) {
|
|
||||||
Assert.notNull(name, "Server name must not be null");
|
|
||||||
Assert.notNull(version, "Server version must not be null");
|
|
||||||
this.serverInfo = new McpSchema.Implementation(name, version);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the server capabilities.
|
* Set the server capabilities.
|
||||||
* @param serverCapabilities The server capabilities configuration
|
* @param serverCapabilities The server capabilities configuration
|
||||||
|
|
|
||||||
|
|
@ -60,27 +60,6 @@ public class McpSyncServer {
|
||||||
this.asyncServer.removeTool(toolName).block();
|
this.asyncServer.removeTool(toolName).block();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify clients that the list of available tools has changed.
|
|
||||||
*/
|
|
||||||
public void notifyToolsListChanged() {
|
|
||||||
this.asyncServer.notifyToolsListChanged().block();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify clients that the list of available resources has changed.
|
|
||||||
*/
|
|
||||||
public void notifyResourcesListChanged() {
|
|
||||||
this.asyncServer.notifyResourcesListChanged().block();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify clients that the list of available prompts has changed.
|
|
||||||
*/
|
|
||||||
public void notifyPromptsListChanged() {
|
|
||||||
this.asyncServer.notifyPromptsListChanged().block();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new resource handler.
|
* Add a new resource handler.
|
||||||
* @param resourceHandler The resource handler to add
|
* @param resourceHandler The resource handler to add
|
||||||
|
|
@ -113,6 +92,27 @@ public class McpSyncServer {
|
||||||
this.asyncServer.removePrompt(promptName).block();
|
this.asyncServer.removePrompt(promptName).block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify clients that the list of available tools has changed.
|
||||||
|
*/
|
||||||
|
public void notifyToolsListChanged() {
|
||||||
|
this.asyncServer.notifyToolsListChanged().block();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify clients that the list of available resources has changed.
|
||||||
|
*/
|
||||||
|
public void notifyResourcesListChanged() {
|
||||||
|
this.asyncServer.notifyResourcesListChanged().block();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify clients that the list of available prompts has changed.
|
||||||
|
*/
|
||||||
|
public void notifyPromptsListChanged() {
|
||||||
|
this.asyncServer.notifyPromptsListChanged().block();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the server gracefully.
|
* Close the server gracefully.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ public class DemoServer {
|
||||||
SseServerTransport transport = new SseServerTransport(new ObjectMapper(), "/mcp/message");
|
SseServerTransport transport = new SseServerTransport(new ObjectMapper(), "/mcp/message");
|
||||||
|
|
||||||
var mcpServer = McpServer.using(transport)
|
var mcpServer = McpServer.using(transport)
|
||||||
.serverInfo("Weather Forecast", "1.0.0")
|
.info("Weather Forecast", "1.0.0")
|
||||||
.tool(new McpSchema.Tool("weather", "Weather forecast tool by location", Map.of("city", "String")),
|
.tool(new McpSchema.Tool("weather", "Weather forecast tool by location", Map.of("city", "String")),
|
||||||
(arguments) -> {
|
(arguments) -> {
|
||||||
String city = (String) arguments.get("city");
|
String city = (String) arguments.get("city");
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testAddTool() {
|
void testAddTool() {
|
||||||
Tool newTool = new McpSchema.Tool("new-tool", "New test tool", Map.of("input", "string"));
|
Tool newTool = new McpSchema.Tool("new-tool", "New test tool", Map.of("input", "string"));
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
Tool duplicateTool = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
Tool duplicateTool = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
||||||
|
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.tool(duplicateTool, args -> new CallToolResult(List.of(), false))
|
.tool(duplicateTool, args -> new CallToolResult(List.of(), false))
|
||||||
.async();
|
.async();
|
||||||
|
|
@ -126,7 +126,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
Tool too = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
Tool too = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
||||||
|
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.tool(too, args -> new CallToolResult(List.of(), false))
|
.tool(too, args -> new CallToolResult(List.of(), false))
|
||||||
.async();
|
.async();
|
||||||
|
|
@ -139,7 +139,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testRemoveNonexistentTool() {
|
void testRemoveNonexistentTool() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
Tool too = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
Tool too = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
||||||
|
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.tool(too, args -> new CallToolResult(List.of(), false))
|
.tool(too, args -> new CallToolResult(List.of(), false))
|
||||||
.async();
|
.async();
|
||||||
|
|
@ -167,7 +167,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNotifyResourcesListChanged() {
|
void testNotifyResourcesListChanged() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").async();
|
var mcpAsyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").async();
|
||||||
|
|
||||||
StepVerifier.create(mcpAsyncServer.notifyResourcesListChanged()).verifyComplete();
|
StepVerifier.create(mcpAsyncServer.notifyResourcesListChanged()).verifyComplete();
|
||||||
|
|
||||||
|
|
@ -176,7 +176,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNotifyPromptsListChanged() {
|
void testNotifyPromptsListChanged() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").async();
|
var mcpAsyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").async();
|
||||||
|
|
||||||
StepVerifier.create(mcpAsyncServer.notifyPromptsListChanged()).verifyComplete();
|
StepVerifier.create(mcpAsyncServer.notifyPromptsListChanged()).verifyComplete();
|
||||||
|
|
||||||
|
|
@ -185,14 +185,14 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGracefulShutdown() {
|
void testGracefulShutdown() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").async();
|
var mcpAsyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").async();
|
||||||
|
|
||||||
StepVerifier.create(mcpAsyncServer.closeGracefully()).verifyComplete();
|
StepVerifier.create(mcpAsyncServer.closeGracefully()).verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testImmediateClose() {
|
void testImmediateClose() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").async();
|
var mcpAsyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").async();
|
||||||
|
|
||||||
assertThatCode(() -> mcpAsyncServer.close()).doesNotThrowAnyException();
|
assertThatCode(() -> mcpAsyncServer.close()).doesNotThrowAnyException();
|
||||||
}
|
}
|
||||||
|
|
@ -200,7 +200,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testAddResource() {
|
void testAddResource() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
|
|
@ -218,7 +218,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testAddResourceWithNullRegistration() {
|
void testAddResourceWithNullRegistration() {
|
||||||
|
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
|
|
@ -232,7 +232,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testAddPromptWithNullRegistration() {
|
void testAddPromptWithNullRegistration() {
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().prompts(false).build())
|
.capabilities(ServerCapabilities.builder().prompts(false).build())
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
|
|
@ -245,7 +245,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testAddResourceWithoutCapability() {
|
void testAddResourceWithoutCapability() {
|
||||||
// Create a server without resource capabilities
|
// Create a server without resource capabilities
|
||||||
McpAsyncServer serverWithoutResources = McpServer.using(createMcpTransport())
|
McpAsyncServer serverWithoutResources = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
|
Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
|
||||||
|
|
@ -263,7 +263,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testAddPromptWithoutCapability() {
|
void testAddPromptWithoutCapability() {
|
||||||
// Create a server without prompt capabilities
|
// Create a server without prompt capabilities
|
||||||
McpAsyncServer serverWithoutPrompts = McpServer.using(createMcpTransport())
|
McpAsyncServer serverWithoutPrompts = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
||||||
|
|
@ -281,7 +281,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testRemoveResourceWithoutCapability() {
|
void testRemoveResourceWithoutCapability() {
|
||||||
// Create a server without resource capabilities
|
// Create a server without resource capabilities
|
||||||
McpAsyncServer serverWithoutResources = McpServer.using(createMcpTransport())
|
McpAsyncServer serverWithoutResources = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
StepVerifier.create(serverWithoutResources.removeResource(TEST_RESOURCE_URI)).verifyErrorSatisfies(error -> {
|
StepVerifier.create(serverWithoutResources.removeResource(TEST_RESOURCE_URI)).verifyErrorSatisfies(error -> {
|
||||||
|
|
@ -294,7 +294,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testRemovePromptWithoutCapability() {
|
void testRemovePromptWithoutCapability() {
|
||||||
// Create a server without prompt capabilities
|
// Create a server without prompt capabilities
|
||||||
McpAsyncServer serverWithoutPrompts = McpServer.using(createMcpTransport())
|
McpAsyncServer serverWithoutPrompts = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
StepVerifier.create(serverWithoutPrompts.removePrompt(TEST_PROMPT_NAME)).verifyErrorSatisfies(error -> {
|
StepVerifier.create(serverWithoutPrompts.removePrompt(TEST_PROMPT_NAME)).verifyErrorSatisfies(error -> {
|
||||||
|
|
@ -313,7 +313,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
List.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
List.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
||||||
|
|
||||||
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
var mcpAsyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
||||||
.prompts(registration)
|
.prompts(registration)
|
||||||
.async();
|
.async();
|
||||||
|
|
@ -326,7 +326,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testRemoveNonexistentPrompt() {
|
void testRemoveNonexistentPrompt() {
|
||||||
var mcpAsyncServer2 = McpServer.using(createMcpTransport())
|
var mcpAsyncServer2 = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
||||||
.async();
|
.async();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testAddTool() {
|
void testAddTool() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
Tool duplicateTool = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
Tool duplicateTool = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", Map.of("input", "string"));
|
||||||
|
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.tool(duplicateTool, args -> new CallToolResult(List.of(), false))
|
.tool(duplicateTool, args -> new CallToolResult(List.of(), false))
|
||||||
.sync();
|
.sync();
|
||||||
|
|
@ -121,7 +121,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
Tool tool = new McpSchema.Tool(TEST_TOOL_NAME, "Test tool", Map.of("input", "string"));
|
Tool tool = new McpSchema.Tool(TEST_TOOL_NAME, "Test tool", Map.of("input", "string"));
|
||||||
|
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.tool(tool, args -> new CallToolResult(List.of(), false))
|
.tool(tool, args -> new CallToolResult(List.of(), false))
|
||||||
.sync();
|
.sync();
|
||||||
|
|
@ -134,7 +134,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testRemoveNonexistentTool() {
|
void testRemoveNonexistentTool() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().tools(true).build())
|
.capabilities(ServerCapabilities.builder().tools(true).build())
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNotifyToolsListChanged() {
|
void testNotifyToolsListChanged() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var mcpSyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatCode(() -> mcpSyncServer.notifyToolsListChanged()).doesNotThrowAnyException();
|
assertThatCode(() -> mcpSyncServer.notifyToolsListChanged()).doesNotThrowAnyException();
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNotifyResourcesListChanged() {
|
void testNotifyResourcesListChanged() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var mcpSyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatCode(() -> mcpSyncServer.notifyResourcesListChanged()).doesNotThrowAnyException();
|
assertThatCode(() -> mcpSyncServer.notifyResourcesListChanged()).doesNotThrowAnyException();
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNotifyPromptsListChanged() {
|
void testNotifyPromptsListChanged() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var mcpSyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatCode(() -> mcpSyncServer.notifyPromptsListChanged()).doesNotThrowAnyException();
|
assertThatCode(() -> mcpSyncServer.notifyPromptsListChanged()).doesNotThrowAnyException();
|
||||||
|
|
||||||
|
|
@ -173,14 +173,14 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGracefulShutdown() {
|
void testGracefulShutdown() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var mcpSyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
|
assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testImmediateClose() {
|
void testImmediateClose() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var mcpSyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatCode(() -> mcpSyncServer.close()).doesNotThrowAnyException();
|
assertThatCode(() -> mcpSyncServer.close()).doesNotThrowAnyException();
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +188,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testAddResource() {
|
void testAddResource() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
|
|
@ -205,7 +205,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testAddResourceWithNullRegistration() {
|
void testAddResourceWithNullRegistration() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
.capabilities(ServerCapabilities.builder().resources(true, false).build())
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
|
|
@ -218,7 +218,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testAddPromptWithNullRegistration() {
|
void testAddPromptWithNullRegistration() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().prompts(false).build())
|
.capabilities(ServerCapabilities.builder().prompts(false).build())
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
|
|
@ -228,7 +228,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAddResourceWithoutCapability() {
|
void testAddResourceWithoutCapability() {
|
||||||
var serverWithoutResources = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var serverWithoutResources = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
|
Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
|
||||||
null);
|
null);
|
||||||
|
|
@ -241,7 +241,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAddPromptWithoutCapability() {
|
void testAddPromptWithoutCapability() {
|
||||||
var serverWithoutPrompts = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var serverWithoutPrompts = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
||||||
PromptRegistration registration = new PromptRegistration(prompt, req -> new GetPromptResult(
|
PromptRegistration registration = new PromptRegistration(prompt, req -> new GetPromptResult(
|
||||||
|
|
@ -254,7 +254,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRemoveResourceWithoutCapability() {
|
void testRemoveResourceWithoutCapability() {
|
||||||
var serverWithoutResources = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var serverWithoutResources = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatThrownBy(() -> serverWithoutResources.removeResource(TEST_RESOURCE_URI)).isInstanceOf(McpError.class)
|
assertThatThrownBy(() -> serverWithoutResources.removeResource(TEST_RESOURCE_URI)).isInstanceOf(McpError.class)
|
||||||
.hasMessage("Server must be configured with resource capabilities");
|
.hasMessage("Server must be configured with resource capabilities");
|
||||||
|
|
@ -262,7 +262,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRemovePromptWithoutCapability() {
|
void testRemovePromptWithoutCapability() {
|
||||||
var serverWithoutPrompts = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var serverWithoutPrompts = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThatThrownBy(() -> serverWithoutPrompts.removePrompt(TEST_PROMPT_NAME)).isInstanceOf(McpError.class)
|
assertThatThrownBy(() -> serverWithoutPrompts.removePrompt(TEST_PROMPT_NAME)).isInstanceOf(McpError.class)
|
||||||
.hasMessage("Server must be configured with prompt capabilities");
|
.hasMessage("Server must be configured with prompt capabilities");
|
||||||
|
|
@ -277,7 +277,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
List.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
List.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
||||||
|
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
||||||
.prompts(registration)
|
.prompts(registration)
|
||||||
.sync();
|
.sync();
|
||||||
|
|
@ -292,7 +292,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
@Test
|
@Test
|
||||||
void testRemoveNonexistentPrompt() {
|
void testRemoveNonexistentPrompt() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport())
|
var mcpSyncServer = McpServer.using(createMcpTransport())
|
||||||
.serverInfo("test-server", "1.0.0")
|
.info("test-server", "1.0.0")
|
||||||
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
.capabilities(ServerCapabilities.builder().prompts(true).build())
|
||||||
.sync();
|
.sync();
|
||||||
|
|
||||||
|
|
@ -304,7 +304,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetAsyncServer() {
|
void testGetAsyncServer() {
|
||||||
var mcpSyncServer = McpServer.using(createMcpTransport()).serverInfo("test-server", "1.0.0").sync();
|
var mcpSyncServer = McpServer.using(createMcpTransport()).info("test-server", "1.0.0").sync();
|
||||||
|
|
||||||
assertThat(mcpSyncServer.getAsyncServer()).isNotNull();
|
assertThat(mcpSyncServer.getAsyncServer()).isNotNull();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue