Artificial Intelligence 10 min read

Build a Model Context Protocol (MCP) Server and Client with Spring Boot 3

This tutorial walks through creating a Model Context Protocol (MCP) server and client using Spring Boot 3, covering dependencies, configuration, tool implementation, registration, and sample code to enable AI models to access external services like weather and IP information.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Build a Model Context Protocol (MCP) Server and Client with Spring Boot 3

1. Introduction

Model Context Protocol (MCP) is a standardized protocol that lets large AI models connect easily to external data sources and tools, much like a universal USB‑C plug.

1.1 What is MCP

MCP abstracts the connection between AI models and external resources, allowing models to read/write files, simulate browser actions, or invoke other tools.

1.2 Why MCP is Needed

Provides a uniform interface so AI models can interact with various tools without custom integration code.

Breaks data silos by unifying access to disparate data sources.

1.3 Java and MCP Architecture

The architecture consists of a client/server layer, a session layer (McpSession), and a transport layer (McpTransport) that handles JSON‑RPC serialization.

MCP Stack Architecture
MCP Stack Architecture

2. Practical Example

2.1 Server Development

Add the following Maven dependencies:

<code>&lt;dependency&gt;
  &lt;groupId&gt;com.alibaba.cloud.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-alibaba-starter&lt;/artifactId&gt;
  &lt;version&gt;1.0.0-M6.1&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-mcp-server-spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-mcp-server-webflux-spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;</code>

Configuration (application.yml):

<code>spring:
  ai:
    dashscope:
      api-key: sk-xxxooo
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
      chat:
        options:
          stream: true
          model: qwen-turbo
---
spring:
  ai:
    mcp:
      server:
        enabled: true
        name: ai_mcp_server
        version: 1.0.0
        type: ASYNC
        sse-message-endpoint: /mcp/message</code>

Implement two external tools:

<code>public class CommonTool {
  @Tool(description = "获取当前天气预报")
  WeatherResponse getCurrentWeather(WeatherRequest request) {
    System.err.printf("准备查询【%s】天气预报%n", request.city());
    RestClient client = RestClient.create(URI.create("https://api.vvhan.com"));
    Map<?,?> result = client.get()
        .uri("/api/weather?city={0}", request.city())
        .retrieve()
        .body(Map.class);
    try {
      return new WeatherResponse(new ObjectMapper().writeValueAsString(result));
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  @Tool(description = "获取IP地址详细信息")
  String getIpAddressInfo(String ip) {
    System.err.printf("准备查询【%s】详细信息%n", ip);
    RestClient client = RestClient.create(URI.create("https://api.vvhan.com"));
    Map<?,?> result = client.get()
        .uri("/api/ipInfo?ip={0}", ip)
        .retrieve()
        .body(Map.class);
    try {
      return new ObjectMapper().writeValueAsString(result);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }
}</code>

Register the tools:

<code>@Configuration
public class ToolsConfig {
  @Bean
  ToolCallbackProvider tools() {
    ToolCallback[] toolCallbacks = ToolCallbacks.from(new CommonTool());
    return ToolCallbackProvider.from(toolCallbacks);
  }
}</code>

Start the server – the console will show the registered tools.

Server start output
Server start output

2.2 Client Development

Add client dependencies:

<code>&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-mcp-client-spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-mcp-client-webflux-spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;com.alibaba.cloud.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-alibaba-starter&lt;/artifactId&gt;
  &lt;version&gt;1.0.0-M6.1&lt;/version&gt;
&lt;/dependency&gt;</code>

Client configuration:

<code>spring:
  ai:
    mcp:
      client:
        enable: true
        name: ai-mcp-client
        initialized: true
        type: ASYNC
        sse:
          connections:
            server1:
              url: http://localhost:8888</code>

Define a controller that uses the injected ToolCallbackProvider and ChatClient :

<code>@RestController
@RequestMapping("/tools")
public class ToolController {
  private final ChatClient chatClient;

  public ToolController(ChatClient.Builder aiClientBuilder, ToolCallbackProvider mcpTools) {
    this.chatClient = aiClientBuilder.defaultTools(mcpTools).build();
  }

  @GetMapping("/weather")
  public ResponseEntity<String> getCurrentWeather(String prompt) {
    System.err.println(prompt);
    String response = this.chatClient.prompt(prompt).call().content();
    return ResponseEntity.ok(response);
  }

  @GetMapping("/ip")
  public ResponseEntity<String> getIpAddressInfo(String prompt) {
    System.err.println(prompt);
    String response = this.chatClient.prompt(prompt).call().content();
    return ResponseEntity.ok(response);
  }
}</code>

When the application starts, the client automatically discovers the two tools (weather and IP lookup) from the server.

Tool discovery output
Tool discovery output

After these steps, you can call the tools via the defined REST endpoints and see the AI model invoking the external services successfully.

Success!

javaMCPSpring BootServerAI integrationClient
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.