상태 없는(Stateless) Streamable-HTTP MCP 서버
상태 없는(Stateless) Streamable-HTTP MCP 서버
상태 없는 Streamable-HTTP MCP 서버는 요청 간에 세션 상태를 유지하지 않는 단순화된 배포를 위해 설계됐어요. 마이크로서비스 아키텍처와 클라우드 네이티브 배포에 이상적인 구조라서, 세션 관리 없이 가볍게 서버를 운영할 수 있어요. 이 글에서 구성 방법과 기능을 살펴볼게요.
출처: 문서
본문
상태 없는 Streamable-HTTP MCP 서버 (Stateless Streamable-HTTP MCP Servers)
상태 없는 Streamable-HTTP MCP 서버는 요청 간에 세션 상태를 유지하지 않는 단순화된 배포를 위해 설계됐어요. 이 서버는 마이크로서비스 아키텍처와 클라우드 네이티브 배포에 이상적이에요.
참고:
spring.ai.mcp.server.protocol=STATELESS프로퍼티를 설정하세요.
참고: 상태 없는 서버에 연결하려면 Streamable-HTTP 클라이언트를 사용하세요.
참고: 상태 없는 서버는 MCP 클라이언트에 대한 메시지 요청(예: elicitation, sampling, ping)을 지원하지 않아요.
상태 없는 WebMVC 서버 (Stateless WebMVC Server)
spring-ai-starter-mcp-server-webmvc 의존성을 사용하세요:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
그리고 spring.ai.mcp.server.protocol 프로퍼티를 STATELESS로 설정하세요.
spring.ai.mcp.server.protocol=STATELESS
- Spring MVC 전송을 사용한 상태 없는 동작
- 세션 상태 관리 없음
- 단순화된 배포 모델
- 클라우드 네이티브 환경에 최적화
상태 없는 WebFlux 서버 (Stateless WebFlux Server)
spring-ai-starter-mcp-server-webflux 의존성을 사용하세요:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
그리고 spring.ai.mcp.server.protocol 프로퍼티를 STATELESS로 설정하세요.
- WebFlux 전송을 사용한 반응형 상태 없는 동작
- 세션 상태 관리 없음
- 블로킹되지 않는 요청 처리
- 높은 처리량 시나리오에 최적화
구성 프로퍼티 (Configuration Properties)
공통 프로퍼티 (Common Properties)
모든 공통 프로퍼티는 spring.ai.mcp.server 프리픽스가 붙어요:
| Property | Description | Default |
|---|---|---|
enabled |
상태 없는 MCP 서버 활성화/비활성화 | true |
protocol |
MCP 서버 프로토콜 | 상태 없는 서버를 활성화하려면 STATELESS로 설정해야 함 |
tool-callback-converter |
Spring AI ToolCallback을 MCP Tool 스펙으로 변환 활성화/비활성화 | true |
name |
식별을 위한 서버 이름 | mcp-server |
version |
서버 버전 | 1.0.0 |
instructions |
클라이언트 상호작용을 위한 선택적 지침 | null |
type |
서버 타입 (SYNC/ASYNC) | SYNC |
capabilities.resource |
리소스 기능 활성화/비활성화 | true |
capabilities.tool |
도구 기능 활성화/비활성화 | true |
capabilities.prompt |
프롬프트 기능 활성화/비활성화 | true |
capabilities.completion |
완성 기능 활성화/비활성화 | true |
expose-mcp-client-tools |
다운스트림 MCP 도구(MCP 클라이언트가 제공)를 이 MCP 서버의 도구로 다시 노출할지 여부 | false |
tool-response-mime-type |
도구 이름별 응답 MIME 타입 | - |
request-timeout |
요청 타임아웃 기간 | 20 seconds |
MCP 어노테이션 프로퍼티 (MCP Annotations Properties)
MCP 서버 어노테이션은 Java 어노테이션을 사용해 MCP 서버 핸들러를 선언적으로 구현하는 방법을 제공해요. 서버 mcp-annotations 프로퍼티는 spring.ai.mcp.server.annotation-scanner 프리픽스가 붙어요:
| Property | Description | Default Value |
|---|---|---|
enabled |
MCP 서버 어노테이션 자동 스캔 활성화/비활성화 | true |
상태 없는 연결 프로퍼티 (Stateless Connection Properties)
모든 연결 프로퍼티는 spring.ai.mcp.server.stateless 프리픽스가 붙어요:
| Property | Description | Default |
|---|---|---|
mcp-endpoint |
커스텀 MCP 엔드포인트 경로 | /mcp |
disallow-delete |
delete 작업 금지 | false |
기능과 역량 (Features and Capabilities)
MCP Server Boot Starter는 서버가 도구, 리소스, 프롬프트를 클라이언트에 노출할 수 있게 해 줘요. Spring 빈으로 등록된 커스텀 기능 핸들러를 서버 타입에 따라 자동으로 동기/비동기 명세로 변환해요:
도구 (Tools)
언어 모델이 호출할 수 있는 도구를 서버가 노출할 수 있게 해 줘요. MCP Server Boot Starter는 다음을 제공해요:
- 변경 알림 지원
- Spring AI 도구를 서버 타입에 따라 자동으로 동기/비동기 명세로 변환
- Spring 빈을 통한 자동 도구 명세:
@Bean
public ToolCallbackProvider myTools(...) {
List<ToolCallback> tools = ...
return ToolCallbackProvider.from(tools);
}
또는 저수준 API 사용:
@Bean
public List<McpStatelessServerFeatures.SyncToolSpecification> myTools(...) {
List<McpStatelessServerFeatures.SyncToolSpecification> tools = ...
return tools;
}
자동 설정은 다음에서 모든 도구 콜백을 자동으로 감지하고 등록해요:
- 개별
ToolCallback빈 ToolCallback빈 목록ToolCallbackProvider빈
도구는 이름으로 중복 제거되며, 각 도구 이름의 첫 번째 등장이 사용돼요.
참고:
tool-callback-converter를false로 설정하면 모든 도구 콜백의 자동 감지·등록을 비활성화할 수 있어요.
참고: 도구 컨텍스트 지원은 상태 없는 서버에는 적용되지 않아요.
리소스 (Resources)
서버가 클라이언트에 리소스를 노출하는 표준화된 방법을 제공해요.
- 정적·동적 리소스 명세
- 선택적 변경 알림
- 리소스 템플릿 지원
- 동기/비동기 리소스 명세 간 자동 변환
- Spring 빈을 통한 자동 리소스 명세:
@Bean
public List<McpStatelessServerFeatures.SyncResourceSpecification> myResources(...) {
var systemInfoResource = McpSchema.Resource.builder(...);
var resourceSpecification = new McpStatelessServerFeatures.SyncResourceSpecification(systemInfoResource, (context, request) -> {
try {
var systemInfo = Map.of(...);
String jsonContent = new JsonMapper().writeValueAsString(systemInfo);
return McpSchema.ReadResourceResult.builder(
List.of(McpSchema.TextResourceContents.builder(request.uri(), jsonContent).mimeType("application/json").build())).build();
}
catch (Exception e) {
throw new RuntimeException("Failed to generate system info", e);
}
});
return List.of(resourceSpecification);
}
프롬프트 (Prompts)
서버가 클라이언트에 프롬프트 템플릿을 노출하는 표준화된 방법을 제공해요.
- 변경 알림 지원
- 템플릿 버전 관리
- 동기/비동기 프롬프트 명세 간 자동 변환
- Spring 빈을 통한 자동 프롬프트 명세:
@Bean
public List<McpStatelessServerFeatures.SyncPromptSpecification> myPrompts() {
var prompt = McpSchema.Prompt.builder("greeting").description("A friendly greeting prompt")
.arguments(List.of(McpSchema.PromptArgument.builder("name").description("The name to greet").required(true).build())).build();
var promptSpecification = new McpStatelessServerFeatures.SyncPromptSpecification(prompt, (context, getPromptRequest) -> {
String nameArgument = (String) getPromptRequest.arguments().get("name");
if (nameArgument == null) { nameArgument = "friend"; }
var userMessage = PromptMessage.builder(Role.USER, TextContent.builder("Hello " + nameArgument + "! How can I assist you today?").build()).build();
return GetPromptResult.builder(List.of(userMessage)).description("A personalized greeting message").build();
});
return List.of(promptSpecification);
}
완성 (Completion)
서버가 클라이언트에 완성 기능을 노출하는 표준화된 방법을 제공해요.
- 동기·비동기 완성 명세 모두 지원
- Spring 빈을 통한 자동 등록:
@Bean
public List<McpStatelessServerFeatures.SyncCompletionSpecification> myCompletions() {
var completion = new McpStatelessServerFeatures.SyncCompletionSpecification(
McpSchema.PromptReference.builder("code-completion").title("Provides code completion suggestions").build(),
(exchange, request) -> {
// Implementation that returns completion suggestions
return new McpSchema.CompleteResult(List.of("python", "pytorch", "pyside"), 10, true);
}
);
return List.of(completion);
}
사용 예시 (Usage Examples)
상태 없는 서버 구성 (Stateless Server Configuration)
spring:
ai:
mcp:
server:
protocol: STATELESS
name: stateless-mcp-server
version: 1.0.0
type: ASYNC
instructions: "This stateless server is optimized for cloud deployments"
streamable-http:
mcp-endpoint: /api/mcp
MCP 서버로 Spring Boot 애플리케이션 만들기
@Service
public class WeatherService {
@Tool(description = "Get weather information by city name")
public String getWeather(String cityName) {
// Implementation
}
}
@SpringBootApplication
public class McpServerApplication {
private static final Logger logger = LoggerFactory.getLogger(McpServerApplication.class);
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
}
자동 설정은 도구 콜백을 MCP 도구로 자동으로 등록해요. ToolCallback을 생성하는 빈이 여러 개 있어도 되며, 자동 설정이 그것들을 병합해요.