MCP 서버
개요
MCP 서버는 Model Context Protocol(MCP) 아키텍처의 기반 구성 요소로, 클라이언트에 도구/리소스/기능을 제공합니다. 즉, 프로토콜의 서버 측을 구현하며 다음을 담당합니다:
- 클라이언트가 탐색하고 실행할 수 있는 도구(tools) 노출
- URI 기반 접근 패턴으로 리소스(resources) 관리
- 프롬프트(prompts) 템플릿 제공 및 프롬프트 요청 처리
- 클라이언트와 capability 협상 지원
- 서버 측 프로토콜 동작 구현
- 동시 클라이언트 연결 관리
- 구조화된 로깅 및 알림(notification) 제공
서버는 동기/비동기 API를 모두 지원하므로, 다양한 애플리케이션 컨텍스트에서 유연하게 통합할 수 있습니다.
// Create a server with custom configuration
McpSyncServer syncServer = McpServer.sync(transport)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(true) // Enable resource support
.tools(true) // Enable tool support
.prompts(true) // Enable prompt support
.logging() // Enable logging support
.build())
.build();
// Register tools, resources, and prompts
syncServer.addTool(syncToolRegistration);
syncServer.addResource(syncResourceRegistration);
syncServer.addPrompt(syncPromptRegistration);
// Send logging notifications
syncServer.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Server initialized")
.build());
// Close the server when done
syncServer.close();// Create an async server with custom configuration
McpAsyncServer asyncServer = McpServer.async(transport)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(true) // Enable resource support
.tools(true) // Enable tool support
.prompts(true) // Enable prompt support
.logging() // Enable logging support
.build())
.build();
// Register tools, resources, and prompts
asyncServer.addTool(asyncToolRegistration)
.doOnSuccess(v -> logger.info("Tool registered"))
.subscribe();
asyncServer.addResource(asyncResourceRegistration)
.doOnSuccess(v -> logger.info("Resource registered"))
.subscribe();
asyncServer.addPrompt(asyncPromptRegistration)
.doOnSuccess(v -> logger.info("Prompt registered"))
.subscribe();
// Send logging notifications
asyncServer.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Server initialized")
.build());
// Close the server when done
asyncServer.close()
.doOnSuccess(v -> logger.info("Server closed"))
.subscribe();서버 전송(transport)
프로세스 기반 전송 생성:
StdioServerTransport transport = new StdioServerTransport(new ObjectMapper());표준 입력/출력(stdin/stdout) 스트림 위에서 양방향 JSON-RPC 메시지 처리를 제공하며, 논블로킹 메시지 처리, 직렬화/역직렬화, 정상 종료(graceful shutdown)를 지원합니다.
주요 기능:
- stdin/stdout 기반 양방향 통신
- 프로세스 기반 통합 지원
- 간단한 설정과 구성
- 경량 구현
WebFlux 기반 SSE 서버 전송을 생성합니다.
mcp-spring-webflux 의존성이 필요합니다.
@Configuration
class McpConfig {
@Bean
WebFluxSseServerTransport webFluxSseServerTransport(ObjectMapper mapper) {
return new WebFluxSseServerTransport(mapper, "/mcp/message");
}
@Bean
RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransport transport) {
return transport.getRouterFunction();
}
}MCP HTTP+SSE 전송 사양을 구현하며, 다음을 제공합니다:
- WebFlux 기반 리액티브 HTTP 스트리밍
- SSE 엔드포인트를 통한 동시 클라이언트 연결
- 메시지 라우팅 및 세션 관리
- 정상 종료 기능
WebMvc 기반 SSE 서버 전송을 생성합니다.
mcp-spring-webmvc 의존성이 필요합니다.
@Configuration
@EnableWebMvc
class McpConfig {
@Bean
WebMvcSseServerTransport webMvcSseServerTransport(ObjectMapper mapper) {
return new WebMvcSseServerTransport(mapper, "/mcp/message");
}
@Bean
RouterFunction<ServerResponse> mcpRouterFunction(WebMvcSseServerTransport transport) {
return transport.getRouterFunction();
}
}MCP HTTP+SSE 전송 사양을 구현하며, 다음을 제공합니다:
- 서버-사이드 이벤트 스트리밍
- Spring WebMVC 통합
- 전통적인 웹 애플리케이션 지원
- 동기 작업 처리
Servlet 기반 SSE 서버 전송을 생성합니다. 코어 mcp 모듈에 포함되어 있습니다.
HttpServletSseServerTransport는 어떤 Servlet 컨테이너에서도 사용할 수 있습니다.
Spring Web 애플리케이션에서 사용하려면 Servlet 빈으로 등록할 수 있습니다:
@Configuration
@EnableWebMvc
public class McpServerConfig implements WebMvcConfigurer {
@Bean
public HttpServletSseServerTransport servletSseServerTransport() {
return new HttpServletSseServerTransport(new ObjectMapper(), "/mcp/message");
}
@Bean
public ServletRegistrationBean customServletBean(HttpServletSseServerTransport servlet) {
return new ServletRegistrationBean(servlet);
}
}전통적인 Servlet API를 사용해 MCP HTTP+SSE 전송 사양을 구현하며, 다음을 제공합니다:
- Servlet 6.0 async 지원을 활용한 비동기 메시지 처리
- 다중 클라이언트 연결을 위한 세션 관리
- 두 종류의 엔드포인트:
- 서버→클라이언트 이벤트를 위한 SSE 엔드포인트(
/sse) - 클라이언트→서버 요청을 위한 메시지 엔드포인트(구성 가능)
- 서버→클라이언트 이벤트를 위한 SSE 엔드포인트(
- 오류 처리 및 응답 포맷팅
- 정상 종료 지원
서버 capability
서버는 다양한 capability로 구성할 수 있습니다:
var capabilities = ServerCapabilities.builder()
.resources(false, true) // Resource support with list changes notifications
.tools(true) // Tool support with list changes notifications
.prompts(true) // Prompt support with list changes notifications
.logging() // Enable logging support (enabled by default with logging level INFO)
.build();로깅 지원
서버는 구조화된 로깅 기능을 제공하며, 다양한 심각도 수준으로 클라이언트에 로그 메시지를 전송할 수 있습니다:
// Send a log message to clients
server.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Custom log message")
.build());클라이언트는 mcpClient.setLoggingLevel(level) 요청을 통해 수신할 최소 로깅 레벨을 제어할 수 있습니다. 설정된 레벨보다 낮은 메시지는 필터링됩니다.
지원 로깅 레벨(심각도 증가 순): DEBUG (0), INFO (1), NOTICE (2), WARNING (3), ERROR (4), CRITICAL (5), ALERT (6), EMERGENCY (7)
도구 등록
// Sync tool registration
var syncToolRegistration = new McpServerFeatures.SyncToolRegistration(
new Tool("calculator", "Basic calculator", Map.of(
"operation", "string",
"a", "number",
"b", "number"
)),
arguments -> {
// Tool implementation
return new CallToolResult(result, false);
}
);// Async tool registration
var asyncToolRegistration = new McpServerFeatures.AsyncToolRegistration(
new Tool("calculator", "Basic calculator", Map.of(
"operation", "string",
"a", "number",
"b", "number"
)),
arguments -> {
// Tool implementation
return Mono.just(new CallToolResult(result, false));
}
);리소스 등록
// Sync resource registration
var syncResourceRegistration = new McpServerFeatures.SyncResourceRegistration(
new Resource("custom://resource", "name", "description", "mime-type", null),
request -> {
// Resource read implementation
return new ReadResourceResult(contents);
}
);// Async resource registration
var asyncResourceRegistration = new McpServerFeatures.AsyncResourceRegistration(
new Resource("custom://resource", "name", "description", "mime-type", null),
request -> {
// Resource read implementation
return Mono.just(new ReadResourceResult(contents));
}
);프롬프트 등록
// Sync prompt registration
var syncPromptRegistration = new McpServerFeatures.SyncPromptRegistration(
new Prompt("greeting", "description", List.of(
new PromptArgument("name", "description", true)
)),
request -> {
// Prompt implementation
return new GetPromptResult(description, messages);
}
);// Async prompt registration
var asyncPromptRegistration = new McpServerFeatures.AsyncPromptRegistration(
new Prompt("greeting", "description", List.of(
new PromptArgument("name", "description", true)
)),
request -> {
// Prompt implementation
return Mono.just(new GetPromptResult(description, messages));
}
);오류 처리
SDK는 McpError 클래스를 통해 포괄적인 오류 처리를 제공합니다. 여기에는 프로토콜 호환성, 전송 통신, JSON-RPC 메시징, 도구 실행, 리소스 관리, 프롬프트 처리, 타임아웃, 연결 문제 등이 포함됩니다. 이처럼 통합된 오류 처리 접근은 동기/비동기 작업 전반에서 일관되고 신뢰할 수 있는 오류 관리를 보장합니다.