본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 25. 15:46

MCP 지식 서버를 처음부터 구축하기: 실제로 작동하는 나의 80줄 Java 구현체

요약

Java Spring Boot를 사용하여 단 80줄의 코드로 작동하는 MCP(Model Context Protocol) 지식 서버를 구축하는 실전 가이드를 제공합니다. 의사 코드가 아닌 실제 운영 가능한 수준의 구현체를 통해 MCP 서버의 핵심 구조를 빠르게 학습할 수 있습니다.

핵심 포인트

  • Java Spring Boot와 Lombok을 활용한 간결한 MCP 서버 구현
  • JSON-RPC 2.0 사양을 준수하는 데이터 모델 설계
  • tools/list 및 tools/call 기능을 통한 지식 검색 구현
  • AI 클라이언트의 중단을 방지하기 위한 예외 처리 및 응답 전략

MCP 지식 서버를 처음부터 구축하기: 실제로 작동하는 나의 80줄 Java 구현체

솔직히 말해서, 저는 지금까지 80개의 MCP 관련 글을 써왔고, 사람들은 계속해서 저에게 똑같은 질문을 합니다:

"좋아요, 교훈은 다 들었습니다. 하지만 제가 복사해서 붙여넣을 수 있는 완전하게 작동하는 예제를 볼 수 있을까요?"

일리가 있는 말입니다. 저는 튜토리얼들이 지저분한 세부 사항들을 건너뛰는 것을 좋아한다는 사실을 고생하며 배웠습니다. 그들은 10줄 정도의 의사 코드 (pseudocode)를 보여주고는 마치 작업이 끝난 것처럼 행동합니다. 하지만 실제로 첫 MCP 서버를 구축하려고 앉아보면, 구성 요소의 절반이 빠져 있다는 것을 깨닫게 됩니다.

그래서 제가 하려는 것은 이렇습니다. Java Spring Boot를 사용하여 처음부터 완전하게 작동하는 MCP 지식 서버를 구축하는 과정을 안내해 드리겠습니다. 총 80줄의 코드입니다. 모든 코드를 여러분의 프로젝트에 복사하여 10분 안에 실행할 수 있습니다.

군더더기 없습니다. 의사 코드 (pseudocode)도 없습니다. 제가 제 지식 베이스를 위해 실제로 운영 환경 (production)에서 실행하고 있는 작동하는 코드뿐입니다.

우리가 구축할 것

우리는 개인 지식 베이스를 MCP 호환 AI 클라이언트에 노출하는 간단한 MCP 서버를 구축할 것입니다. 무엇을 할 수 있을까요?

  • tools/list: 사용 가능한 도구 (search_knowledge)를 반환합니다.
  • tools/call: 지식 베이스에 대한 검색을 실행하고 관련 발췌문을 반환합니다.

그게 전부입니다. 기능적인 MCP 지식 서버를 위해 필요한 것은 이것뿐입니다. 나머지는 AI가 처리합니다.

전체 프로젝트 구조는 다음과 같습니다:

src/
└── main/
    └── java/
...

파일 세 개. 그게 전부입니다.

1단계: 모델 클래스 (30줄)

먼저, MCP 요청 및 응답에 필요한 간단한 데이터 클래스를 정의해 보겠습니다. 코드를 깔끔하게 유지하기 위해 Lombok을 사용합니다:

package com.yourname.knowledge.model;

import lombok.Data;
...

이것으로 30줄입니다. 특별할 것은 없습니다. MCP 사양 (specification)과 일치하는 평범한 POJO들일 뿐입니다.

전문가 팁: 이것을 너무 복잡하게 만들지 마세요. MCP는 JSON-RPC 2.0을 사용하며, 이 클래스들은 사양이 기대하는 것과 정확히 일치합니다. 어떤 JSON 직렬화기 (serializer) (Spring Boot의 Jackson 같은)라도 나머지를 처리할 것입니다.

