mcpField
J
java-mcp-server-generator

java-mcp-server-generator

github.com/github開発40.5k8.8k 回インストール今日更新
リポジトリ

java-mcp-server-generator について

公式のMCP Java SDK 2.xを使ったJava MCPサーバーの作成を支援するスキルです。プロジェクト作成、実装、子プロセスでのテスト、ビルド、クライアント設定に加え、SDK固有の注意点も扱います。

主な機能

  1. 01Mavenプロジェクトのひな型作成
  2. 02Java SDK 2.xでのサーバー実装
  3. 03ツールスキーマと結果の検証
  4. 04stdioを使った子プロセステスト
  5. 05ビルドとクライアント設定の案内
  6. 06SDK移行とトランスポートの注意点

活用シーン

  1. 01依頼されたツールを備えるJava MCPサーバーの生成
  2. 02SDKクライアントを使ったstdio動作のテスト
  3. 03VS CodeまたはClaude Desktopからのサーバー起動設定

MCP 対応

公式Java SDK 2.xを使ってMCPサーバーを作成し、デフォルトのトランスポートとしてstdioを案内します。VS Code、Claude Desktop、Streamable HTTP向けのクライアント設定も説明します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/github/awesome-copilot --skill java-mcp-server-generator

インストール後、Claude Code で/java-mcp-server-generatorを入力して読み込まれたか確認します。

同梱ファイルreferences/gradle.mdreferences/streamable-http.md

詳細

Java MCP サーバー生成ツール

公式のMCP Java SDK 2.xを使用して、JavaでModel Context Protocol(MCP)サーバーを作成します。SDK 2.0.xは、MCP仕様のリビジョン2025-11-25と、それ以前のリビジョンをサポートしています。SDK 3.xでは、リビジョン2026-07-28が追加される予定です。

ワークフロー

このチェックリストをコピーして、進捗を記録してください。

  • ステップ 1:プロジェクトを作成します。
  • ステップ 2:サーバーを実装します。
  • ステップ 3:テストを実装します。
  • ステップ 4:テストに合格するまでビルドします。
  • ステップ 5:クライアントを設定します。
ステップ 1:プロジェクトを作成する

デフォルトではMavenを使用します。プロジェクトがGradleを使用する場合、またはユーザーがGradleを希望する場合は、references/gradle.mdを読んでください。ステップ 1、ステップ 4、ステップ 5でその内容を使用します。

次の構成を作成します。

project-name/
├── pom.xml
└── src/
    ├── main/java/com/example/McpServerApp.java
    └── test/java/com/example/McpServerAppTest.java

pom.xmlを記述します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>mcp-server-demo</artifactId>
  <version>0.1.0</version>

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.modelcontextprotocol.sdk</groupId>
        <artifactId>mcp-bom</artifactId>
        <version>2.0.1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>6.1.3</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>io.modelcontextprotocol.sdk</groupId>
      <artifactId>mcp</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>2.0.17</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.6.2</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <createDependencyReducedPom>false</createDependencyReducedPom>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.example.McpServerApp</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
  • mcpアーティファクトには、mcp-coreとJackson 3のJSONマッパーmcp-json-jackson3が含まれています。
  • slf4j-simpleは、SDKのログをstderrに出力します。
  • shadeプラグインは、すべての依存関係を含む実行可能JARを1つ作成します。
ステップ 2:サーバーを実装する

次のテンプレートから始めます。

package com.example;

import java.util.List;
import java.util.Map;

import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures.SyncToolSpecification;
import io.modelcontextprotocol.server.transport.StdioServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
import io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;
import io.modelcontextprotocol.spec.McpSchema.Tool;

public final class McpServerApp {

