How to Use Spring AI MCP to Let Large Language Models Call Your Java APIs

This article walks through the complete process of building a Spring AI MCP server and client in Java, covering protocol layers, Maven setup, configuration, tool definition with @Tool, bean registration, client integration, common pitfalls, and the language‑agnostic benefits of the MCP protocol.

Coder Circle
Coder Circle
Coder Circle
How to Use Spring AI MCP to Let Large Language Models Call Your Java APIs

What is MCP?

MCP (Model Context Protocol) standardizes interaction between AI models and external tools or resources. It is organized into three layers:

Client/Server layer – MCP Client manages connections, protocol negotiation, capability discovery, and tool calls; MCP Server exposes tools/resources and manages client connections.

Session layer – Handles communication mode and maintains connection state.

Transport layer – Performs message transport and JSON‑RPC serialization; supports STDIO, HTTP/SSE, and Streamable‑HTTP.

Spring AI MCP Support

Server : Dependency spring-ai-starter-mcp-server-webflux. WebFlux implementation, supports SSE, Streamable‑HTTP, stateless.

Client : Dependency spring-ai-starter-mcp-client-webflux. WebFlux implementation, supports SSE and Streamable‑HTTP.

Building the MCP Server

Project structure

java-ai-mcp-server/
├── pom.xml
└── src/main/
    ├── java/com/why/
    │   ├── McpServerApplication.java
    │   └── mcp/server/tool/WeatherService.java
    └── resources/
        └── application.properties

Maven dependencies

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.5</version>
</parent>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>2.0.0-M4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

application.properties

server.port=9000
spring.ai.mcp.server.annotation-scanner.enabled=true
spring.ai.mcp.server.name=java-ai-mcp-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.type=sync
spring.ai.mcp.server.protocol=sse

Enabling annotation-scanner.enabled=true allows automatic discovery of methods annotated with @Tool.

Define an MCP tool

@Service
public class WeatherService {
    private static final String BASE_URL = "https://restapi.amap.com/v3/weather/weatherInfo";
    private final RestClient restClient = RestClient.builder().baseUrl(BASE_URL).build();

    @Tool(description = "Get weather for a city")
    public String getWeather(String cityCode) {
        return restClient.get()
            .uri(uriBuilder -> uriBuilder
                .queryParam("key", "YOUR_GAODE_API_KEY")
                .queryParam("city", cityCode)
                .build())
            .retrieve()
            .body(String.class);
    }
}

Register the tool

@SpringBootApplication
public class McpServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(McpServerApplication.class, args);
    }

    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder()
            .toolObjects(weatherService)
            .build();
    }
}

After launching, the server is reachable at http://localhost:9000/mcp-server.

Building the MCP Client

Project structure

java-ai-mcp-client/
├── pom.xml
└── src/main/
    ├── java/com/why/
    │   ├── McpClientApplication.java
    │   └── controller/ChatClientController.java
    └── resources/
        └── application.properties

Maven dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-minimax</artifactId>
</dependency>

application.properties

server.port=9001
spring.ai.minimax.base-url=api.minimax.chat
spring.ai.minimax.api-key=YOUR_API_KEY
spring.ai.minimax.chat.options.model=minimax-m2.7

spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.name=java-ai-mcp-client
spring.ai.mcp.client.version=1.0.0
spring.ai.mcp.client.type=sync
spring.ai.mcp.client.sse.connections.java-ai-mcp-server.url=http://localhost:9000/mcp-server

The client property sse.connections.xxx.url must match the server’s spring.ai.mcp.server.name value.

Use MCP tools in a controller

@Slf4j
@RestController
@RequestMapping("minimax")
public class ChatClientController {
    @Resource
    private MiniMaxChatModel miniMaxChatModel;

    @Resource
    private SyncMcpToolCallbackProvider mcpToolCallbackProvider;

    @GetMapping(value = "/stream/event", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamEvent(@RequestParam("question") String question) {
        ChatClient chatClient = ChatClient.builder(miniMaxChatModel).build();
        var toolCallbacks = mcpToolCallbackProvider.getToolCallbacks();
        return chatClient.prompt(question)
            .toolCallbacks(toolCallbacks)
            .stream()
            .content();
    }
}

Common Pitfalls

Protocol mismatch : Server and client must use the same transport protocol (e.g., both SSE). Mismatched protocols cause 400 Bad Request or 404 Not Found errors.

Tool class not scanned : Methods annotated with @Tool must reside in a Spring bean (e.g., a class annotated with @Service) so that the annotation scanner can register them.

Callback creation : Do not instantiate SyncMcpToolCallback manually. Obtain registered callbacks via SyncMcpToolCallbackProvider.getToolCallbacks() for stability.

Summary

Add @Tool to any method you want to expose as an MCP tool.

Configure matching Server and Client properties (name, version, protocol, URL) so that the client can locate the server.

Inject the discovered tool callbacks into a ChatClient using SyncMcpToolCallbackProvider.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MCPSpring AIAI integrationtool callingspring-boot
Coder Circle
Written by

Coder Circle

Limited experience, continuously learning and summarizing knowledge, aiming to join a top tech company.

0 followers
Reader feedback

How this landed with the community

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.