여러 개의 MCP 서버를 구축하며 깨달은 점: 좋은 서버와 데모용 서버의 차이점
요약
다양한 용도의 MCP(Model Context Protocol) 서버를 구축하며 얻은 실전 설계 원칙을 공유합니다. 컨텍스트 비용 최적화, 도구와 리소스의 구분, 보안 및 인증 설계 등 데모용이 아닌 실제 서비스 가능한 서버를 만들기 위한 핵심 요소를 다룹니다.
핵심 포인트
- 도구 정의는 매 요청마다 컨텍스트 비용을 발생시키므로 최소화해야 함
- 읽기 작업은 도구 대신 리소스를 사용하여 컨텍스트 비용을 절감할 것
- 인증은 실패 시 차단(fail closed), 제한은 실패 시 허용(fail open) 원칙 적용
- 도구에 readOnly, destructive 등의 힌트를 주석으로 달아 에이전트의 안전한 동작 유도
올해 저는 상당히 다른 세 가지 형태에 걸쳐, 의도했던 것보다 더 많은 MCP 서버를 구축했습니다.
- vellum: 마크다운 폴더를 기반으로 하는 셀프 호스팅 (self-hosted) 서버로, 제 에이전트가 제가 소유한 파일들만으로 메모리를 가질 수 있게 합니다. (오픈 소스, MIT.)
- Metrifyr: GA4, Search Console, AdSense, Tag Manager를 하나의 연결 뒤로 통합하는 마케팅 데이터 서버입니다.
- 기업의 내부 사용자 데이터 스택에 대한 **읽기 전용 게이트웨이 (read-only gateway)**로, 반 다스(half a dozen)의 내부 서비스를 하나의 감사 가능한 MCP 인터페이스 뒤로 연합(federating)합니다.
개인용, 제품용, 기업용. 데이터도 완전히 다르고 이해관계도 완전히 다릅니다. 하지만 실제 에이전트가 실전에서 사용하자마자 무너져 버리는 화려한 데모와 달리, 각 서버를 '좋게' 만드는 요소들은 매번 동일했습니다. 반복해서 나타나는 일곱 가지 핵심 요소는 다음과 같습니다.
1. 노출하는 모든 도구(tool)는 에이전트의 컨텍스트(context)에 대한 세금입니다
이것은 아무도 경고해주지 않는 부분입니다. 모든 도구 정의(이름, 설명, JSON schema)는 해당 도구가 실제로 호출되었는지 여부와 상관없이 모든 요청마다 모델의 컨텍스트(context)에 로드됩니다. 상용구(boilerplate)로 이루어진 20개의 도구가 있다면, 에이전트는 당신의 데이터에 접근하기도 전에 수 페이지에 달하는 배관(plumbing) 작업을 읽어야 합니다.
따라서 설계 압박은 일반적인 API와는 반대 방향으로 작용합니다. 좁은 범위의 많은 도구보다, 적고 넓은 범위의 도구가 더 낫습니다. vellum은 15개의 핵심 도구를 가지고 있으며, 저는 이를 유지하기 위해 노력했습니다. 만약 어떤 도구가 대부분의 요청에서 컨텍스트 창(context window) 내의 자리를 차지할 만큼의 가치를 증명하지 못한다면, 그것은 도구가 되어서는 안 됩니다.
2. 도구(Tools)는 행동하기 위한 것이고, 리소스(Resources)는 읽기 위한 것입니다.
리소스(resource)를 통해 읽는 것은 도구 정의(tool definition) 비용이 들지 않습니다. 하지만 도구를 통해 읽는 것은 매 요청마다 하나의 도구 정의 비용을 발생시킵니다. 적절한 프리미티브(primitive)를 사용하세요.
3. 인증(auth)은 실패 시 차단(fail closed)하고, 제한(limits)은 실패 시 허용(fail open)하세요
권한(grants)이 없는 토큰은 도구가 전혀 보이지 않아야(zero tools) 합니다. 도구를 호출하려고 할 때 에러가 발생하는 것이 아니라, tools/list 결과에 실제로 아무것도 없어야 합니다. 즉, 인증(Authorization)은 실패 시 차단(fail closed)되어야 합니다. 반면, 속도 제한기(Rate limiter)는 실패 시 허용(fail open)되어야 합니다. 제한기 자체가 고장 나더라도, 모든 사용자를 차단하는 것이 아니라 요청을 처리하는 방식으로 성능을 낮추어(degrade) 서비스해야 합니다. 이 두 가지를 반대로 적용하면 권한을 유출하거나 시스템을 스스로 마비시키게 됩니다.
4. 무엇이 안전하고 무엇이 안전하지 않은지 주석(Annotate)을 다세요
MCP를 사용하면 도구에 readOnlyHint, destructiveHint, idempotentHint와 같은 힌트를 태그할 수 있습니다. 이를 적극 활용하세요. 이는 잘 설계된 클라이언트가 귀하의 검색(search) 도구는 자유롭게 호출할 수 있지만, 삭제(delete) 도구를 호출하기 전에는 신중해야 함을 인지하는 방법입니다. 마케팅용 서버에서 이 주석은 "에이전트가 귀하의 분석 데이터에 관한 어떤 질문에도 답할 수 있음"과 "에이전트가 귀하의 분석 설정을 재구성할 수 있음" 사이의 경계선이며, 주석은 이 두 세계를 시각적으로 명확하게 분리해 주는 역할을 합니다.
5. 쓰기 작업은 충돌로부터 안전해야 합니다 (conflict-safe)
두 개 이상의 주체(에이전트와 사람, 또는 두 명의 에이전트)가 동시에 쓰기 작업을 할 수 있는 순간, 마지막에 쓴 사람이 이기는 방식(last-write-wins)은 데이터를 조용히 잡아먹습니다. vellum은 모든 읽기 작업 시 콘텐츠 해시(content hash)를 반환하며, 해시가 일치하지 않으면 데이터를 덮어쓰는 대신 쓰기 작업을 실패 처리합니다. 이는 데이터베이스가 오랫동안 사용해 온 방식인 낙관적 동시성 제어(Optimistic concurrency)이며, 이를 통해 "에이전트가 내 수정을 덮어썼다"라는 상황을 고객 지원 티켓(support ticket) 이슈가 아닌 단순 재시도(retry) 문제로 바꿀 수 있습니다.
6. 실제 데이터에 접근하는 모든 것에 대하여: 읽기 전용으로 설정하고 모든 것을 감사(audit)하세요
엔터프라이즈 게이트웨이를 구축하며 뼈저리게 배운 점입니다. MCP 서버가 기업의 실제 사용자 데이터 앞에 위치할 때, 기본 방침은 읽기 전용(read-only)이어야 합니다. 모든 도구 호출은 누가 호출했는지와 어떤 결과가 반환되었는지 로그로 기록되어야 하며, 응답에 포함된 모든 개인정보(PII)는 원본 값이 아닌 해시 형태로 반환되어야 합니다. 에이전트는 새로운 유형의 호출자입니다. 나중에 보안 검토(security review) 단계에서 에이전트에 대해 설명해야 할 상황이 반드시 올 것이므로, 처음부터 그에 맞춰 대우하십시오.
7. 에이전트에게 당신을 어떻게 사용하는지 알려주세요
MCP는 핸드셰이크(handshake) 과정 중 **서버 지침 (server instructions)**을 위한 자리를 가지고 있습니다. 이는 에이전트가 어떤 작업을 수행하기 전에 읽게 되는 짧은 문서입니다. 이곳에서 여러분은 "노트는 볼트(vault) 상대 경로입니다", "재작성(rewrite)보다 패치(patch)를 선호합니다", "태그가 포함된 빈 쿼리는 순수 태그 필터입니다"와 같은 내용을 명시할 수 있습니다. 이는 여러분의 API를 더듬거리며 사용하는 에이전트와, 첫 시도부터 의도한 대로 사용하는 에이전트 사이의 차이를 만듭니다. 대부분의 서버는 이 부분을 비워둡니다. 그러지 마십시오.
오후 시간을 통째로 날리게 만든 주의사항 하나
structuredContent는 대략 응답 크기를 두 배로 만듭니다. 페이로드(payload)가 응답에 두 번 직렬화(serialized)되기 때문입니다. 만약 크기 기반의 메트릭(metrics)이나 제한 사항을 사용하고 있다면, 명확한 이유 없이 수치가 갑자기 높게 나타날 것입니다. 이를 재조정하십시오. 그렇지 않으면 존재하지도 않는 메모리 누수(leak)를 쫓느라 오후 시간을 허비하게 될 것입니다.
이 모든 것은 영리한 기능에 관한 것이 아닙니다. 노트 볼트(note vault), 마케팅 스택, 그리고 엔터프라이즈 게이트웨이에 이르기까지, 성능이 좋았던 서버들은 에이전트의 컨텍스트(context)를 존중하고, 각 작업에 적합한 프리미티브(primitive)를 사용하며, 무엇을 호출하는 것이 안전한지에 대해 정직했던 서버들이었습니다. 데모는 쉽습니다. 위의 일곱 가지 사항이야말로 실제 에이전트와 접촉했을 때 서버가 살아남게 만드는 요소들입니다.
만약 여러분이 MCP를 기반으로 구축하고 있다면: 이 중 어떤 것이 여러분을 가장 먼저 괴롭혔나요? 저의 경우에는 1번이었습니다. 첫 번째 서버에서 도구(tools)를 너무 많이 노출했고, 에이전트가 스스로의 도구 상자에 빠져 허우적거리는 것을 지켜봐야 했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기