Spring-MCP を利用した STDIO モード開発ガイド

1. STDIO モードの基本仕組み

  • 通信方式:標準入力出力ストリーム (stdin/stdout) を通じてプロセス間通信を実現。ローカルでのデバッグや IDE、AI エージェントフレームワーク (Claude Desktop、Cursor 等) への組み込みに適しています。
  • メリット
    • 軽量性:ネットワークポートを必要とせず、リソース消費を最小限に抑えます。
    • 迅速な検証:コマンドラインから直接ツールメソッドをテスト可能です。
    • クロスプラットフォーム:Windows、Linux、macOS に対応しています。
  • 依存管理:MCP サーバー用のスターターを導入し、Web サービスを明示的に無効化します。

2. サーバー側の開発設定

1. 開発環境の準備

  • JDK:17 以上
  • ビルドツール:Maven 3.6+ または Gradle 7.0+ を利用します。
  • Spring Boot:3.x 系列を使用します。

2. リポジトリの依存関係設定

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId>
    <version>1.0.0-M8</version> <!-- 最新安定版を利用 -->
</dependency>

3. application.yml 設定

spring:
  main:
    web-application-type: none  # Web サービスを無効化
    banner-mode: off           # 起動時バナーを表示しない
  ai:
    mcp:
      server:
        name: climate-server    # サービス名(ユニークな識別子)
        version: 1.0.0         # サービスバージョン
        type: SYNC             # 同期通信モード
        stdio: true            # STDIO モードを有効化

4. ツールメソッドの実装

以下の例では、@Tool アノテーションを用いて外部から利用可能なツールを定義しています。Spring AI が自動的に MCP プロトコルに変換します。

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;

@Service
public class ClimateService {
    @Tool(description = "気象データを取得します")
    public String getClimateData(
        @ToolParam(description = "高度") String altitude,
        @ToolParam(description = " longitude ") String longitude
    ) {
        // 気象APIを模擬的に呼び出す
        return String.format("現在の温度: 22℃, 天気: 曇り (高度: %s, 経度: %s)", altitude, longitude);
    }
}

5. アプリケーションの起動クラス

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

3. クライアント側の呼び出し設定

1. クライアントがサーバープロセスを起動する方法

クライアントアプリケーションは、サーバーJARをコマンドラインから起動し、絶対パスを指定します。

# クライアント設定例(Claude Desktop 設定ファイル)
mcpServers:
  climate-server:
    command: "java"
    args:
      - "-jar"
      - "/absolute/path/to/climate-server-1.0.0.jar"  # サーバーJARの絶対パス

2. クライアントからのツール呼び出し(Spring AI Client を例に)

import org.springframework.ai.mcp.client.McpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ClimateClient {
    @Autowired
    private McpClient mcpClient;

    public String invokeClimateTool(String altitude, String longitude) {
        // ClimateService.getClimateData メソッドを呼び出す
        var result = mcpClient.invoke(
            "getClimateData",              // 呼び出すツール名
            List.of(altitude, longitude)   // 传递的参数列表
        );
        return result.getOutput();         // 取得した結果を返す
    }
}

4. 完なる呼び出しフロー

  1. サーバー起動
    java -jar /absolute/path/to/climate-server-1.0.0.jar

    サーバープロセスが起動し、STDIO を介してクライアントからのリクエストを待機します。

  2. クライアントがリクエストを送信

    クライアント(例:Claude Desktop)は設定されたコマンドを利用してサーバープロセスを起動し、getClimateData メソッドを呼び出します。

  3. サーバーがリクエストを処理し応答

    サーバーがリクエストを受信し、 ClimateService.getClimateData() メソッドを実行後、STDIO 出力ストリームを通じて結果をクライアントに返します。

  4. クライアントが結果を受信

    クライアントがサーバーから返された JSON 形式のデータを解析し、天気情報を取り出します。

5. デバッグと検証

1. ログの確認

  • サーバーログ:ツール呼び出しのログが表示されることを確認します。
  • クライントログ:リクエスト送信とレスポンス受信の状態を確認します。

2. 手動検証

curl または MCP プロトコル対応のデバッガーツール(例:npx @modelcontextprotocol/inspector)を利用してリクエストを模擬します。

echo '{"id": "1", "method": "getClimateData", "params": ["39.9042", "116.4074"]}' | java -jar climate-server-1.0.0.jar

3. 常見問題解決

  • ポート衝突:STDIO モードではポート設定が不要です。 server.port 設定がある場合、起動に失敗します。
  • ツール未登録:@Tool アノテーションが正しく配置されているか、または MCP サーバーのログで登録状況を確認します。
  • パスエラー:クライアント側の JAR パスは絶対パスを指定し、相対パスを使用しないようにします。

タグ: Spring-MCP STDIO MCPプロトコル プロセス間通信 クロスプラットフォーム

6月14日 17:12 投稿