AI/MCP

MCP(Java) 예제 따라 하기

silbaram 2025. 4. 21. 11:45
728x90

1. MCP란 무엇인가?

  • LLM 호스트(Claude Desktop, IDE 플러그인 등)와 도구(툴) 서버 사이의 JSON‑RPC 2.0 프로토콜
  • 툴 정의 (+JSON Schema)
    • 파라미터 타입·설명, 결과 타입 포함 → 호스트가 UI·검증 자동화
  • 전송(Transport)
    • STDIO : 부모‑자식 프로세스 간 파이프
    • SSE(Server‑Sent Events) : HTTP 스트림

2. 프로젝트 골격

📁 mcp-add
 ├─ build.gradle.kts         # Kotlin DSL
 ├─ settings.gradle.kts
 └─ src
     └─ main/java/com/example/mcp
         ├─ AddTool.java     # 툴 로직
         └─ Main.java        # 서버 부트스트랩

2‑1 build.gradle.kts

plugins {
    id("java")
    id("application")
    id("com.github.johnrengelman.shadow") version "8.1.1"
}

group = "com.example"
version = "1.0.0"

java {
    sourceCompatibility = JavaVersion.VERSION_21
}

repositories { mavenCentral() }

val mcpVersion = "0.9.0"  // 2025‑03 최신

dependencies {
    implementation(platform("io.modelcontextprotocol.sdk:mcp-bom:$mcpVersion"))
    implementation("io.modelcontextprotocol.sdk:mcp")

    testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
}

application {
    mainClass.set("com.example.mcp.Main")
}
  • mcp-bom 으로 SDK 하위 모듈 버전을 통일
  • Shadow 플러그인 → ./gradlew shadowJar 로 Fat‑JAR 생성

3. AddTool.java – 핵심 로직

package com.example.mcp;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.exchange.McpSyncServerExchange;
import io.modelcontextprotocol.spec.McpSchema;

import java.util.Map;

public class AddTool {
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /** 3‑1 툴 정의(JSON Schema 포함) */
    public McpSchema.Tool definition() {
        String schemaJson = """
            {
              "type": "object",
              "properties": {
                "a": { "type": "number", "description": "첫 번째 수" },
                "b": { "type": "number", "description": "두 번째 수" }
              },
              "required": ["a", "b"]
            }""";
        return new McpSchema.Tool("add", "두 숫자를 더합니다.", schemaJson);
    }

    /** 3‑2 실제 계산 후 CallToolResult 빌드 */
    private McpSchema.CallToolResult doAdd(Map<String, Object> args) {
        double a = ((Number) args.get("a")).doubleValue();
        double b = ((Number) args.get("b")).doubleValue();
        return McpSchema.CallToolResult.builder()
                .addTextContent(String.valueOf(a + b))
                .build();
    }

    /** 3‑3 서버 등록용 스펙 */
    public McpServerFeatures.SyncToolSpecification registration() {
        return new McpServerFeatures.SyncToolSpecification(
                definition(),
                (McpSyncServerExchange exch, Map<String,Object> map) -> doAdd(map)
        );
    }
}

주요 포인트

라인 설명

schemaJson 입력 파라미터를 JSON Schema 로 선언 → 호스트가 유효성 검사 & UI 자동화
CallToolResult SDK 0.8+부터 결과 타입이 JsonNode → CallToolResult 로 변경
registration() SyncToolSpecification (정의 + 람다) 반환 → 서버에 등록

4. Main.java – 서버 부트스트랩

package com.example.mcp;

import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.server.transport.StdioServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema;

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) throws Exception {
        var transportProvider = new StdioServerTransportProvider();

        AddTool addTool = new AddTool();

        McpSyncServer server = McpServer
                .sync(transportProvider)
                .serverInfo(new McpSchema.Implementation("mcp-add", "1.0.0"))
                .tools(addTool.registration())
                .build();

        Runtime.getRuntime().addShutdownHook(new Thread(server::closeGracefully));

        new CountDownLatch(1).await(); // 메인 스레드 영구 대기
    }
}

5. 실행 & 테스트

5‑1 Gradle CLI

./gradlew run              # STDIO 서버 실행
./gradlew shadowJar        # Fat‑JAR 생성

5‑2 JSON‑RPC 직접 호출

echo '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"add","arguments":{"a":3,"b":4}}}' | \
  java -jar build/libs/mcp-add-1.0.0-all.jar
# → {"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"7.0"}]}}

6. IntelliJ IDEA 빠른 테스트 팁

  1. Run Main 우클릭 → 실행/디버그
  2. Gradle Tool Window application ▸ run 더블클릭
  3. JUnit 테스트로 AddTool 로직 검증

7. Claude Desktop 연동

  1. build/libs/mcp-add-1.0.0-all.jar 경로 확인
  2. claude_desktop_config.json 에 추가
"mcpServers": {
  "adder-java": {
    "command": "java",
    "args": ["-jar", "/absolute/path/mcp-add-1.0.0-all.jar"]
  }
}
  1. Claude 재시작 → 채팅창에 17+25 물어보기
    • 망치🔨 아이콘 나타나면 연결 성공

전체 코드

https://github.com/silbaram/mcp-server-study-example/tree/main/src/main/java/io/github/silbaram

728x90