    static SyncToolSpecification divideTool() {
        Tool tool = Tool.builder("divide", Map.of(
                        "type", "object",
                        "properties", Map.of(
                                "a", Map.of("type", "number", "description", "Dividend"),
                                "b", Map.of("type", "number", "description", "Divisor")),
                        "required", List.of("a", "b")))
                .description("Divide a by b.")
                .build();

        return SyncToolSpecification.builder()
                .tool(tool)
                .callHandler((exchange, request) -> {
                    double a = ((Number) request.arguments().get("a")).doubleValue();
                    double b = ((Number) request.arguments().get("b")).doubleValue();
                    if (b == 0) {
                        return CallToolResult.builder().addTextContent("b must not be zero.").isError(true).build();
                    }
                    return CallToolResult.builder().addTextContent(String.valueOf(a / b)).build();
                })
                .build();
    }

    public static void main(String[] args) {
        McpServer.sync(new StdioServerTransportProvider(McpJsonDefaults.getMapper()))
                .serverInfo("demo", "0.1.0")
                .capabilities(ServerCapabilities.builder().tools(false).build())
                .tools(divideTool())
                .build();
    }
}

次に、ユーザーのリクエストに合わせてテンプレートを変更します。

  1. divideTool()を、ユーザーが求めるツールに置き換えます。ツールごとにメソッドを1つ作成します。
  2. 各ツールにJSON SchemaのinputSchemaとdescriptionを設定します。説明には、モデルがそのツールをいつ使用するかを記述します。
  3. クライアントが機械可読データを必要とする場合は、ツールに.outputSchema(Map)を追加します。CallToolResult.builder().structuredContent(map)でデータを返します。古いクライアント向けに、同じデータをテキストコンテンツとしても追加します。
  4. 読み取り専用のツールには.annotations(ToolAnnotations.builder().readOnlyHint(true).build())を設定します。破壊的なツールにはdestructiveHint(true)を使用します。
  5. ユーザーが求めた場合にのみ、リソース、リソーステンプレート、プロンプトを追加します。また、ServerCapabilitiesでそれらを有効にします。

デフォルトではstdioを使用します。ユーザーがリモートサーバー、HTTPサーバー、またはSpring Bootを求めた場合にのみ、references/streamable-http.mdを読んでください。

ステップ 3:テストを実装する

テストではサーバーをサブプロセスとして起動し、SDKクライアントで接続します。各ツールと各エラー結果のテストを作成します。

package com.example;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.nio.file.Path;
import java.util.Map;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.client.transport.ServerParameters;
import io.modelcontextprotocol.client.transport.StdioClientTransport;
import io.modelcontextprotocol.json.McpJsonDefaults;
import io.modelcontextprotocol.spec.McpSchema.CallToolRequest;
import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
import io.modelcontextprotocol.spec.McpSchema.TextContent;

class McpServerAppTest {

    private static McpSyncClient client;

    @BeforeAll
    static void startServer() {
        String java = Path.of(System.getProperty("java.home"), "bin", "java").toString();
        ServerParameters server = ServerParameters.builder(java)
                .args("-cp", System.getProperty("java.class.path"), McpServerApp.class.getName())
                .build();
        client = McpClient.sync(new StdioClientTransport(server, McpJsonDefaults.getMapper())).build();
        client.initialize();
    }

    @AfterAll
    static void stopServer() {
        client.close();
    }

    @Test
    void divide() {
        CallToolResult result = client.callTool(
                CallToolRequest.builder("divide").arguments(Map.of("a", 6, "b", 3)).build());
        assertEquals("2.0", ((TextContent) result.content().get(0)).text());
    }

    @Test
    void divideByZero() {
        CallToolResult result = client.callTool(
                CallToolRequest.builder("divide").arguments(Map.of("a", 1, "b", 0)).build());
        assertTrue(result.isError());
        assertTrue(((TextContent) result.content().get(0)).text().contains("must not be zero"));
    }
}
  • テストでは、Mavenの実行に使用されるJDKのjavaコマンドを使用します。PATHにあるjavaコマンドは使用しないでください。
  • テストでは、実際のstdioトランスポートと実際のJSON-RPCメッセージを使用します。
