MCP를 통해 90개 이상의 도구를 노출하는 방법: 카탈로그가 서버보다 먼저 깨지는 이유
요약
본 글은 Model Context Protocol (MCP)을 통해 다수의 도구(90개 이상)를 노출하는 플랫폼 설계 원칙을 제시합니다. MCP 서버를 단순한 엔드포인트가 아닌, LLM 게이트웨이와 같은 '도구 브로커'로 취급해야 한다고 강조합니다. 이를 위해 일관된 신원 규칙, 이벤트 기반 측정 방식, 엄격한 감사 규율 적용이 필수적입니다.
핵심 포인트
- MCP 서버는 도구 브로커(tool broker)로 설계되어야 합니다.
- 도구 이름은 `{카테고리}.{동사}_{명사}` 형태의 계약적인 명명 규칙을 따릅니다.
- 쓰기 작업에는 Idempotency 키를 적용하고, 모든 쓰기 이벤트에 대한 감사 기록이 필요합니다.
- 무한정 확장되는 목록 도구는 컨텍스트 창 폭탄이므로 페이지네이션을 사용해야 합니다.
내부 도구 중 하나를 Model Context Protocol (MCP)을 통해 노출하는 것은 주말 프로젝트 수준입니다. 하지만 90개의 도구를 사람과 에이전트 모두에게 노출하면서, MCP 엔드포인트를 자격 증명(credential) 저장소로 만들거나 감사 로그(audit log)를 화재 위험 지역으로 만드는 것을 피하는 것은 플랫폼 문제입니다.
본 게시물은 제가 이 플랫폼을 어떻게 설계할지에 대한 간략한 버전입니다. 한 줄 요약하자면 다음과 같습니다: MCP 서버를 LLM 게이트웨이와 같은 계열의 도구 브로커(tool broker)로 취급해야 합니다. 동일한 신원 규칙(정적 키 사용 금지), 동일한 측정 방식(모든 호출은 이벤트임), 동일한 감사 규율을 적용해야 합니다. 또한, LLM 경로에서는 필요하지 않은 두 가지 요소가 더 필요합니다: 저장된 제3자 자격 증명을 위한 엔벨로프(envelope)와 반환되는 데이터에 대한 PII 마스킹 단계입니다.
1. 도구를 카테고리별로 구성하고, 도구별로 구성하지 말 것
90개 이상의 도구가 되면, 첫 번째 실패는 성능 문제가 아니라 조직적인 문제입니다. 다음 몇 가지 규칙이 카탈로그를 건전하게 유지합니다:
- 명명 규칙은 계약이다:
{카테고리}.{동사}_{명사}형태입니다. 예:issues.create_ticket,mail.send_draft,ci.get_pipeline_logs. 도구의 이름을 변경하는 것은 조용한 수정이 아니라, 사용 중단 기간(deprecation window)을 거치는 파괴적인 변경(breaking change)입니다. - 도구 하나 = 권한, 감사, 테스트 단위 하나.
• 재시도 가능한 쓰기 작업의 Idempotency 키. 동일한 키로 재시도된 생성 요청은 중복이 아닌 동일한 티켓을 반환해야 합니다. 이를 쓰기 도구에 대한 등록 시점 검사(lint)로 만드세요.
• 오류는 계약의 일부입니다. 상위 시스템의 실패를 retryable 플래그가 있는 작은 분류 체계로 정규화하고 (그리고 가능하다면 Retry-After 헤더와 함께). 에이전트는 이 플래그에 따라 재시도하고, 사람은 코드를 읽습니다.
• 읽기는 저렴하지만, 쓰기는 크고 명확합니다. 쓰기 작업은 최소한의 역할과 범위(프로젝트, 공간, 폴더)가 필요합니다. 쓰기에 대한 감사 이벤트는 전체 (마스킹된) 입력을 포함하고; 읽기에 대한 것은 모양만 가져야 합니다.
• 모든 목록에 경계를 설정하세요. 기본 limit 50, 서버 최대치 200, 커서 기반 페이지네이션을 사용해야 합니다. 무한정 확장되는 목록 도구는 컨텍스트 창(context-window) 폭탄입니다.
• 알고 있는 것을 반환하지 말고, 요청된 것만 반환하세요. 보강 정보(
- PKCE를 모든 클라이언트 유형(IDE 및 에이전트 런타임 포함)에 적용해야 합니다. MCP 클라이언트는 일반적으로 비밀 키(secret)를 보유할 수 없습니다.
- 리소스 식별자. 토큰의 대상(audience)은 MCP 서버입니다. 다른 서비스용으로 발급된 유효한 토큰은 거부됩니다.
- 동적 클라이언트 등록(DCR)은 승인(grant)이 아닙니다. DCR은 '사용자 자체 에이전트 런타임 가져오기'를 가능하게 유지합니다(리디렉션 URI 허용 목록, 인증 방법 확인). 하지만 도구 접근은 여전히 명시적인 승인을 통해 이루어집니다.
- 조직 전체에 대한 단일 토큰 시간 자세(posture)를 유지합니다. 예를 들어, 대화형 클라이언트는 15분짜리 액세스 토큰을 사용하고, 워크로드는 1시간짜리를 사용하며, 에이전트의 경우 리프레시 토큰 없이 (워크로드 ID를 통해 재인증합니다).
- 도구 그룹별 스코프(Scope)(
mcp:ci:read,mcp:issues:write)를 사용하여 동의 화면이 94개의 문자열 벽처럼 보이지 않고 읽기 쉬워집니다. - 클라이언트의 토큰은 절대 SaaS로 전송되지 않습니다. 브로커는 자체 자격 증명(credential)을 사용하여 다운스트림 시스템에 호출하고 감사 및 계량화를 위해 주체(principal)를 인밴드(in-band)로 전달합니다. 만약 다운스트림 시스템이 깔끔한 사용자별 위임 모델을 가지고 있다면, 그것을 사용하는 것이 더 강력한 설계입니다.
4. 저장된 비밀 정보: 엔벨로프 암호화(envelope encryption)와 이것이 제어 방식이 아닌 이유
브로커는 뒤에 있는 시스템들의 자격 증명을 저장해야 합니다. 표준 엔벨로프로 처리하십시오:
KMS 키-암호화 키 (KMS를 벗어나지 않으며, 자동 순환됨)
└── 카테고리별 데이터 암호화 키 (AES-256, KEK에 의해 래핑됨)
└── 비밀 값: AES-256-GCM(DEK, 값), 쓰기마다 새로운 96비트 논스
- **카테고리별 DEK(Data Encryption Key)**는 피해 범위를 한 카테고리로 제한합니다. 사용자별 토큰은 해당 카테고리 DEK 아래에 사용자별 DEK를 받습니다.
- 회전(Rotation)이 설계상 저렴함: KMS가 KEK(Key Encryption Key)를 회전시키고, 예약된 작업이 DEK를 재래핑합니다. 이 과정에서 비밀 암호문은 건드리지 않습니다.
- 하지만 저장 시 암호화는 단지 'DB 유출이 자격 증명 유출이 아님'만을 알려줄 뿐입니다. 진정한 통제는 어떤 역할(비상 접근 제외)도 비밀을 읽을 수 없다는 것입니다. 브로커는 이를 호출 과정에서만 사용하고, 버퍼를 0으로 만들며, 감사 이벤트에는 호출과 주체(principal)가 기록될 뿐, 자격 증명 자체는 절대 기록되지 않습니다. 포털은 '자격 증명 존재, 마지막 회전 N일 전'이라는 내용만을 보여줘야 합니다.
5. 반환 경로에서의 마스킹 (Mask on the way back)
LLM 게이트웨이는 페이로드에 대한 가시성을 유지할 수 있습니다. 하지만 MCP 경로는 그럴 수 없습니다. 도구 결과 자체가 제품이기 때문입니다. 따라서 결과는 클라이언트에게 전달되기 전, 그리고 저장되기 전에 PII(개인 식별 정보) 마스킹 단계를 거치며, 카탈로그의 도구별 pii 필드는 어떤 입력과 출력이 이를 필요로 하는지 명시합니다. 이 때문에 쓰기 감사 로그도 원본이 아닌 마스킹된 입력을 저장하는 것입니다.
체크리스트 버전
- 프록시가 아닌 브로커: 정적 키 없음, 모든 호출은 측정 및 감사됨
- 카테고리 명명 규칙, 도구당 하나의 권한, 스키마 버전 관리, 그룹 권한 부여
- 멱등성(Idempotency), 오류 분류법(error taxonomy), 경계가 있는 목록(bounded lists), 과도한 반환 금지
- OAuth 2.1 + PKCE, 청중 제한 토큰(audience-bound tokens), DCR ≠ grant, 그룹 스코프
- 카테고리별 DEK를 사용한 엔벨로프 암호화, 비밀은 사용만 되고 읽히지 않음
- 결과 및 저장된 감사 입력에 대한 PII 마스킹
이 내용은 제 책 **The AI Gateway Playbook**의 5장 요약본이며, 이 책은 LLM 게이트웨이 자체(모델 레지스트리, 키 없는 인증 및 RBAC, 할당량 및 예산, RAG 팀 비서, 운영 매뉴얼)에 대해서도 다루고 있습니다. Leanpub 페이지에서 무료 샘플을 받을 수 있습니다.
공개 고지: 이 기사와 책은 제가 이러한 종류의 플랫폼을 설계하고 운영한 경험을 바탕으로 AI의 도움을 받아 작성되었습니다. 모든 예시는 일반적입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기