Skip to main content
Glama
adamabdo-xynora

mcp-capability-guard

mcp-capability-guard

대부분의 MCP 서버는 모델에게 공유 베어러 토큰이 장전된 총을 쥐여줍니다. 자격 증명 하나로 모든 도구, 모든 호출이 가능하죠. 이 서버는 모델이 총알 하나하나마다 허가를 받도록 만듭니다.

이 서버는 가상의 인메모리 CRM(Larkspur Supply Co., 가상의 연락처 7개) 위에 구축된 작고 완전한 MCP 서버로, 역량 토큰(capability-token) 쓰기 권한 부여를 시연합니다. 이는 실제 12,000개 이상의 연락처를 보유한 CRM 에이전트에서 추출한 패턴입니다. 여기 있는 데이터는 허구이며, 강제(enforcement) 로직이 실제로 배포되는 부분입니다.

설계, 다섯 계층으로

  1. 계층화된 도구 표면. 읽기(list_contacts, get_contact)는 자유롭게 허용됩니다. 쓰기는 단일 도구로 존재하지 않습니다. add_note 도구도, delete_contact 도구도 없습니다. 모든 변경은 정확히 두 번의 호출, 즉 propose_writeexecute_write를 통해서만 이루어집니다.

  2. 역량 토큰(핵심 요소). propose_write정확히 하나의 변경에 묶인 일회용 TTL 제한 영장(warrant)을 발행합니다. 토큰은 변경을 내장(embed)하며 변경을 가리키지 않으므로, 오염시킬 조회 테이블도 없고 재타겟팅할 id도 없습니다. execute_write는 토큰을 변경과 함께 제시하고, 가드는 필드별 동등성을 검증합니다. 다른 변경과 함께 영장을 제시하면 실패할 뿐만 아니라 토큰이 소각(burn) 되어 공격자의 정당한 쓰기까지 함께 무너집니다.

  3. 파괴적 계층에 대한 인간 확인. change_stage, remove_tag, delete_contact는 추가로 운영자의 명시적 동의를 MCP 폼 유도(form elicitation)를 통해 요구하며, 작업 이름, 연락처, 페이로드를 한 문장으로 명시하는 프롬프트로 진행됩니다. 요청은 가드가 조회되기 이전에 실행되므로, 거절해도 영장이 소모되지 않습니다. 그리고 유도 채널이 없는 클라이언트는 파괴적 쓰기가 조용히 실행되는 대신 거부됩니다. 양방향 모두 실패 시 폐쇄(fail closed)입니다.

  4. 상위 계층이 덮어쓸 수 없는 바닥. Closed-Lost-DNC 단계(연락 금지, 법적 보류)의 연락처는 토큰이나 MCP를 전혀 모르는 스토어 내부에서 모든 쓰기를 거부합니다. 완전히 승인된 흐름(유효한 영장, 일치하는 변경, 확인된 인간)도 그 지점에서 막다른 길에 도달합니다. 이것이 단일 게이트에 표지판 세 개를 붙인 것이 아니라 심층 방어(defence in depth)인 이유입니다.

  5. 영장이 새어나갈 수 없는 추가 전용 감사 로그. 모든 제안, 확인, 실행, 거부가 기록됩니다. 토큰 id는 8자리 지문(fingerprint)으로만 로그에 들어가며, 이는 컴파일 타임 보장입니다. 지문 필드는 잘림(truncating) 함수만이 생성할 수 있는 브랜드 TypeScript 타입을 보유합니다. 자유 텍스트도 값 기준으로 정리(scrub)되는데, 가드 자신의 거부 메시지가 거부한 토큰을 명명하기 때문입니다. (이것은 제 webhook-guard와 동일한 값 기준 정리 원칙입니다. 거기서는 HTTP 자격 증명, 여기서는 활성 영장입니다.) read_audit는 기본 거부(deny-by-default)입니다. 서버가 exposeAudit: true로 빌드되지 않는 한 도구 자체가 등록되지 않습니다.

