백엔드 개발자의 첫 MCP 서버 만들기 (1편) - AI와 데이터 연결하기
TL;DR
- 문제: AI가 외부 데이터(DB, API, 파일)를 직접 읽을 수 없어서 수동으로 복사/붙여넣기 필요
- 원인: Claude, ChatGPT는 인터넷에 연결되지 않음, 실시간 데이터 접근 불가
- 해결: MCP(Model Context Protocol) - AI가 외부 데이터를 읽을 수 있는 표준 프로토콜
- 효과: 수동 작업 제로, AI가 직접 검색, 백엔드 개발자 친화적 (REST API와 유사)
- 한계: Python 필수 (Java 공식 SDK 없음), 러닝 커브 존재
서론
얼마 전 회사 동료가 MCP에 대해 물어봤습니다. Anthropic에서 만든 Model Context Protocol이라는데, AI와 애플리케이션을 연결하는 표준이라고요.
솔직히 처음엔 “또 새로운 프로토콜인가” 싶었습니다. HTTP, gRPC, WebSocket도 모자라서 또 뭘 배워야 하나…
그런데 실제로 써보니 생각이 완전히 바뀌었습니다. REST API 설계하듯이 AI와 통신하는 API를 만드는 거거든요. Spring Boot로 REST API 개발하던 경험이 그대로 통합니다.
이번 포스팅에서는 자바 백엔드 개발자 관점에서 MCP가 무엇이고, 왜 필요한지, 어떻게 시작하면 되는지 정리해봤습니다.
MCP란 무엇인가? - REST API 개발자라면 5분 컷
MCP(Model Context Protocol)는 AI가 외부 데이터를 읽을 수 있게 해주는 표준 프로토콜입니다.
백엔드 개발자 입장에서 이해하기 쉽게 비유하면 이렇습니다.
REST API vs MCP 서버
graph LR
subgraph "REST API (우리가 아는 것)"
Client1[웹 클라이언트]
Server1[Spring Boot API]
DB1[(Database)]
Client1 --"HTTP GET /users"--> Server1
Server1 --> DB1
end
subgraph "MCP 서버 (새로운 것)"
AI[AI Claude/GPT]
MCPServer[MCP Server]
Data[(External Data)]
AI --"Tools 호출"--> MCPServer
MCPServer --> Data
end
style Client1 fill:#E3F2FD,stroke:#1976D2
style AI fill:#E3F2FD,stroke:#1976D2
style Server1 fill:#FFF3E0,stroke:#F57C00
style MCPServer fill:#FFF3E0,stroke:#F57C00
style DB1 fill:#E8F5E9,stroke:#388E3C
style Data fill:#E8F5E9,stroke:#388E3CREST API:
- 클라이언트(브라우저, 앱)가 HTTP로 서버에 요청
- 서버는 DB나 외부 리소스에 접근해서 응답
MCP 서버:
- AI(Claude, GPT)가 Tools로 서버에 요청
- 서버는 파일, DB, 외부 API에 접근해서 응답
핵심 차이:
| 구분 | REST API | MCP 서버 |
|---|---|---|
| 클라이언트 | 웹/앱 | AI (Claude, GPT) |
| 프로토콜 | HTTP/HTTPS | Stdio 또는 SSE over HTTP |
| 인터페이스 | Endpoint (GET /users) | Tools (search_users) |
| 응답 형식 | JSON | JSON + 메타데이터 |
REST API 개발 경험이 있다면 MCP 서버를 만드는 건 어렵지 않습니다. API 설계 철학이 똑같거든요.
왜 백엔드 개발자가 MCP를 알아야 하는가?
“그래서 이게 왜 중요한데?”
저도 처음엔 이런 생각이었습니다. 그런데 실무에서 AI 기능을 구현하다 보면 느끼게 됩니다.
문제 상황: AI에게 회사 데이터를 안전하게 전달하기
제가 운영하는 블로그를 예로 들어보겠습니다. 50개 넘는 포스팅이 있는데, AI에게 “Spring Batch 글 써본 적 있어?”라고 물어보고 싶습니다.
시도 1: 통 복붙
// Bad: 전체 포스팅 복붙
String allPosts = readAllMarkdownFiles();
claudeAPI.chat("다음 포스팅 목록에서 Spring Batch 관련 글을 찾아줘: " + allPosts);
// ❌ 문제: 토큰 제한 초과 (50개 포스팅 ≈ 500K tokens)시도 2: 매번 수동 복붙
// Bad: 필요한 글만 수동으로 복붙
String springPosts = "1. Spring Batch 성능 최적화 (1편)\n2. Spring Batch 성능 최적화 (2편)";
// ❌ 문제: 매번 10~15분씩 검색 시간 낭비시도 3: RAG (Retrieval-Augmented Generation)
// Bad: 벡터 DB + 임베딩 활용
pinecone.upsert(embeddingAPI.embed(allPosts));
results = pinecone.query(embeddingAPI.embed("Spring Batch"));
// ❌ 문제: 월 $70 비용 + 복잡도 증가 (오버엔지니어링)해결책: MCP 서버
# Good: MCP 서버로 Tools 제공
@server.tool()
def search_posts(keyword: str) -> List[Dict]:
"""키워드로 포스팅 검색"""
posts = load_all_posts()
return [post for post in posts if keyword.lower() in post['content'].lower()]
# AI가 자동으로 호출
# AI: "Spring Batch 글이 있나요?"
# → search_posts("Spring Batch") 자동 실행장점:
- 토큰 절약: 필요한 데이터만 AI에게 전달
- 자동화: 수동 복붙 불필요, AI가 알아서 검색
- 저비용: 월 $0.10 수준 (Cloud Run 무료 티어 활용 가능)
- 확장성: Tools 추가만으로 기능 확장
MCP 서버의 핵심 개념 - Tools
MCP 서버의 가장 중요한 개념은 Tools입니다. REST API의 Endpoint라고 생각하면 됩니다.
Spring Boot와 비교
Spring Boot REST Controller:
@RestController
@RequestMapping("/api/posts")
public class PostController {
@GetMapping("/search")
public List<Post> searchPosts(@RequestParam String keyword) {
return postService.search(keyword);
}
}MCP Server Tools:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Blog MCP Server")
@mcp.tool()
def search_posts(keyword: str) -> list[dict]:
"""키워드로 포스팅 검색"""
posts = get_all_posts()
return [post for post in posts
if keyword.lower() in post['content'].lower()]비교:
| Spring Boot | MCP Server |
|---|---|
@GetMapping("/search") | @mcp.tool() |
@RequestParam String keyword | 함수 파라미터: keyword: str |
return List<Post> | return list[dict] |
| HTTP GET 요청 | AI가 Tools 호출 |
똑같죠? 단지 클라이언트가 웹 브라우저가 아니라 AI일 뿐입니다.
토이프로젝트로 시작하기 - 내 블로그 MCP 서버 만들기
이론은 여기까지. 이제 실제로 MCP 서버를 만들어보겠습니다.