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>
This commit is contained in:
Christian Tzolov 2026-02-15 19:00:21 +01:00 • committed by GitHub
commit a1048b9342
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 2130 additions and 328 deletions

27
.github/workflows/docs.yml vendored Normal file
View 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
View file

@ -57,6 +57,9 @@ node_modules/
package-lock.json
package.json
### MkDocs ###
site/
### Other ###
.antlr/
.profiler/

106
docs/CONTRIBUTING.md Normal file
View 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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 67 KiB

12
docs/images/logo-dark.svg Normal file
View 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

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 75 KiB

131
docs/index.md Normal file
View 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:
![MCP Stack Architecture](images/mcp-stack.svg)
- **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.
![Java MCP Client Architecture](images/java-mcp-client-architecture.jpg)
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.
![Java MCP Server Architecture](images/java-mcp-server-architecture.jpg)
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
View 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
View 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.

View 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;
}

View file

@ -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
View 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