연결하는 모든 MCP 서버는 tools/list 응답 — 서버를 만든 누군가가 작성한 JSON 문서 — 을 검토 없이 그대로 모델의 컨텍스트로 흘려보냅니다. 그 응답을 VeriSwarm의 스캐너에 붙여넣으면 몇 초 만에 11가지 결정론적 검사 결과를 받을 수 있습니다: 툴 포이즈닝, 타이포스쿼팅, 스키마 조작, 러그풀 패턴, 프롬프트 인젝션, 과도한 권한, 모델 오바인딩, 컨텍스트 스푸핑, 은닉 채널, 안전하지 않은 메모리 참조, 헤더 인젝션입니다. LLM이 도구를 판단하는 과정은 전혀 없으며 — 매번 동일한 판정을 내리는 패턴·구조 분석만 있을 뿐입니다.
MCP 도구 메타데이터는 시스템의 근간을 이룹니다. 모델은 뒤에 있는 코드가 아니라 설명 텍스트를 바탕으로 무엇을 어떻게 호출할지 결정합니다. 오염된 설명은 무언가를 직접 침해할 필요조차 없습니다. 공격은 전적으로 모델의 추론 내부에서 일어납니다. MCPTox 벤치마크는 실제 MCP 서버 45개와 실제 도구 353개를 대상으로 이를 테스트했고, 공격 성공률이 60%를 넘고 최대 72%에 달하는 것을 확인했습니다. 도구 설명을 눈으로 읽는 방식은 첫 번째 서버를 넘어서면 확장되지 않으며, 러그풀 — 검토 중에는 깔끔하게 동작하다가 다음 버전 업데이트 때 다른 것을 내놓는 서버 — 앞에서는 무력합니다.
이는 스캐너가 원래 대상으로 삼았던 위험 범주 — 오염되었거나 부주의하게 작성된 도구 정의에서 가장 흔히 나타나는 것들 — 을 다룹니다.
설명이나 매개변수 텍스트에 숨겨진 지시문 — “이전 지시를 무시하라” 같은 문구, 은폐 지시, 페르소나 탈취 등입니다. 스캐너는 oneOf/anyOf 가지 안에 중첩된 속성을 포함해 스키마 트리 전체를 순회하므로, 4단계 아래 깊숙이 묻힌 페이로드도 결국 드러납니다.
잘 알려진 도구와 의심스러울 만큼 비슷한 도구 이름 — 대소문자만 다른 위장까지 포함합니다. 예를 들어 READ_FILE이 read_file인 척하는 경우, 단순한 완전 일치 비교로는 이를 완전히 놓치게 됩니다.
임의의 입력을 받아들이는 빈 객체 스키마, 숨겨진 필드를 슬쩍 끼워 넣는 additionalProperties: true, 그리고 4단계 이상 깊이 중첩된 스키마 — 악성 매개변수를 숨기기에 흔히 쓰이는 자리입니다.
도구가 명시한 목적으로는 정당화되지 않는, 자격 증명·토큰이나 민감한 파일 및 내부 네트워크 엔드포인트에 대한 접근을 요구하는 문구 — 도구가 신뢰를 얻은 뒤 나중에 재정의하기 위한 사전 준비입니다.
읽을 수 있는 텍스트로 디코딩되는 Base64 블롭 — 페이로드 밀반입 — 이나, 키릴 문자 а가 여러분의 a를 대신하는 유니코드 동형 문자(homoglyph) 등이, 시각적 검토를 피해 지시를 몰래 끼워 넣는 데 사용됩니다.
읽기 전용이라고 이름 붙이거나 그렇게 설명된 도구가 command, script 또는 sql 같은 매개변수를 받는다면, 하나의 기능을 내세우면서 실제로는 다른 기능을 제공하는 것입니다.
원래의 여섯 가지로는 다루지 못하는 프로토콜 고유의 위험들입니다. 11가지 검사 전체를 통해 스캐너는 OWASP MCP Top 10 v0.1-beta(2025)의 10개 위험 중 9개를 다룹니다. 열 번째인 MCP08(Lack of Audit and Telemetry)은 정적인 도구 정의로는 보여줄 수 없는 것으로, 스키마의 결함이 아니라 런타임 로깅의 공백입니다.
특정 모델에 고정된 도구 — “GPT-4에서만 작동합니다” 같은 문구나 특정 시스템 프롬프트와의 결합을 요구하는 조건입니다. 라우팅 의존성과 해당 모델에 특화된 공격 표면을 만들어냅니다.
대화 기록을 다시 쓰거나, 가짜 턴을 주입하거나, 사용자나 어시스턴트인 척할 수 있다고 주장하는 도구 — 안전 필터와 감사 추적을 동시에 무력화할 수 있는 기능입니다.
표준을 벗어난 최상위 키, 벤더 확장 스키마 필드(x-), 설명문에 삽입된 긴 base64 블롭 — 서술형 텍스트를 훑어보는 검토자가 눈여겨보지 않을 만한 자리입니다.
전역·공유·세션 간 상태에 접근할 수 있다고 주장하는 문구, 또는 와일드카드를 기본값으로 삼는 session_id 매개변수 — 테넌트 격리가 깨지는 원인이 되는 패턴입니다.
헤더 이름 형태를 한 매개변수 — authorization, cookie 또는 host 등을 포함하거나, MCP 스펙의 x-mcp-header 확장을 통해 나가는 요청에 연결된 매개변수입니다. 둘 다 호출자가 결코 보지 못하는 신뢰 경계 헤더를 덮어쓸 수 있습니다.
동일한 11가지 검사, 동일한 보고서 형식, 실행하는 방법은 세 가지입니다:
POST /v1/suite/guard/scan-mcp에 도구 정의를 본문에 담아 요청합니다. 판정(pass / warn / fail), 0~1 사이의 위험 점수, 그리고 발견 항목 배열을 반환합니다 — 각 발견 항목에는 도구 이름, 발동된 검사, 심각도, 근거, 권장 조치가 포함됩니다.scanMcpTools()는 Node SDK에서, scan_mcp_tools()는 Python SDK에서 — 두 함수 모두 동일한 엔드포인트를 타입이 지정된 요청/응답 형태로 감쌉니다.scan_mcp_tools 도구를 이용해 다른 서버의 도구를 호출하기 전에 미리 스캔할 수 있습니다 — 별도의 HTTP 클라이언트가 필요하지 않습니다.심각도가 치명적이거나 높은 발견 항목은 테넌트에 Guard 스캔 결과로 저장되므로, 스캔 결과는 한 번 쓰고 마는 콘솔 출력이 아니라 — 시간이 지나도 검토하고 우선순위를 매기고 종결할 수 있는 기록이 됩니다.
오늘 깨끗하게 스캔된 도구 정의가 내일은 다른 것을 내놓을 수 있습니다 — 러그풀을 정의하는 특성은 바로 여러분이 감사한 버전이 다음 주에 실행될 버전과 다르다는 점입니다. 처음 연결할 때뿐 아니라 MCP 서버의 버전이 올라갈 때마다, 또는 일정에 따라 스캔을 실행하세요. 스캐너는 이 이야기의 배포 이전 절반입니다. 서버가 이미 스캔을 통과한 뒤 실제로 발생하는 라이브 도구 호출을 필터링하는 런타임 절반은 Guard Proxy입니다. 어느 쪽도 다른 쪽을 대신하지 못합니다: 스캐너는 도구가 선언하는 것을 감지하고, Guard Proxy는 그것이 실제로 행동하는 것을 감지합니다.
툴 포이즈닝은 깊이 이해할 가치가 가장 큰 검사입니다 — 네트워크 계층에서는 아무것도 가로챌 것이 없이, 공격이 전적으로 모델의 추론 내부에서 일어나는 유일한 검사이기 때문입니다. 공격의 메커니즘, 실제 공격 성공률, 그리고 스캐너가 이를 어떻게 감지하는지는 「MCP 툴 포이즈닝: 공격은 어떻게 작동하고 어떻게 탐지하는가」에서 자세히 다룹니다.
tools/list 메서드를 호출해 도구 정의를 가져온 뒤, 그 배열을 VeriSwarm의 스캐너 — POST /v1/suite/guard/scan-mcp, Node SDK의 scanMcpTools(), Python SDK의 scan_mcp_tools(), 또는 호스팅형 MCP 서버의 scan_mcp_tools 도구 중 하나 — 로 보냅니다. 네 가지 방법 모두 동일한 11개 검사 엔진을 호출하고 동일한 구조화된 보고서를 반환합니다: 판정(pass/warn/fail), 0-1 위험 점수, 그리고 각 발견 항목별 심각도, 근거, 권장 조치입니다.
11가지 결정론적 검사입니다: 툴 포이즈닝, 타이포스쿼팅, 스키마 조작, 러그풀 패턴, 프롬프트 인젝션, 과도한 권한은 원래의 여섯 가지 위험 범주를 다룹니다. 모델 오바인딩, 컨텍스트 스푸핑, 은닉 채널, 안전하지 않은 메모리 참조, 헤더 인젝션은 스캐너를 OWASP MCP Top 10 v0.1-beta(2025)의 10개 위험 중 9개 — MCP08(Lack of Audit and Telemetry)을 제외한 모든 위험 — 에 대응시킵니다. 이 항목은 정적인 도구 정의로는 보여줄 수 없으며, 스키마 스캔이 아니라 런타임 로깅이 필요합니다. 모든 검사는 패턴과 구조를 기반으로 하므로 — 과정에 LLM이 전혀 없어, 동일한 도구 정의는 스캔할 때마다 동일한 결과를 만들어냅니다.
아니요. 이것은 정적 분석기입니다 — 정규식 패턴, 스키마 트리 순회, 유니코드 정규화이지 모델 호출이 아닙니다. 이는 의도적인 트레이드오프입니다: 확률적 판정 방식이 문제인 이유는, YARA 기반 MCP 스캐너에 대한 독립 감사 중 적어도 한 건에서 오탐률이 약 78%로 보고되었다는 사실에서 드러납니다. 결정론적 검사는 약간의 재현율을 희생하는 대신, CI 파이프라인이 실제로 게이트로 사용할 수 있는 결과를 제공합니다 — 동일한 입력은 두 번 모두 동일한 판정을 내립니다.
둘 다 가능합니다. CI에서는 서버의 tools/list 응답을 파일로 저장한 뒤 파이프라인 단계로서 스캔하세요 — 치명적인 발견 항목은 나중에 확인하는 Slack 스레드가 아니라 빌드 실패가 됩니다. 프로덕션에서는 일정에 따라, 또는 MCP 서버의 버전이 올라갈 때마다 API 엔드포인트를 호출하세요. 한 번 깨끗하게 스캔된 도구도 그 시점에만 안전하다고 알려진 것이기 때문입니다. 재스캔은 검토 중에는 잘 작동하다가 이후에 악의적으로 변하는 러그풀 서버를, 놓치지 않고 잡아내는 방법입니다.
스캐너는 배포 이전 절반을 담당합니다: 에이전트가 서버를 실제로 호출하기 전에 선언된 도구 정의를 읽습니다. Guard Proxy는 런타임 절반을 담당합니다: 에이전트와 그 도구들 사이에 위치해, 발생하는 모든 라이브 호출을 필터링합니다. 어느 쪽도 다른 쪽을 대신하지 못합니다. 스캐너는 도구가 무엇을 한다고 말하는지를 감지하고, Guard Proxy는 호출 시점에 실제로 무엇을 하는지를 감지합니다.
이것은 실측된 것이지 이론적인 것이 아닙니다. MCPTox 벤치마크는 실제 MCP 서버 45개와 실제 도구 353개를 대상으로 툴 포이즈닝을 테스트했고, 공격 성공률이 60%를 넘고 최고 72%에 달하는 것을 발견했습니다 — 더 뛰어난 모델일수록 더 자주 지시를 따랐는데, 이는 지시를 더 잘 따른다는 것이 악의적인 지시도 더 잘 따른다는 뜻이기 때문입니다. 공격 메커니즘과 스캐너의 tool_poisoning 검사가 이를 어떻게 감지하는지에 대한 전체 설명은 전용 해설 자료에 있습니다.
하나의 tools/list 응답을 Guard에 보내 여러분의 에이전트가 지금까지 무엇을 읽어왔는지 확인해 보세요. Gate의 무료 플랜으로 신뢰 점수화 및 이벤트 파이프라인을 먼저 이용할 수 있고, Guard의 스캐너는 그 위에서 동작합니다.