MCP 서버 디스커버리 레지스트리가 안전성을 위해 보장해야 하는 것
요약
MCP(Model Context Protocol) 서버의 동적 디스커버리 과정에서 발생할 수 있는 보안 위협을 분석하고, 안전한 레지스트리가 갖춰야 할 필수 요건을 다룹니다. 단순한 목록 제공을 넘어 인증과 무결성 보장이 에이전트 생태계의 핵심임을 강조합니다.
핵심 포인트
- MCP 서버 디스커버리는 단순 조회가 아닌 신뢰(Trust)의 문제임
- 악의적인 서버를 통한 데이터 유출 및 타이포스쿼팅 위험 존재
- 검증된 발행자를 통한 인증(Authenticity) 확보가 필수적임
- 런타임 데이터와 레지스트리 정보 간의 무결성(Integrity) 보장 필요
Model Context Protocol (MCP)을 다뤄본 적이 있다면, 아마 다음과 같은 디스커버리(discovery) 문제에 직면했을 것입니다: 에이전트가 명시적으로 설정되지 않은 MCP 서버를 어떻게 찾아낼 수 있을까? 명확한 답은 "레지스트리 (registry)"입니다. 하지만 MCP 서버를 위한 디스커버리 레지스트리는 단순히 항목을 나열하는 것 이상의 것을 보장해야 합니다.
정적 설정 (static-config)의 안락함
현재 대부분의 MCP 설정은 다음과 같이 작동합니다: Claude Desktop 설정, Agent SDK 설정 또는 MCP 클라이언트의 설정 파일에 JSON 블록을 넣는 방식입니다. 각 항목은 서버 이름을 명령(command) 또는 URL에 매핑합니다. 이는 명시적이고, 가시적이며, 안전합니다. 에이전트가 어떤 도구에 접근할 수 있는지 정확히 알 수 있기 때문입니다.
{
"mcpServers": {
"filesystem": {
...
이 방식은 사용자가 직접 검증한 소수의 서버를 사용하는 데에는 문제가 없습니다. 하지만 에이전트가 설정 항목이 없는 새로운 기능을 찾기를(find) 원하는 순간, 이 방식은 무너집니다.
그 지점에서 디스커버리가 등장하며, 대부분의 사람들이 디스커버리 레지스트리가 실제로 무엇을 보장해야 하는지에 대한 고민을 멈추는 지점이기도 합니다.
디스커버리는 조회(lookup)의 문제가 아니라 신뢰(trust)의 문제입니다
동적인 MCP 서버 디스커버리는 이론적으로는 간단해 보입니다: 에이전트가 레지스트리에 "X를 제공하는 서버가 있나요?"라고 묻고, 목록을 받아 연결하는 방식입니다. 어려운 부분은 그 두 단계 사이에 어떤 일이 일어나는가 하는 점입니다.
레지스트리가 에이전트에게 전달하는 것을 생각해 보십시오:
- 연결할 서버 URL
- 사용 가능한 도구(tools) 또는 리소스(resources) 목록
- 어쩌면 신원 주장 (누가 서명했는가?)
이제 악의적인 레지스트리 항목이 무엇을 할 수 있는지 생각해 보십시오. "코드 분석"을 제공한다고 주장하지만 실제로는 파일을 유출하는 서버. 타이포스쿼팅(typosquatted)된 패키지 이름. 발행자의 신원을 전혀 검증하지 않은 레지스트리. 유지 관리자의 키가 교체되었거나 탈취된, 한때는 합법적이었던 서버 등을 말입니다.
이는 가설이 아닙니다. 패키지 레지스트리(npm, PyPI, crates.io)를 괴롭히는 것과 동일한 역학 관계가 여기서는 두 배로 적용됩니다. MCP 서버는 단순히 node_modules에 수동적으로 머무는 것이 아니라, 사용자의 기기에서 도구(tools)를 실행하고, 데이터를 읽으며, 그 결과를 AI 에이전트(AI agent)에게 전달하기 때문입니다. 피해 범위(blast radius)가 훨씬 더 넓습니다.
레지스트리가 보장해야 하는 것
에이전트가 모든 항목을 사람이 일일이 읽지 않고도 안전하게 사용할 수 있는 디스커버리 레지스트리가 되려면 네 가지가 필요합니다.
1. 인증 (Authenticity): 모든 항목에 검증된 발행자가 있어야 함
레지스트리는 각 서버를 누가 발행했는지 반드시 알고 있어야 합니다. 단순한 사용자 이름이 아니라, 등록 시 확인된 검증 가능한 신원(verifiable identity)이어야 합니다. 이것이 없다면 타이포스쿼팅(typosquatting)과 사회 공학적 공격(social-engineering attacks)은 매우 쉬워집니다. 예를 들어, 제가 mcp-server-aws-s3-storage라는 이름을 등록하면, 당신은 그것이 진짜처럼 보이기 때문에 설치하게 될 것입니다.
패키지 레지스트리들은 이를 뼈아픈 경험을 통해 배웠습니다. MCP 서버를 위한 디스커버리 레지스트리는 이러한 교훈을 반복하는 것이 아니라 계승해야 합니다.
2. 무결성 (Integrity): 페이로드(payload)가 검토된 내용과 일치해야 함
에이전트가 런타임(runtime)에 확인하는 항목은 레지스트리가 발행 시점에 승인한 페이로드와 정확히 일치해야 합니다. 도구 정의(tool definition)의 변경, 다운로드 URL의 리다이렉션, 주입된 파라미터(parameter) 등 어떠한 드리프트(drift)라도 발생한다면 이는 무결성 실패입니다.
이는 서명(signing)을 의미합니다. 단순히 전송 중인 TLS(TLS-in-transit, 네트워크 공격자로부터 보호)뿐만 아니라, 재호스팅(re-hosting), 캐싱(caching) 또는 DNS 리바인딩(DNS rebinding) 상황에서도 유지되는 아티팩트 수준의 서명이 필요합니다. 에이전트는 서빙 엔드포인트(serving endpoint)를 신뢰해서는 안 되며, 페이로드와 함께 제공된 서명을 신뢰해야 합니다.
3. 권한 경계 (Capability boundaries): 서버는 주장하는 기능만 수행할 수 있어야 함
레지스트리는 서버가 수행한다고 주장하는 내용을 단언할 수는 있지만, 런타임에서 그 제한을 강제할 수는 없습니다. 중요한 것은 에이전트가 서버의 신원과 함께 권한 선언(capability declaration)을 함께 전달받아, 접근 권한을 부여할지 여부를 스스로 결정할 수 있어야 한다는 점입니다.
이것은 Android 매니페스트(manifest)나 macOS 권한 설정(entitlements) 파일과 유사한 비유입니다. 설치 시점에 사용자(또는 이 경우에는 에이전트)는 서버가 무엇을 필요로 한다고 주장하는지 확인하고, 이를 수락하거나 거부합니다. 주변 권한(Ambient authority)은 허용되지 않습니다. 레지스트리의 역할은 서버가 시작되기 전에 이러한 정보를 표면화하여 보여주는 것입니다.
4. 권한 취소(Revocation): 신뢰는 철회될 수 있습니다
서버는 해킹될 수 있습니다. 유지 관리자는 키를 교체합니다. 합법적인 프로젝트가 방치되거나 탈취되기도 합니다. 권한 취소(Revocation) 메커니즘이 없는 레지스트리는 6개월 이내에 안전하지 않은 레지스트리가 될 것입니다.
이것은 제대로 구현하기 가장 어려운 부분이며, 많은 시스템이 이를 아예 구현하지 못합니다. 하지만 MCP 디스커버리(discovery)가 자율적으로 사용되기 위해서는(에이전트가 서버를 찾고, 에이전트가 서버를 설치하고, 에이전트가 서버를 사용하는 방식), 에이전트에게 다음과 같은 확인 방법이 필요합니다: "이 발행자가 여전히 올바른 발행자인가? 내가 마지막으로 확인한 이후에 이 서버가 철회되었는가?"
기존 방식들은 어떠한가?
MCP 명세(specification) 자체는 디스커버리 레지스트리(discovery registry)를 정의하지 않습니다. 대신 클라이언트와 서버 간의 도구 호출(tool invocation) 및 리소스 접근을 위한 프로토콜을 정의합니다. 디스커버리는 현재 각 클라이언트나 생태계에 맡겨져 있습니다. 어떤 프로젝트들은 큐레이션된 디렉터리(curated directories)를 제공합니다. 다른 프로젝트들은 MCP 서버가 우연히 게시되는 기존 패키지 레지스트리(npm, PyPI)에 의존합니다.
각 접근 방식은 문제의 일부를 해결합니다:
-
**패키지 레지스트리 (Package registries)**는 인증 (대부분의 플랫폼에서 검증된 게시자)과 무결성 (체크섬이 포함된 아티팩트)을 처리하지만, 기능 경계 (capability boundaries)를 표현하지는 않습니다. 즉, 레지스트리는 특정 패키지가 MCP 서버인지, 더 나아가 어떤 도구 (tools)를 노출하는지 알지 못하거나 확인하지 않습니다.
-
큐레이션된 디렉토리 (Curated directories) (팀이 모든 항목을 검토)는 인증과 기능 검토 문제를 해결하지만, 확장성이 떨어지며 단일 검토 병목 현상을 생성합니다. 또한 권한 취소 (revocation)를 제대로 처리하는 경우가 드뭅니다. 목록에서 항목을 삭제하더라도 이미 해당 항목을 캐싱한 클라이언트를 중단시킬 수 없습니다.
-
서명된 매니페스트 체계 (Signed manifest schemes) (서버가 매니페스트를 게시하고 클라이언트가 이를 독립적으로 검증)는 무결성과 배포 문제를 해결하지만, 디스커버리 (discovery) 문제를 해결하지는 못합니다. 에이전트는 애초에 매니페스트를 찾기 위한 시작점이 여전히 필요하기 때문입니다.
MCP 서버 디스커버리의 한 가지 접근 방식: 서명 검증을 결합한 앱 스토어 모델
이 지점이 바로 Pilot Protocol의 앱 스토어와 같은 시스템이 적합한 곳입니다. 이것은 그 자체로 MCP 레지스트리는 아니며, 에이전트를 위한 범용 기능 레지스트리 (general-purpose capability registry)입니다. 하지만 이 시스템이 제공하는 보장 사항들은 위의 네 가지 요구 사항과 직접적으로 일치합니다.
이 모델은 다음과 같이 구조화되어 있습니다:
-
모든 앱은 서명됩니다 (Every app is signed). 매니페스트 (Manifest)에는 발행자의 SHA-256 해시와 Ed25519 서명이 포함됩니다. 데몬 (Daemon)은 설치 시점뿐만 아니라 매 실행 (spawn) 시마다 이를 재검증합니다. 따라서 보안이 침해된 레지스트리 서버가 나중에 다른 아티팩트 (artifact)를 제공하더라도 감지되지 않은 채 넘어가는 일이 발생할 수 없습니다.
-
권한은 부여 범위 내로 제한됩니다 (Permissions are grant-scoped). 앱을 설치할 때, 매니페스트는 필요한 기능 (capabilities) (네트워크 액세스, 파일 시스템 등)을 선언합니다. 에이전트 (Agent) (또는 운영자)는 설치 시점에 이를 수락하거나 거부합니다. 데몬은 런타임 (runtime)에 이 경계를 강제하며, 주변 권한 (ambient authority)은 허용되지 않습니다.
-
취소 (Revocation)는 명시적입니다. 발행자는 매니페스트를 게시 취소하거나 다시 서명할 수 있습니다. 데몬은 앱을 실행할 때마다 최신 상태를 확인합니다. 취소된 앱은 단순히 해결 (resolving)이 중단됩니다.
-
디스커버리 (Discovery)는 설정이 아닌 런타임에 이루어집니다. 에이전트는 카탈로그를 조회하고 (
pilotctl appstore catalogue) 단일 명령으로 설치합니다. 설정 파일을 편집하거나 수동으로 URL을 고정 (pinning)할 필요가 없습니다.
구체적인 루프는 디스커버리(discover) → 설치(install) → 호출(call)이며, 안전 보장 사항은 중앙 검토 팀에 의존하기보다 프로토콜 자체에 내장되어 있습니다.
# Discover
pilotctl appstore catalogue
...
이것이 MCP 전용 레지스트리를 대체하는 것은 아닙니다. 하지만 이러한 아키텍처 설계 선택 (서명 검증, 부여 범위 내 권한, 런타임 취소, 발행자 신원)은 모든 MCP 서버 디스커버리 레지스트리가 제공해야 하는 바로 그 보장 사항들입니다.
핵심 요약 (The bottom line)
MCP 서버 디스커버리는 DNS나 API 설계에 관한 기술적 퍼즐이 아닙니다. 이것은 신뢰의 퍼즐입니다. 즉, 사람이 모든 코드를 읽지 않고도 어떻게 에이전트가 이전에 본 적 없는 기능을 안전하게 설치하고 호출하도록 허용할 것인가의 문제입니다.
이 문제를 해결하는 레지스트리에는 서명된 아티팩트, 검증된 발행자 신원, 강제성이 동반된 기능 선언, 그리고 작동하는 취소 경로가 필요합니다. 이보다 못한 것은 그저 이름만 바꾼 패키지 레지스트리일 뿐이며, 패키지 레지스트리는 이미 대규모 환경에서의 신뢰 문제로 어려움을 겪고 있습니다.
안전한 에이전트 네이티브 (agent-native) 도구 디스커버리를 위한 인프라는 이미 존재합니다. 다음 단계는 이를 보편적으로 만드는 컨벤션 (conventions)을 구축하는 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기