
Spring AI와 Ollama를 사용하여 MCP 서버 및 클라이언트 구축하기
요약
Spring AI와 Ollama를 활용하여 Model Context Protocol(MCP) 서버 및 클라이언트를 구축하는 방법을 다룹니다. SSE 전송 방식을 통해 도구, 리소스, 프롬프트를 표준화된 방식으로 노출하고 상호작용하는 아키텍처를 설명합니다.
핵심 포인트
- MCP를 통한 AI 애플리케이션과 외부 시스템 간의 표준화된 통신 구현
- Spring WebFlux와 SSE를 이용한 MCP 서버-클라이언트 통신 방식
- Ollama와 Spring AI를 결합한 로컬 LLM 기반 MCP 클라이언트 구축
- 도구(Tools), 리소스(Resources), 프롬프트(Prompts)의 MCP 활용법
Spring AI를 사용하여 MCP 서버와 클라이언트 연결하기
주요 기술
- Docker
- Java 17
- Spring Boot 4.0.6
- Spring AI 1.0.0
- Ollama
서론
대규모 언어 모델 (LLMs)은 더 이상 질문에 답하는 것에 국한되지 않습니다. 이들은 외부 시스템과 상호작용하고, 정보를 검색하며, 사용자를 대신하여 작업을 수행할 수도 있습니다.
이를 가능하게 하려면 모델과 애플리케이션이 통신할 수 있는 표준화된 방법이 필요합니다. 여기서 **Model Context Protocol (MCP)**이 등장합니다.
MCP는 AI 애플리케이션이 일관된 방식으로 기능을 노출하고 소비할 수 있도록 하는 개방형 프로토콜입니다. 모든 모델이나 프레임워크에 대해 맞춤형 통합을 구축하는 대신, MCP는 서로 다른 시스템이 이해할 수 있는 공통 언어를 제공합니다.
MCP 서버는 세 가지 유형의 기능을 노출할 수 있습니다:
- Tools (도구) → 실행 가능한 작업.
- Resources (리소스) → 읽을 수 있는 데이터.
- Prompts (프롬프트) → 재사용 가능한 프롬프트 템플릿.
예를 들어:
- 도구는 API에서 날씨 정보를 가져올 수 있습니다.
- 리소스는 문서나 설정 파일을 노출할 수 있습니다.
- 프롬프트는 텍스트 요약이나 코드 생성을 위한 지침을 제공할 수 있습니다.
MCP를 사용함으로써 애플리케이션은 더 쉽게 확장, 재사용 및 다양한 AI 모델과 통합될 수 있습니다.
구축하게 될 내용
이 글을 마칠 때쯤 여러분은 다음을 구축하게 됩니다:
- 도구를 노출하고, 도구 목록을 나열하며, Postman MCP 요청으로 이를 테스트할 수 있는 MCP (Model Context Protocol) 서버. 클라이언트와 서버는 Spring WebFlux로 구현된 SSE (Server-Sent Events) 전송 방식을 사용하여 통신합니다.
- Ollama LLM 모델과 Spring AI를 사용하여 WebFlux를 통해 MCP 서버 도구에 연결하는 MCP 클라이언트 및 Postman으로 대규모 언어 모델 (LLM)을 테스트할 수 있는 방법. 결과는 실시간으로 스트리밍됩니다.
- 도구 실행이 가능하고 매우 가벼운
granite4:3b모델을 사용하는 Ollama의 로컬 Docker 배포.
이 글에서 다루는 모든 내용은 다음 GitHub 저장소에 있습니다.
이 글에서 다루는 모든 내용은 다음 GitHub 저장소에 있습니다.
[https://github.com/jlcastrillon91/spring-ai-mcp-sample.git]
아키텍처 개요 (Architecture Overview)
Rest API / MCP 클라이언트 (MCP Client)
Spring AI를 사용하여 LLM에 연결하는 Spring Boot Rest API입니다. 이 LLM은 로컬(Ollama 사용) 또는 원격 클라우드 LLM 제공업체(예: Anthropic 또는 OpenAI)와 연결될 수 있으며, 프롬프트를 받으면 MCP 서버로 전송하여 원격 도구 실행을 수행하는 엔드포인트를 노출합니다.
MCP 서버 (MCP Server)
MCP 서버는 퍼즐의 핵심 부분이며, 에이전트가 원격으로 연결할 수 있도록 도구(tools), 프롬프트 및 리소스를 제공하는 것이 주요 책임인 Spring Boot 애플리케이션입니다. 각 에이전트는 여러 개의 MCP 서버에 연결할 수 있습니다.
Ollama LLM
Ollama는 사용자의 컴퓨터에서 로컬로 LLM을 실행할 수 있게 해주는 도구입니다. 프롬프트를 클라우드 제공업체에 보내는 대신, Ollama는 모델을 다운로드하여 사용자 컴퓨터에서 직접 서비스합니다. 멋지지 않나요?
로컬 Ollama LLM 구성하기 (Configure local Ollama LLM)
Ollama의 로컬 배포를 위한 docker-compose.yml 파일을 생성합니다.
version: '3.8'
services:
...
이제 Ollama 모델이 localhost에서 실행되는지 확인해야 합니다. 다음 스크립트는 Ollama 모델을 가져오고 초기화하며, 모델을 가져오기 전에 Ollama 서버가 실행 중이어야 한다는 것이 필요합니다.
#!/bin/bash
# 모델을 제대로 가져오려면 백그라운드에서 ollama를 서비스합니다.
...
매우 중요!! 스크립트를 실행 가능하게 만드는 것을 잊지 마세요.
chmod +x scripts/init-ollama.sh
참고: 우리는 두 가지 주요 이유로 granite4:3b를 선택했습니다. 가볍고 도구 실행을 허용하기 때문입니다.
이제 docker-compose를 사용하여 도커 컨테이너를 실행합니다.
docker-compose up -d
Ollama가 실행 중인지 확인하려면 콘솔에서 다음 명령을 실행하면 됩니다.
curl http://localhost:11434/api/tags
다음과 같은 JSON 응답을 받을 수 있어야 합니다.
{"models":[{"name":"granite4:3b","model":"granite4:3b","modified_at":"2026-06-15T12:13:11.272613013Z","size":2099521385,"digest":"89962fcc75239ac434cdebceb6b7e0669397f92eaef9c487774b718bc36a3e5f","details":{"parent_model":"/Users/runner/.ollama/models/blobs/sha256-6c02683809a8dc4eb05c78d44bc63bcd707703b078998fa58829c858ab337bb0","format":"gguf","family":"granite","families":["granite"],"parameter_size":"3.4B","quantization_level":"Q4_K_M","context_length":131072,"embedding_length":2560},"capabilities":["completion","tools"]}]}
MCP 서버 구축하기
MCP 서버는 매우 간단한 Spring Boot 서비스입니다. 모든 Spring Boot 애플리케이션의 좋은 시작점은 https://start.spring.io에서 공식 Spring Initializr를 사용하는 것입니다. 'Dependencies' 섹션에 종속성을 지정할 때 Model Context Protocol Server 종속성을 추가할 수 있습니다. 이 부분은 건너뛰고 나중에 Ollama 종속성을 수동으로 추가해도 되지만, MCP 서버 측면에서 작업하는 데 필요한 모든 것을 구성해 줄 것입니다.
build.gradle 파일로 이동하여 WebFlux 전송을 사용하려면 org.springframework.ai:spring-ai-starter-mcp-server를 org.springframework.ai:spring-ai-starter-mcp-server-webflux로 변경해야 합니다. 따라서 종속성의 최종 버전은 다음과 같아야 합니다.
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-mcp-server-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
...
./gradlew build를 실행하여 모든 의존성이 정상인지 확인하세요. 콘솔에 "BUILD SUCCESSFUL" 메시지가 나타나면 계속 진행하면 됩니다.
이제 application.properties를 열고 서버 포트로 8081을 사용하도록 설정하세요. 이 글에서는 클라이언트에 8080 포트를 사용할 예정이지만, 원하는 포트를 사용하는 것은 자유입니다.
server.port=8081
도구 (Tools) 생성하기
이제 첫 번째 도구를 만들어 보겠습니다. UndervaluedProperties.java 클래스를 생성하고, 외부 API에서 데이터를 가져오는 것을 시뮬레이션하는 모의 (mocked) 도구가 포함된 다음 코드를 추가하세요.
package com.example.mcp_server.tools;
import org.springframework.ai.mcp.annotation.McpTool;
...
org.springframework.ai.mcp.annotation.McpTool 클래스는 메서드를 장식(decorate)하여, MCP 클라이언트를 통해 서버에 연결된 원격 LLM (Large Language Models)에서 사용할 수 있는 재사용 가능한 도구로 변환합니다. 도구의 이름은 나중에 도구 목록을 나열할 때 인식되는 방식이라는 점에 유의하세요. 도구의 이름과 설명이 지정된 시스템 및 사용자 프롬프트 (prompts)와 결합되어 LLM 모델이 도구를 실행할지 결정할 수 있게 하므로, 가능한 한 구체적으로 작성해야 합니다.
도구의 또 다른 중요한 측면은 org.springframework.ai.mcp.annotation.McpToolParam입니다. 이 클래스를 사용하여 각 도구 파라미터 (parameter)를 장식하고 설명(description)을 가능한 한 구체적으로 작성하세요. 이는 모델이 사용자로부터 필요한 파라미터를 캡처하고 파싱 (parse)하는 데 도움이 됩니다.
중요! Spring AI 스타터 (starter)의 자동 설정 (auto-configuration)이 도구를 올바르게 등록할 수 있도록 도구 클래스를 @Component로 선언하는 것을 잊지 마세요.
프롬프트 (Prompts) 생성하기
LLM의 수준을 높이는 정말 강력한 방법은 프롬프트를 추가하는 것입니다. 네, 알고 있습니다. 로컬 프롬프트를 사용하여 에이전트 (agent)에게 직접 전달할 수도 있지만, 이 방식은 확장성 (scalability)이 부족하고 많은 경우 매우 무질서합니다. MCP를 사용하면 프롬프트를 선언적인 (declarative) 방식으로 지정할 수 있으므로, 프롬프트는 다음과 같은 구성 요소를 가질 수 있습니다.
- Name: 이것은 프롬프트(Prompt)를 식별하기 위한 식별자이며, 단순한 ID입니다.
- Title: 이것은 프롬프트를 표시하기 위한, 사람이 읽을 수 있는 (또는 AI가 읽을 수 있는 😀) 이름입니다.
- Description: 설명(Description)은 에이전트(Agent)가 해당 프롬프트가 무엇을 하는지 알 수 있도록 하는 사람이 읽을 수 있는 텍스트이며, 이는 에이전트가 프롬프트 실행 여부를 결정하는 데 매우 중요합니다.
- Arguments: 프롬프트를 재사용 가능하고 확장 가능하게 만들어 주는 인자(Arguments) 목록입니다.
이제 코드로 넘어가 보겠습니다. 다음을 캡슐화하는 또 다른 @Component인 InvestorGreetingPrompt를 생성하겠습니다.
package com.example.mcp_server.prompts;
import io.modelcontextprotocol.spec.McpSchema;
...
@McpArg 클래스를 사용하여 프롬프트 인자(Arguments)를 지정하십시오. 이들은 프롬프트가 가질 변수가 될 것이며, 우리의 경우에는 사용자의 이름이 됩니다. @McpArg 클래스에는 기본값이 false인 필수 인자(required argument)가 있는데, 우리의 경우에는 사용자의 이름이 선택 사항(optional)임을 의미합니다.
MCP 서버 테스트하기
이제 서버를 실행합니다: ./gradlew run
애플리케이션 로그에 다음과 같은 항목이 보인다면 서버가 정상적으로 작동하고 있다는 의미입니다.
Registered tools: 1
Registered prompts: 1
이것이 서버 측의 전부입니다. 간단하죠? 이제 Postman으로 테스트를 해보겠습니다. Postman을 설치하고 실행한 뒤, 새로운 요청(Request)을 생성하고 MCP 타입을 선택하세요.
요청 URL로 http://localhost:8081/sse를 붙여넣으면 짜잔! 이제 도구(Tools)와 프롬프트(Prompts)를 테스트할 수 있습니다. 직접 이것저것 만져보며 시작해 보세요.
MCP 클라이언트 구축하기
MCP 클라이언트 구축하기
MCP 클라이언트는 Ollama 로컬 모델을 사용하여 프롬프트(prompt)에 답하고 MCP 서버의 도구(tools)를 실행하는 Spring Boot REST API가 될 것입니다. https://start.spring.io를 열고 의존성(dependencies)을 지정하세요. 의존성(Dependencies) 섹션에 다음 항목들을 추가합니다.
- Ollama
- Model Context Protocol Client
- Spring Web
Generate를 클릭하고, 다운로드된 파일의 압축을 푼 뒤 선호하는 IDE에서 프로젝트를 여세요. 이 글에서는 https://www.jetbrains.com/idea/download를 사용합니다.
프로젝트를 연 후, 프로젝트가 제대로 구성되었고 잘 실행되는지 확인하세요.
./gradlew bootRun --args='--spring.profiles.active=dev'
로그가 보여야 하며, 이는 프로젝트가 정상적으로 실행되고 있음을 의미합니다!
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기


