Add embedded MkDocs documentation site (#795)
Copy and convert existing MCP documentation into an embedded docs site using MkDocs with Material theme. Includes client and server guides, quickstart, development/contributing docs, architecture diagrams, and a GitHub Actions workflow for publishing to GitHub Pages. --------- Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
27
.github/workflows/docs.yml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
name: Deploy Documentation
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'mkdocs.yml'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
|
||||||
|
- run: pip install mkdocs-material
|
||||||
|
|
||||||
|
- run: mkdocs gh-deploy --force
|
||||||
3
.gitignore
vendored
|
|
@ -57,6 +57,9 @@ node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
package.json
|
package.json
|
||||||
|
|
||||||
|
### MkDocs ###
|
||||||
|
site/
|
||||||
|
|
||||||
### Other ###
|
### Other ###
|
||||||
.antlr/
|
.antlr/
|
||||||
.profiler/
|
.profiler/
|
||||||
|
|
|
||||||
106
docs/CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
---
|
||||||
|
title: Contributing
|
||||||
|
description: How to contribute to the MCP Java SDK
|
||||||
|
---
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to the Model Context Protocol Java SDK!
|
||||||
|
This guide outlines how to contribute to this project.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
!!! info "Required Software"
|
||||||
|
- **Java 17** or above
|
||||||
|
- **Docker**
|
||||||
|
- **npx**
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Clone your fork:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/YOUR-USERNAME/java-sdk.git
|
||||||
|
cd java-sdk
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Build from source:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./mvnw clean install -DskipTests # skip the tests
|
||||||
|
./mvnw test # run tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reporting Issues
|
||||||
|
|
||||||
|
Please create an issue in the repository if you discover a bug or would like to
|
||||||
|
propose an enhancement. Bug reports should have a reproducer in the form of a code
|
||||||
|
sample or a repository attached that the maintainers or contributors can work with to
|
||||||
|
address the problem.
|
||||||
|
|
||||||
|
## Making Changes
|
||||||
|
|
||||||
|
1. Create a new branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Make your changes.
|
||||||
|
|
||||||
|
3. Validate your changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./mvnw clean test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Change Proposal Guidelines
|
||||||
|
|
||||||
|
#### Principles of MCP
|
||||||
|
|
||||||
|
1. **Simple + Minimal**: It is much easier to add things to the codebase than it is to
|
||||||
|
remove them. To maintain simplicity, we keep a high bar for adding new concepts and
|
||||||
|
primitives as each addition requires maintenance and compatibility consideration.
|
||||||
|
2. **Concrete**: Code changes need to be based on specific usage and implementation
|
||||||
|
challenges and not on speculative ideas. Most importantly, the SDK is meant to
|
||||||
|
implement the MCP specification.
|
||||||
|
|
||||||
|
## Submitting Changes
|
||||||
|
|
||||||
|
1. For non-trivial changes, please clarify with the maintainers in an issue whether
|
||||||
|
you can contribute the change and the desired scope of the change.
|
||||||
|
2. For trivial changes (for example a couple of lines or documentation changes) there
|
||||||
|
is no need to open an issue first.
|
||||||
|
3. Push your changes to your fork.
|
||||||
|
4. Submit a pull request to the main repository.
|
||||||
|
5. Follow the pull request template.
|
||||||
|
6. Wait for review.
|
||||||
|
7. For any follow-up work, please add new commits instead of force-pushing. This will
|
||||||
|
allow the reviewer to focus on incremental changes instead of having to restart the
|
||||||
|
review process.
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
|
||||||
|
This project follows a Code of Conduct. Please review it in
|
||||||
|
[CODE_OF_CONDUCT.md](https://github.com/modelcontextprotocol/java-sdk/blob/main/CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
If you have questions, please create a discussion in the repository.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing, you agree that your contributions will be licensed under the MIT
|
||||||
|
License.
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
This SDK is maintained by [Anthropic](https://www.anthropic.com/) as part of the Model Context Protocol project.
|
||||||
|
|
||||||
|
The security of our systems and user data is Anthropic's top priority. We appreciate the work of security researchers acting in good faith in identifying and reporting potential vulnerabilities.
|
||||||
|
|
||||||
|
!!! warning "Reporting Security Vulnerabilities"
|
||||||
|
Do **not** report security vulnerabilities through public GitHub issues. Instead, report them through our HackerOne [submission form](https://hackerone.com/anthropic-vdp/reports/new?type=team&report_type=vulnerability).
|
||||||
|
|
||||||
|
Our Vulnerability Disclosure Program guidelines are defined on our [HackerOne program page](https://hackerone.com/anthropic-vdp).
|
||||||
424
docs/client.md
Normal file
|
|
@ -0,0 +1,424 @@
|
||||||
|
---
|
||||||
|
title: MCP Client
|
||||||
|
description: Learn how to use the Model Context Protocol (MCP) client to interact with MCP servers
|
||||||
|
---
|
||||||
|
|
||||||
|
# MCP Client
|
||||||
|
|
||||||
|
The MCP Client is a key component in the Model Context Protocol (MCP) architecture, responsible for establishing and managing connections with MCP servers. It implements the client-side of the protocol, handling:
|
||||||
|
|
||||||
|
- Protocol version negotiation to ensure compatibility with servers
|
||||||
|
- Capability negotiation to determine available features
|
||||||
|
- Message transport and JSON-RPC communication
|
||||||
|
- Tool discovery and execution with optional schema validation
|
||||||
|
- Resource access and management
|
||||||
|
- Prompt system interactions
|
||||||
|
- Optional features like roots management, sampling, and elicitation support
|
||||||
|
- Progress tracking for long-running operations
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
The core `io.modelcontextprotocol.sdk:mcp` module provides STDIO, SSE, and Streamable HTTP client transport implementations without requiring external web frameworks.
|
||||||
|
|
||||||
|
Spring-specific transport implementations are available as an **optional** dependency `io.modelcontextprotocol.sdk:mcp-spring-webflux` for [Spring Framework](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html) users.
|
||||||
|
|
||||||
|
The client provides both synchronous and asynchronous APIs for flexibility in different application contexts.
|
||||||
|
|
||||||
|
=== "Sync API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Create a sync client with custom configuration
|
||||||
|
McpSyncClient client = McpClient.sync(transport)
|
||||||
|
.requestTimeout(Duration.ofSeconds(10))
|
||||||
|
.capabilities(ClientCapabilities.builder()
|
||||||
|
.roots(true) // Enable roots capability
|
||||||
|
.sampling() // Enable sampling capability
|
||||||
|
.elicitation() // Enable elicitation capability
|
||||||
|
.build())
|
||||||
|
.sampling(request -> new CreateMessageResult(response))
|
||||||
|
.elicitation(request -> new ElicitResult(ElicitResult.Action.ACCEPT, content))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Initialize connection
|
||||||
|
client.initialize();
|
||||||
|
|
||||||
|
// List available tools
|
||||||
|
ListToolsResult tools = client.listTools();
|
||||||
|
|
||||||
|
// Call a tool
|
||||||
|
CallToolResult result = client.callTool(
|
||||||
|
new CallToolRequest("calculator",
|
||||||
|
Map.of("operation", "add", "a", 2, "b", 3))
|
||||||
|
);
|
||||||
|
|
||||||
|
// List and read resources
|
||||||
|
ListResourcesResult resources = client.listResources();
|
||||||
|
ReadResourceResult resource = client.readResource(
|
||||||
|
new ReadResourceRequest("resource://uri")
|
||||||
|
);
|
||||||
|
|
||||||
|
// List and use prompts
|
||||||
|
ListPromptsResult prompts = client.listPrompts();
|
||||||
|
GetPromptResult prompt = client.getPrompt(
|
||||||
|
new GetPromptRequest("greeting", Map.of("name", "Spring"))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add/remove roots
|
||||||
|
client.addRoot(new Root("file:///path", "description"));
|
||||||
|
client.removeRoot("file:///path");
|
||||||
|
|
||||||
|
// Close client
|
||||||
|
client.closeGracefully();
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Create an async client with custom configuration
|
||||||
|
McpAsyncClient client = McpClient.async(transport)
|
||||||
|
.requestTimeout(Duration.ofSeconds(10))
|
||||||
|
.capabilities(ClientCapabilities.builder()
|
||||||
|
.roots(true) // Enable roots capability
|
||||||
|
.sampling() // Enable sampling capability
|
||||||
|
.elicitation() // Enable elicitation capability
|
||||||
|
.build())
|
||||||
|
.sampling(request -> Mono.just(new CreateMessageResult(response)))
|
||||||
|
.elicitation(request -> Mono.just(new ElicitResult(ElicitResult.Action.ACCEPT, content)))
|
||||||
|
.toolsChangeConsumer(tools -> Mono.fromRunnable(() -> {
|
||||||
|
logger.info("Tools updated: {}", tools);
|
||||||
|
}))
|
||||||
|
.resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> {
|
||||||
|
logger.info("Resources updated: {}", resources);
|
||||||
|
}))
|
||||||
|
.promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> {
|
||||||
|
logger.info("Prompts updated: {}", prompts);
|
||||||
|
}))
|
||||||
|
.progressConsumer(progress -> Mono.fromRunnable(() -> {
|
||||||
|
logger.info("Progress: {}", progress);
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Initialize connection and use features
|
||||||
|
client.initialize()
|
||||||
|
.flatMap(initResult -> client.listTools())
|
||||||
|
.flatMap(tools -> {
|
||||||
|
return client.callTool(new CallToolRequest(
|
||||||
|
"calculator",
|
||||||
|
Map.of("operation", "add", "a", 2, "b", 3)
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.flatMap(result -> {
|
||||||
|
return client.listResources()
|
||||||
|
.flatMap(resources ->
|
||||||
|
client.readResource(new ReadResourceRequest("resource://uri"))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.flatMap(resource -> {
|
||||||
|
return client.listPrompts()
|
||||||
|
.flatMap(prompts ->
|
||||||
|
client.getPrompt(new GetPromptRequest(
|
||||||
|
"greeting",
|
||||||
|
Map.of("name", "Spring")
|
||||||
|
))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.flatMap(prompt -> {
|
||||||
|
return client.addRoot(new Root("file:///path", "description"))
|
||||||
|
.then(client.removeRoot("file:///path"));
|
||||||
|
})
|
||||||
|
.doFinally(signalType -> {
|
||||||
|
client.closeGracefully().subscribe();
|
||||||
|
})
|
||||||
|
.subscribe();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Client Transport
|
||||||
|
|
||||||
|
The transport layer handles the communication between MCP clients and servers, providing different implementations for various use cases. The client transport manages message serialization, connection establishment, and protocol-specific communication patterns.
|
||||||
|
|
||||||
|
=== "STDIO"
|
||||||
|
|
||||||
|
Creates transport for process-based communication using stdin/stdout:
|
||||||
|
|
||||||
|
```java
|
||||||
|
ServerParameters params = ServerParameters.builder("npx")
|
||||||
|
.args("-y", "@modelcontextprotocol/server-everything", "dir")
|
||||||
|
.build();
|
||||||
|
McpTransport transport = new StdioClientTransport(params);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "SSE (HttpClient)"
|
||||||
|
|
||||||
|
Creates a framework-agnostic (pure Java API) SSE client transport. Included in the core `mcp` module:
|
||||||
|
|
||||||
|
```java
|
||||||
|
McpTransport transport = new HttpClientSseClientTransport("http://your-mcp-server");
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Streamable HTTP"
|
||||||
|
|
||||||
|
Creates a Streamable HTTP client transport for efficient bidirectional communication. Included in the core `mcp` module:
|
||||||
|
|
||||||
|
```java
|
||||||
|
McpTransport transport = HttpClientStreamableHttpTransport
|
||||||
|
.builder("http://your-mcp-server")
|
||||||
|
.endpoint("/mcp")
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
The Streamable HTTP transport supports:
|
||||||
|
|
||||||
|
- Resumable streams for connection recovery
|
||||||
|
- Configurable connect timeout
|
||||||
|
- Custom HTTP request customization
|
||||||
|
- Multiple protocol version negotiation
|
||||||
|
|
||||||
|
=== "SSE (WebFlux)"
|
||||||
|
|
||||||
|
Creates WebFlux-based SSE client transport. Requires the `mcp-spring-webflux` dependency:
|
||||||
|
|
||||||
|
```java
|
||||||
|
WebClient.Builder webClientBuilder = WebClient.builder()
|
||||||
|
.baseUrl("http://your-mcp-server");
|
||||||
|
McpTransport transport = new WebFluxSseClientTransport(webClientBuilder);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Client Capabilities
|
||||||
|
|
||||||
|
The client can be configured with various capabilities:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var capabilities = ClientCapabilities.builder()
|
||||||
|
.roots(true) // Enable filesystem roots support with list changes notifications
|
||||||
|
.sampling() // Enable LLM sampling support
|
||||||
|
.elicitation() // Enable elicitation support (form and URL modes)
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also configure elicitation with specific mode support:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var capabilities = ClientCapabilities.builder()
|
||||||
|
.elicitation(true, false) // Enable form-based elicitation, disable URL-based
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Roots Support
|
||||||
|
|
||||||
|
Roots define the boundaries of where servers can operate within the filesystem:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Add a root dynamically
|
||||||
|
client.addRoot(new Root("file:///path", "description"));
|
||||||
|
|
||||||
|
// Remove a root
|
||||||
|
client.removeRoot("file:///path");
|
||||||
|
|
||||||
|
// Notify server of roots changes
|
||||||
|
client.rootsListChangedNotification();
|
||||||
|
```
|
||||||
|
|
||||||
|
The roots capability allows servers to:
|
||||||
|
|
||||||
|
- Request the list of accessible filesystem roots
|
||||||
|
- Receive notifications when the roots list changes
|
||||||
|
- Understand which directories and files they have access to
|
||||||
|
|
||||||
|
### Sampling Support
|
||||||
|
|
||||||
|
Sampling enables servers to request LLM interactions ("completions" or "generations") through the client:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Configure sampling handler
|
||||||
|
Function<CreateMessageRequest, CreateMessageResult> samplingHandler = request -> {
|
||||||
|
// Sampling implementation that interfaces with LLM
|
||||||
|
return new CreateMessageResult(response);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create client with sampling support
|
||||||
|
var client = McpClient.sync(transport)
|
||||||
|
.capabilities(ClientCapabilities.builder()
|
||||||
|
.sampling()
|
||||||
|
.build())
|
||||||
|
.sampling(samplingHandler)
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
This capability allows:
|
||||||
|
|
||||||
|
- Servers to leverage AI capabilities without requiring API keys
|
||||||
|
- Clients to maintain control over model access and permissions
|
||||||
|
- Support for both text and image-based interactions
|
||||||
|
- Optional inclusion of MCP server context in prompts
|
||||||
|
|
||||||
|
### Elicitation Support
|
||||||
|
|
||||||
|
Elicitation enables servers to request additional information or user input through the client. This is useful when a server needs clarification or confirmation during an operation:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Configure elicitation handler
|
||||||
|
Function<ElicitRequest, ElicitResult> elicitationHandler = request -> {
|
||||||
|
// Present the request to the user and collect their response
|
||||||
|
// The request contains a message and a schema describing the expected input
|
||||||
|
Map<String, Object> userResponse = collectUserInput(request.message(), request.requestedSchema());
|
||||||
|
return new ElicitResult(ElicitResult.Action.ACCEPT, userResponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create client with elicitation support
|
||||||
|
var client = McpClient.sync(transport)
|
||||||
|
.capabilities(ClientCapabilities.builder()
|
||||||
|
.elicitation()
|
||||||
|
.build())
|
||||||
|
.elicitation(elicitationHandler)
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
The `ElicitResult` supports three actions:
|
||||||
|
|
||||||
|
- `ACCEPT` - The user accepted and provided the requested information
|
||||||
|
- `DECLINE` - The user declined to provide the information
|
||||||
|
- `CANCEL` - The operation was cancelled
|
||||||
|
|
||||||
|
### Logging Support
|
||||||
|
|
||||||
|
The client can register a logging consumer to receive log messages from the server and set the minimum logging level to filter messages:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var mcpClient = McpClient.sync(transport)
|
||||||
|
.loggingConsumer(notification -> {
|
||||||
|
System.out.println("Received log message: " + notification.data());
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mcpClient.initialize();
|
||||||
|
|
||||||
|
mcpClient.setLoggingLevel(McpSchema.LoggingLevel.INFO);
|
||||||
|
|
||||||
|
// Call the tool that sends logging notifications
|
||||||
|
CallToolResult result = mcpClient.callTool(new CallToolRequest("logging-test", Map.of()));
|
||||||
|
```
|
||||||
|
|
||||||
|
Clients can control the minimum logging level they receive through the `mcpClient.setLoggingLevel(level)` request. Messages below the set level will be filtered out.
|
||||||
|
Supported logging levels (in order of increasing severity): DEBUG (0), INFO (1), NOTICE (2), WARNING (3), ERROR (4), CRITICAL (5), ALERT (6), EMERGENCY (7)
|
||||||
|
|
||||||
|
### Progress Notifications
|
||||||
|
|
||||||
|
The client can register a progress consumer to track the progress of long-running operations:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var mcpClient = McpClient.sync(transport)
|
||||||
|
.progressConsumer(progress -> {
|
||||||
|
System.out.println("Progress: " + progress.progress() + "/" + progress.total());
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using MCP Clients
|
||||||
|
|
||||||
|
### Tool Execution
|
||||||
|
|
||||||
|
Tools are server-side functions that clients can discover and execute. The MCP client provides methods to list available tools and execute them with specific parameters. Each tool has a unique name and accepts a map of parameters.
|
||||||
|
|
||||||
|
=== "Sync API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List available tools
|
||||||
|
ListToolsResult tools = client.listTools();
|
||||||
|
|
||||||
|
// Call a tool with a CallToolRequest
|
||||||
|
CallToolResult result = client.callTool(
|
||||||
|
new CallToolRequest("calculator", Map.of(
|
||||||
|
"operation", "add",
|
||||||
|
"a", 1,
|
||||||
|
"b", 2
|
||||||
|
))
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List available tools asynchronously
|
||||||
|
client.listTools()
|
||||||
|
.doOnNext(tools -> tools.tools().forEach(tool ->
|
||||||
|
System.out.println(tool.name())))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Call a tool asynchronously
|
||||||
|
client.callTool(new CallToolRequest("calculator", Map.of(
|
||||||
|
"operation", "add",
|
||||||
|
"a", 1,
|
||||||
|
"b", 2
|
||||||
|
)))
|
||||||
|
.subscribe();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tool Schema Validation and Caching
|
||||||
|
|
||||||
|
The client supports optional JSON schema validation for tool call results and automatic schema caching:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var client = McpClient.sync(transport)
|
||||||
|
.jsonSchemaValidator(myValidator) // Enable schema validation
|
||||||
|
.enableCallToolSchemaCaching(true) // Cache tool schemas
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Access
|
||||||
|
|
||||||
|
Resources represent server-side data sources that clients can access using URI templates. The MCP client provides methods to discover available resources and retrieve their contents through a standardized interface.
|
||||||
|
|
||||||
|
=== "Sync API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List available resources
|
||||||
|
ListResourcesResult resources = client.listResources();
|
||||||
|
|
||||||
|
// Read a resource
|
||||||
|
ReadResourceResult resource = client.readResource(
|
||||||
|
new ReadResourceRequest("resource://uri")
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List available resources asynchronously
|
||||||
|
client.listResources()
|
||||||
|
.doOnNext(resources -> resources.resources().forEach(resource ->
|
||||||
|
System.out.println(resource.name())))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Read a resource asynchronously
|
||||||
|
client.readResource(new ReadResourceRequest("resource://uri"))
|
||||||
|
.subscribe();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt System
|
||||||
|
|
||||||
|
The prompt system enables interaction with server-side prompt templates. These templates can be discovered and executed with custom parameters, allowing for dynamic text generation based on predefined patterns.
|
||||||
|
|
||||||
|
=== "Sync API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List available prompt templates
|
||||||
|
ListPromptsResult prompts = client.listPrompts();
|
||||||
|
|
||||||
|
// Get a prompt with parameters
|
||||||
|
GetPromptResult prompt = client.getPrompt(
|
||||||
|
new GetPromptRequest("greeting", Map.of("name", "World"))
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List available prompt templates asynchronously
|
||||||
|
client.listPrompts()
|
||||||
|
.doOnNext(prompts -> prompts.prompts().forEach(prompt ->
|
||||||
|
System.out.println(prompt.name())))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Get a prompt asynchronously
|
||||||
|
client.getPrompt(new GetPromptRequest("greeting", Map.of("name", "World")))
|
||||||
|
.subscribe();
|
||||||
|
```
|
||||||
75
docs/development.md
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
---
|
||||||
|
title: Documentation
|
||||||
|
description: How to contribute to the MCP Java SDK documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
# Documentation Development
|
||||||
|
|
||||||
|
This guide covers how to set up and preview the MCP Java SDK documentation locally.
|
||||||
|
|
||||||
|
!!! info "Prerequisites"
|
||||||
|
- Python 3.x
|
||||||
|
- pip (Python package manager)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Install mkdocs-material:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install mkdocs-material
|
||||||
|
```
|
||||||
|
|
||||||
|
## Preview Locally
|
||||||
|
|
||||||
|
From the project root directory, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdocs serve
|
||||||
|
```
|
||||||
|
|
||||||
|
A local preview of the documentation will be available at `http://localhost:8000`.
|
||||||
|
|
||||||
|
### Custom Ports
|
||||||
|
|
||||||
|
By default, mkdocs uses port 8000. You can customize the port with the `-a` flag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdocs serve -a localhost:3333
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
To build the static site for deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdocs build
|
||||||
|
```
|
||||||
|
|
||||||
|
The built site will be output to the `site/` directory.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
docs/
|
||||||
|
├── index.md # Overview page
|
||||||
|
├── quickstart.md # Quickstart guide
|
||||||
|
├── client.md # MCP Client documentation
|
||||||
|
├── server.md # MCP Server documentation
|
||||||
|
├── contributing.md # Contributing guide
|
||||||
|
├── development.md # This page
|
||||||
|
├── images/ # Images and diagrams
|
||||||
|
└── stylesheets/ # Custom CSS
|
||||||
|
mkdocs.yml # MkDocs configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Writing Guidelines
|
||||||
|
|
||||||
|
- Documentation pages use standard Markdown with [mkdocs-material extensions](https://squidfunk.github.io/mkdocs-material/reference/)
|
||||||
|
- Use content tabs (`=== "Tab Label"`) for Maven/Gradle or Sync/Async code examples
|
||||||
|
- Use admonitions (`!!! tip`, `!!! info`, `!!! warning`) for callouts
|
||||||
|
- All code blocks should specify a language for syntax highlighting
|
||||||
|
- Images go in the `docs/images/` directory
|
||||||
|
|
||||||
|
## IDE Support
|
||||||
|
|
||||||
|
We suggest using extensions on your IDE to recognize and format Markdown. If you're a VSCode user, consider the [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) extension for enhanced Markdown support, and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) for code formatting.
|
||||||
69
docs/images/favicon.svg
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="180"
|
||||||
|
height="180"
|
||||||
|
viewBox="0 0 180 180"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3"
|
||||||
|
sodipodi:docname="Model_Context_Protocol_logo copy 2.svg"
|
||||||
|
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview3"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="1.3111111"
|
||||||
|
inkscape:cx="89.618644"
|
||||||
|
inkscape:cy="89.618644"
|
||||||
|
inkscape:window-width="1728"
|
||||||
|
inkscape:window-height="944"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="38"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg3" />
|
||||||
|
<g
|
||||||
|
clip-path="url(#clip0_19_13)"
|
||||||
|
id="g3">
|
||||||
|
<path
|
||||||
|
d="M18 84.8528L85.8822 16.9706C95.2548 7.59798 110.451 7.59798 119.823 16.9706V16.9706C129.196 26.3431 129.196 41.5391 119.823 50.9117L68.5581 102.177"
|
||||||
|
stroke="black"
|
||||||
|
stroke-width="12"
|
||||||
|
stroke-linecap="round"
|
||||||
|
id="path1"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="M69.2652 101.47L119.823 50.9117C129.196 41.5391 144.392 41.5391 153.765 50.9117L154.118 51.2652C163.491 60.6378 163.491 75.8338 154.118 85.2063L92.7248 146.6C89.6006 149.724 89.6006 154.789 92.7248 157.913L105.331 170.52"
|
||||||
|
stroke="black"
|
||||||
|
stroke-width="12"
|
||||||
|
stroke-linecap="round"
|
||||||
|
id="path2"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="M102.853 33.9411L52.6482 84.1457C43.2756 93.5183 43.2756 108.714 52.6482 118.087V118.087C62.0208 127.459 77.2167 127.459 86.5893 118.087L136.794 67.8822"
|
||||||
|
stroke="black"
|
||||||
|
stroke-width="12"
|
||||||
|
stroke-linecap="round"
|
||||||
|
id="path3"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs3">
|
||||||
|
<clipPath
|
||||||
|
id="clip0_19_13">
|
||||||
|
<rect
|
||||||
|
width="180"
|
||||||
|
height="180"
|
||||||
|
fill="white"
|
||||||
|
id="rect3" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
BIN
docs/images/java-mcp-client-architecture.jpg
Normal file
|
After Width: | Height: | Size: 661 KiB |
BIN
docs/images/java-mcp-server-architecture.jpg
Normal file
|
After Width: | Height: | Size: 840 KiB |
1
docs/images/java-mcp-uml-classdiagram.svg
Normal file
|
After Width: | Height: | Size: 67 KiB |
12
docs/images/logo-dark.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_19_13)">
|
||||||
|
<path d="M18 84.8528L85.8822 16.9706C95.2548 7.59798 110.451 7.59798 119.823 16.9706V16.9706C129.196 26.3431 129.196 41.5391 119.823 50.9117L68.5581 102.177" stroke="black" stroke-width="12" stroke-linecap="round"/>
|
||||||
|
<path d="M69.2652 101.47L119.823 50.9117C129.196 41.5391 144.392 41.5391 153.765 50.9117L154.118 51.2652C163.491 60.6378 163.491 75.8338 154.118 85.2063L92.7248 146.6C89.6006 149.724 89.6006 154.789 92.7248 157.913L105.331 170.52" stroke="black" stroke-width="12" stroke-linecap="round"/>
|
||||||
|
<path d="M102.853 33.9411L52.6482 84.1457C43.2756 93.5183 43.2756 108.714 52.6482 118.087V118.087C62.0208 127.459 77.2167 127.459 86.5893 118.087L136.794 67.8822" stroke="black" stroke-width="12" stroke-linecap="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_19_13">
|
||||||
|
<rect width="180" height="180" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 973 B |
69
docs/images/logo-light.svg
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="180"
|
||||||
|
height="180"
|
||||||
|
viewBox="0 0 180 180"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3"
|
||||||
|
sodipodi:docname="Model_Context_Protocol_logo copy 2.svg"
|
||||||
|
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview3"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="1.3111111"
|
||||||
|
inkscape:cx="89.618644"
|
||||||
|
inkscape:cy="89.618644"
|
||||||
|
inkscape:window-width="1728"
|
||||||
|
inkscape:window-height="944"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="38"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg3" />
|
||||||
|
<g
|
||||||
|
clip-path="url(#clip0_19_13)"
|
||||||
|
id="g3">
|
||||||
|
<path
|
||||||
|
d="M18 84.8528L85.8822 16.9706C95.2548 7.59798 110.451 7.59798 119.823 16.9706V16.9706C129.196 26.3431 129.196 41.5391 119.823 50.9117L68.5581 102.177"
|
||||||
|
stroke="black"
|
||||||
|
stroke-width="12"
|
||||||
|
stroke-linecap="round"
|
||||||
|
id="path1"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="M69.2652 101.47L119.823 50.9117C129.196 41.5391 144.392 41.5391 153.765 50.9117L154.118 51.2652C163.491 60.6378 163.491 75.8338 154.118 85.2063L92.7248 146.6C89.6006 149.724 89.6006 154.789 92.7248 157.913L105.331 170.52"
|
||||||
|
stroke="black"
|
||||||
|
stroke-width="12"
|
||||||
|
stroke-linecap="round"
|
||||||
|
id="path2"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="M102.853 33.9411L52.6482 84.1457C43.2756 93.5183 43.2756 108.714 52.6482 118.087V118.087C62.0208 127.459 77.2167 127.459 86.5893 118.087L136.794 67.8822"
|
||||||
|
stroke="black"
|
||||||
|
stroke-width="12"
|
||||||
|
stroke-linecap="round"
|
||||||
|
id="path3"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs3">
|
||||||
|
<clipPath
|
||||||
|
id="clip0_19_13">
|
||||||
|
<rect
|
||||||
|
width="180"
|
||||||
|
height="180"
|
||||||
|
fill="white"
|
||||||
|
id="rect3" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
197
docs/images/mcp-stack.svg
Normal file
|
After Width: | Height: | Size: 75 KiB |
131
docs/index.md
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
---
|
||||||
|
title: Overview
|
||||||
|
description: Introduction to the Model Context Protocol (MCP) Java SDK
|
||||||
|
---
|
||||||
|
|
||||||
|
# MCP Java SDK
|
||||||
|
|
||||||
|
Java SDK for the [Model Context Protocol](https://modelcontextprotocol.io/docs/concepts/architecture)
|
||||||
|
enables standardized integration between AI models and tools.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- MCP Client and MCP Server implementations supporting:
|
||||||
|
- Protocol [version compatibility negotiation](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization) with multiple protocol versions
|
||||||
|
- [Tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools) discovery, execution, list change notifications, and structured output with schema validation
|
||||||
|
- [Resources](https://modelcontextprotocol.io/specification/2025-11-25/server/resources) management with URI templates
|
||||||
|
- [Roots](https://modelcontextprotocol.io/specification/2025-11-25/client/roots) list management and notifications
|
||||||
|
- [Prompts](https://modelcontextprotocol.io/specification/2025-11-25/server/prompts) handling and management
|
||||||
|
- [Sampling](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling) support for AI model interactions
|
||||||
|
- [Elicitation](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation) support for requesting user input from servers
|
||||||
|
- [Completions](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/completion) for argument autocompletion suggestions
|
||||||
|
- [Progress](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/progress) - progress notifications for tracking long-running operations
|
||||||
|
- [Logging](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging) - structured logging with configurable severity levels
|
||||||
|
- Multiple transport implementations:
|
||||||
|
- Default transports (included in core `mcp` module, no external web frameworks required):
|
||||||
|
- [STDIO](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#stdio)-based transport for process-based communication
|
||||||
|
- Java HttpClient-based SSE client transport for HTTP SSE Client-side streaming
|
||||||
|
- Servlet-based SSE server transport for HTTP SSE Server streaming
|
||||||
|
- [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#streamable-http) transport for efficient bidirectional communication (client and server)
|
||||||
|
- Optional Spring-based transports (convenience if using Spring Framework):
|
||||||
|
- WebFlux SSE client and server transports for reactive HTTP streaming
|
||||||
|
- WebFlux Streamable HTTP server transport
|
||||||
|
- WebMVC SSE server transport for servlet-based HTTP streaming
|
||||||
|
- WebMVC Streamable HTTP server transport
|
||||||
|
- WebMVC Stateless server transport
|
||||||
|
- Supports Synchronous and Asynchronous programming paradigms
|
||||||
|
- Pluggable JSON serialization (Jackson 2.x and Jackson 3.x)
|
||||||
|
- Pluggable authorization hooks for server security
|
||||||
|
- DNS rebinding protection with Host/Origin header validation
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
The core `io.modelcontextprotocol.sdk:mcp` module provides default STDIO, SSE, and Streamable HTTP client and server transport implementations without requiring external web frameworks.
|
||||||
|
|
||||||
|
Spring-specific transports are available as optional dependencies for convenience when using the [MCP Client Boot Starter](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html) and [MCP Server Boot Starter](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html).
|
||||||
|
Also consider the [MCP Annotations](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-annotations-overview.html) and [MCP Security](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-security.html).
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
The SDK follows a layered architecture with clear separation of concerns:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- **Client/Server Layer (McpClient/McpServer)**: Both use McpSession for sync/async operations,
|
||||||
|
with McpClient handling client-side protocol operations and McpServer managing server-side protocol operations.
|
||||||
|
- **Session Layer (McpSession)**: Manages communication patterns and state.
|
||||||
|
- **Transport Layer (McpTransport)**: Handles JSON-RPC message serialization/deserialization via:
|
||||||
|
- StdioTransport (stdin/stdout) in the core module
|
||||||
|
- HTTP SSE transports in dedicated transport modules (Java HttpClient, Spring WebFlux, Spring WebMVC)
|
||||||
|
- Streamable HTTP transports for efficient bidirectional communication
|
||||||
|
|
||||||
|
The MCP Client is a key component in the Model Context Protocol (MCP) architecture, responsible for establishing and managing connections with MCP servers.
|
||||||
|
It implements the client-side of the protocol.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The MCP Server is a foundational component in the Model Context Protocol (MCP) architecture that provides tools, resources, and capabilities to clients.
|
||||||
|
It implements the server-side of the protocol.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Key Interactions:
|
||||||
|
|
||||||
|
- **Client/Server Initialization**: Transport setup, protocol compatibility check, capability negotiation, and implementation details exchange.
|
||||||
|
- **Message Flow**: JSON-RPC message handling with validation, type-safe response processing, and error handling.
|
||||||
|
- **Resource Management**: Resource discovery, URI template-based access, subscription system, and content retrieval.
|
||||||
|
|
||||||
|
## Module Structure
|
||||||
|
|
||||||
|
The SDK is organized into modules to separate concerns and allow adopters to bring in only what they need:
|
||||||
|
|
||||||
|
| Module | Artifact ID | Purpose |
|
||||||
|
|--------|------------|---------|
|
||||||
|
| `mcp-bom` | `mcp-bom` | Bill of Materials for dependency management |
|
||||||
|
| `mcp-core` | `mcp-core` | Core reference implementation (STDIO, JDK HttpClient, Servlet, Streamable HTTP) |
|
||||||
|
| `mcp-json-jackson2` | `mcp-json-jackson2` | Jackson 2.x JSON serialization implementation |
|
||||||
|
| `mcp-json-jackson3` | `mcp-json-jackson3` | Jackson 3.x JSON serialization implementation |
|
||||||
|
| `mcp` | `mcp` | Convenience bundle (`mcp-core` + `mcp-json-jackson3`) |
|
||||||
|
| `mcp-test` | `mcp-test` | Shared testing utilities and integration tests |
|
||||||
|
| `mcp-spring-webflux` | `mcp-spring-webflux` | Spring WebFlux integration (SSE and Streamable HTTP) |
|
||||||
|
| `mcp-spring-webmvc` | `mcp-spring-webmvc` | Spring WebMVC integration (SSE and Streamable HTTP) |
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
A minimal adopter may depend only on `mcp` (core + Jackson 3), while a Spring-based application can add `mcp-spring-webflux` or `mcp-spring-webmvc` for deeper framework integration.
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
<div class="grid cards" markdown>
|
||||||
|
|
||||||
|
- :rocket:{ .lg .middle } **Quickstart**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Get started with dependencies and BOM configuration.
|
||||||
|
|
||||||
|
[:octicons-arrow-right-24: Quickstart](quickstart.md)
|
||||||
|
|
||||||
|
- :material-monitor:{ .lg .middle } **MCP Client**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Learn how to create and configure MCP clients.
|
||||||
|
|
||||||
|
[:octicons-arrow-right-24: Client](client.md)
|
||||||
|
|
||||||
|
- :material-server:{ .lg .middle } **MCP Server**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Learn how to implement and configure MCP servers.
|
||||||
|
|
||||||
|
[:octicons-arrow-right-24: Server](server.md)
|
||||||
|
|
||||||
|
- :fontawesome-brands-github:{ .lg .middle } **GitHub**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
View the source code and contribute.
|
||||||
|
|
||||||
|
[:octicons-arrow-right-24: Repository](https://github.com/modelcontextprotocol/java-sdk)
|
||||||
|
|
||||||
|
</div>
|
||||||
160
docs/quickstart.md
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
---
|
||||||
|
title: Quickstart
|
||||||
|
description: Get started with the MCP Java SDK dependencies and configuration
|
||||||
|
---
|
||||||
|
|
||||||
|
# Quickstart
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Add the following dependency to your project:
|
||||||
|
|
||||||
|
=== "Maven"
|
||||||
|
|
||||||
|
The convenience `mcp` module bundles `mcp-core` with Jackson 3.x JSON serialization:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
This includes default STDIO, SSE, and Streamable HTTP transport implementations without requiring external web frameworks.
|
||||||
|
|
||||||
|
If you need only the core module without a JSON implementation (e.g., to bring your own):
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
For Jackson 2.x instead of Jackson 3.x:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp-json-jackson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're using the Spring Framework and want Spring-specific transport implementations, add one of the following optional dependencies:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Optional: Spring WebFlux-based SSE and Streamable HTTP client and server transport -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp-spring-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Optional: Spring WebMVC-based SSE and Streamable HTTP server transport -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp-spring-webmvc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Gradle"
|
||||||
|
|
||||||
|
The convenience `mcp` module bundles `mcp-core` with Jackson 3.x JSON serialization:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
dependencies {
|
||||||
|
implementation "io.modelcontextprotocol.sdk:mcp"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This includes default STDIO, SSE, and Streamable HTTP transport implementations without requiring external web frameworks.
|
||||||
|
|
||||||
|
If you need only the core module without a JSON implementation (e.g., to bring your own):
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
dependencies {
|
||||||
|
implementation "io.modelcontextprotocol.sdk:mcp-core"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For Jackson 2.x instead of Jackson 3.x:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
dependencies {
|
||||||
|
implementation "io.modelcontextprotocol.sdk:mcp-core"
|
||||||
|
implementation "io.modelcontextprotocol.sdk:mcp-json-jackson2"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're using the Spring Framework and want Spring-specific transport implementations, add one of the following optional dependencies:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
// Optional: Spring WebFlux-based SSE and Streamable HTTP client and server transport
|
||||||
|
dependencies {
|
||||||
|
implementation "io.modelcontextprotocol.sdk:mcp-spring-webflux"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Spring WebMVC-based SSE and Streamable HTTP server transport
|
||||||
|
dependencies {
|
||||||
|
implementation "io.modelcontextprotocol.sdk:mcp-spring-webmvc"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bill of Materials (BOM)
|
||||||
|
|
||||||
|
The Bill of Materials (BOM) declares the recommended versions of all the dependencies used by a given release.
|
||||||
|
Using the BOM from your application's build script avoids the need for you to specify and maintain the dependency versions yourself.
|
||||||
|
Instead, the version of the BOM you're using determines the utilized dependency versions.
|
||||||
|
It also ensures that you're using supported and tested versions of the dependencies by default, unless you choose to override them.
|
||||||
|
|
||||||
|
Add the BOM to your project:
|
||||||
|
|
||||||
|
=== "Maven"
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.modelcontextprotocol.sdk</groupId>
|
||||||
|
<artifactId>mcp-bom</artifactId>
|
||||||
|
<version>0.17.2</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Gradle"
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
dependencies {
|
||||||
|
implementation platform("io.modelcontextprotocol.sdk:mcp-bom:0.17.2")
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Gradle users can also leverage Gradle (5.0+) native support for declaring dependency constraints using a Maven BOM.
|
||||||
|
This is implemented by adding a 'platform' dependency handler method to the dependencies section of your Gradle build script.
|
||||||
|
As shown in the snippet above this can then be followed by version-less declarations of the dependencies.
|
||||||
|
|
||||||
|
Replace the version number with the latest version from [Maven Central](https://central.sonatype.com/artifact/io.modelcontextprotocol.sdk/mcp).
|
||||||
|
|
||||||
|
## Available Dependencies
|
||||||
|
|
||||||
|
The following dependencies are available and managed by the BOM:
|
||||||
|
|
||||||
|
- **Core Dependencies**
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp-core` - Core MCP library providing the base functionality, APIs, and default transport implementations (STDIO, SSE, Streamable HTTP). JSON binding is abstracted for pluggability.
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp` - Convenience bundle that combines `mcp-core` with `mcp-json-jackson3` for out-of-the-box usage.
|
||||||
|
- **JSON Serialization**
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp-json-jackson3` - Jackson 3.x JSON serialization implementation (included in `mcp` bundle).
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp-json-jackson2` - Jackson 2.x JSON serialization implementation for projects that require Jackson 2.x compatibility.
|
||||||
|
- **Optional Transport Dependencies** (convenience if using Spring Framework)
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp-spring-webflux` - WebFlux-based SSE and Streamable HTTP transport implementation for reactive applications.
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp-spring-webmvc` - WebMVC-based SSE and Streamable HTTP transport implementation for servlet-based applications.
|
||||||
|
- **Testing Dependencies**
|
||||||
|
- `io.modelcontextprotocol.sdk:mcp-test` - Testing utilities and support for MCP-based applications.
|
||||||
755
docs/server.md
Normal file
|
|
@ -0,0 +1,755 @@
|
||||||
|
---
|
||||||
|
title: MCP Server
|
||||||
|
description: Learn how to implement and configure a Model Context Protocol (MCP) server
|
||||||
|
---
|
||||||
|
|
||||||
|
# MCP Server
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The MCP Server is a foundational component in the Model Context Protocol (MCP) architecture that provides tools, resources, and capabilities to clients. It implements the server-side of the protocol, responsible for:
|
||||||
|
|
||||||
|
- Exposing tools that clients can discover and execute
|
||||||
|
- Managing resources with URI-based access patterns and resource templates
|
||||||
|
- Providing prompt templates and handling prompt requests
|
||||||
|
- Supporting capability negotiation with clients
|
||||||
|
- Providing argument autocompletion suggestions (completions)
|
||||||
|
- Implementing server-side protocol operations
|
||||||
|
- Managing concurrent client connections
|
||||||
|
- Providing structured logging and notifications
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
The core `io.modelcontextprotocol.sdk:mcp` module provides STDIO, SSE, and Streamable HTTP server transport implementations without requiring external web frameworks.
|
||||||
|
|
||||||
|
Spring-specific transport implementations are available as **optional** dependencies `io.modelcontextprotocol.sdk:mcp-spring-webflux`, `io.modelcontextprotocol.sdk:mcp-spring-webmvc` for [Spring Framework](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html) users.
|
||||||
|
|
||||||
|
The server supports both synchronous and asynchronous APIs, allowing for flexible integration in different application contexts.
|
||||||
|
|
||||||
|
=== "Sync API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Create a server with custom configuration
|
||||||
|
McpSyncServer syncServer = McpServer.sync(transportProvider)
|
||||||
|
.serverInfo("my-server", "1.0.0")
|
||||||
|
.capabilities(ServerCapabilities.builder()
|
||||||
|
.resources(false, true) // Enable resource support with list changes
|
||||||
|
.tools(true) // Enable tool support with list changes
|
||||||
|
.prompts(true) // Enable prompt support with list changes
|
||||||
|
.completions() // Enable completions support
|
||||||
|
.logging() // Enable logging support
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Register tools, resources, and prompts
|
||||||
|
syncServer.addTool(syncToolSpecification);
|
||||||
|
syncServer.addResource(syncResourceSpecification);
|
||||||
|
syncServer.addPrompt(syncPromptSpecification);
|
||||||
|
|
||||||
|
// Close the server when done
|
||||||
|
syncServer.close();
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Create an async server with custom configuration
|
||||||
|
McpAsyncServer asyncServer = McpServer.async(transportProvider)
|
||||||
|
.serverInfo("my-server", "1.0.0")
|
||||||
|
.capabilities(ServerCapabilities.builder()
|
||||||
|
.resources(false, true) // Enable resource support with list changes
|
||||||
|
.tools(true) // Enable tool support with list changes
|
||||||
|
.prompts(true) // Enable prompt support with list changes
|
||||||
|
.completions() // Enable completions support
|
||||||
|
.logging() // Enable logging support
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Register tools, resources, and prompts
|
||||||
|
asyncServer.addTool(asyncToolSpecification)
|
||||||
|
.doOnSuccess(v -> logger.info("Tool registered"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
asyncServer.addResource(asyncResourceSpecification)
|
||||||
|
.doOnSuccess(v -> logger.info("Resource registered"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
asyncServer.addPrompt(asyncPromptSpecification)
|
||||||
|
.doOnSuccess(v -> logger.info("Prompt registered"))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
// Close the server when done
|
||||||
|
asyncServer.close()
|
||||||
|
.doOnSuccess(v -> logger.info("Server closed"))
|
||||||
|
.subscribe();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Server Types
|
||||||
|
|
||||||
|
The SDK supports multiple server creation patterns depending on your transport requirements:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Single-session server with SSE transport provider
|
||||||
|
McpSyncServer server = McpServer.sync(sseTransportProvider).build();
|
||||||
|
|
||||||
|
// Streamable HTTP server
|
||||||
|
McpSyncServer server = McpServer.sync(streamableTransportProvider).build();
|
||||||
|
|
||||||
|
// Stateless server (no session management)
|
||||||
|
McpSyncServer server = McpServer.sync(statelessTransport).build();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Server Transport Providers
|
||||||
|
|
||||||
|
The transport layer in the MCP SDK is responsible for handling the communication between clients and servers.
|
||||||
|
It provides different implementations to support various communication protocols and patterns.
|
||||||
|
The SDK includes several built-in transport provider implementations:
|
||||||
|
|
||||||
|
=== "STDIO"
|
||||||
|
|
||||||
|
Create process-based transport using stdin/stdout:
|
||||||
|
|
||||||
|
```java
|
||||||
|
StdioServerTransportProvider transportProvider =
|
||||||
|
new StdioServerTransportProvider(new ObjectMapper());
|
||||||
|
```
|
||||||
|
|
||||||
|
Provides bidirectional JSON-RPC message handling over standard input/output streams with non-blocking message processing, serialization/deserialization, and graceful shutdown support.
|
||||||
|
|
||||||
|
Key features:
|
||||||
|
|
||||||
|
- Bidirectional communication through stdin/stdout
|
||||||
|
- Process-based integration support
|
||||||
|
- Simple setup and configuration
|
||||||
|
- Lightweight implementation
|
||||||
|
|
||||||
|
=== "Streamable HTTP (Servlet)"
|
||||||
|
|
||||||
|
Creates a Servlet-based Streamable HTTP server transport. Included in the core `mcp` module:
|
||||||
|
|
||||||
|
```java
|
||||||
|
HttpServletStreamableServerTransportProvider transportProvider =
|
||||||
|
HttpServletStreamableServerTransportProvider.builder()
|
||||||
|
.jsonMapper(jsonMapper)
|
||||||
|
.mcpEndpoint("/mcp")
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
To use with a Spring Web application, register it as a Servlet bean:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class McpServerConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HttpServletStreamableServerTransportProvider transportProvider(McpJsonMapper jsonMapper) {
|
||||||
|
return HttpServletStreamableServerTransportProvider.builder()
|
||||||
|
.jsonMapper(jsonMapper)
|
||||||
|
.mcpEndpoint("/mcp")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServletRegistrationBean<?> mcpServlet(
|
||||||
|
HttpServletStreamableServerTransportProvider transportProvider) {
|
||||||
|
return new ServletRegistrationBean<>(transportProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Key features:
|
||||||
|
|
||||||
|
- Efficient bidirectional HTTP communication
|
||||||
|
- Session management for multiple client connections
|
||||||
|
- Configurable keep-alive intervals
|
||||||
|
- Security validation support
|
||||||
|
- Graceful shutdown support
|
||||||
|
|
||||||
|
=== "Streamable HTTP (WebFlux)"
|
||||||
|
|
||||||
|
Creates WebFlux-based Streamable HTTP server transport. Requires the `mcp-spring-webflux` dependency:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
class McpConfig {
|
||||||
|
@Bean
|
||||||
|
WebFluxStreamableServerTransportProvider transportProvider(McpJsonMapper jsonMapper) {
|
||||||
|
return WebFluxStreamableServerTransportProvider.builder()
|
||||||
|
.jsonMapper(jsonMapper)
|
||||||
|
.messageEndpoint("/mcp")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RouterFunction<?> mcpRouterFunction(
|
||||||
|
WebFluxStreamableServerTransportProvider transportProvider) {
|
||||||
|
return transportProvider.getRouterFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Key features:
|
||||||
|
|
||||||
|
- Reactive HTTP streaming with WebFlux
|
||||||
|
- Concurrent client connections
|
||||||
|
- Configurable keep-alive intervals
|
||||||
|
- Security validation support
|
||||||
|
|
||||||
|
=== "Streamable HTTP (WebMvc)"
|
||||||
|
|
||||||
|
Creates WebMvc-based Streamable HTTP server transport. Requires the `mcp-spring-webmvc` dependency:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
class McpConfig {
|
||||||
|
@Bean
|
||||||
|
WebMvcStreamableServerTransportProvider transportProvider(McpJsonMapper jsonMapper) {
|
||||||
|
return WebMvcStreamableServerTransportProvider.builder()
|
||||||
|
.jsonMapper(jsonMapper)
|
||||||
|
.mcpEndpoint("/mcp")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RouterFunction<ServerResponse> mcpRouterFunction(
|
||||||
|
WebMvcStreamableServerTransportProvider transportProvider) {
|
||||||
|
return transportProvider.getRouterFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "SSE (WebFlux)"
|
||||||
|
|
||||||
|
Creates WebFlux-based SSE server transport. Requires the `mcp-spring-webflux` dependency:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
class McpConfig {
|
||||||
|
@Bean
|
||||||
|
WebFluxSseServerTransportProvider webFluxSseServerTransportProvider(ObjectMapper mapper) {
|
||||||
|
return new WebFluxSseServerTransportProvider(mapper, "/mcp/message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {
|
||||||
|
return transportProvider.getRouterFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Implements the MCP HTTP with SSE transport specification, providing:
|
||||||
|
|
||||||
|
- Reactive HTTP streaming with WebFlux
|
||||||
|
- Concurrent client connections through SSE endpoints
|
||||||
|
- Message routing and session management
|
||||||
|
- Graceful shutdown capabilities
|
||||||
|
|
||||||
|
=== "SSE (WebMvc)"
|
||||||
|
|
||||||
|
Creates WebMvc-based SSE server transport. Requires the `mcp-spring-webmvc` dependency:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
class McpConfig {
|
||||||
|
@Bean
|
||||||
|
WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper mapper) {
|
||||||
|
return new WebMvcSseServerTransportProvider(mapper, "/mcp/message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RouterFunction<ServerResponse> mcpRouterFunction(
|
||||||
|
WebMvcSseServerTransportProvider transportProvider) {
|
||||||
|
return transportProvider.getRouterFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Implements the MCP HTTP with SSE transport specification, providing:
|
||||||
|
|
||||||
|
- Server-side event streaming
|
||||||
|
- Integration with Spring WebMVC
|
||||||
|
- Support for traditional web applications
|
||||||
|
- Synchronous operation handling
|
||||||
|
|
||||||
|
=== "SSE (Servlet)"
|
||||||
|
|
||||||
|
Creates a Servlet-based SSE server transport. Included in the core `mcp` module.
|
||||||
|
The `HttpServletSseServerTransportProvider` can be used with any Servlet container.
|
||||||
|
To use it with a Spring Web application, you can register it as a Servlet bean:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class McpServerConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HttpServletSseServerTransportProvider servletSseServerTransportProvider() {
|
||||||
|
return new HttpServletSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServletRegistrationBean<?> customServletBean(
|
||||||
|
HttpServletSseServerTransportProvider transportProvider) {
|
||||||
|
return new ServletRegistrationBean<>(transportProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Implements the MCP HTTP with SSE transport specification using the traditional Servlet API, providing:
|
||||||
|
|
||||||
|
- Asynchronous message handling using Servlet 6.0 async support
|
||||||
|
- Session management for multiple client connections
|
||||||
|
- Two types of endpoints:
|
||||||
|
- SSE endpoint (`/sse`) for server-to-client events
|
||||||
|
- Message endpoint (configurable) for client-to-server requests
|
||||||
|
- Error handling and response formatting
|
||||||
|
- Graceful shutdown support
|
||||||
|
|
||||||
|
## Server Capabilities
|
||||||
|
|
||||||
|
The server can be configured with various capabilities:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var capabilities = ServerCapabilities.builder()
|
||||||
|
.resources(false, true) // Resource support (subscribe, listChanged)
|
||||||
|
.tools(true) // Tool support with list changes notifications
|
||||||
|
.prompts(true) // Prompt support with list changes notifications
|
||||||
|
.completions() // Enable completions support
|
||||||
|
.logging() // Enable logging support
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tool Specification
|
||||||
|
|
||||||
|
The Model Context Protocol allows servers to [expose tools](https://spec.modelcontextprotocol.io/specification/2024-11-05/server/tools/) that can be invoked by language models.
|
||||||
|
The Java SDK allows implementing Tool Specifications with their handler functions.
|
||||||
|
Tools enable AI models to perform calculations, access external APIs, query databases, and manipulate files.
|
||||||
|
|
||||||
|
The recommended approach is to use the builder pattern and `CallToolRequest` as the handler parameter:
|
||||||
|
|
||||||
|
=== "Sync"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Sync tool specification using builder
|
||||||
|
var syncToolSpecification = SyncToolSpecification.builder()
|
||||||
|
.tool(Tool.builder()
|
||||||
|
.name("calculator")
|
||||||
|
.description("Basic calculator")
|
||||||
|
.inputSchema(schema)
|
||||||
|
.build())
|
||||||
|
.callHandler((exchange, request) -> {
|
||||||
|
// Access arguments via request.arguments()
|
||||||
|
String operation = (String) request.arguments().get("operation");
|
||||||
|
int a = (int) request.arguments().get("a");
|
||||||
|
int b = (int) request.arguments().get("b");
|
||||||
|
// Tool implementation
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Result: " + result)))
|
||||||
|
.build();
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Async tool specification using builder
|
||||||
|
var asyncToolSpecification = AsyncToolSpecification.builder()
|
||||||
|
.tool(Tool.builder()
|
||||||
|
.name("calculator")
|
||||||
|
.description("Basic calculator")
|
||||||
|
.inputSchema(schema)
|
||||||
|
.build())
|
||||||
|
.callHandler((exchange, request) -> {
|
||||||
|
// Access arguments via request.arguments()
|
||||||
|
String operation = (String) request.arguments().get("operation");
|
||||||
|
int a = (int) request.arguments().get("a");
|
||||||
|
int b = (int) request.arguments().get("b");
|
||||||
|
// Tool implementation
|
||||||
|
return Mono.just(CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Result: " + result)))
|
||||||
|
.build());
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
The Tool specification includes a Tool definition with `name`, `description`, and `inputSchema` followed by a call handler that implements the tool's logic.
|
||||||
|
The handler receives `McpSyncServerExchange`/`McpAsyncServerExchange` for client interaction and a `CallToolRequest` containing the tool arguments.
|
||||||
|
|
||||||
|
You can also register tools directly on the server builder using the `toolCall` convenience method:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var server = McpServer.sync(transportProvider)
|
||||||
|
.toolCall(
|
||||||
|
Tool.builder().name("echo").description("Echoes input").inputSchema(schema).build(),
|
||||||
|
(exchange, request) -> CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent(request.arguments().get("text").toString())))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Specification
|
||||||
|
|
||||||
|
Specification of a resource with its handler function.
|
||||||
|
Resources provide context to AI models by exposing data such as: File contents, Database records, API responses, System information, Application state.
|
||||||
|
|
||||||
|
=== "Sync"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Sync resource specification
|
||||||
|
var syncResourceSpecification = new McpServerFeatures.SyncResourceSpecification(
|
||||||
|
Resource.builder()
|
||||||
|
.uri("custom://resource")
|
||||||
|
.name("name")
|
||||||
|
.description("description")
|
||||||
|
.mimeType("text/plain")
|
||||||
|
.build(),
|
||||||
|
(exchange, request) -> {
|
||||||
|
// Resource read implementation
|
||||||
|
return new ReadResourceResult(contents);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Async resource specification
|
||||||
|
var asyncResourceSpecification = new McpServerFeatures.AsyncResourceSpecification(
|
||||||
|
Resource.builder()
|
||||||
|
.uri("custom://resource")
|
||||||
|
.name("name")
|
||||||
|
.description("description")
|
||||||
|
.mimeType("text/plain")
|
||||||
|
.build(),
|
||||||
|
(exchange, request) -> {
|
||||||
|
// Resource read implementation
|
||||||
|
return Mono.just(new ReadResourceResult(contents));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Template Specification
|
||||||
|
|
||||||
|
Resource templates allow servers to expose parameterized resources using URI templates:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Resource template specification
|
||||||
|
var resourceTemplateSpec = new McpServerFeatures.SyncResourceTemplateSpecification(
|
||||||
|
ResourceTemplate.builder()
|
||||||
|
.uriTemplate("file://{path}")
|
||||||
|
.name("File Resource")
|
||||||
|
.description("Access files by path")
|
||||||
|
.mimeType("application/octet-stream")
|
||||||
|
.build(),
|
||||||
|
(exchange, request) -> {
|
||||||
|
// Read the file at the requested URI
|
||||||
|
return new ReadResourceResult(contents);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prompt Specification
|
||||||
|
|
||||||
|
As part of the [Prompting capabilities](https://spec.modelcontextprotocol.io/specification/2024-11-05/server/prompts/), MCP provides a standardized way for servers to expose prompt templates to clients.
|
||||||
|
The Prompt Specification is a structured template for AI model interactions that enables consistent message formatting, parameter substitution, context injection, response formatting, and instruction templating.
|
||||||
|
|
||||||
|
=== "Sync"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Sync prompt specification
|
||||||
|
var syncPromptSpecification = new McpServerFeatures.SyncPromptSpecification(
|
||||||
|
new Prompt("greeting", "description", List.of(
|
||||||
|
new PromptArgument("name", "description", true)
|
||||||
|
)),
|
||||||
|
(exchange, request) -> {
|
||||||
|
// Prompt implementation
|
||||||
|
return new GetPromptResult(description, messages);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Async prompt specification
|
||||||
|
var asyncPromptSpecification = new McpServerFeatures.AsyncPromptSpecification(
|
||||||
|
new Prompt("greeting", "description", List.of(
|
||||||
|
new PromptArgument("name", "description", true)
|
||||||
|
)),
|
||||||
|
(exchange, request) -> {
|
||||||
|
// Prompt implementation
|
||||||
|
return Mono.just(new GetPromptResult(description, messages));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
The prompt definition includes name (identifier for the prompt), description (purpose of the prompt), and list of arguments (parameters for templating).
|
||||||
|
The handler function processes requests and returns formatted templates.
|
||||||
|
The first argument is `McpSyncServerExchange`/`McpAsyncServerExchange` for client interaction, and the second argument is a `GetPromptRequest` instance.
|
||||||
|
|
||||||
|
### Completion Specification
|
||||||
|
|
||||||
|
Completions allow servers to provide argument autocompletion suggestions for prompts and resources:
|
||||||
|
|
||||||
|
=== "Sync"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Sync completion specification
|
||||||
|
var syncCompletionSpec = new McpServerFeatures.SyncCompletionSpecification(
|
||||||
|
new McpSchema.PromptReference("greeting"), // Reference to a prompt
|
||||||
|
(exchange, request) -> {
|
||||||
|
String argName = request.argument().name();
|
||||||
|
String partial = request.argument().value();
|
||||||
|
// Return matching suggestions
|
||||||
|
List<String> suggestions = findMatches(partial);
|
||||||
|
return new McpSchema.CompleteResult(
|
||||||
|
new McpSchema.CompleteResult.CompleteCompletion(suggestions, suggestions.size(), false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Async completion specification
|
||||||
|
var asyncCompletionSpec = new McpServerFeatures.AsyncCompletionSpecification(
|
||||||
|
new McpSchema.PromptReference("greeting"),
|
||||||
|
(exchange, request) -> {
|
||||||
|
String argName = request.argument().name();
|
||||||
|
String partial = request.argument().value();
|
||||||
|
List<String> suggestions = findMatches(partial);
|
||||||
|
return Mono.just(new McpSchema.CompleteResult(
|
||||||
|
new McpSchema.CompleteResult.CompleteCompletion(suggestions, suggestions.size(), false)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Completions can be registered for both `PromptReference` and `ResourceReference` types.
|
||||||
|
|
||||||
|
### Using Sampling from a Server
|
||||||
|
|
||||||
|
To use [Sampling capabilities](https://spec.modelcontextprotocol.io/specification/2024-11-05/client/sampling/), connect to a client that supports sampling.
|
||||||
|
No special server configuration is needed, but verify client sampling support before making requests.
|
||||||
|
Learn about [client sampling support](client.md#sampling-support).
|
||||||
|
|
||||||
|
Once connected to a compatible client, the server can request language model generations:
|
||||||
|
|
||||||
|
=== "Sync API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Create a server
|
||||||
|
McpSyncServer server = McpServer.sync(transportProvider)
|
||||||
|
.serverInfo("my-server", "1.0.0")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Define a tool that uses sampling
|
||||||
|
var calculatorTool = SyncToolSpecification.builder()
|
||||||
|
.tool(Tool.builder()
|
||||||
|
.name("ai-calculator")
|
||||||
|
.description("Performs calculations using AI")
|
||||||
|
.inputSchema(schema)
|
||||||
|
.build())
|
||||||
|
.callHandler((exchange, request) -> {
|
||||||
|
// Check if client supports sampling
|
||||||
|
if (exchange.getClientCapabilities().sampling() == null) {
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Client does not support AI capabilities")))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a sampling request
|
||||||
|
CreateMessageRequest samplingRequest = CreateMessageRequest.builder()
|
||||||
|
.messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
|
||||||
|
new McpSchema.TextContent("Calculate: " + request.arguments().get("expression")))))
|
||||||
|
.modelPreferences(McpSchema.ModelPreferences.builder()
|
||||||
|
.hints(List.of(
|
||||||
|
McpSchema.ModelHint.of("claude-3-sonnet"),
|
||||||
|
McpSchema.ModelHint.of("claude")
|
||||||
|
))
|
||||||
|
.intelligencePriority(0.8)
|
||||||
|
.speedPriority(0.5)
|
||||||
|
.build())
|
||||||
|
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
|
||||||
|
.maxTokens(100)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Request sampling from the client
|
||||||
|
CreateMessageResult result = exchange.createMessage(samplingRequest);
|
||||||
|
|
||||||
|
// Process the result
|
||||||
|
String answer = ((McpSchema.TextContent) result.content()).text();
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent(answer)))
|
||||||
|
.build();
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Add the tool to the server
|
||||||
|
server.addTool(calculatorTool);
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Async API"
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Create a server
|
||||||
|
McpAsyncServer server = McpServer.async(transportProvider)
|
||||||
|
.serverInfo("my-server", "1.0.0")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Define a tool that uses sampling
|
||||||
|
var calculatorTool = AsyncToolSpecification.builder()
|
||||||
|
.tool(Tool.builder()
|
||||||
|
.name("ai-calculator")
|
||||||
|
.description("Performs calculations using AI")
|
||||||
|
.inputSchema(schema)
|
||||||
|
.build())
|
||||||
|
.callHandler((exchange, request) -> {
|
||||||
|
// Check if client supports sampling
|
||||||
|
if (exchange.getClientCapabilities().sampling() == null) {
|
||||||
|
return Mono.just(CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Client does not support AI capabilities")))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a sampling request
|
||||||
|
CreateMessageRequest samplingRequest = CreateMessageRequest.builder()
|
||||||
|
.messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
|
||||||
|
new McpSchema.TextContent("Calculate: " + request.arguments().get("expression")))))
|
||||||
|
.modelPreferences(McpSchema.ModelPreferences.builder()
|
||||||
|
.hints(List.of(
|
||||||
|
McpSchema.ModelHint.of("claude-3-sonnet"),
|
||||||
|
McpSchema.ModelHint.of("claude")
|
||||||
|
))
|
||||||
|
.intelligencePriority(0.8)
|
||||||
|
.speedPriority(0.5)
|
||||||
|
.build())
|
||||||
|
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
|
||||||
|
.maxTokens(100)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Request sampling from the client
|
||||||
|
return exchange.createMessage(samplingRequest)
|
||||||
|
.map(result -> {
|
||||||
|
String answer = ((McpSchema.TextContent) result.content()).text();
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent(answer)))
|
||||||
|
.build();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Add the tool to the server
|
||||||
|
server.addTool(calculatorTool)
|
||||||
|
.subscribe();
|
||||||
|
```
|
||||||
|
|
||||||
|
The `CreateMessageRequest` object allows you to specify: `Content` - the input text or image for the model,
|
||||||
|
`Model Preferences` - hints and priorities for model selection, `System Prompt` - instructions for the model's behavior and
|
||||||
|
`Max Tokens` - maximum length of the generated response.
|
||||||
|
|
||||||
|
### Using Elicitation from a Server
|
||||||
|
|
||||||
|
Servers can request user input from connected clients that support elicitation:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var tool = SyncToolSpecification.builder()
|
||||||
|
.tool(Tool.builder()
|
||||||
|
.name("confirm-action")
|
||||||
|
.description("Confirms an action with the user")
|
||||||
|
.inputSchema(schema)
|
||||||
|
.build())
|
||||||
|
.callHandler((exchange, request) -> {
|
||||||
|
// Check if client supports elicitation
|
||||||
|
if (exchange.getClientCapabilities().elicitation() == null) {
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Client does not support elicitation")))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request user confirmation
|
||||||
|
ElicitRequest elicitRequest = ElicitRequest.builder()
|
||||||
|
.message("Do you want to proceed with this action?")
|
||||||
|
.requestedSchema(Map.of(
|
||||||
|
"type", "object",
|
||||||
|
"properties", Map.of("confirmed", Map.of("type", "boolean"))
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ElicitResult result = exchange.elicit(elicitRequest);
|
||||||
|
|
||||||
|
if (result.action() == ElicitResult.Action.ACCEPT) {
|
||||||
|
// User accepted
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Action confirmed")))
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Action declined")))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logging Support
|
||||||
|
|
||||||
|
The server provides structured logging capabilities that allow sending log messages to clients with different severity levels.
|
||||||
|
Log notifications can only be sent from within an existing client session, such as tools, resources, and prompts calls.
|
||||||
|
|
||||||
|
The server can send log messages using the `McpAsyncServerExchange`/`McpSyncServerExchange` object in the tool/resource/prompt handler function:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var tool = new McpServerFeatures.AsyncToolSpecification(
|
||||||
|
Tool.builder().name("logging-test").description("Test logging notifications").inputSchema(emptyJsonSchema).build(),
|
||||||
|
null,
|
||||||
|
(exchange, request) -> {
|
||||||
|
|
||||||
|
exchange.loggingNotification( // Use the exchange to send log messages
|
||||||
|
McpSchema.LoggingMessageNotification.builder()
|
||||||
|
.level(McpSchema.LoggingLevel.DEBUG)
|
||||||
|
.logger("test-logger")
|
||||||
|
.data("Debug message")
|
||||||
|
.build())
|
||||||
|
.block();
|
||||||
|
|
||||||
|
return Mono.just(CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Logging test completed")))
|
||||||
|
.build());
|
||||||
|
});
|
||||||
|
|
||||||
|
var mcpServer = McpServer.async(mcpServerTransportProvider)
|
||||||
|
.serverInfo("test-server", "1.0.0")
|
||||||
|
.capabilities(
|
||||||
|
ServerCapabilities.builder()
|
||||||
|
.logging() // Enable logging support
|
||||||
|
.tools(true)
|
||||||
|
.build())
|
||||||
|
.tools(tool)
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
On the client side, you can register a logging consumer to receive log messages from the server:
|
||||||
|
|
||||||
|
```java
|
||||||
|
var mcpClient = McpClient.sync(transport)
|
||||||
|
.loggingConsumer(notification -> {
|
||||||
|
System.out.println("Received log message: " + notification.data());
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mcpClient.initialize();
|
||||||
|
mcpClient.setLoggingLevel(McpSchema.LoggingLevel.INFO);
|
||||||
|
```
|
||||||
|
|
||||||
|
Clients can control the minimum logging level they receive through the `mcpClient.setLoggingLevel(level)` request. Messages below the set level will be filtered out.
|
||||||
|
Supported logging levels (in order of increasing severity): DEBUG (0), INFO (1), NOTICE (2), WARNING (3), ERROR (4), CRITICAL (5), ALERT (6), EMERGENCY (7)
|
||||||
|
|
||||||
|
## 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.
|
||||||
13
docs/stylesheets/extra.css
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
:root {
|
||||||
|
--md-primary-fg-color: #16A34A;
|
||||||
|
--md-primary-fg-color--light: #07C983;
|
||||||
|
--md-primary-fg-color--dark: #15803D;
|
||||||
|
--md-accent-fg-color: #07C983;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-md-color-scheme="slate"] {
|
||||||
|
--md-primary-fg-color: #07C983;
|
||||||
|
--md-primary-fg-color--light: #07C983;
|
||||||
|
--md-primary-fg-color--dark: #15803D;
|
||||||
|
--md-accent-fg-color: #07C983;
|
||||||
|
}
|
||||||
|
|
@ -1,328 +0,0 @@
|
||||||
# MCP Java SDK Migration Guide: 0.7.0 to 0.8.0
|
|
||||||
|
|
||||||
This document outlines the breaking changes and provides guidance on how to migrate your code from version 0.7.0 to 0.8.0.
|
|
||||||
|
|
||||||
The 0.8.0 refactoring introduces a session-based architecture for server-side MCP implementations.
|
|
||||||
It improves the SDK's ability to handle multiple concurrent client connections and provides an API better aligned with the MCP specification.
|
|
||||||
The main changes include:
|
|
||||||
|
|
||||||
1. Introduction of a session-based architecture
|
|
||||||
2. New transport provider abstraction
|
|
||||||
3. Exchange objects for client interaction
|
|
||||||
4. Renamed and reorganized interfaces
|
|
||||||
5. Updated handler signatures
|
|
||||||
|
|
||||||
## Breaking Changes
|
|
||||||
|
|
||||||
### 1. Interface Renaming
|
|
||||||
|
|
||||||
Several interfaces have been renamed to better reflect their roles:
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `ClientMcpTransport` | `McpClientTransport` |
|
|
||||||
| `ServerMcpTransport` | `McpServerTransport` |
|
|
||||||
| `DefaultMcpSession` | `McpClientSession`, `McpServerSession` |
|
|
||||||
|
|
||||||
### 2. New Server Transport Architecture
|
|
||||||
|
|
||||||
The most significant change is the introduction of the `McpServerTransportProvider` interface, which replaces direct usage of `ServerMcpTransport` when creating servers. This new pattern separates the concerns of:
|
|
||||||
|
|
||||||
1. **Transport Provider**: Manages connections with clients and creates individual transports for each connection
|
|
||||||
2. **Server Transport**: Handles communication with a specific client connection
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `ServerMcpTransport` | `McpServerTransportProvider` + `McpServerTransport` |
|
|
||||||
| Direct transport usage | Session-based transport usage |
|
|
||||||
|
|
||||||
#### Before (0.7.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Create a transport
|
|
||||||
ServerMcpTransport transport = new WebFluxSseServerTransport(objectMapper, "/mcp/message");
|
|
||||||
|
|
||||||
// Create a server with the transport
|
|
||||||
McpServer.sync(transport)
|
|
||||||
.serverInfo("my-server", "1.0.0")
|
|
||||||
.build();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### After (0.8.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Create a transport provider
|
|
||||||
McpServerTransportProvider transportProvider = new WebFluxSseServerTransportProvider(objectMapper, "/mcp/message");
|
|
||||||
|
|
||||||
// Create a server with the transport provider
|
|
||||||
McpServer.sync(transportProvider)
|
|
||||||
.serverInfo("my-server", "1.0.0")
|
|
||||||
.build();
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Handler Method Signature Changes
|
|
||||||
|
|
||||||
Tool, resource, and prompt handlers now receive an additional `exchange` parameter that provides access to client capabilities and methods to interact with the client:
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `(args) -> result` | `(exchange, args) -> result` |
|
|
||||||
|
|
||||||
The exchange objects (`McpAsyncServerExchange` and `McpSyncServerExchange`) provide context for the current session and access to session-specific operations.
|
|
||||||
|
|
||||||
#### Before (0.7.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Tool handler
|
|
||||||
.tool(calculatorTool, args -> new CallToolResult("Result: " + calculate(args)))
|
|
||||||
|
|
||||||
// Resource handler
|
|
||||||
.resource(fileResource, req -> new ReadResourceResult(readFile(req)))
|
|
||||||
|
|
||||||
// Prompt handler
|
|
||||||
.prompt(analysisPrompt, req -> new GetPromptResult("Analysis prompt"))
|
|
||||||
```
|
|
||||||
|
|
||||||
#### After (0.8.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Tool handler
|
|
||||||
.tool(calculatorTool, (exchange, args) -> new CallToolResult("Result: " + calculate(args)))
|
|
||||||
|
|
||||||
// Resource handler
|
|
||||||
.resource(fileResource, (exchange, req) -> new ReadResourceResult(readFile(req)))
|
|
||||||
|
|
||||||
// Prompt handler
|
|
||||||
.prompt(analysisPrompt, (exchange, req) -> new GetPromptResult("Analysis prompt"))
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Registration vs. Specification
|
|
||||||
|
|
||||||
The naming convention for handlers has changed from "Registration" to "Specification":
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `AsyncToolRegistration` | `AsyncToolSpecification` |
|
|
||||||
| `SyncToolRegistration` | `SyncToolSpecification` |
|
|
||||||
| `AsyncResourceRegistration` | `AsyncResourceSpecification` |
|
|
||||||
| `SyncResourceRegistration` | `SyncResourceSpecification` |
|
|
||||||
| `AsyncPromptRegistration` | `AsyncPromptSpecification` |
|
|
||||||
| `SyncPromptRegistration` | `SyncPromptSpecification` |
|
|
||||||
|
|
||||||
### 5. Roots Change Handler Updates
|
|
||||||
|
|
||||||
The roots change handlers now receive an exchange parameter:
|
|
||||||
|
|
||||||
#### Before (0.7.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
.rootsChangeConsumers(List.of(
|
|
||||||
roots -> {
|
|
||||||
// Process roots
|
|
||||||
}
|
|
||||||
))
|
|
||||||
```
|
|
||||||
|
|
||||||
#### After (0.8.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
.rootsChangeHandlers(List.of(
|
|
||||||
(exchange, roots) -> {
|
|
||||||
// Process roots with access to exchange
|
|
||||||
}
|
|
||||||
))
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Server Creation Method Changes
|
|
||||||
|
|
||||||
The `McpServer` factory methods now accept `McpServerTransportProvider` instead of `ServerMcpTransport`:
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `McpServer.async(ServerMcpTransport)` | `McpServer.async(McpServerTransportProvider)` |
|
|
||||||
| `McpServer.sync(ServerMcpTransport)` | `McpServer.sync(McpServerTransportProvider)` |
|
|
||||||
|
|
||||||
The method names for creating servers have been updated:
|
|
||||||
|
|
||||||
Root change handlers now receive an exchange object:
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `rootsChangeConsumers(List<Consumer<List<Root>>>)` | `rootsChangeHandlers(List<BiConsumer<McpSyncServerExchange, List<Root>>>)` |
|
|
||||||
| `rootsChangeConsumer(Consumer<List<Root>>)` | `rootsChangeHandler(BiConsumer<McpSyncServerExchange, List<Root>>)` |
|
|
||||||
|
|
||||||
### 7. Direct Server Methods Moving to Exchange
|
|
||||||
|
|
||||||
Several methods that were previously available directly on the server are now accessed through the exchange object:
|
|
||||||
|
|
||||||
| 0.7.0 (Old) | 0.8.0 (New) |
|
|
||||||
|-------------|-------------|
|
|
||||||
| `server.listRoots()` | `exchange.listRoots()` |
|
|
||||||
| `server.createMessage()` | `exchange.createMessage()` |
|
|
||||||
| `server.getClientCapabilities()` | `exchange.getClientCapabilities()` |
|
|
||||||
| `server.getClientInfo()` | `exchange.getClientInfo()` |
|
|
||||||
|
|
||||||
The direct methods are deprecated and will be removed in 0.9.0:
|
|
||||||
|
|
||||||
- `McpSyncServer.listRoots()`
|
|
||||||
- `McpSyncServer.getClientCapabilities()`
|
|
||||||
- `McpSyncServer.getClientInfo()`
|
|
||||||
- `McpSyncServer.createMessage()`
|
|
||||||
- `McpAsyncServer.listRoots()`
|
|
||||||
- `McpAsyncServer.getClientCapabilities()`
|
|
||||||
- `McpAsyncServer.getClientInfo()`
|
|
||||||
- `McpAsyncServer.createMessage()`
|
|
||||||
|
|
||||||
## Deprecation Notices
|
|
||||||
|
|
||||||
The following components are deprecated in 0.8.0 and will be removed in 0.9.0:
|
|
||||||
|
|
||||||
- `ClientMcpTransport` interface (use `McpClientTransport` instead)
|
|
||||||
- `ServerMcpTransport` interface (use `McpServerTransport` instead)
|
|
||||||
- `DefaultMcpSession` class (use `McpClientSession` instead)
|
|
||||||
- `WebFluxSseServerTransport` class (use `WebFluxSseServerTransportProvider` instead)
|
|
||||||
- `WebMvcSseServerTransport` class (use `WebMvcSseServerTransportProvider` instead)
|
|
||||||
- `StdioServerTransport` class (use `StdioServerTransportProvider` instead)
|
|
||||||
- All `*Registration` classes (use corresponding `*Specification` classes instead)
|
|
||||||
- Direct server methods for client interaction (use exchange object instead)
|
|
||||||
|
|
||||||
## Migration Examples
|
|
||||||
|
|
||||||
### Example 1: Creating a Server
|
|
||||||
|
|
||||||
#### Before (0.7.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Create a transport
|
|
||||||
ServerMcpTransport transport = new WebFluxSseServerTransport(objectMapper, "/mcp/message");
|
|
||||||
|
|
||||||
// Create a server with the transport
|
|
||||||
var server = McpServer.sync(transport)
|
|
||||||
.serverInfo("my-server", "1.0.0")
|
|
||||||
.tool(calculatorTool, args -> new CallToolResult("Result: " + calculate(args)))
|
|
||||||
.rootsChangeConsumers(List.of(
|
|
||||||
roots -> System.out.println("Roots changed: " + roots)
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Get client capabilities directly from server
|
|
||||||
ClientCapabilities capabilities = server.getClientCapabilities();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### After (0.8.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Create a transport provider
|
|
||||||
McpServerTransportProvider transportProvider = new WebFluxSseServerTransportProvider(objectMapper, "/mcp/message");
|
|
||||||
|
|
||||||
// Create a server with the transport provider
|
|
||||||
var server = McpServer.sync(transportProvider)
|
|
||||||
.serverInfo("my-server", "1.0.0")
|
|
||||||
.tool(calculatorTool, (exchange, args) -> {
|
|
||||||
// Get client capabilities from exchange
|
|
||||||
ClientCapabilities capabilities = exchange.getClientCapabilities();
|
|
||||||
return new CallToolResult("Result: " + calculate(args));
|
|
||||||
})
|
|
||||||
.rootsChangeHandlers(List.of(
|
|
||||||
(exchange, roots) -> System.out.println("Roots changed: " + roots)
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 2: Implementing a Tool with Client Interaction
|
|
||||||
|
|
||||||
#### Before (0.7.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
McpServerFeatures.SyncToolRegistration tool = new McpServerFeatures.SyncToolRegistration(
|
|
||||||
new Tool("weather", "Get weather information", schema),
|
|
||||||
args -> {
|
|
||||||
String location = (String) args.get("location");
|
|
||||||
// Cannot interact with client from here
|
|
||||||
return new CallToolResult("Weather for " + location + ": Sunny");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
var server = McpServer.sync(transport)
|
|
||||||
.tools(tool)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Separate call to create a message
|
|
||||||
CreateMessageResult result = server.createMessage(new CreateMessageRequest(...));
|
|
||||||
```
|
|
||||||
|
|
||||||
#### After (0.8.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
McpServerFeatures.SyncToolSpecification tool = new McpServerFeatures.SyncToolSpecification(
|
|
||||||
new Tool("weather", "Get weather information", schema),
|
|
||||||
(exchange, args) -> {
|
|
||||||
String location = (String) args.get("location");
|
|
||||||
|
|
||||||
// Can interact with client directly from the tool handler
|
|
||||||
CreateMessageResult result = exchange.createMessage(new CreateMessageRequest(...));
|
|
||||||
|
|
||||||
return new CallToolResult("Weather for " + location + ": " + result.content());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
var server = McpServer.sync(transportProvider)
|
|
||||||
.tools(tool)
|
|
||||||
.build();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 3: Converting Existing Registration Classes
|
|
||||||
|
|
||||||
If you have custom implementations of the registration classes, you can convert them to the new specification classes:
|
|
||||||
|
|
||||||
#### Before (0.7.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
McpServerFeatures.AsyncToolRegistration toolReg = new McpServerFeatures.AsyncToolRegistration(
|
|
||||||
tool,
|
|
||||||
args -> Mono.just(new CallToolResult("Result"))
|
|
||||||
);
|
|
||||||
|
|
||||||
McpServerFeatures.AsyncResourceRegistration resourceReg = new McpServerFeatures.AsyncResourceRegistration(
|
|
||||||
resource,
|
|
||||||
req -> Mono.just(new ReadResourceResult(List.of()))
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### After (0.8.0):
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Option 1: Create new specification directly
|
|
||||||
McpServerFeatures.AsyncToolSpecification toolSpec = new McpServerFeatures.AsyncToolSpecification(
|
|
||||||
tool,
|
|
||||||
(exchange, args) -> Mono.just(new CallToolResult("Result"))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Option 2: Convert from existing registration (during transition)
|
|
||||||
McpServerFeatures.AsyncToolRegistration oldToolReg = /* existing registration */;
|
|
||||||
McpServerFeatures.AsyncToolSpecification toolSpec = oldToolReg.toSpecification();
|
|
||||||
|
|
||||||
// Similarly for resources
|
|
||||||
McpServerFeatures.AsyncResourceSpecification resourceSpec = new McpServerFeatures.AsyncResourceSpecification(
|
|
||||||
resource,
|
|
||||||
(exchange, req) -> Mono.just(new ReadResourceResult(List.of()))
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Architecture Changes
|
|
||||||
|
|
||||||
### Session-Based Architecture
|
|
||||||
|
|
||||||
In 0.8.0, the MCP Java SDK introduces a session-based architecture where each client connection has its own session. This allows for better isolation between clients and more efficient resource management.
|
|
||||||
|
|
||||||
The `McpServerTransportProvider` is responsible for creating `McpServerTransport` instances for each session, and the `McpServerSession` manages the communication with a specific client.
|
|
||||||
|
|
||||||
### Exchange Objects
|
|
||||||
|
|
||||||
The new exchange objects (`McpAsyncServerExchange` and `McpSyncServerExchange`) provide access to client-specific information and methods. They are passed to handler functions as the first parameter, allowing handlers to interact with the specific client that made the request.
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
The changes in version 0.8.0 represent a significant architectural improvement to the MCP Java SDK. While they require some code changes, the new design provides a more flexible and maintainable foundation for building MCP applications.
|
|
||||||
|
|
||||||
For assistance with migration or to report issues, please open an issue on the GitHub repository.
|
|
||||||
88
mkdocs.yml
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
site_name: MCP Java SDK
|
||||||
|
site_url: https://modelcontextprotocol.github.io/java-sdk/
|
||||||
|
site_description: Java SDK for the Model Context Protocol - standardized integration between AI models and tools
|
||||||
|
repo_url: https://github.com/modelcontextprotocol/java-sdk
|
||||||
|
repo_name: modelcontextprotocol/java-sdk
|
||||||
|
edit_uri: edit/main/docs/
|
||||||
|
|
||||||
|
theme:
|
||||||
|
name: material
|
||||||
|
favicon: images/favicon.svg
|
||||||
|
logo: images/logo-light.svg
|
||||||
|
palette:
|
||||||
|
- scheme: default
|
||||||
|
primary: green
|
||||||
|
accent: green
|
||||||
|
toggle:
|
||||||
|
icon: material/brightness-7
|
||||||
|
name: Switch to dark mode
|
||||||
|
- scheme: slate
|
||||||
|
primary: green
|
||||||
|
accent: green
|
||||||
|
toggle:
|
||||||
|
icon: material/brightness-4
|
||||||
|
name: Switch to light mode
|
||||||
|
features:
|
||||||
|
- navigation.instant
|
||||||
|
- navigation.instant.progress
|
||||||
|
- navigation.tabs
|
||||||
|
- navigation.tabs.sticky
|
||||||
|
- navigation.sections
|
||||||
|
- navigation.top
|
||||||
|
- navigation.path
|
||||||
|
- navigation.indexes
|
||||||
|
- toc.follow
|
||||||
|
- search.suggest
|
||||||
|
- search.highlight
|
||||||
|
- content.code.copy
|
||||||
|
- content.code.annotate
|
||||||
|
- content.tabs.link
|
||||||
|
|
||||||
|
nav:
|
||||||
|
- Getting Started:
|
||||||
|
- Overview: index.md
|
||||||
|
- Quickstart: quickstart.md
|
||||||
|
- MCP Components:
|
||||||
|
- MCP Client: client.md
|
||||||
|
- MCP Server: server.md
|
||||||
|
- Contributing:
|
||||||
|
- Contributing Guide: contributing.md
|
||||||
|
- Documentation: development.md
|
||||||
|
- API Reference: https://javadoc.io/doc/io.modelcontextprotocol.sdk/mcp-core/latest
|
||||||
|
|
||||||
|
markdown_extensions:
|
||||||
|
- admonition
|
||||||
|
- pymdownx.details
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.tabbed:
|
||||||
|
alternate_style: true
|
||||||
|
- pymdownx.highlight:
|
||||||
|
anchor_linenums: true
|
||||||
|
line_spans: __span
|
||||||
|
- pymdownx.inlinehilite
|
||||||
|
- pymdownx.snippets
|
||||||
|
- pymdownx.mark
|
||||||
|
- pymdownx.critic
|
||||||
|
- pymdownx.caret
|
||||||
|
- pymdownx.keys
|
||||||
|
- pymdownx.tilde
|
||||||
|
- pymdownx.emoji:
|
||||||
|
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||||||
|
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||||||
|
- attr_list
|
||||||
|
- md_in_html
|
||||||
|
- tables
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- search
|
||||||
|
|
||||||
|
extra:
|
||||||
|
social:
|
||||||
|
- icon: fontawesome/brands/github
|
||||||
|
link: https://github.com/modelcontextprotocol/java-sdk
|
||||||
|
generator: false
|
||||||
|
|
||||||
|
extra_css:
|
||||||
|
- stylesheets/extra.css
|
||||||