MCP는 현대 애플리케이션이 대형 언어 모델에 맥락 정보를 효과적으로 제공할 수 있는 방법을 표준화한 개방형 프로토콜이다. 이 프로토콜은 AI 모델과 다양한 데이터 소스 및 도구를 단일 인터페이스로 연결할 수 있게 해주며, 일반적으로 “AI 분야의 USB-C 표준”이라는 비유로 설명된다. MCP의 출현 이전에는 각 AI 모델마다 외부 데이터를 활용하기 위해 맞춤형 통합이 필요했으며, 이로 인해 복잡한 연동 코드 작성이 요구되었다. 하지만 MCP는 이러한 문제를 해결하여 LLM이 실시간 외부 데이터와 도구에 쉽게 접근할 수 있도록 지원한다.
MCP의 주요 기능으로는 최신 정보 제공, 도메인 지식 보강, 통합 비용 감소, 모델 및 벤더 교체 용이성을 들 수 있다. 이를 통해 LLM은 더 정확하고 풍부한 응답을 생성할 수 있으며, 사용자는 최신 정보와 전문성을 활용할 수 있다. MCP의 구조는 클라이언트가 MCP 서버에 연결하여 필요한 맥락을 공급함으로써 AI 비서나 에이전트가 고립되지 않고 실제 환경과 양방향으로 소통할 수 있게 한다.
MCP 설치 및 초기 설정
MCP는 다양한 언어의 SDK를 제공하며, 여기서는 JavaScript(Node.js), Kotlin, Java 환경에서 MCP를 설치하고 설정하는 방법을 소개한다.
JavaScript 환경 (Node.js)
Node.js에서 MCP를 설치하려면 NPM을 통해 MCP 공식 TypeScript SDK를 설치해야 한다. 터미널에서 다음 명령을 실행하면 된다:
bash
npm install @modelcontextprotocol/sdk
또한, 스키마 정의를 위해 zod 라이브러리도 필요하다:
bash
npm install zod
Node.js에서 ESM 모듈을 사용하도록 설정하거나, CommonJS 환경에서는 require 문을 사용한다.
Kotlin 환경
Kotlin에서는 Maven Central에 배포된 MCP SDK를 사용할 수 있다. Gradle 프로젝트에서는 build.gradle 파일에 다음과 같은 의존성을 추가해야 한다:
groovy
implementation 'io.modelcontextprotocol:kotlin-sdk-jvm:0.4.0'
Maven 프로젝트의 경우 pom.xml에 다음과 같은 의존성을 추가한다:
xml
<dependency>
<groupId>io.modelcontextprotocol</groupId>
<artifactId>kotlin-sdk-jvm</artifactId>
<version>0.4.0</version>
</dependency>
Kotlin SDK는 JetBrains와 Anthropic이 협력하여 개발한 공식 SDK이다.
Java 환경
Java SDK는 Maven Central에도 배포되어 있다. Gradle 프로젝트에서는 다음과 같이 의존성을 추가한다:
groovy
implementation 'io.modelcontextprotocol.sdk:mcp:0.8.1'
Maven 프로젝트의 경우 pom.xml에 다음 내용을 추가한다:
xml
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
<version>0.8.1</version>
</dependency>
Java SDK는 Spring AI 팀과 협력하여 만들어졌으며, Java 17 이상을 권장한다.
MCP 서버 구성 및 활용하기
MCP 서버는 LLM에 노출할 데이터나 기능을 제공하는 경량 서버 프로그램이다. 다음은 JavaScript, Kotlin, Java 각 언어별로 MCP 서버를 구현하는 예제이다.
JavaScript 예제 (Node.js)
아래 코드는 Node.js 환경에서 MCP 서버를 생성하고 표준 입출력으로 통신하도록 설정한 예제이다:
“`javascript
import { McpServer, ResourceTemplate } from “@modelcontextprotocol/sdk/server/mcp.js”;
import { StdioServerTransport } from “@modelcontextprotocol/sdk/server/stdio.js”;
import { z } from “zod”;
const server = new McpServer({
name: “Demo”,
version: “1.0.0”
});
server.tool(
“add”,
{
a: z.number(),
b: z.number()
},
async ({ a, b }) => ({
content: [{ type: “text”, text: String(a + b) }]
})
);
server.resource(
“greeting”,
new ResourceTemplate(“greeting://{name}”, { list: undefined }),
async (uri, { name }) => ({
contents: [{ uri: uri.href, text: Hello, ${name}! }]
})
);
const transport = new StdioServerTransport();
await server.connect(transport);
“`
Kotlin 예제
Kotlin SDK를 사용하여 MCP 서버를 구현하는 방식은 다음과 같다:
“`kotlin
import io.modelcontextprotocol.kotlin.sdk.server.Server
import io.modelcontextprotocol.kotlin.sdk.server.ServerOptions
import io.modelcontextprotocol.kotlin.sdk.server.StdioServerTransport
import io.modelcontextprotocol.kotlin.sdk.ServerCapabilities
import io.modelcontextprotocol.kotlin.sdk.resources.ReadResourceResult
import io.modelcontextprotocol.kotlin.sdk.contents.TextResourceContents
val server = Server(
serverInfo = Implementation(name = “Demo”, version = “1.0.0”),
options = ServerOptions(
capabilities = ServerCapabilities(
resources = ServerCapabilities.Resources(
subscribe = true,
listChanged = true
)
)
)
)
server.addResource(
uri = “greeting://hello”,
name = “Greeting”,
description = “Returns a greeting message”,
mimeType = “text/plain”
) { request ->
ReadResourceResult(
contents = listOf(
TextResourceContents(
text = “Hello, MCP!”,
uri = request.uri,
mimeType = “text/plain”
)
)
)
}
val transport = StdioServerTransport()
server.connect(transport)
“`
Java 예제
Java 환경에서 MCP 서버를 구현하는 예제는 다음과 같다:
“`java
import io.modelcontextprotocol.sdk.McpServer;
import io.modelcontextprotocol.sdk.McpSyncServer;
import io.modelcontextprotocol.sdk.transport.StdioServerTransport;
import io.modelcontextprotocol.sdk.schema.Tool;
import io.modelcontextprotocol.sdk.schema.CallToolResult;
import io.modelcontextprotocol.sdk.schema.TextContent;
import java.util.List;
import java.util.Map;
public class DemoMCP {
public static void main(String[] args) throws Exception {
McpSyncServer server = McpServer.sync(new StdioServerTransport())
.serverInfo(“Demo”, “1.0.0”)
.build();
Tool addTool = new Tool(
"add",
"두 수를 더하는 도구",
"""
{ "type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a","b"]
}
"""
);
server.addTool(addTool, (exchange, arguments) -> {
double a = ((Number) arguments.get("a")).doubleValue();
double b = ((Number) arguments.get("b")).doubleValue();
String resultText = String.valueOf(a + b);
return new CallToolResult(
List.of(new TextContent(resultText)),
false
);
});
server.connect();
}
}
“`
이처럼 각 언어별로 MCP 서버를 구현할 수 있으며, 이를 통해 사용자는 LLM에 필요한 다양한 기능을 손쉽게 제공할 수 있다.
MCP의 주요 구성 요소
MCP를 이해하기 위해서는 핵심 개념들을 정리할 필요가 있다. 주요 용어는 다음과 같다:
컨텍스트(Context)
LLM이 답변을 생성할 때 참고할 수 있는 추가 데이터를 의미한다. MCP에서는 주로 리소스 형태로 제공되며, 예를 들어 파일 내용이나 데이터베이스 쿼리 결과 등이 해당된다.
프롬프트(Prompt)
LLM에게 주어지는 질문 또는 명령을 가리킨다. 사용자 입력뿐 아니라 시스템의 지시문이나 대화의 역사도 포함된다.
모델(Model)
LLM 자체를 지칭하며, MCP는 다양한 모델을 지원하여 유연성을 제공한다. 모델 API 호출 시 MCP를 통해 얻은 컨텍스트를 포함시킬 수 있다.
응답(Response)
LLM이 생성한 최종 답변을 의미하며, 사용자 질문을 받고 모델이 컨텍스트와 지식을 종합하여 생성한 결과이다.
이 외에도 서버, 클라이언트, 도구 등 다양한 용어가 존재하며, MCP의 다양한 기능과 구조를 이해하는 데 도움이 된다. MCP는 AI 비서와 같은 애플리케이션이 외부 세계와 유기적으로 소통할 수 있도록 지원하여, 실제 환경에서 유용한 답변을 생성할 수 있게 해준다.