Step 2: 지식 서비스 (25줄)

다음은 지식 검색 서비스입니다. 이곳은 실제 지식 베이스(knowledge base)에 연결하는 부분입니다. 이 예제에서는 아주 단순하게 유지하기 위해, string.contains()를 사용하여 인메모리(in-memory) 노트를 검색하도록 구현했습니다. 실제 운영 환경(production)에서는 PostgreSQL, Elasticsearch 또는 사용 중인 다른 데이터베이스에 연결하게 될 것입니다.

하지만 핵심은 이것입니다: 이것만 있으면 충분합니다.

package com.yourname.knowledge.service;

import com.yourname.knowledge.model.TextContent;
...

이게 25줄입니다. 보시다시피 전혀 복잡하지 않습니다. 실제 애플리케이션에서는 knowledgeBase 리스트를 실제 데이터베이스에 대한 쿼리로 교체하면 됩니다.

제가 고생하며 배운 핵심적인 교훈은 다음과 같습니다: 결과가 없더라도 항상 사람이 읽을 수 있는 무언가를 반환하라는 것입니다. 만약 빈 응답(empty response)을 반환하면, AI 클라이언트가 멈춰버릴(hang) 수 있습니다. 제 말을 믿으세요. 저도 그 문제로 디버깅을 해봤으니까요.

Step 3: 컨트롤러 (25줄)

이제 메인 이벤트인 MCP 엔드포인트(endpoint)입니다. 이 부분은 tools/listtools/call을 모두 처리합니다:

package com.yourname.knowledge.controller;

import com.yourname.knowledge.model.*;
...

컨트롤러 코드가 25줄입니다. 총 라인 수: 30 + 25 + 25 = 80줄. 이것이 하나의 작동하는 MCP 서버 전체입니다.

잠깐 — 이게 정말 끝인가요? 네, 정말 이게 끝입니다.

무슨 일이 일어나고 있는지 분석해 보겠습니다:

  1. JSON-RPC 2.0 래퍼 (wrapper): 우리는 항상 jsonrpc 버전과 요청 id를 포함하는 올바른 JSON-RPC 봉투(envelope)로 응답합니다.
  2. tools/list: 이름, 설명, 그리고 입력을 위한 JSON 스키마(JSON Schema)를 사용하여 우리의 search_knowledge 도구를 기술합니다. 이것이 MCP가 도구를 사용하기 위해 알아야 할 전부입니다.
  3. tools/call: 쿼리(query) 인자를 추출하고, 검색을 실행한 뒤, 텍스트 콘텐츠를 반환합니다. 끝입니다.
  4. 에러 처리 (Error handling): 메서드가 존재하지 않으면 올바른 JSON-RPC 에러 코드를 반환합니다.

Step 4: CORS 설정 (10줄)

잠깐 — 한 가지 더 있습니다. 만약 MCP 서버가 AI 클라이언트와 다른 도메인에 있다면 (아마 그럴 것입니다), CORS를 적절히 설정해야 합니다. 다음은 간단한 Spring Boot CORS 설정입니다:

package com.yourname.knowledge.config;

import org.springframework.context.annotation.Bean;
...

하지만 잠깐 — 제가 인증(authentication) 관련 글에서 언급했던 큰 함정을 기억하시나요? OPTIONS 프리플라이트 요청 (preflight requests)에는 인증 자격 증명 (authentication credentials)이 포함되지 않습니다. 만약 인증을 사용하고 있다면 (당연히 사용해야 합니다), 보안 설정(security configuration)에서 /mcp 경로로 들어오는 OPTIONS 요청에 대해서는 인증을 건너뛰도록 설정해야 합니다.

Spring Security에서는 다음과 같이 작성합니다:

// SecurityFilterChain 내에서
http.authorizeHttpRequests(auth -> auth
    .requestMatchers(org.springframework.http.HttpMethod.OPTIONS, "/mcp").permitAll()
...

이 설정을 잊어버리면 CORS가 깨지게 되고, 저처럼 디버깅하는 데 3시간을 허비하게 될 것입니다. 미리 감사 인사를 전하죠.

장단점: 솔직하게 말해봅시다

현실적으로 말씀드리겠다고 약속했으니, 이 방식의 좋은 점과 그렇지 않은 점을 정리해 보겠습니다.

장점 ✅

  1. 매우 단순함 (Dead simple): 단 80줄입니다. 어떤 Java 개발자라도 이를 이해하고 자신의 필요에 맞게 수정할 수 있습니다. 배울 필요가 있는 복잡한 프레임워크도 없습니다.
  2. 개인정보 보호 우선 (Privacy first): 모든 지식은 귀하의 서버에 머뭅니다. 오직 특정 검색 결과만이 AI 클라이언트로 전송됩니다. 전체 데이터베이스가 귀하의 인프라를 벗어나는 일은 절대 없습니다.
  3. 표준 프로토콜 (Standard protocol): 모든 MCP 호환 클라이언트와 작동합니다. Claude Desktop, Continue.dev, OpenAI Platform (MCP를 추가할 경우) 등 다음에 무엇이 나오든 상관없습니다. 하나의 구현으로 여러 클라이언트를 사용할 수 있습니다.
  4. 점진적 도입 (Incremental adoption): 기존의 지식 베이스를 버릴 필요가 없습니다. 그 위에 이 얇은 계층(thin layer)을 추가하기만 하면 됩니다.
  5. 확장 용이성 (Easy to extend): 더 많은 도구(tools)를 추가하고 싶나요? tools/list에 다른 도구를 추가하고 tools/call에서 처리하기만 하면 됩니다. 끝입니다.

단점 ❌

  1. 기본 검색 (Basic search): 이 예제는 단순한 string.contains() 검색을 사용합니다. 대규모 지식 베이스(knowledge bases)의 경우, 적절한 전문 검색 (full-text search)이 필요할 것입니다 (PostgreSQL의 전문 검색 기능은 매우 훌륭하며 추가하기도 쉽습니다).
  2. 세션 관리 없음 (No session management): 이 예제는 호출 간의 대화 컨텍스트 (conversation context)를 추적하지 않습니다. 토큰을 줄이기 위해 이전 결과를 캐싱하고 싶다면, 제가 작성한 MCP 세션 컨텍스트 (MCP session context)에 관한 기사를 확인해 보세요. 추가하는 데 또 80줄 정도가 필요합니다.
  3. 스트리밍 없음 (No streaming): 이 예제는 모든 결과를 한 번에 반환합니다. 일부 MCP 클라이언트는 스트리밍 (streaming)을 지원하지만, 지식 검색의 경우 일반적으로 스트리밍이 필요하지 않습니다.
  4. 직접 호스팅해야 함 (You have to host it): 클라우드 기반 AI 노트 앱과 달리, 이 서버를 어딘가에 직접 호스팅해야 합니다. 하지만 제가 배포 (deployment) 관련 기사에서 다루었듯이, Fly.io를 사용하면 월 2~5달러로 호스팅할 수 있습니다. 어차피 대부분의 노트 앱보다 저렴합니다.

MCP 서버 테스트하기

서버가 실행되면 간단한 curl 명령어로 테스트할 수 있습니다:

# 도구 목록 조회 (List tools)
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
...

search_knowledge 도구가 정의된 응답을 받아야 합니다.

그 다음 호출을 테스트합니다:

# 검색 도구 호출 (Call search tool)
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
...

짠. 일치하는 결과가 반환됩니다. 이것이 작동한다면, 당신의 MCP 서버는 정상적으로 작동하고 있는 것입니다.

이제 즐겨 사용하는 MCP 클라이언트에 추가할 수 있습니다. Claude Desktop의 경우, claude_desktop_config.json에 다음을 추가합니다:

{
  "mcpServers": {
    "my-knowledge-base": {
...

Claude Desktop을 재시작하면 끝입니다. 이제 Claude는 질문에 답변할 때 당신의 개인 지식 베이스를 검색할 수 있습니다.

이것을 만들며 배운 점

솔직히 말해서, 처음 MCP 서버를 만들기 시작했을 때 저는 너무 복잡하게 생각했습니다. 화려한 프레임워크나 복잡한 의존성 주입 (dependency injection) 같은 것들이 모두 필요하다고 생각했죠.

하지만 80개의 기사와 10개 이상의 MCP 서버를 거치며 깨달은 점이 있습니다: MCP는 단순합니다. 너무 복잡하게 생각하지 마세요.

프로토콜 자체는 매우 작습니다. 전체 사양(spec)이 단 한 페이지에 들어갈 정도입니다. 이를 구현하기 위해 거대한 SDK나 복잡한 프레임워크가 필요하지 않습니다. 80줄이면 유용한 기능을 수행하는 완전히 작동하는 서버를 만들 수 있습니다.

어쨌든 진짜 가치는 서버에 있는 것이 아닙니다. 진짜 가치는 여러분의 데이터에 있습니다. MCP는 여러분이 모든 개인정보(privacy)를 포기하지 않고도 AI가 데이터에 접근할 수 있게 해줄 뿐입니다.

자주 묻는 질문 (Frequently Asked Questions)

Q: 반드시 Java/Spring Boot를 사용해야 하나요?
A: 전혀 그렇지 않습니다. 이것은 단지 제가 사용하는 방식일 뿐입니다. 웹 서버를 실행할 수 있는 언어라면 어떤 것이든 동일한 패턴을 구현할 수 있습니다. Python/Flask, Go, Node.js/Express — 원리는 같습니다. 어떤 언어로든 80줄이면 충분합니다.

Q: 이것을 프로덕션(production) 환경에서 바로 사용할 수 있나요?
A: 저는 이와 매우 유사한 것을 몇 달 동안 프로덕션 환경에서 운영해 왔습니다. 잘 작동합니다. 여기에 포함되지 않은 유일한 추가 사항은 인증(authentication, 인증 관련 기사에서 다룸)과 세션 캐싱(session caching, 세션 컨텍스트 기사에서 다룸)입니다. 두 가지 모두 사용 사례에 따라 선택 사항입니다.

Q: 도구(tools)를 더 추가할 수 있나요?
A: 네! tools/list 응답에 다른 도구를 추가하고, switch 문에 이를 처리할 case를 추가하기만 하면 됩니다. 그게 전부입니다. MCP는 여러분이 얼마나 많은 도구를 가지고 있는지 상관하지 않습니다.

Q: HTTPS는 어떻게 하나요?
A: 이것을 배포할 때는 Nginx와 같은 리버스 프록시(reverse proxy) 뒤에 두거나, 자동 HTTPS를 제공하는 Fly.io와 같은 플랫폼을 사용하세요. 프로덕션 환경에서는 항상 HTTPS를 사용해야 합니다. 특히 개인 데이터를 다룰 때는 더욱 그렇습니다.

이제 여러분의 차례입니다

저는 여러분이 프로젝트에 복사해서 붙여넣을 수 있는, 완전히 작동하는 80줄짜리 MCP 지식 서버를 제공해 드렸습니다. 10분 안에 실행할 수 있습니다.

궁금합니다 — 여러분은 MCP로 무엇을 만들 계획인가요? 개인 지식 서버를 구축하고 계신가요? 이미 하나를 만들어 보았는데 제가 여기서 다루지 않은 부분에서 막히셨나요? 아래에 댓글을 남겨 알려주세요. 모든 댓글을 읽고 있으며, 여러분의 디버깅을 돕기 위해 최선을 다하겠습니다.

이미 MCP를 시도해 보셨나요? 첫 번째 서버를 만들 때 가장 힘들었던 점은 무엇이었나요?

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0