ステップ 4:テストに合格するまでビルドする
  1. mvn verifyを実行します。このコマンドはコードをコンパイルし、テストを実行して、target/mcp-server-demo-0.1.0.jarを作成します。
  2. テストが失敗した場合は、エラーを確認します。サーバーまたはテストを修正します。
  3. mvn verifyを再度実行します。
  4. ビルドが成功するまで続けます。
ステップ 5:クライアントを設定する

VS Codeの場合は、.vscode/mcp.jsonを記述します。

{
  "servers": {
    "demo": {
      "type": "stdio",
      "command": "java",
      "args": ["-jar", "/absolute/path/to/project/target/mcp-server-demo-0.1.0.jar"]
    }
  }
}

Claude Desktopの場合は、同じcommandとargsをclaude_desktop_config.jsonのmcpServersキーの下に記述します。

HTTPサーバーの場合は、references/streamable-http.mdにあるクライアント設定を使用します。

次の情報をユーザーに伝えます。

  • java -jar target/mcp-server-demo-0.1.0.jarでstdioサーバーが起動します。サーバーはstdinでホストからの接続を待機します。SDKのログはstderrに出力されます。
  • サーバーを手動でテストするには、同じコマンドでMCP Inspectorを起動します。InspectorはNode.jsを使用します。

注意点

SDK 2.x では、SDK 0.x および 1.x のパターンの多くが変更されています。以前のバージョンの例をそのまま使わないでください。詳細については、移行ガイドをお読みください。

  • 必須フィールドを先に受け取るビルダーを使用してください:Tool.builder(name, inputSchema)、Resource.builder(uri, name)、Prompt.builder(name)、TextContent.builder(text)、および ReadResourceResult.builder(contents)。引数を取らないビルダーは非推奨です。
  • 必須フィールドに null を指定してはいけません。null 値を指定すると IllegalArgumentException が発生します。
  • ツール名は1~128文字で、使用できる文字は英字、数字、_、-、. です。サーバービルダーは、不正な名前を IllegalArgumentException で拒否します。実行時の addTool() では名前をチェックしません。
  • inputSchema と outputSchema は Map<String, Object> の値です。JsonSchema レコードは非推奨です。
  • サーバーは、build() または addTool() を呼び出したときに各スキーマを JSON Schema 2020-12 に照らして検証します。不正なスキーマを指定すると IllegalArgumentException が発生します。
  • SDK はツールの引数を inputSchema に照らして検証します。また、structuredContent を outputSchema に照らして検証します。検証に失敗すると、クライアントには isError が true に設定されたツール結果が返されます。そのため、ハンドラーが受け取るのは有効な引数のみです。
  • ツールに outputSchema がある場合は、成功した結果ごとに structuredContent を返してください。返さない場合、SDK は isError が true に設定されたツール結果を返します。
  • モデルに読み取らせるエラーには、isError(true) を指定した CallToolResult を返してください。
  • ツールの失敗時に例外や McpError をスローしないでください。クライアントにはツール結果ではなく、JSON-RPC エラーが返されます。多くのホストでは、このエラーはモデルに表示されません。
  • stdio サーバーでは、stdout はプロトコルの通信チャネルです。System.out.println() を呼び出さないでください。
  • SLF4J で stderr にログを出力してください。Logback のデフォルトのコンソールアペンダーは stdout に書き込みます。Logback を使用する場合は、出力先を System.err に設定してください。
  • Spring トランスポートは Spring AI 2.0 以降(グループ org.springframework.ai)に移行しました。io.modelcontextprotocol.sdk:mcp-spring-* アーティファクトは使用しないでください。
  • 非推奨の SSE トランスポートは使用しないでください。リモートサーバーには Streamable HTTP を使用してください。
  • 2026-07-28 の改訂により、以下の機能は非推奨になりました(SEP-2577)。新しいサーバーには追加しないでください:
    • サンプリング(exchange.createMessage()):LLM プロバイダーの API を直接呼び出してください。
    • プロトコルロギング(exchange.loggingNotification()):SLF4J を使用してください。
    • ルート(exchange.listRoots()):ツールの引数、リソース URI、またはサーバー設定からパスを取得してください。

コメント