사내 시스템 연동 커스텀 MCP 도구 개발
1. 개요 및 MCP 표준 규격
Model Context Protocol (MCP)은 인공지능 에이전트가 외부 데이터 소스(데이터베이스, 사내 ERP, 배포 파이프라인 등)와 상호작용하기 위해 사용하는 개방형 JSON-RPC 2.0 통신 규격입니다.
SyncSeries에서는 사내 레거시 시스템의 기능을 에이전트가 이해할 수 있는 정형화된 JSON Schema 도구로 노출하고, 이를 에이전트가 필요에 따라 자율적으로 호출(Tool Calling)할 수 있도록 표준화된 어노테이션 기반 도구 등록 메커니즘을 제공합니다.
2. Java 기반 커스텀 도구 구현
SyncSeries의 백엔드 모듈은 @Tool 애너테이션을 통해 일반 Spring Bean 메서드를 즉시 MCP 도구로 등록할 수 있습니다.
1) 도구 클래스 정의 및 스키마 선언
java
package com.empasy.sync.custom.tools;
import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderManagementTools {
private final InternalOrderRepository orderRepository;
@Tool(
name = "get_order_status",
description = "고객의 주문번호(orderId)를 기반으로 현재 주문 상태, 결제 금액, 택배 송장번호를 조회합니다."
)
public OrderStatusResult getOrderStatus(
@ToolParam(name = "orderId", description = "조회할 주문 고유 식별자 (예: ORD-2026-001)", required = true)
String orderId
) {
log.info("[MCP Tool] get_order_status 호출 수신 - orderId: {}", orderId);
// 1. 입력값 기본 유효성 검증
if (orderId == null || !orderId.matches("^ORD-\\d{4}-\\d{3,}$")) {
throw new IllegalArgumentException("유효하지 않은 주문번호 형식입니다.");
}
// 2. 내부 데이터베이스 조회
return orderRepository.findByOrderId(orderId)
.map(order -> OrderStatusResult.builder()
.orderId(order.getId())
.status(order.getStatus().name())
.amount(order.getTotalAmount())
.trackingNumber(order.getTrackingNumber())
.build())
.orElseThrow(() -> new OrderNotFoundException("주문 정보를 찾을 수 없습니다: " + orderId));
}
}2) DTO 모델 설계 (Lombok 적용)
java
package com.empasy.sync.custom.tools;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
@Getter
@Builder
public class OrderStatusResult {
private String orderId;
private String status;
private BigDecimal amount;
private String trackingNumber;
}3. 입력값 검증 및 보안 가드레일 (RBAC)
에이전트가 호출하는 도구는 악의적이거나 비정상적인 파라미터가 유입될 수 있으므로, 반드시 엄격한 가드레일을 적용해야 합니다.
- JSON Schema 엄격 바인딩:
- 허용되지 않은 추가 필드(
additionalProperties: false)는 자동 차단합니다. - 숫자 파라미터는 최소/최대 범위(
minimum,maximum), 문자열은 정규식 패턴(pattern)을 명시합니다.
- 허용되지 않은 추가 필드(
- 역할 기반 인가 (Tool RBAC):
- 데이터 삭제, 설정 변경 등 쓰기 권한이 필요한 도구는 세션의 사용자 권한을 검증합니다:java
@Tool(name = "cancel_order", description = "주문을 취소하고 결제를 환불 처리합니다.") @PreAuthorize("hasRole('ROLE_SHOP_ADMIN')") public OrderCancelResult cancelOrder(...) { ... }
- 데이터 삭제, 설정 변경 등 쓰기 권한이 필요한 도구는 세션의 사용자 권한을 검증합니다:
4. MCP JSON-RPC 통신 규격 확인
등록된 도구는 표준 MCP 클라이언트에 의해 다음과 같이 조회되고 실행됩니다.
도구 목록 조회 응답 (tools/list)
json
{
"jsonrpc": "2.0",
"result": {
"tools": [
{
"name": "get_order_status",
"description": "고객의 주문번호(orderId)를 기반으로 현재 주문 상태를 조회합니다.",
"inputSchema": {
"type": "object",
"properties": {
"orderId": {
"type": "string",
"description": "조회할 주문 고유 식별자"
}
},
"required": ["orderId"],
"additionalProperties": false
}
}
]
},
"id": 1
}도구 실행 요청 (tools/call)
json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_order_status",
"arguments": {
"orderId": "ORD-2026-001"
}
},
"id": 2
}