SpringとKotlinでシンプルなWebMVC MCP Serverを作成する

MCP ServerへWebMVCを適用します。

はじめに

前回はSpringでSTDIO方式のMCP Serverを作成しました。ここではWebMVC転送方式のサーバーを作成します。

MCPプロトコルと実行モード

Spring AI MCP Serverは次の方式を提供します。

  • STDIO: プロセスの標準入出力で通信します。
  • SSE: Server-Sent Eventsでリアルタイムに通信します。
  • Streamable HTTP: HTTP通信を拡張し、POSTとGETで複数クライアントを処理しながらレスポンスをストリーミングします。
  • Stateless Streamable HTTP: 1つのHTTPエンドポイントでリクエスト送信とレスポンスストリーミングを行い、リクエスト間でセッションを保持しません。マイクロサービス環境に適しています。

この例ではStateless Streamable HTTPを使用します。

MCP ServerをWebMVC方式へ変更する

既存のSTDIO MCP Serverコードを再利用します。

既存コードをコピーする

前回のプロジェクト、またはGitHubの例をコピーします。

% mv spring-ai-mcp-server spring-ai-mcp-server-webmvc

ビルドスクリプト

settings.gradle.ktsのルートプロジェクト名を変更します。

rootProject.name = "spring-ai-mcp-server-webmvc"

WebMVC MCP Serverの依存関係を追加します。

dependencies {
  ...
  implementation("org.springframework.ai:spring-ai-starter-mcp-server")
  implementation("org.springframework.ai:spring-ai-starter-mcp-server-webmvc")
  ...
}

アプリケーション設定

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

サーバー設定へprotocol: STATELESSを追加します。STDIO専用設定を削除すると、デーモンWebプロセスが起動し、コンソールログも確認できます。

テスト用MCP Clientを実装する

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へHTTPアドレスを渡します。クライアントを実行する前にMCP Serverを起動してください。STDIO版と同様に、利用可能なツールを表示し、get_weatherを呼び出します。

参考資料