
Java로 MCP 서버를 Jetty에서 구동하는 방법
요약
Java 환경에서 Jetty를 사용하여 MCP(Model Context Protocol) 서버를 구축하고 구동하는 방법을 설명합니다. MCP의 전송 방식(transport) 차이와 Jetty를 활용한 경량 서버 구성 계층을 상세히 다룹니다.
핵심 포인트
- MCP의 두 가지 전송 방식인 stdio와 Streamable HTTP의 차이점 이해
- 기존 Java 코드에 가볍게 추가하기 위한 Jetty 서버 활용법
- Jetty, Servlet, MCP SDK로 이어지는 4계층 구조 분석
- 도구 구현 계층과 MCP 계층의 분리를 통한 재사용성 확보
MCP 서버의 Java 구현을 인계받게 되었습니다. Jetty를 사용하고 있었는데, '왜 Jetty인지', 'transport가 무엇인지' 잘 몰랐기 때문에 코드를 읽으면서 조사한 기록입니다.
Java 메인이 아니라 다른 언어에 더 익숙한 제가 조사하면서 정리했기 때문에, 비슷한 상황의 분들에게 참고가 되기를 바랍니다.
AI 클라이언트(Claude, Cursor 등)로부터 호출되는 '도구(Tool)'를 호스팅하는 서버입니다. 도구의 내용은 무엇이든 상관없습니다. DB 쿼리일 수도 있고 외부 API 호출일 수도 있으며 파일 쓰기일 수도 있습니다. MCP라는 프로토콜을 따르고 있다면, AI 측에서 '이 도구를 호출하라'는 지시가 오면 실행해 줍니다.
MCP의 연결 방식(transport)을 조사해보니, 현행 사양(2025-03-26)에서는 두 가지가 정의되어 있습니다.
| transport | 개요 |
|---|---|
| stdio | 클라이언트가 서버를 서브 프로세스로 시작. 로컬 전용 |
| Streamable HTTP | HTTP로 통신. 서버가 독립 프로세스로 구동. 현행 표준 |
이와 별개로, 구(舊) HTTP+SSE transport라는 것이 있습니다. 이 방식은 2025-03-26 사양 개정으로 deprecated 되었으며, Streamable HTTP로의 전환이 권장됩니다. 지금도 작동하고 각 SDK도 대응하지만, 새로 만들 때는 Streamable HTTP를 선택하는 것이 안전해 보입니다.
이번에 인계받은 코드는 구(舊) HTTP+SSE transport의 구현이었습니다. Streamable HTTP로 바꾸고 싶다는 생각도 들지만, 여기서는 SSE 구성 전제를 바탕으로 설명하겠습니다.
Java로 MCP 서버를 만들 경우, 프레임워크 선택지는 몇 가지 있습니다.
| 선택지 | 특징 |
|---|---|
| Spring Boot + MCP SDK | 정보가 많다. 의존성이 무겁다 |
| Quarkus | 네이티브 이미지 대응. 0부터 만든다면 고려할 만한 선택지 |
| Jetty | 기존 Java 코드에 추가하고 싶을 때. 의존성을 줄이기 쉽다 |
인계받은 코드에서 Jetty가 채택된 이유를 들은 적은 없지만, 아마도 기존의 Java 클라이언트 코드에 MCP 기능을 붙이는 구성이었기 때문에, Spring Boot 전체를 넣기보다는 Jetty를 가볍게 얹는 것이 자연스러웠던 것 같습니다.
Java에 익숙하지 않으면 '서블릿(Servlet)'이라는 단어 자체가 와닿지 않을 수 있는데, 서블릿은 HTTP 요청을 받아 처리하는 클래스를 말합니다. Jetty는 그 서블릿을 구동하는 HTTP 서버이며, 여기서는 new Server(8080)와 같이 코드에 직접 작성하여 Jetty를 구동하고 있습니다. Spring Boot 같은 외부 프레임워크를 사용하지 않고도 HTTP 서버가 올라오는 느낌입니다. Java 외의 사람에게 친화적인 간단한 구성이었습니다.
구성은 4개 계층으로 되어 있습니다.
Jetty— HTTP 요청을 받음 -
McpTransportServlet— MCP SDK의 HttpServletSseServerTransportProvider를 상속받은 서블릿. 클라이언트와의 SSE 연결을 관리함 -
SampleMcpService— McpSyncServer.addTool()로 도구를 등록합니다. 어떤 도구가 사용 가능한지 MCP 클라이언트에 전달함 -
도구 구현— 실제로 무언가를 하는 장소. 여기만 용도에 따라 교체하면 됩니다.
위의 3개 계층은 'MCP를 서비스하기 위한 공통 부분'이므로, 도구 구현 계층만 바꿔주면 다른 용도로도 재사용할 수 있습니다.
이번 코드에서는 OSLC라는 IBM ELM의 REST 프로토콜을 호출하는 Java SDK가 도구 구현 계층에 들어있습니다. MCP 계층은 OSLC를 전혀 모르고, OSLC 쪽도 MCP를 모릅니다. 그 사이의 연결 고리 역할을 하는 것이 MCP 서버인 것입니다.
용도에 따라 이 부분을 교체하면, DB 클라이언트든 사내 API 래퍼(wrapper)든 같은 구성으로 구동할 수 있을 것 같습니다.
- 연결 방식은 Streamable HTTP가 현행 표준입니다. 구(舊) HTTP+SSE는 작동하지만 deprecated 상태입니다.
- Jetty 내장 방식은 기존 Java 자산에 추가하기 좋은 선택지 중 하나입니다.
- 4개 계층으로 분리되어 있다는 것을 알면, 인계받은 코드의 어느 부분을 건드려야 무엇이 바뀌는지 파악하기 쉬워졌습니다.
잘못된 부분이나 보충할 내용이 있다면 댓글로 알려주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기