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. 完なる呼び出しフロー
- サーバー起動:
java -jar /absolute/path/to/climate-server-1.0.0.jarサーバープロセスが起動し、STDIO を介してクライアントからのリクエストを待機します。
- クライアントがリクエストを送信:
クライアント(例:Claude Desktop)は設定されたコマンドを利用してサーバープロセスを起動し、getClimateData メソッドを呼び出します。
- サーバーがリクエストを処理し応答:
サーバーがリクエストを受信し、 ClimateService.getClimateData() メソッドを実行後、STDIO 出力ストリームを通じて結果をクライアントに返します。
- クライアントが結果を受信:
クライアントがサーバーから返された 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 パスは絶対パスを指定し、相対パスを使用しないようにします。