Building a Simple WebMVC MCP Server with Spring and Kotlin
Getting Started
The previous example built a STDIO MCP Server with Spring. This page creates a server using WebMVC transport.
MCP Protocols and Execution Modes
Spring AI MCP Server provides:
- STDIO: Communicates through process standard input and output.
- SSE: Uses Server-Sent Events for real-time server-client communication.
- Streamable HTTP: Extends HTTP communication to stream responses and handle multiple clients with POST and GET requests.
- Stateless Streamable HTTP: Sends requests and streams responses through one HTTP endpoint without retaining session memory between requests, which suits microservice environments.
This example uses Stateless Streamable HTTP.
Changing the MCP Server to WebMVC
Reuse the existing STDIO MCP Server code.
Copying the Existing Code
Copy the previous project or use the GitHub example.
% mv spring-ai-mcp-server spring-ai-mcp-server-webmvc
Build Script
Change the root project name in settings.gradle.kts.
rootProject.name = "spring-ai-mcp-server-webmvc"
Add the WebMVC MCP Server dependency.
dependencies {
...
implementation("org.springframework.ai:spring-ai-starter-mcp-server")
implementation("org.springframework.ai:spring-ai-starter-mcp-server-webmvc")
...
}
Application Configuration
Change application.yml.
spring:
main:
# web-application-type: none
banner-mode: off
ai:
mcp:
server:
name: my-weather-server
version: 0.0.1
protocol: STATELESS
logging:
# pattern:
# console:
file:
name: ./log/spring-ai-starter-mcp-server-webmvc.log
The server configuration adds protocol: STATELESS. Removing the STDIO-only settings starts a daemon web process and allows console logging.
Implementing an MCP Client for Testing
Create HttpClient.kt.
package com.devkuma.ai.mcp.client
import io.modelcontextprotocol.client.McpClient
import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport
import io.modelcontextprotocol.spec.McpSchema.CallToolRequest
fun main() {
val transport = HttpClientStreamableHttpTransport.builder("http://localhost:8080")
.build()
val client = McpClient.sync(transport)
.build()
client.initialize()
client.ping()
val toolsList = client.listTools()
println("Available Tools = $toolsList")
val alertResult = client.callTool(CallToolRequest("get_weather", mapOf("city" to "seoul")))
println("get_weather Response = $alertResult")
client.closeGracefully()
}
HttpClientStreamableHttpTransport receives the HTTP address. Start the MCP Server process before running the client. The client prints the available tools and calls get_weather, just as the STDIO version does.
References
- Spring | Model Context Protocol (MCP)
- GitHub | spring-ai-examples | starter-webmvc-server
- Example code