Related MCP server: tenant-scoped-crm

실행 확인

npm install
npm run demo

데모는 실제 서버를 스크립트된 클라이언트에 인메모리 MCP 전송으로 연결하고 여덟 단계를 서술합니다. 두 번의 쓰기(하나는 되돌릴 수 있고, 하나는 파괴적이면서 확인됨), 그다음 다섯 가지 공격(재생(replay), 미끼 교체(bait-and-switch), 거절된 확인, 대상 변경(target shift), 동결된 레코드에 대한 완전 승인 쓰기)이 각각 타입화된 거부를 만나고 스토어는 바이트 단위로 동일하게 유지됩니다. 마지막으로 감사 추적을 읽고 전체 토큰 id가 어디에도 나타나지 않는지 확인합니다. 데모는 모든 기대치를 인라인으로 검증하고 실패 시 0이 아닌 종료 코드로 종료되므로, 스모크 테스트를 겸하며 모든 푸시에서 CI로 실행됩니다.

npm test              # 158 offline tests
npm run typecheck     # strict TypeScript, no emit

모든 것이 오프라인입니다. API 키도, 네트워크도, 환경 변수도, 설정할 것도 없습니다. 그래서 CI가 데모를 포함한 전체 스위트를 비밀 없이 모든 푸시에서 실행합니다.

증거는 테스트 스위트에 있습니다

위 주장의 정직성을 지키기 위해 두 개의 스위트가 존재합니다:

  • **test/structural.test.ts**는 소스를 텍스트로 읽어 아키텍처를 고정합니다. src/tools.ts가 MCP SDK를 가져오는 유일한 모듈이고, 스토어는 그 위의 어떤 것도 알지 못하며, 가드와 감사 모듈은 헤더가 주장하는 것만 가져오고, 토큰 발행은 가드에 국한되며, tokenId 문자열은 src/audit.ts에 절대 나타나지 않습니다. 리팩터링이 SDK 코드를 조용히 스토어로 옮기면, 이 스위트는 어떤 동작보다 먼저 실패합니다.

  • **test/adversarial.test.ts**는 적대적 모델을 완전히 연결된 서버에 대입합니다. propose 건너뛰기, 재생, 소각 검증이 포함된 미끼 교체, 영장을 다른 연락처로 재지정, 동결 레코드에 대한 완전 승인 공격, 주입된 시계를 통한 만료 영장, 확인 회피, 공격자가 선택한 토큰 id를 사용한 감사 무결성 검사. 모든 공격은 정확한 타입화된 거부를 만나야 하며, 모든 공격 후 스토어는 변경되지 않아야 합니다.

나머지 약 140개의 테스트는 스토어, 가드, 감사, 도구 표면을 단위별로 다루며, 확인이 영장 소모 전에 실행되어야 한다는 순서 불변식(invariant)도 포함합니다.

버전 및 범위

@modelcontextprotocol/sdk 1.30.0 기반으로 구축되었으며, 이는 MCP 개정 2025-11-25를 대상으로 합니다. 2026-07-28 개정은 서버가 발행한 핸들을 일반 도구 인수로 전달하는 것을 교차 호출 상태의 표준 메커니즘(SEP-2567)으로 만듭니다. 이 저장소의 역량 토큰은 정확히 그 패턴을 권한 부여 원시 요소(authorization primitive)로 사용한 것이므로, 설계는 무상태(stateless) 프로토콜에서도 변경 없이 이어집니다.

런타임 의존성 두 가지: SDK 자체와 zod. zod는 SDK 자신의 피어 의존성 스키마 언어입니다. 도구 입력 스키마는 SDK 설계상 zod 스키마이므로, 추가된 의존성이라기보다 SDK의 나머지 절반에 가깝습니다. 그 외에는 트리에 아무것도 들어오지 않습니다. 스토어, 가드, 감사 모듈은 node:crypto와 서로의 타입 외에는 가져오는 것이 전혀 없는 순수 TypeScript이며, 덕분에 158개의 테스트가 오프라인에서 0.5초 안에 실행됩니다.

