Protobuf를 이용한 MCP 서버 구축 (4부) – 실제로 MCP 도구를 실행하면서 얻은 통찰력
Charlie Zhang
2025년 10월 11일
이 블로그 시리즈에서는 유용한 도구들로 가득 찬 MCP (Model Context Protocol) 서버를 구축하는 방법을 보여드렸습니다. 처음부터 시작하는 대신, 기존의 프로토콜 버퍼와 Google의 gRPC 트랜스코딩을 활용했습니다. 맞춤형 protoc 플러그인을 생성하여 MCP 서버를 자동으로 생성했으며, 이 통합된 접근 방식을 통해 gRPC 서비스, OpenAPI 사양, REST API 및 MCP 서버를 모두 동일한 소스에서 생성할 수 있었습니다.
블로그 시리즈 구성
이 블로그 시리즈는 4개의 기사로 구성되어 있습니다:
- 1부: gRPC 트랜스코딩을 사용하여 Protobuf에서 REST API 생성하기
- 2부: Protoc 플러그인을 사용하여 MCP 서버 생성 자동화하기
- 3부: Proto 주석으로 AI 상호작용 향상시키기
- 4부: (본 기사) 실제로 MCP 도구를 실행하면서 얻은 통찰력
얻게 될 내용
자동 생성된 MCP 도구를 테스트하는 과정에서, 우리는 몇 가지 중요한 한계점을 발견했습니다. 이 글에서는 실제 AI 에이전트와 MCP 도구를 실행하면서 얻은 실용적인 통찰력을 공유하며 다음 내용을 다룹니다:
- 자동 생성된 MCP 도구의 결정적인 한계점
- 도구의 개수가 중요한 이유 (20개 미만 유지)
- 응답 크기가 AI 워크플로우를 망가뜨리는 방식
- 자동 생성이 적합한 경우와 맞춤 설계가 필요한 경우
자동 생성된 MCP 도구의 주요 문제점 (Key Challenges)
문제 1: 너무 많은 도구는 혼란을 야기합니다.
모든 API 엔드포인트를 MCP 도구로 변환하면 AI가 압도적인 선택지에 직면하게 됩니다. 한 서비스는 20개 이상의 도구를 생성했고, 이로 인해 다음과 같은 문제가 발생했습니다.
- 잘못된 도구 선택: AI가 비슷하게 들리지만 잘못된 도구를 선택합니다.
- 재시도 루프: 잘못된 도구 변형을 반복적으로 시도합니다.
- 열악한 도구 체이닝: 여러 단계로 이루어진 워크플로우가 실패합니다.
- 저하된 사용자 경험: 과도한 확인 질문이 발생합니다.
해결책: AI 에이전트당 도구 수를 20개 미만으로 유지하는 것입니다. 집중된 도구 그룹을 만드세요.
# 20개의 도구 대신, 집중된 그룹 생성:
bookstore_core = ["get_book", "create_book", "search_books"] # 3개 도구
user_management = ["get_user", "create_user", "authenticate_user"] # 3개 도구
order_processing = ["create_order", "get_order_status", "process_payment"] # 3개 도구
# ...
문제 2: ID 기반 vs. 이름 기반 입력
전통적인 API는 프로그래밍 방식의 접근을 위해 ID를 사용합니다:
// 전통적 방식 (개발자 친화적)
message GetBookRequest {
string book_id = 1; // "550e8400-e29b-41d4-a716-446655440000"
}
하지만 AI 에이전트는 자연어를 다룹니다. 사용자는 “ID 550e8400…”을 사용하여 책을 가져오라고 말하는 대신, “Learning Python” 책을 가져와라고 말합니다.
해결책: 다음과 같이 자연어를 입력으로 받아들이도록 설계해야 합니다.
// AI 친화적 방식 (사용자 친화적)
message SearchBookRequest {
string title = 1;
string author = 2; // 선택적 필터
}
문제 3: 입력 매개변수의 복잡한 중첩 구조
전통적인 API는 유연성을 위해 중첩 구조를 사용합니다. 하지만 AI 에이전트는 다음과 같은 이유로 이러한 구조를 이해하는 데 어려움을 겪습니다.
- 필드 간의 관계를 이해하기 어려움
- 복잡한 객체 구성 시 실수 발생
피해야 할 설계:
message CreateOrderRequest {
OrderDetails order = 1;
PaymentInfo payment = 2;
repeated PromotionCode promotions = 4;
OrderOptions options = 5;
}
더 나은 설계 (평탄화):
message CreateSimpleOrder {
string customer_name = 1;
string item_name = 2;
int32 quantity = 3;
string shipping_address = 4;
}
문제 4: 대규모 응답 페이로드
전통적인 API는 포괄적인 중첩 데이터를 반환합니다. 자동 생성된 도구는 응답을 사용자 정의할 수 없으므로 컨텍스트 창 오버플로우를 유발합니다.
예를 들어, get_location 도구가 인프라, 규정 준수, 네트워크 데이터를 포함한 완전한 정보를 반환하면, AI의 컨텍스트 창 대부분을 소모하는 대규모 JSON이 생성될 수 있습니다.
해결책: 포괄적인 API를 MCP 도구로 노출하지 마세요. 대신 내부적으로 사용하고 작업 중심의 도구를 노출합니다.
# MCP 도구가 아님 - 내부 도우미
async def _get_location_internal(location_id: str) -> Location:
# ... (모든 데이터를 가져옴)
# MCP 도구 - 집중된 작업
async def validate_deployment_location(location_name: str) -> ValidationResult:
"""위치가 배포 요구 사항을 충족하는지 확인합니다."""
location = await _get_location_internal(location_name)
# 내부적으로 처리 및 검증 수행
# ...
# 필수적인 정보만 반환
return ValidationResult(
location_name=location.name,
is_valid=checks.passed,
summary=f"Location {location.name} is {'ready' if checks.passed else 'not ready'}"
)
자동 생성과 맞춤 설계가 필요한 시점
| 영역 | 자동 생성이 적합한 경우 | 맞춤 MCP 도구가 필요한 경우 |
| 속도 | 신속한 프로토타이핑 및 개념 증명(PoC) | 운영 환경 배포 |
| 복잡성 | 단순한 CRUD (생성, 읽기, 업데이트, 삭제) 작업 | 20개 이상의 엔드포인트를 가진 복잡한 API |
| 입력 | 이미 ID가 잘 알려져 있는 시스템 | 자연어 기반의 사용자 상호작용이 필요한 시스템 |
| 구조 | 평탄하고 단순한 요청/응답 구조 | 복잡한 중첩 구조를 가진 API |
| 출력 | 소규모 응답 페이로드 | 대규모 응답 페이로드 및 컨텍스트 오버플로우 위험이 있는 경우 |
| 사용자 | 내부 도구 또는 개발/테스트 목적 | 최종 사용자 대상 애플리케이션 |
LLM 모델 선택의 영향
LLM 모델의 선택은 도구 설계 전략에 상당한 영향을 미칩니다.
강력한 LLM 모델
강력한 모델은 다음과 같은 이유로 단순하고 간결한 설명으로 작업할 수 있습니다.
- 최소한의 정보로 컨텍스트와 의도를 추론하는 데 탁월합니다.
- 도구 간의 암묵적인 관계를 이해합니다.
- 모호성과 예외 상황을 원활하게 처리합니다.
async def create_database_cluster():
"""새 데이터베이스 클러스터를 생성합니다. 필요 항목: 이름, 리전, 인스턴스 유형."""
이러한 모델은 최소한의 안내만으로도 도구를 지능적으로 연결할 수 있습니다.
덜 강력한 모델
소규모 또는 성능이 낮은 모델은 제한된 추론 능력을 보완하기 위해 상세하고 명시적인 설명이 필요합니다.
async def create_database_cluster():
"""자동 구성으로 새 데이터베이스 클러스터를 생성합니다.
이 도구는 다음을 포함한 완전한 클러스터 설정을 처리합니다:
- 규정 준수 요구 사항 기반 리전 선택
- 워크로드 힌트 기반 자동 인스턴스 크기 조정
- 네트워크 구성 및 보안 그룹
사용 시점: 사용자가 모든 세부 정보를 지정하지 않고 데이터베이스를 생성하고자 할 때 사용합니다. AI가 컨텍스트에서 적절한 설정을 추론합니다.
사용하지 말아야 할 시점: 모든 설정을 수동으로 제어해야 하는 경우 create_database_cluster_advanced를 대신 사용하십시오.
피해야 할 일반적인 실수:
- 사용자가 사용자 지정 네트워크 설정을 지정하는 경우 사용하지 마십시오.
- 특정 규정 준수가 필요한 운영 클러스터에 사용하지 마십시오.
"""
따라서 우리는 약한 모델이 아닌 강력한 LLM 모델로 시작하는 것을 권장합니다. 그 이유는 다음과 같습니다.
- 조기 최적화 방지: 약한 모델로 도구 문제를 디버깅하는 것은 더 나은 모델에서는 존재하지 않을 문제에 시간을 낭비하는 것입니다.
- 더 나은 오류 복구: 강력한 모델은 예외 상황을 처리하고 과도한 도움 없이 오류에서 복구합니다.
- 더 빠른 반복: 설명이 단순할수록 작성하고 유지 관리할 문서가 줄어들어 반복 속도가 빨라집니다.
- 운영 품질: 대부분의 운영 환경 배포는 어차피 강력한 모델의 이점을 얻습니다.
일단 MCP 도구가 강력한 모델에서 잘 작동하면, 다음 방법을 통해 선택적으로 더 작은 모델을 지원할 수 있습니다.
- 상세한 설명과 예시 추가
- 에이전트 워크플로우를 더 간단하고 순차적인 것으로 분할
하이브리드 접근 방식: 자동 생성 + 맞춤 설계
자동 생성을 사용하여 개념을 신속하게 검증한 다음, 운영 환경을 위해 맞춤형 MCP 도구를 만드세요.
1단계: 자동 생성으로 프로토타이핑
기존 API를 MCP 도구로 자동 변환하는 가이드를 따릅니다. 이는 신속한 반복, PoC 및 내부 도구에 유용합니다.
2단계: 운영을 위한 맞춤형 Proto 정의 설계
운영 환경으로 이동할 때는 MCP 도구를 처음부터 만듭니다. API 엔드포인트가 아닌 사용자 작업을 중심으로 설계하세요. 자연어 입력, 평탄한 구조, 집중된 응답을 사용합니다. “이 API가 무엇을 하는가?” 대신 “사용자가 무엇을 달성하고 싶어 하는가?”에 초점을 맞추세요.
이러한 하이브리드 접근 방식은 초기 개발 속도와 함께 필요할 때 운영 품질을 모두 제공합니다.
결론
이 네 부분에 걸쳐, 우리는 AI 에이전트를 위한 자동화된 API 생성의 강점과 한계를 모두 보여드렸습니다. 핵심은 언제 자동화를 사용해야 하는지 그리고 언제 맞춤형 설계에 투자해야 하는지를 아는 것입니다.

