MCP 디자인 패턴: AI 도구를 위한 6가지 아키텍처
요약
Model Context Protocol(MCP)을 활용하여 AI 에이전트와 외부 시스템을 연결할 때 고려해야 할 6가지 아키텍처 패턴을 소개합니다. 단순한 API 래퍼부터 복잡한 오케스트레이션 계층까지, 사용 사례에 맞는 적절한 MCP 서버 설계 방식을 제안합니다.
핵심 포인트
- MCP는 도구, 리소스, 프롬프트라는 세 가지 주요 프리미티브를 노출함
- 단순 API 래퍼 패턴은 안정적인 API를 빠르게 통합할 때 유용함
- 모델이 저수준 데이터를 직접 처리하게 하면 프롬프트 복잡도가 증가함
- 효율적인 MCP 설계는 데이터, 동작, 권한, 리스크 사이의 경계를 정의하는 것임
Model Context Protocol (MCP)이 현재 어디에나 있습니다. 모두가 MCP 서버를 구축하고, 도구를 에이전트(Agent)에 연결하며, 내부 시스템을 AI 클라이언트(Client)에 노출하고 있습니다.
상대적으로 주목을 덜 받는 것은 이러한 서버 뒤에 숨겨진 아키텍처(Architecture)입니다.
MCP 서버는 한 번 설정하고 잊어버리는 단순한 템플릿이 아닙니다. 사용 사례에 따라 적절한 구조는 완전히 다를 수 있습니다. API를 감싸는 얇은 래퍼(Wrapper), 로컬 리소스 서버(Local resource server), 그리고 장기 실행 작업(Long-running jobs)을 위한 오케스트레이션 계층(Orchestration layer)은 모두 MCP를 통해 기능을 노출하지만, 설계 방식은 동일해서는 안 됩니다.
저는 실무에서 여섯 가지 패턴이 나타나는 것을 목격했습니다. 이것은 학술적인 분류가 아닙니다. 다음과 같은 질문에 대한 의사결정 보조 도구입니다:
어떤 MCP 서버 형태가 문제에 적합한가?
MCP 서버란 무엇인가?
Model Context Protocol (MCP)은 AI 애플리케이션을 외부 컨텍스트(Context) 및 기능(Capabilities)에 연결하기 위한 개방형 프로토콜입니다.
MCP 서버는 세 가지 주요 유형의 프리미티브(Primitives)를 노출할 수 있습니다:
- 도구 (Tools): 호출 가능한 작업으로, 대개 매개변수(Parameters)와 구조화된 결과(Structured results)를 가집니다.
- 리소스 (Resources): 파일, 문서, 데이터베이스 레코드 또는 생성된 뷰(Views)와 같이 읽을 수 있는 컨텍스트입니다.
- 프롬프트 (Prompts): 재사용 가능한 프롬프트 템플릿(Prompt templates) 또는 상호작용 패턴입니다.
실제로 대부분의 사람들은 MCP에서 가장 눈에 띄는 부분인 도구(Tools)부터 시작합니다. 하지만 좋은 MCP 서버는 단순히 함수들의 집합이 아닙니다. 그것은 AI 클라이언트와 데이터, 동작(Behavior), 권한(Permissions), 그리고 리스크(Risk)를 가진 시스템 사이의 경계입니다.
중요한 질문은 단지 이것만이 아닙니다:
에이전트(Agent)가 무엇을 호출할 수 있는가?
또한 다음과 같은 질문도 중요합니다:
클라이언트(Client)는 어떤 형태(Shape)로, 어떤 권한(Permissions)을 가지고, 어느 정도의 추상화 수준(Level of abstraction)으로 노출해야 하는가?
패턴 1: 직접 API 래퍼 (Direct API Wrapper)
이것은 가장 단순하고 일반적인 패턴입니다. 하나의 MCP 도구(Tool)가 하나의 기존 API 엔드포인트(Endpoint)와 밀접하게 매핑됩니다. 서버는 주로 MCP 클라이언트와 기존 서비스 사이의 얇은 어댑터(Adapter) 역할을 합니다.
AI Client
|
MCP Tool: get_user(id)
...
적합한 경우:
API가 안정적이고 문서화가 잘 되어 있으며, 모델이 필요로 하는 요구사항에 이미 근접해 있는 경우입니다. MCP 서버에 많은 도메인 로직 (Domain Logic)을 추가하지 않고 빠르게 통합하고 싶을 때 적합합니다.
적합하지 않은 경우:
API가 모델이 여전히 조인 (Join), 필터링 (Filter), 해석 (Interpret) 또는 정제 (Clean up)해야 하는 저수준 (Low-level) 데이터를 노출하는 경우입니다. 이 경우 복잡성이 프롬프트 (Prompt)로 이동하며, 모델이 API 통합 계층 (API Integration Layer)처럼 동작해야 합니다. 이는 취약한 구조입니다.
전형적인 예시:
- GitHub 이슈 조회 (Issue lookup)
- Jira 티켓 검색 (Ticket retrieval)
- 내부 REST 서비스 (Internal REST services)
- 단순 CRM 쿼리 (Simple CRM queries)
주요 리스크:
도구 비대화 (Tool bloat). 모든 엔드포인트 (Endpoint)가 도구가 되면, 모델은 너무 많은 유사한 옵션을 갖게 되고 추론해야 할 가공되지 않은 API 세부 정보가 너무 많아집니다.
설계 규칙:
작고 명확하며 리스크가 낮은 API 작업에는 직접적인 래퍼 (Wrapper)를 사용하세요. 에이전트 (Agent)가 여러 개의 가공되지 않은 엔드포인트를 결합하거나 해석해야 할 때는 작업 수준 (Task-level)의 도구로 전환하세요.
패턴 2: 복합 서비스 (Composite Service)
복합 MCP 서버는 하나의 작업 수준 (Task-level) 도구 뒤에 여러 개의 백엔드 호출 (Backend calls)을 숨깁니다. 에이전트는 실제로 필요한 결과를 요청하고, 서버가 집계 (Aggregation)를 수행합니다.
AI Client
|
MCP Tool: get_order_summary(order_id)
...
적합한 경우:
에이전트가 하나의 작업을 수행하기 위해 동일한 데이터 조합을 반복적으로 필요로 하는 경우입니다. 이 패턴이 없다면 에이전트는 여러 번의 도구 호출을 수행하고 스스로 결과를 조립해야 할 것입니다.
적합하지 않은 경우:
필요한 조합이 끊임없이 변하는 경우입니다. 모든 작업마다 데이터의 형태가 달라져야 한다면, 고정된 복합 도구는 너무 경직될 수 있습니다.
전형적인 예시:
주문 데이터, 고객 프로필, 배송 상태 및 제품 정보를 함께 필요로 하는 고객 서비스 에이전트.
주요 리스크:
복합 도구가 숨겨진 미니 애플리케이션 (Mini-application)이 될 수 있습니다. 도구가 너무 많은 가정을 하기 시작하면 에이전트의 유연성이 떨어집니다.
설계 규칙:
백엔드 데이터를 통째로 덤프 (Dump)하지 말고, 작업에 즉시 사용 가능한 컨텍스트 (Context)를 반환하세요. 출력값은 원본 데이터 소스보다 더 작고, 명확하며, 안전해야 합니다.
패턴 3: 리소스 지향 MCP (Resource-Oriented MCP)
모든 기능이 도구 (Tool)가 되어야 하는 것은 아닙니다. 때로는 가장 좋은 MCP 서버가 클라이언트가 읽어서 컨텍스트 (Context)로 주입할 수 있는 구조화된 리소스 (Resources)를 노출하는 방식입니다.
AI Client
|
MCP Resource: file://project/README.md
...
적합한 경우:
에이전트 (Agent)에게 실행 (Action)보다 컨텍스트 (Context)가 더 많이 필요한 경우입니다. 데이터가 읽기 전용이거나 참조 자료로 취급되어야 할 때 적합합니다.
적합하지 않은 경우:
모델이 매개변수화된 연산 (Parameterized operation)을 실행하거나, 상태를 변경 (Mutate state)하거나, 워크플로 (Workflow)를 트리거하거나, 의미 있는 부작용 (Side effects) 또는 비용이 발생하는 검색을 수행해야 하는 경우입니다.
전형적인 예시:
- 코드 저장소 (Code repositories)
- 문서 모음 (Documentation collections)
- 로컬 지식 베이스 (Local knowledge bases)
- 생성된 시스템 상태 스냅샷 (Generated system state snapshots)
- 설정 뷰 (Configuration views)
주요 위험:
과도한 노출 (Overexposure). 가공되지 않은 리소스 접근은 의도치 않게 너무 많은 정보를 드러낼 수 있습니다. 예를 들어, 파일 시스템 서버는 기본적으로 전체 머신을 노출해서는 안 됩니다.
설계 규칙:
명확한 루트 (Roots), 메타데이터 (Metadata), 그리고 권한 경계 (Permission boundaries)를 가진 큐레이션된 리소스를 노출하세요. 제한 없는 원시 접근 (Unrestricted raw access)보다는 읽기 가능한 뷰 (Readable views)를 선호해야 합니다.
패턴 4: 에이전트 지원 도구 (Agent-Backed Tool)
이 패턴에서 MCP 도구 (Tool)는 일반적인 API를 호출하지 않습니다. 대신 다른 AI 에이전트 (Agent), 모델 (Model), 또는 특화된 추론 구성 요소 (Specialized reasoning component)에 작업을 위임합니다.
Main AI Client
|
MCP Tool: analyze_code(snippet)
...
적합한 경우:
하위 작업 (Subtask)이 다른 모델, 더 좁은 컨텍스트 (Context), 특화된 도구, 또는 제어된 추론 워크플로 (Reasoning workflow)를 통해 이점을 얻을 수 있는 경우입니다.
적합하지 않은 경우:
작업이 메인 모델이 수행하기에 충분히 단순한 경우입니다. 추가적인 에이전트 홉 (Agent hops)은 지연 시간 (Latency), 비용, 그리고 디버깅 복잡성을 증가시킵니다.
전형적인 예시:
- 코드 보안 리뷰 (Code security review)
- 정책 준수 분석 (Policy compliance analysis)
- 도메인 특화 문서 분류 (Domain-specific document classification)
- 특화된 컨텍스트를 활용한 테스트 생성 (Test generation with a specialized context)
주요 위험:
추적 가능성 (Traceability)의 상실. 한 에이전트가 다른 에이전트를 호출하게 되면, 실패 원인을 설명하기가 더 어려워집니다. 메인 모델은 결과는 볼 수 있지만, 그 뒤에 숨겨진 추론 품질 (Reasoning quality)까지 반드시 알 수 있는 것은 아닙.
설계 규칙 (Design rule):
하위 에이전트 (subagent)가 제한적이고 검증 가능한 결과를 생성할 때 에이전트 기반 도구 (agent-backed tools)를 사용하세요. 가능한 경우 증거 (evidence), 신뢰도 (confidence), 그리고 한계점 (limitations)을 반환하세요.
패턴 5: 이벤트 기반 제어 인터페이스 (Event-Driven Control Surface)
어떤 작업들은 동기식 (synchronous) MCP 도구 호출 내부에서 수행되어서는 안 됩니다. 해당 작업은 몇 분이 걸릴 수도 있고, 큐 (queues)를 포함하거나 백그라운드 서비스 (background service)에서 실행될 수도 있습니다.
이 패턴에서 MCP 서버는 비동기 인프라 (asynchronous infrastructure)에 대한 제어 인터페이스 (control surface)를 노출합니다.
AI Client
|
MCP Tool: start_report_generation(params)
...
적합한 경우:
작업이 일반적인 요청-응답 (request-response) 호출을 수행하기에는 너무 느리거나 비용이 많이 드는 경우입니다. 에이전트는 작업을 시작하고, 작업 ID (job ID)를 받은 뒤, 나중에 상태를 확인해야 합니다.
적합하지 않은 경우:
작업이 빠르고 결정론적 (deterministic)인 경우입니다. 200ms 걸리는 호출에 큐를 추가하는 것은 불필요한 오버헤드 (overhead)입니다.
전형적인 예시:
- 보고서 생성 (report generation)
- 장시간 실행되는 데이터 처리 (long-running data processing)
- 배치 임포트 (batch imports)
- 문서 변환 (document conversion)
- 비동기 승인 워크플로 (asynchronous approval workflows)
주요 리스크:
모호한 상태 (Ambiguous state). 만약 에이전트가 작업이 대기 중인지, 실행 중인지, 실패했는지, 완료되었는지, 또는 만료되었는지 구분할 수 없다면 워크플로의 신뢰성이 떨어집니다.
설계 규칙 (Design rule):
작업 상태를 명시적으로 만드세요. 상태 (status), 진행률 (progress), 실패 원인 (failure reason), 결과 위치 (result location), 취소 (cancellation), 그리고 재시도 의미론 (retry semantics)을 제공하세요.
패턴 6: 게이트웨이 또는 연합 MCP (Gateway or Federated MCP)
더 큰 시스템에서는 하나의 MCP 서버가 여러 도메인 특화 서버 또는 서비스 앞단에서 게이트웨이 (gateway) 역할을 할 수 있습니다. 이것은 특별한 MCP 기본 요소 (primitive)가 아니라, 하나의 아키텍처 패턴 (architectural pattern)입니다.
많은 클라이언트가 여러 MCP 서버에 직접 연결할 수 있습니다. 게이트웨이는 공통된 관심사 (shared concerns)를 한 곳에서 관리해야 할 때 유용합니다.
AI Client
|
MCP Gateway: Auth, Routing, Logging, Policy
...
적합한 경우:
시스템에 많은 도메인, 팀, 또는 권한 경계 (permission boundaries)가 있는 경우입니다. 중앙 집중식 인증 (authentication), 라우팅 (routing), 감사 로깅 (audit logging), 도구 필터링 (tool filtering), 또는 속도 제한 (rate limiting)이 필요할 때 적합합니다.
적합하지 않은 경우:
시스템 규모가 작은 경우입니다. 이 경우 게이트웨이(gateway)는 클라이언트와 몇 개의 단순한 도구들 사이에 불필요한 계층이 됩니다.
전형적인 사례:
- 엔터프라이즈 AI 플랫폼 (enterprise AI platforms)
- 다수 팀이 사용하는 내부 도구 생태계 (multi-team internal tool ecosystems)
- 규제 환경 (regulated environments)
- 전사적 공유 어시스턴트 인프라 (shared company-wide assistant infrastructure)
주요 리스크:
게이트웨이가 병목 현상(bottleneck)을 일으키거나 제2의 플랫폼이 되어버립니다. 모든 도메인 변경 시마다 게이트웨이 변경이 필요하게 된다면, 팀의 독립성이 사라집니다.
설계 규칙:
게이트웨이는 횡단 관심사(cross-cutting) 정책을 위해 사용해야 하며, 도메인 로직(domain logic)을 위해 사용해서는 안 됩니다. 도메인 소유권은 도메인 서버(domain servers)에 머물러야 합니다.
로컬 액세스(Local Access)에 관한 참고 사항
로컬 리소스 액세스는 API 통합과는 다르게 느껴지기 때문에 종종 별도의 카테고리로 취급됩니다. 로컬 MCP 서버는 파일을 읽거나, 리포지토리(repository)를 조사하거나, 로컬 데이터베이스를 쿼리하거나, Obsidian 보관함(vault)을 노출할 수 있습니다.
아키텍처 측면에서 로컬 액세스는 대개 다음 두 가지 패턴 중 하나에 속합니다:
- 읽기 전용 로컬 컨텍스트를 위한 리소스 지향 MCP (Resource-Oriented MCP)
- 검색, 인덱싱(indexing), 변환(transformation) 또는 파일 생성과 같이 제어된 로컬 작업을 위한 직접 또는 복합 도구 (Direct or Composite Tools)
핵심 이슈는 권한 범위(permission scope)입니다. 로컬 액세스는 매우 강력할 수 있습니다. 훌륭한 로컬 MCP 서버는 루트(roots)를 제한하고, 결과를 필터링하며, 비밀 정보(secrets)가 유출되는 것을 방지하고, 위험한 동작을 명시적으로 만들어야 합니다.
의사결정 로직
다음 질문들은 적절한 패턴을 선택하는 데 도움을 줍니다:
| 질문 | 가장 적합한 패턴 |
|---|---|
| 노출할 간단한 기존 API 작업이 있는가? | 직접 API 래퍼 (Direct API Wrapper) |
| ... |
이 패턴들은 상호 배타적이지 않습니다. 프로덕션 시스템은 종종 이들을 결합합니다:
Gateway MCP
|
+-- 고객 지원을 위한 복합 도구 (Composite tools for customer support)
...
더 중요한 결정은 복잡성(complexity)이 어디에 위치해야 하는가입니다:
- MCP 서버 내
- 클라이언트 내
- 모델 프롬프트(model prompt) 내
- 백엔드 서비스 내
- 게이트웨이 계층 내
원칙적으로, 결정론적(deterministic)이거나 보안에 민감하거나 반복적인 복잡성은 프롬프트 외부에서 관리되어야 합니다.
모든 패턴에 필요한 보안 질문들
MCP를 통해 기능을 노출하기 전에 다음 질문들을 던져보세요:
- 읽기 전용(read-only)인가, 아니면 상태를 변경할 수 있는가?
- 사용자 확인(user confirmation)이 필요한가?
- 작동 가능한 가장 작은 권한 범위(permission scope)는 무엇인가?
- 도구가 가공되지 않은 출력(raw output)을 통해 비밀 정보(secrets)를 유출할 수 있는가?
- 결과가 모델이 안전하게 사용할 수 있을 만큼 충분히 구조화되어 있는가?
- 사용자, 시간, 입력 및 결과와 함께 작업이 로그(log)에 기록되는가?
- 해당 작업을 안전하게 재실행(replay)할 수 있는가?
- 모델이 잘못되었거나 악의적인 입력(malformed or hostile input)으로 도구를 호출하면 어떤 일이 발생하는가?
MCP는 통합을 더 쉽게 만들어 주지만, 신뢰 경계(trust boundaries)를 사라지게 만들지는 않습니다.
결론
MCP 서버를 구축하는 것은 쉽습니다. 하지만 올바른 MCP 서버를 구축하려면 형태(shape), 추상화 수준(abstraction level), 그리고 위험(risk)에 대한 의식적인 결정이 필요합니다.
요구사항을 충족하는 가장 단순한 패턴부터 시작하세요:
- 단순 API 작업을 위한 직접적인 래퍼(direct wrappers)
- 반복적인 다중 소스 작업을 위한 복합 도구(composite tools)
- 읽기 가능한 컨텍스트를 위한 리소스(resources)
- 제한된 전문 작업을 위한 에이전트 기반 도구(agent-backed tools)
- 장기 실행 작업을 위한 이벤트 기반 제어 인터페이스(event-driven control surfaces)
- 도메인 간 정책이 정말로 중요한 경우에만 사용하는 게이트웨이(gateways)
최고의 MCP 서버는 백엔드가 할 수 있는 모든 것을 노출하지 않습니다. 모델에게 불필요한 권한이나 불필요한 가공되지 않은 데이터(raw data)를 주지 않으면서, 모델이 작업을 완료하는 데 도움이 되는 가장 작고 안정적인 기능(capability)만을 노출합니다.
그것이 진정한 아키텍처 결정입니다.
참고 문헌
- 공식 MCP 사양 및 문서: https://modelcontextprotocol.io/specification/latest
- MCP 서버 개념: https://modelcontextprotocol.io/docs/learn/server-concepts
- 공식 MCP GitHub 저장소: https://github.com/modelcontextprotocol/modelcontextprotocol
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기