(WIP) Base for Java docs (#125)

* Base for Java docs

* docs(java): Migrate Java-SDK/docs

Add visual documentation for Java SDK architecture:

- PlantUML class diagrams showing core components and relationships
- Client and server architecture diagrams
- Stack architecture overview
- Generated UML class diagram with detailed implementation structure

* Add Java Client and Server quickstarts

* reorder, redact, correct java-sdk docs

Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>

* updated updates.mdx

* fix docs.json

---------

Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
Co-authored-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
Co-authored-by: David Soria Parra <davidsp@anthropic.com>
This commit is contained in:
Zachary Lee 2025-02-14 09:43:35 -05:00 • committed by GitHub
commit 904083c681
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 1780 additions and 5 deletions

View file

@ -401,6 +401,120 @@ If you see:
</Tab>
<Tab title="Java">
<Note>
This is a quickstart demo based on Spring AI MCP auto-configuraiton and boot starters.
To learn how to create sync and async McpClients programatically consult the [Java SDK Client guid](TODO: add URL)
</Note>
This example demonstrates how to build an interactive chatbot that combines Spring AI's Model Context Protocol (MCP) with the [Brave Search MCP Server](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search). The application creates a conversational interface powered by Anthropic's Claude AI model that can perform internet searches through Brave Search, enabling natural language interactions with real-time web data.
[You can find the complete code for this tutorial here.](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/brave-chatbot)
## System Requirements
Before starting, ensure your system meets these requirements:
- Java 17 or higher
- Maven 3.6+
- npx package manager
- Anthropic API key (Claude)
- Brave Search API key
## Setting Up Your Environment
1. Install npx (Node Package eXecute):
First, make sure to install [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
and then run:
```bash
npm install -g npx
```
2. Clone the repository:
```bash
git clone https://github.com/spring-projects/spring-ai-examples.git
cd model-context-protocol/brave-chatbot
```
3. Set up your API keys:
```bash
export ANTHROPIC_API_KEY='your-anthropic-api-key-here'
export BRAVE_API_KEY='your-brave-api-key-here'
```
4. Build the application:
```bash
./mvnw clean install
```
5. Run the application using Maven:
```bash
./mvnw spring-boot:run
```
<Warning>
Make sure you keep your `ANTHROPIC_API_KEY` and `BRAVE_API_KEY` keys secure!
</Warning>
## How it Works
The application integrates Spring AI with the Brave Search MCP server through several components:
### MCP Client Configuration
1. Required dependencies in pom.xml:
```xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-anthropic-spring-boot-starter</artifactId>
</dependency>
```
2. Application properties (application.properties):
```properties
spring.ai.mcp.client.stdio.enabled=true
spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-servers-config.json
spring.ai.anthropic.api-key=${ANTHROPIC_API_KEY}
```
This acivates the `spring-ai-mcp-spring-boot-starter` to create one or more `McpClient`s based on the provided server configuration.
3. MCP Server Configuration (mcp-servers-config.json):
```json
{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-brave-search"
],
"env": {
"BRAVE_API_KEY": "<PUT YOUR BRAVE API KEY>"
}
}
}
}
```
### Chat Implementation
The chatbot is implemented using Spring AI's ChatClient with MCP tool integration:
```java
var chatClient = chatClientBuilder
.defaultSystem("You are useful assistant, expert in AI and Java.")
.defaultTools((Object[]) mcpToolAdapter.toolCallbacks())
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
.build();
```
</Tab>
</Tabs>
## Next steps

View file

@ -739,6 +739,305 @@ This tells Claude for Desktop:
2. Launch it by running `node /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/index.js`
Save the file, and restart **Claude for Desktop**.
</Tab>
<Tab title='Java'>
Let's get started with building our weather server!
[You can find the complete code for what we'll be building here.](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/mcp-weather-server-quickstart)
### System requirements
- Java 17 or higher installed.
- [Spring Boot 3.4](https://docs.spring.io/spring-boot/installing.html) or higher
### Set up your environment
Use the [Spring Initizer](https://start.spring.io/) to bootstrat a the [application skeleton](https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.4.2&packaging=jar&jvmVersion=17&groupId=com.example.mcp.server&artifactId=weather&name=weather&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.mcp.server.weather&dependencies=spring-ai-anthropic,webflux).
You will need to add the following dependencies:
<Tabs>
<Tab title="Maven">
```xml
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
```
</Tab>
<Tab title="Gradle">
```groovy
dependencies {
implementation platform("org.springframework.ai:spring-ai-mcp-spring-boot-starter")
implementation platform("org.springframework:spring-web")
implementation platform("org.springframework.boot:spring-boot-starter")
}
```
</Tab>
</Tabs>
Then configure your application by setting the applicaiton properties:
<CodeGroup>
```bash application.properties
spring.main.bannerMode=off
logging.pattern.console=
spring.ai.mcp.server.enabled=true
```
```yaml application.yml
logging:
pattern:
console:
spring:
main:
banner-mode: off
ai:
mcp:
server:
enabled: true
```
</CodeGroup>
Now let's dive into building your server.
## Building your server
### Weather Service
Let's implement a weather service that uses a REST client to query the data from the National Weather Service API:
```java
@Service
public class WeatherService {
private final RestClient restClient;
public WeatherService() {
this.restClient = RestClient.builder()
.baseUrl("https://api.weather.gov")
.defaultHeader("Accept", "application/geo+json")
.defaultHeader("User-Agent", "WeatherApiClient/1.0 (your@email.com)")
.build();
}
public record Points(Props properties) {
public record Props(String forecast) { }
}
public record Forecast(Props properties) {
public record Props(List<Period> periods) {}
public record Period(Integer number, String name, String startTime, String endTime, Boolean isDayTime, Integer temperature, String temperatureUnit, String temperatureTrend, Map probabilityOfPrecipitation, String windSpeed, String windDirection, String icon, String shortForecast, String detailedForecast) {}
}
public record Alert(List<Feature> features) {
public record Feature(Properties properties) {}
public record Properties(String event, String areaDesc, String severity, String description, String instruction) {}
}
// ......
}
```
The `@Service` annotation with auto-register the service in your applicaiton context.
### Implementing tool execution
The tool execution handler is responsible for actually executing the logic of each tool.
The Spring AI `@Tool` annotation, making it easy to create and maintain MCP tools:
```java
@Tool(description = "Get weather forecast for a specific latitude/longitude")
public String getWeatherForecastByLocation(double latitude, double longitude) {
var points = restClient.get()
.uri("/points/{latitude},{longitude}", latitude, longitude)
.retrieve()
.body(Points.class);
var forecast = restClient.get().uri(points.properties().forecast()).retrieve().body(Forecast.class);
String forecastText = forecast.properties().periods().stream().map(p -> {
return String.format("""
%s:
Temperature: %s %s
Wind: %s %s
Forecast: %s
""", p.name(), p.temperature(), p.temperatureUnit(), p.windSpeed(), p.windDirection(),
p.detailedForecast());
}).collect(Collectors.joining());
return forecastText;
}
@Tool(description = "Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)")
public String getAlerts(String state) {
Alert alert = restClient.get().uri("/alerts/active/area/{state}", state).retrieve().body(Alert.class);
return alert.features()
.stream()
.map(f -> String.format("""
Event: %s
Area: %s
Severity: %s
Description: %s
Instructions: %s
""", f.properties().event(), f.properties.areaDesc(), f.properties.severity(),
f.properties.description(), f.properties.instruction()))
.collect(Collectors.joining("\n"));
}
```
### Build your Boot Applicaiton
```java
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public List<ToolCallback> weatherTools(WeatherService weatherService) {
return List.of(ToolCallbacks.from(weatherService));
}
}
```
Uses the the `ToolCallbacks.from(...)` utils to convert the `@Tools` into actionalble callbackes used by the MCP server.
### Running the server
Finally, let's build and run the server:
```bash
./mvnw clean install
java -jar model-context-protocol/mcp-weather-server-quickstart/target/mcp-weather-server-quickstart-0.0.1-SNAPSHOT.jar
```
Let's now test your server from an existing MCP host, Claude for Desktop.
## Testing your server with Claude for Desktop
<Note>
Claude for Desktop is not yet available on Linux. Linux users can proceed to the [Building a client](/quickstart/client) tutorial to build an MCP client that connects to the server we just built.
</Note>
First, make sure you have Claude for Desktop installed. [You can install the latest version
here.](https://claude.ai/download) If you already have Claude for Desktop, **make sure it's updated to the latest version.**
We'll need to configure Claude for Desktop for whichever MCP servers you want to use. To do this, open your Claude for Desktop App configuration at `~/Library/Application Support/Claude/claude_desktop_config.json` in a text editor. Make sure to create the file if it doesn't exist.
For example, if you have [VS Code](https://code.visualstudio.com/) installed:
<Tabs>
<Tab title="MacOS/Linux">
```bash
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
```
</Tab>
<Tab title="Windows">
```powershell
code $env:AppData\Claude\claude_desktop_config.json
```
</Tab>
</Tabs>
You'll then add your servers in the `mcpServers` key. The MCP UI elements will only show up in Claude for Desktop if at least one server is properly configured.
In this case, we'll add our single weather server like so:
<Tabs>
<Tab title="MacOS/Linux">
```json java
{
"mcpServers": {
"spring-ai-mcp-weather": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.transport=STDIO",
"-jar",
"/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-server-quickstart-0.0.1-SNAPSHOT.jar"
]
}
}
}
```
</Tab>
<Tab title="Windows">
```json java
{
"mcpServers": {
"spring-ai-mcp-weather": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.transport=STDIO",
"-jar",
"C:\\ABSOLUTE\\PATH\\TO\\PARENT\\FOLDER\\weather\\mcp-weather-server-quickstart-0.0.1-SNAPSHOT.jar"
]
}
}
}
```
</Tab>
</Tabs>
<Note>
Make sure you pass in the absolute path to your server.
</Note>
This tells Claude for Desktop:
1. There's an MCP server named "my-weather-server"
2. To launch it by running `java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-server-quickstart-0.0.1-SNAPSHOT.jar`
Save the file, and restart **Claude for Desktop**.
## Testing your server with Java client
Use the `McpClient` to connect to the server:
```java
var stdioParams = ServerParameters.builder("java")
.args("-jar", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-server-quickstart-0.0.1-SNAPSHOT.jar")
.build();
var stdioTransport = new StdioClientTransport(stdioParams);
var mcpClient = McpClient.sync(stdioTransport).build();
mcpClient.initialize();
ListToolsResult toolsList = mcpClient.listTools();
CallToolResult weather = mcpClient.callTool(
new CallToolRequest("getWeatherForecastByLocation",
Map.of("latitude", "47.6062", "longitude", "-122.3321")));
CallToolResult alert = mcpClient.callTool(
new CallToolRequest("getAlerts", Map.of("state", "NY")));
mcpClient.closeGracefully();
```
## More Java MCP Server examples
The [mcp-webflux-server-starter](https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/mcp-webflux-server-starter) demonstrates how to create a MCP server using SSE transport.
It showcases how to define and register MCP Tools, Resources, and Prompts, using the Spring Boot's auto-configuration capabilities.
</Tab>
</Tabs>