이것이 아닌 것. 이 저장소는 OAuth나 MCP 권한 부여 스펙의 리소스 서버 역할을 구현하지 않습니다. 그것들은 다른 문제를 해결합니다. 즉, 전송 경계에서 클라이언트가 누구인지 증명하는 것입니다. 역량 토큰은 인증된 세션이 무엇을 할 수 있는지, 쓰기 하나씩을 규율합니다. 둘은 경쟁이 아니라 상호 보완적이며, 이 둘을 혼동하는 것이 서버가 모든 것을 승인하는 단일 베어러 토큰을 갖게 되는 이유입니다. 전송 신원(transport identity)은 권한 부여 패턴이 명확하게 유지되도록 의도적으로 범위 밖입니다.

한계, 명확히 밝힘

  • CRM은 허구이며 인메모리입니다. 영속성, 동시성, 다중 사용자 세션은 이 데모가 다루지 않는 실제 문제입니다.

  • 토큰은 서버 메모리에 존재하며, 재시작하면 잊혀집니다. 프로덕션에서는 동일한 패턴이 동일한 일회용 의미론으로 영구 저장소에 대해 실행됩니다.

  • 유도 확인은 클라이언트의 렌더링만큼만 신뢰할 수 있습니다. 서버의 문장 대신 사용자에게 "허용하시겠습니까?"만 보여주는 클라이언트는 보장을 약화시킵니다. 이는 이 서버가 하는 것처럼 전체 문장을 요청에 넣어야 한다는 주장이지, 질문을 건너뛰어야 한다는 주장이 아닙니다.

  • 스토어의 메모 타임스탬프는 벽시계(wall clock)를 사용하므로 데모 출력 한 줄이 실행마다 달라집니다. 가드와 감사 로그는 주입된 시계를 사용하며 결정적입니다.

적용하기

이 패턴은 쓰기에 결과가 따르는 모든 MCP 서버에 이전됩니다. 스토어를 자신의 시스템으로 교체하고, propose/execute 분리를 유지하고, 자신의 계층을 결정하고, 바닥 규칙을 도구 계층이 아닌 데이터 계층에 유지하세요. 가드와 감사 모듈은 MCP에서 아무것도 가져오지 않으므로 통째로 떼어낼 수 있습니다.

MIT 라이선스.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Security-enforcing MCP proxy that sits between an AI agent and any number of downstream MCP servers, intercepting every tool call through a capability-token policy gateway that can allow, deny, or escalate to human approval before the call reaches any real tool. It also exposes built-in operator tools for approval workflows, audit trail queries, token management, voice/HUD output, and hierarchical
    21
    12
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    A reference MCP server demonstrating safe agent access to multi-tenant CRM data with tenant isolation enforced in the data layer, role-based permissions, and human confirmation on writes.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    A secure MCP server for CRM operations (contacts and deals) with Auth0 OIDC authentication, role-based access control (sales-rep read-only vs sales-manager full access), and on-behalf-of token exchange.
  • A
    license
    B
    quality
    A
    maintenance
    A secure MCP server enabling tool calls (kb_search, read_doc, publish_report) through a zero-trust CapabilityBroker with OWASP LLM Top-10 guardrails and human-in-the-loop approval.
    3
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • An authenticated remote MCP server for user-owned devices and one-shot capability invocation.

  • Personal MCP server for humans who create. Proof of authorship, license control.

  • Viridis Verified: wrap any MCP server with tamper-evident delivery receipts + metered fees.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/adamabdo-xynora/mcp-capability-guard'

If you have feedback or need assistance with the MCP directory API, please join our Discord server