최근 AI가 빠르게 발전하면서 개발자들의 생산성이 크게 증가하게 되었습니다. 이와 관련하여 더욱더 편리하게 AI를 사용할 수 있는 MCP라는 개념에 대해서 간단하게 설명하고 '어떻게 사용할 수 있는지'이 집중해서 설명드리겠습니다.
✅ MCP의 개념
MCP란 Model Context Protocol로써 Anthropic이 오픈 소스로 공개한 프로토콜입니다. 프로토콜이란 컴퓨터나 원거리 통신 장비 사이에서 메시지를 주고받는 규칙인데요, MCP는 AI에 최적화된 표준 프로토콜이라고 생각하시면 됩니다.
공식 문서에서는 MCP를 AI 어플리케이션을 위한 USB-C포트라고 비유하는데요, 사실 MCP의 개념은 MCP를 어떤 것에 활용 가능한지에 주목하면 조금 더 쉬운 이해가 가능합니다.
✅ MCP를 적용하면 이런게 가능해요
- AI를 깃허브에 연결하고 사용할 수 있습니다.
- 데이터 소스(MySQL 같은 DB 뿐만 아니라 로컬 파일)에 접근 가능하게 할 수 있습니다.
- 검색 엔진 및 여러 MCP 서버에 연결하여 사용할 수 있습니다.
예를 들어 볼까요?
내가 사용하는 노션에 MCP를 연결하고 다음과 같은 질문은 CLAUDE에게 할 수 있습니다.
" 내가 메모장 페이지에 정리한 내용 중 ~부분의 내용을 정리해서 내게 설명해 줘"
지도 정보를 가지고 있는 MCP 서버에 연결하고 다음과 같은 질문을 CLAUDE에게 할 수 있습니다.
"현재 사람들이 가장 많이 검색하고 있는 여행지가 어디야? 안내해 줘"
그리고 MCP는 양방향 통신이기 때문에 메일을 보내거나 피그마를 편집하는 작업 또한 가능합니다.
즉, AI와 어떤 것을 연결하여 더 개인화되고 나에게 편리한 AI로 만들어줄 수 있는 기능입니다.
✅ MCP의 세부 개념
MCP를 개인 AI에 붙이는 정도로 활용할 계획이시라면 MCP의 세부 개념까지는 알지 못해도 전혀 무방합니다. 적용하는 부분이 궁금하시면 바로 다음 주제로 넘어가도 됩니다. 하지만, MCP는 java application에 붙여서 응용할 수도 있고 세부 개념을 공부하게 되면 MCP의 작동 원리에 대해서 좀 더 깊게 이해가 가능합니다.
이런 부분과 관련하여 MCP의 세부 개념에 대해서 조금 알아보도록 하겠습니다.
1️⃣ MCP의 구조
MCP 클라이언트-서버 아키텍처를 따릅니다.
MCP의 구성 요소는 크게 3가지입니다.
- MCP Host: Claude나 GPT 같은 AI 애플리케이션
- MCP Client: 서버로부터 컨텍스트(데이터, 도구 접근)를 가져와 HOST가 사용할 수 있도록 제공하는 일종의 연결 핸들러 같은 개념
- MCP Server: MCP클라이언트에게 컨텍스트를 제공하는 프로그램
여기서 MCP 호스트(Claude Code나 Claude Desktop 같은 AI 애플리케이션)가 하나 이상의 MCP 서버와 연결을 설정하며, MCP 호스트는 각 MCP 서버마다 하나의 MCP 클라이언트를 생성함으로써 이를 수행합니다. 각 MCP 클라이언트는 해당 MCP 서버와 전용의 일대일 연결을 유지합니다.
여기서 Client는 MCP를 통해서 정보를 받는 주체 그리고 Server는 정보를 제공하는 주체입니다. 나중에 프로젝트에서 MCP를 활용하신다고 해도 Client는 크게 만 질 일이 없습니다.
Server는 어떤 정보를 어떻게 Host에게 제공할지 결정하는 주체이기 때문에 만약 프로젝트를 MCP와 연결을 하게 된다면 Server 쪽을 개발할 수도 있습니다.
2️⃣ MCP의 Layer 구조
MCP는 데이터 계층과 전송 계층으로 이루어져 있습니다.
데이터 계층(내부 계층)
데이터 계층은 JSON-RPC 2.0 기반 교환 프로토콜을 구현하며, 메시지 구조와 의미를 정의합니다. 또한, 다음과 같은 것들을 포함하고 있습니다.
- 라이프사이클 관리(Lifecycle management): 클라이언트와 서버 간의 연결 초기화, 기능 협상(capability negotiation), 연결 종료를 처리.
- 서버 기능(Server features): 서버가 클라이언트에 핵심 기능을 제공할 수 있게 합니다. 여기에는 AI 동작을 위한 도구(tools), 컨텍스트 데이터를 제공하는 리소스(resources), 상호작용 템플릿(prompts) 등이 포함된다.
- 클라이언트 기능(Client features): 서버가 클라이언트에게 요청할 수 있도록 합니다. ex) 호스트 LLM에서 샘플링, 사용자 입력 요청, 클라이언트에 로그 메시지 전송.
- 유틸리티 기능(Utility features): 실시간 업데이트를 위한 알림(notifications), 장기 실행 작업의 진행 상황 추적(progress tracking) 같은 추가 기능을 지원한다.
전송 계층(외부 계층)
전송 계층은 클라이언트와 서버 간의 통신 채널 및 인증을 관리합니다. ex) 연결 설정, 메시지 프레이밍, MCP 참여자 간의 보안 통신을 처리
- Stdio transport: 동일한 기기 내에서 로컬 프로세스 간 직접 통신을 위해 표준 입력/출력 스트림을 사용합니다. 네트워크 오버헤드가 없어서 최적의 성능을 제공함. (로컬에서만 MCP를 사용할 때!)
- Streamable HTTP transport: 클라이언트에서 서버로 가는 메시지를 HTTP POST로 전송하며, 필요할 경우 Server-Sent Events(SSE)를 통해 스트리밍 기능을 제공합니다. 이 전송 방식은 원격 서버 통신을 가능하게 하고, bearer 토큰, API 키, 커스텀 헤더 등 표준 HTTP 인증 방식을 지원함. (MCP는 인증 토큰을 얻기 위해 OAuth 사용을 권장한다)
3️⃣ ⭐⭐프리미티브 (Primitives)
프리미티브는 MCP 내에서 가장 중요한 개념입니다. 클라이언트와 서버가 서로에게 제공할 수 있는 것을 정의합니다.
Primitives를 이해하게 되면 MCP가 어떻게 작동하는지 어느 정도 감을 잡을 수 있습니다.
Server Primitives
- 도구(Tools): AI 애플리케이션이 실행할 수 있는 함수 (예: 파일 작업, API 호출, 데이터베이스 쿼리).
- 리소스(Resources): AI 애플리케이션에 컨텍스트 정보를 제공하는 데이터 소스 (예: 파일 내용, 데이터베이스 레코드, API 응답).
- 프롬프트(Prompts): 언어 모델과의 상호작용을 구조화하는 재사용 가능한 템플릿 (예: 시스템 프롬프트, few-shot 예제).
각 프리미티브 유형에는 관련 메서드가 있다:
- 탐색(list)
- 검색(get)
- 실행(call, 도구의 경우)
저는 추후에 Java 애플리케이션에서 MCP를 사용하는 것을 예시로 들 것이기 때문에 Java 코드를 기준으로 예시를 들어보겠습니다.
예를 들어서 다음과 같은 니즈를 생각해 보겠습니다.
내 Java 프로젝트의 DB 구조를 AI가 알고 있고 이를 바탕으로 나를 도와줬으면 좋겠다.
- 더미 데이터 같은 것도 테이블 제약등을 고려해서 알아서 넣어주는 SQL 스크립트를 작성해 주면 좋겠다.
- DB 내부 데이터를 조회하고 인사이트를 알려주면 좋겠다.
이런 경우를 가정해서 MCP를 설계한다면 어떻게 해야 할까요?
1. Resource
Resource는 AI에게 컨텍스트 정보를 제공하는 데이터 소스입니다. 위의 니즈에 따른 작업을 하려면 DB를 알고 있기는 해야 하니까요!
따라서, 지금과 같은 상황에서는 DB의 스키마 정보 그리고 예시 데이터 정도가 resource가 될 수 있습니다.
public interface McpResource {
String getName();
String getDescription();
Object getData();
}
/**
* Schema에 대한 정보를 제공하는 Resource
*/
public class SchemaResource implements McpResource {
@Override
public String getName() {
return "DB Schema";
}
@Override
public String getDescription() {
return "DB 스키마에 대한 정보를 제공합니다.";
}
@Override
public Object getData() {
return List.of(
// 메타 데이터를 가져오는 로직 ~~~
);
}
}
/**
* 데이터 샘플을 가져올 수 있는 Resource
*/
public class SampleDataResource implements McpResource {
@Override
public String getName() {
return "Sample Data";
}
@Override
public String getDescription() {
return "테이블의 예시 데이터를 던져줍니다.";
}
@Override
public Object getData() {
return new QueryResult(List.of(
어떤 테이블의 몇개의 row를 가져오는 로직 ~~
));
}
}
이런 느낌으로 구현을 해주게 됩니다.
예를 들어서, 해당 리소스가 정의되고 MCP가 연결된 상태에서 다음과 같은 요청을 한다고 가정해 봅시다.
"테이블 A에 대한 더미 데이터를 현실적으로 100개 정도 넣어줘"
1) 그럼 AI는 해당 응답에 답장하기 위해서 클라이언트는 MCP 프로토콜은 내부적으로 JSON-RPC 2.0을 사용해서
- resources/list : 탐색 메서드를 호출합니다.
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list",
"params": {}
}
2) 서버는 요청에 대해서 가지고 있는 resource 값들을 반환해 줍니다.
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resources": [
{
"name": "DB Schema",
"description": "DB 스키마에 대한 정보를 제공합니다."
},
{
"name": "Sample Data",
"description": "테이블의 예시 데이터를 던져줍니다."
}
]
}
}
3) AI는 자체적으로"DB 스키마를 알아야겠다"라고 판단하고 DB 스키마를 제공하는 resource에 대해서 검색(get)을 호출합니다. (신기 신기)
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/get",
"params": {
"name": "dbSchema"
}
}
4) 응답
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"data": [
{
"tableName": "users",
"columns": ["id INT", "name VARCHAR(255)", "age INT"]
},
{
"tableName": "orders",
"columns": ["id INT", "user_id INT", "amount DECIMAL"]
}
]
}
}
이제 Resource를 이해하셨나요?
"Resource는 AI의 판단을 위해 어떤 값들을 어떻게 줄 것인가?"를 결정하는 부분입니다.
그다음에 행위 자체는 Tools를 통해서 이루어지게 됩니다.
2. Tools
위의 예시에 계속 이어서 이제 행위에서는 데이터를 주입할 수 있어야겠죠?
그럼 다음과 같은 Tool을 만들 수 있어요.
public class InsertRowTool implements McpTool {
@Override
public String getName() {
return "insertRow";
}
@Override
public String getDescription() {
return "특정 테이블에 데이터를 삽입합니다.";
}
// JSON Schema: 클라이언트(AI)가 보고 arguments를 채움
@Override
public JSONObject getInputSchema() {
JSONObject schema = new JSONObject();
schema.put("type", "object");
JSONObject props = new JSONObject();
props.put("table", new JSONObject().put("type", "string"));
props.put("id", new JSONObject().put("type", "integer"));
props.put("name", new JSONObject().put("type", "string"));
props.put("age", new JSONObject().put("type", "integer"));
schema.put("properties", props);
schema.put("required", new String[]{"table", "id", "name"}); // 필수 인자
return schema;
}
@Override
public Object call(Map<String, Object> arguments) throws Exception {
String table = (String) arguments.get("table");
Integer id = (Integer) arguments.get("id");
String name = (String) arguments.get("name");
Integer age = (Integer) arguments.get("age");
String sql = "INSERT INTO " + table + " (id, name, age) VALUES (?, ?, ?)";
try (Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/testdb", "admin", "password");
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
ps.setString(2, name);
ps.setInt(3, age);
int rows = ps.executeUpdate();
return Map.of(
"success", rows > 0,
"message", rows + " row(s) inserted into " + table
);
}
}
}
AI를 위한 API를 만들어 준다고 이해하시면 될 것 같습니다.
1) AI는 Resource 요청 이후에 DB에 데이터를 주입하기 위해 Tool List를 요청 탐색(list).
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
2) 서버는 Tool List를 반환합니다.
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "insertRow",
"description": "특정 테이블에 데이터를 삽입합니다.",
"inputSchema": {
"type": "object",
"properties": {
"table": {"type": "string"},
"id": {"type": "integer"},
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["table", "id", "name"]
}
}
]
}
}
3) AI는 insertRow Tool를 현재 사용해야 한다고 판단하고 실행(Call) 요청을 하게 됩니다. (인자를 알아서 넣어서)
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "insertRow",
"arguments": {
"table": "users",
"id": 10,
"name": "Alice",
"age": 25
}
}
}
4) 성공 응답
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"success": true,
"message": "1 row(s) inserted into users"
}
}
3. Prompt
이건 사용자에게 어떻게 답장을 해야 하는지 또는 어떻게 실행해야 하는지 AI에게 안내하는 템플릿 정도로 생각하면 됩니다.
public class InsertRowPrompt {
private final String name = "insertRowExample";
private final String description = "데이터를 삽입하는 예시 프롬프트";
// 템플릿 설명
private final String template =
"사용자가 특정 테이블에 데이터를 넣어달라고 하면, 반드시 insertRow Tool을 호출해야 합니다. " +
"아래 JSON 구조에 맞게 입력값을 채워 Tool 호출을 수행하세요.";
// 예시 JSON (AI가 그대로 참고 가능)
private final String example =
"{\n" +
" \"table\": \"users\",\n" +
" \"id\": 10,\n" +
" \"name\": \"Alice\",\n" +
" \"age\": 25\n" +
"}";
public String getName() { return name; }
public String getDescription() { return description; }
public String getTemplate() { return template; }
public String getExample() { return example; }
}
이런 식으로 설정을 하면
{
"success": true,
"message": "1 row(s) inserted into users"
}
InsertRow를 호출하고 응답값을 반환하게 됩니다.
직접 MCP 서버를 구축하게 된다면 알면 좋을 정보이기도 하지만, 저는 이 개념을 통해서 MCP가 어떻게 작동하는지 이해하기 수월했습니다. 내가 만든 앱 서비스에 AI를 붙이고 유용하게 사용하고 싶다면 위와 같은 개발을 해야 합니다. 그렇지만, 대부분 이미 많은 플렛폼에서 MCP 서버를 구현해 놨기 때문에 저희는 연결해서 사용하기만 하면 됩니다!
Client Primitives
MCP는 클라이언트가 노출할 수 있는 프리미티브도 정의합니다. 이건 반대로 서버가 클라이언트에게 요청할 수 있는 부분들입니다.
- 샘플링(Sampling): 서버가 클라이언트의 AI 애플리케이션에서 언어 모델 완성(completion)을 요청할 수 있게 합니다.
- 서버 개발자가 모델 SDK를 직접 포함하지 않고도 언어 모델에 접근할 수 있다.
- 예: sampling/complete 메서드를 사용해 클라이언트의 AI 애플리케이션에 모델 출력을 요청.
- 정보 요청(Elicitation): 서버가 사용자에게 추가 정보를 요청할 수 있게 합니다.
- 예: 서버가 어떤 작업을 하기 전에 사용자에게 더 많은 데이터를 묻거나, 실행을 확인받고 싶을 때.
- elicitation/request 메서드를 사용한다.
- 로깅(Logging): 서버가 클라이언트에 로그 메시지를 전송해 디버깅이나 모니터링을 할 수 있게 합니다.
Client 쪽은 참고만 하셔도 좋을 것 같아요.
4️⃣ 알림(Notifications)
이 부분은 실시간 동기화와 관련이 있습니다. 예를 들어서, 서버 쪽 Too이나 Resource가 바뀌는 경우를 클라이언트가 계속 polling을 통해서 확인을 하게 되면 비효율적일 텐데요. 이에 따라서 서버 측에서 바뀐 부분이 있으면 알림을 통해서 클라이언트에게 바뀐 정보를 전달합니다.
- 결과적으로 Client는 다시 Tool 목록 또는 Resource 목록을 요청해서 바뀐 부분을 동기화할 수 있습니다!
✅ MCP를 적용해 보자!
1️⃣ MCP 소스는 어디서 찾아야 하나요?
개인적으로 MCP를 프로젝트에도 적용해 보고 개인 생산성 향상에도 사용해 보았는데요,
제 생각에는 개인 수준에서 MCP를 앱서비스에 기능으로 탑재시킬 일은 크게 없는 것 같습니다( 정말 사용자가 많고 AI와 연동되었을 때 도움이 되는 Notion 같은 앱을 개발한 것이 아닌 이상). 왜냐하면 결국 MCP를 사용하는 사용자는 개발자일 가능성이 매우 높으며 로컬 AI에 연결을 해야 하기 때문이죠!
저는 오히려 이미 개발된 MCP서버를 연동하여 AI를 효율적으로 사용할 수 있다는 점에서 MCP가 더 가치 있고 혁신적이라고 느꼈습니다.
또한, 여러분들이 굳이 만들지 않으셔도 이미 수많은 MCP 서버들이 구현되어 있고 필요한 것들만 꼽아서 사용하면 됩니다!
제가 전부 다뤄보지 않았고 또한 더 유용한 기능들이 있을 수 있지만, 저는 백엔드 개발자의 입장에서 제가 생각하기에 쓸만한 몇 가지 기능들을 소개해 드리고.. 사용하는 것까지 해보겠습니다.
https://github.com/modelcontextprotocol/servers
GitHub - modelcontextprotocol/servers: Model Context Protocol Servers
Model Context Protocol Servers. Contribute to modelcontextprotocol/servers development by creating an account on GitHub.
github.com
Smithery - Extend your agent's capabilities
Your Agent's Gateway to the World Integrate your AI with 6559 skills and extensions built by the community.
smithery.ai
우선 대표적으로 MCP를 찾을 수 있는 곳은 Smithery와 Github의 공식 페이지가 있는데요.
- Github 공식 페이지는 소스 코드 전체를 주기 때문에 Customizing이 가능합니다. (단, 직접 서버를 돌려야 함)
- Smithery는 직접 서버에서 MCP 서버를 돌리고 있고 바로 연결해서 사용이 가능합니다. (단, 사람들이 만들어서 올려놓은 것이고.. 커스터 마이징이 불가능합니다.)
이런 부분에 있어서 사용 자체는 Smithery가 훨씬 유용하다고 생각했어요!
2️⃣ MCP가 적용 가능한 AI 플랫폼
현재, GPT는 아직 MCP가 적용되지 않습니다.
대표적으로 둘 중 하나를 사용하는데요,
- Claude : 가장 익숙하다 (GPT랑 비슷함)
- Cursor: 개발자 친화적
백엔드 개발자가 사용하기에는 커서가 더 좋다고 생각했습니다.
3️⃣ 추천하는 MCP 리스트
- Context7 : 최신 문서 및 코드 예시 기반 정보를 자동으로 활용합니다.
맨날 GPT에게 테스트 코드를 물어보면 없어진 @MockBean을 기준으로 코딩해 줬는데 해결되겠네요. - Sequential Thinking : Anthropic이 제공하는 공식 레퍼런스 MCP 서버 중 하나로 AI의 사고 과정을 구조화하고 단계별로 추론할 수 있게 도와주는 도구입니다.
- Task Master : 기존 AI의 문제점인 가끔 엉뚱한 결과 생성, 일관성 부족, 범우 제어의 어려움, 그리고 프로젝트 전체 파악이 부족한 문제를 해결해 줍니다. 업무를 작은 단위로 자르고 잘린 작업들을 AI가 무시할 수 없는 명확한 경계와 목표를 가지게 해 줍니다. (다만 , 다른 API Key를 활용해야 하는데 유료로 알고 있음...)
- Fire crawl :
- 웹 스크래핑 / 크롤링 / 검색
- 콘텐츠 추출 (구조화된 데이터, 텍스트 등)
- 딥 리서치(Deep Research) → 검색 + 크롤링 + LLM 분석을 결합해 종합 리포트 생성
- 배치 스크래핑 → 여러 URL을 동시에 처리
이런 기능 등을 통해 웹을 띄워놨다면 여러 가지 기능 테스트 후 리포트 생성 가능.
etc) 메일 보내주기, slack, Notion 등 ( Notion 같은 경우는 정말 애용하는 편입니다!)
4️⃣ 실습 예시
먼저, Context 7을 한번 적용해 볼게요! (저는 Smithery를 기준으로 진행합니다.)
- Smithery는 Auto 탭에서 커서를 선택하고 One-click Install이 가능합니다.
- 바로 적용이 됩니다. 벌써 끝났네요..
- 이러면 적용이 되었고 설명을 최신 라이브러리를 확인해서 대답해 줍니다!
너무 빨리 끝났으니 하나 더 사용해 볼까요?
Notion 같은 경우는 내 노션 라이브러리들을 봐야 하기 때문에 Notion Token을 주입해 주어야 합니다.
- notion을 Auto추가하면 NotionApiKey를 입력하라고 하며 , 주소를 누르면 자동으로 발급 화면으로 넘어갑니다.
- 저는 자소서를 모아놓는 페이지에 대한 부분을 연결하고 싶어서 제목과 워크스페이스를 위처럼 설정하고 저장했습니다.
- 기존의 값이 바뀌는 건 싫어서 업데이트는 해제했고요
- 자소서 페이지에 대한 사용권한을 주었습니다.
- 다시 돌아와서 토큰을 입력해 주면 원클릭으로 추가가 됩니다.
- 이런 식으로 정보를 가져올 수도 있고 직접 어떤 페이지에 내용을 정리하게 할 수도 있습니다.
저는 자소서 관련 DB를 만들고 지원 사항과 공고등을 이것으로 정리할 예정입니다!
이외에도 MCP를 활용 가능한 방법은 정말 다양하게 많이 있습니다!
AI 활용이 개발자의 생산성을 높여줄 수 있는 좋은 도구가 된 만큼 MCP를 활용해서 효율적인 코딩을 하는 개발자가 되면 좋을 것 같아요 :)
Reference:
유튜브 - 장담하건대 가장 쉬운 MCP영상이 될 겁니다 |클로드로 mcp 연결하는 법식 - 코딩 알려주는 누나 🔗
공식 문서 - MCP Anthropic 공식 문서 🔗
티스토리 - 갓대희's 작은 공간 블로그 🔗
'ETC' 카테고리의 다른 글
Clokey 프로젝트 회고 (0) | 2025.04.04 |
---|---|
우테코 7기 프리코스 회고 (1) | 2025.02.10 |