mcpclerk
mcpclerk
MCP 서버를 위한 거버넌스 프록시: 모든 MCP 서버 앞에 위치하여, 도구별 허용 목록(allowlist)을 적용하고, 쓰기(write) 계열 도구는 사람의 승인을 받도록 보류하며, 도구별 할당량(quota)을 적용하고, 비밀번호처럼 보이는 인자를 마스킹하며, 모든 호출의 해시 체인 감사 로그를 기록합니다.
MCP 서버 위의 AI 에이전트는 노출된 어떤 도구든, 원하는 만큼 자주, 어떤 인자로든 호출할 수 있으며, 누구나 감사할 수 있는 형태로 무엇을 했는지 기록하는 것은 없습니다. 기업 환경에서 질문은 "에이전트가 일을 할 수 있는가"가 아니라 무엇을 하도록 허용되었는가, 위험한 부분은 누가 승인했는가, 실제로 무엇을 했는가입니다.
mcpclerk는 이 세 가지 질문에 코드로 답합니다. mcpclerk 자체가 MCP 서버입니다. 에이전트는 mcpclerk에 연결하고, mcpclerk는 실제 서버에 연결하여 그 도구들을 upstream.tool로 다시 노출합니다. 모든 호출은 하나의 파이프라인을 거칩니다: 허용 목록, 할당량, 마스킹, 승인, 전달, 로깅. 목록에 없는 도구는 거부됩니다. 쓰기 계열 도구는 사람이 y라고 답할 때까지 대기합니다. 거부는 읽을 수 있는 오류로 반환됩니다. 로그는 추가 전용(append-only) JSON Lines이며, 각 항목은 이전 항목과 해시로 연결되므로 어디든 수정하면 체인이 끊어집니다.
데모는 공식 파일시스템 서버를 감쌉니다: 읽기는 통과하고, 쓰기는 보류 후 승인되며, 이동(move)은 거부되고, 1분 내 네 번째 검색은 할당량으로 거부되며, 로그는 검증됩니다. 49개의 테스트가 가짜 업스트림에 대해 각 통제를 증명하며, 업스트림이 항상 마스킹되지 않은 원본 인자를 받는다는 것도 포함합니다.

설치
pip install mcpclerk # Python 3.10+ (the MCP SDK requires it); pulls in mcp and pyyaml
mcpclerk --version소스에서: git clone https://github.com/hishamalward/mcpclerk && cd mcpclerk && pip install -e ".[dev]" && pytest.
Related MCP server: Agentrim MCP
5분 가이드
정책을 작성합니다. 데모에서 사용한 정책입니다 (
examples/policy.filesystem.yaml):version: 1 defaults: unlisted: deny # a tool not named here is an unreviewed tool approval_timeout_s: 120 # a call nobody answers in time is refused, and logged as such upstreams: fs: transport: stdio command: npx args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/mcpclerk-demo-sandbox"] tools: "read_*": allow list_directory: allow search_files: { decision: allow, quota: { per_minute: 3 } } write_file: approve edit_file: approve create_directory: approve move_file: deny # the filesystem server has no delete; move is its destructive op업스트림이 제공하는 것과 정책이 그것에 대해 무엇을 하는지 확인합니다. 서버 자체의 주석이 여러분의 결정 옆에 표시되며, 이를 통해 파괴적인 도구를 허용했음을 알아차릴 수 있습니다:
$ mcpclerk tools --policy examples/policy.filesystem.yaml tool decision rule read_only destructive quota fs.read_file allow glob:read_* True None -/- fs.write_file approve exact False True -/- fs.move_file deny exact False True -/- fs.search_files allow exact True None -/3에이전트가 MCP 서버를 찾는 곳에 프록시를 등록합니다. Claude Code의 경우,
examples/.mcp.json:{ "mcpServers": { "fs-governed": { "command": "mcpclerk", "args": ["serve", "--policy", "examples/policy.filesystem.yaml"] } } }두 번째 터미널에서 승인을 기다립니다:
mcpclerk approve. 에이전트가fs.write_file을 호출하면, 비밀이 이미 마스킹된 호출이 표시되고y또는n으로 답합니다.이후:
mcpclerk verify audit/mcpclerk.jsonl및mcpclerk report audit/mcpclerk.jsonl.
다섯 가지 통제
통제 | 기능 | 방지하는 것 | 방지할 수 없는 것 | 증명 |
허용 목록 | 도구별 | 아무도 검토하지 않은 도구를 에이전트가 사용하는 것. | 정책 자체의 잘못된 결정. |
|
승인 |
| 감독 없는 쓰기. | 읽지 않고 승인하는 사람. |
|
할당량 | 도구별 | 무한 루프; 저렴한 도구가 양으로 인해 비싸지는 것. | 여러 도구에 걸친 루프 분산, 또는 프록시 재시작에 걸친 분산 ( |
|
마스킹 | 키 규칙( | 비밀이 로그나 승인자의 화면에 노출되는 것. | 목록의 어떤 형태와도 일치하지 않는 비밀. |
|
감사 로그 | 호출당 하나의 JSON Lines 항목: 타임스탬프, 업스트림, 도구, 마스킹된 인자, 결정, 승인자, 결과, 지연 시간, | 사후 항목의 조용한 편집, 삭제 또는 재정렬; 완료된 실행의 잘림( | 제네시스부터 전체 체인을 다시 쓰는 공격자 (이것은 체인일 뿐 서명이 아닙니다. 아래 참조). 중간에 죽은 실행의 잘림. |
|
결과는 로그에 기록되지 않으며, 크기와 콘텐츠 유형만 기록됩니다. 로그는 결정에 대한 감사이지 데이터의 사본이 아닙니다. 결과를 저장하면 비밀이 새어나갈 두 번째 장소가 됩니다.
호출이 진행되는 방식
agent ──tools/call fs.write_file──▶ mcpclerk ──▶ [namespace] ──▶ [allowlist] ──▶ [quota] ──▶ [redact for log]
│ │ │
refused-unknown refused-denied refused-quota
│
┌── decision = approve ──▶ [hold: approvals/<id>.json] ──▶ y ─┐
│ │ n / timeout │
│ refused-by-human / refused-timeout │
└── decision = allow ────────────────────────────────────────┤
▼
[forward with ORIGINAL args] ──▶ upstream ──▶ result
│
[append log entry, hash-chained]거부를 포함한 모든 경로는 로그 항목으로 끝납니다. 거부는 is_error: true와 한 줄 이유를 가진 일반 도구 결과로 에이전트에게 반환됩니다: mcpclerk: refused-quota fs.search_files: 3/min exhausted; retry after 60s.
승인, 자세히
프록시는 보통 에이전트의 MCP 클라이언트에 의해 시작되며, MCP SDK는 stdio 서버를 새 세션에서 시작하므로 프록시는 일반적으로 자체 터미널이 없습니다. 그래서 메커니즘은 파일 큐이고 터미널 프롬프트는 그것의 클라이언트입니다:
approvals/<id>.json은 보류된 모든 호출에 대해 마스킹된 인자,requested_at,expires_at,"approved": null과 함께 기록됩니다.mcpclerk approve(같은 머신의 아무 터미널에서)는 대기 중인 요청을 표시하고 답변을 기록합니다.--once는 하나에 답하고 종료합니다. 없으면 계속 감시합니다.파일을 직접
"approved": true로 편집하는 것도 작동하며, 이것이 헤드리스 작업이나 스크립트가 하는 방식입니다.프록시에 제어 터미널이 있다면 (수동으로 시작한 경우), 그곳에서도 프롬프트가 표시됩니다. 두 경로가 경쟁하며, 먼저 온 답변이 승리합니다.
approval_timeout_s내에 답변이 없으면 거부이며,refused-timeout으로 기록됩니다. 쓰기에 대한 침묵은 '아니오'입니다.serve --approve-session은 해당 프로세스의 모든 approve 계열 호출을 자동 승인합니다. 시작 시 경고를 출력하고,run-start항목이 이를 기록하며, 영향을 받는 모든 항목은approved_by: session-flag라고 표시하고,report가 이를 강조합니다. 정책 파일에서 설정할 수 없습니다. 프로세스를 시작하는 사람의 호출별 행위입니다.
감사 로그
{"kind":"call","ts":"2026-08-24T01:14:40.822Z","run_id":"20260824T011440Z-3e1c","id":"20260824T011440Z-0002",
"name":"fs.write_file","upstream":"fs","tool":"write_file","rule":"exact",
"args":{"content":"# notes\n[REDACTED:kv-secret]\n","path":"/tmp/mcpclerk-demo-sandbox/notes.md"},
"decision":"approved","approved_by":"file","held_ms":253.7,"outcome":"ok","is_error":false,
"latency_ms":7.7,"content_bytes":57,"content_types":["text"],
"seq":4,"prev_hash":"5c0e…","hash":"b41a…"}decision은allowed,approved,refused-denied,refused-unknown,refused-quota,refused-timeout,refused-by-human중 하나입니다.latency_ms는 업스트림 시간만 포함합니다. 사람의 사고 시간은held_ms이므로,report의 p95 지연 시간은 사람이 아닌 도구를 의미합니다.이벤트 항목(
run-start는 정책의 SHA-256과 플래그 포함,discover는 노출/숨김 개수 포함,run-end는 항목 개수 포함)은 같은 체인을 공유합니다.verify는OK n entries, chain intact와 함께 0으로 종료하거나FAIL at line N: <what>과 함께 1로 종료합니다. 직접 해보세요:sed -i '' 's/allowed/approved/' examples/audit.demo.jsonl && mcpclerk verify examples/audit.demo.jsonl.
examples/audit.demo.jsonl의 예제 로그는 데모 실행의 실제 출력입니다. 구조적으로 게시해도 안전합니다. 마스킹 테스트가 이를 증명하며, 데모는 가짜 API 키를 파일에 기록하여 로그가 있었을 위치에 [REDACTED:kv-secret]을 표시할 수 있게 합니다.
CLI
mcpclerk serve --policy policy.yaml [--log audit/mcpclerk.jsonl] [--approvals approvals] [--approve-session] [--no-tty]
mcpclerk approve [--approvals approvals] [--once] [--wait 60]
mcpclerk tools --policy policy.yaml [--json]
mcpclerk verify audit/mcpclerk.jsonl
mcpclerk report audit/mcpclerk.jsonl [--json]종료 코드: 0 정상, 1 검증 실패 또는 정책 오류, 2 사용법 오류. 정책은 시작 시 검증되며 어떤 문제든 (알 수 없는 키, 잘못된 결정, 설정되지 않은 ${ENV_VAR}, command 없는 stdio 업스트림) 아무것도 서빙하기 전에 프록시를 중지시킵니다.
정책 참조
version: 1
namespace_separator: "." # "__" for clients that reject dots in tool names
defaults:
unlisted: deny # allow | deny | approve
approval_timeout_s: 120
quota: { per_run: null, per_minute: null }
redaction:
extend: ['(?i)my[-_ ]?internal[-_ ]?token\s*[:=]\s*\S+'] # value regexes, added to the built-ins
extend_keys: [client_secret] # key names, added to the built-ins
replace_builtin: false # true: only your patterns (warned about)
upstreams:
<name>: # [a-z0-9_-]+ ; becomes the prefix in <name>.<tool>
transport: stdio | http
command: ... args: [...] env: { KEY: "${FROM_PROXY_ENV}" } cwd: ... # stdio
url: https://... # http
tools:
<tool or glob>: allow | deny | approve
<tool>: { decision: approve, quota: { per_run: 10, per_minute: 3 }, approval_timeout_s: 60 }선행 기술, 그리고 이것이 대신하는 것
MCP용 게이트웨이는 존재하며 이것보다 더 많은 기능을 제공합니다: Lasso Security의 mcp-gateway, IBM의 mcp-context-forge, Docker의 MCP Gateway는 레지스트리, 멀티 테넌트 인증, 플러그인 파이프라인 및 관측성을 제공합니다. mcpclerk는 새로움을 주장하지 않습니다. 작음과 검증 가능성을 주장합니다: 단일 목적의, 읽기 쉬운, 로컬 프록시로서 전체 표면이 위의 다섯 가지 통제와 확인할 수 있는 로그입니다. 약 1,000줄의 Python으로 오후에 읽을 수 있으며, MCP SDK 외에 의존성이 하나뿐입니다 (YAML 파서).
아직 하지 않는 것
신원 및 사용자별 정책. 운영자는 한 명으로 가정합니다. 로그에는 어떤 사람이 승인했는지가 아니라 승인했다는 사실만 기록됩니다.
웹 UI 또는 원격 승인 채널(Slack, 이메일).
mcpclerk approve는 로컬 터미널입니다.업스트림 간 정책 상속 또는 템플릿화.
리소스 및 프롬프트. v0.1은 도구만 프록시합니다.
resources/list와prompts/list는 비어 있습니다.요청 헤더가 필요한 HTTP 업스트림. 이 버전의 SDK HTTP 전송은 헤더를 받지 않습니다.
headers를 설정하는 정책은 조용히 아무것도 보내지 않는 대신 명시적으로 실패합니다.Windows: 파일 큐와
mcpclerk approve는 작동하지만, 프로세스 내 터미널 프롬프트는 작동하지 않습니다(/dev/tty없음). CI는 Windows를 최선 노력(best-effort)으로 실행합니다.
위협 모델, 솔직하게
에이전트의 자리를 차지한 공격자가 가장 먼저 시도할 것은 목록에서 숨겨진 도구를 이름으로 호출하는 것입니다. 이는 거부되고 기록됩니다(refused-unknown 또는 refused-denied). 이것이 막지 못하는 것: 허용된 도구가 유해한 용도로 사용되는 것(정책은 사용자의 판단이며, mcpclerk는 이를 집행합니다), 승인을 기계적으로 해주는 승인자, 그리고 로그 파일에 쓰기 권한이 있는 사람이 첫 항목부터 전체 체인을 다시 쓰는 것입니다. 체인은 조용한 편집(현실적인 위협)을 방어합니다. 서명 또는 외부 앵커(통제하지 않는 곳에 일일 헤드 해시를 게시하는 것)가 다음 단계가 될 수 있으며, v0.1에는 포함되지 않습니다.
개발
pip install -e ".[dev]"
pytest -q # 49 tests, all in-process, no network, no subprocesses
python examples/demo_driver.py --approve-via-file # the demo against the real filesystem server (needs npx)
vhs examples/demo.tape # re-record the GIF테스트는 양쪽 모두 MCP SDK의 인메모리 전송을 사용합니다: Client(proxy) → proxy → Client(fake_upstream). 가짜 업스트림(tests/fake_upstream.py)에는 받은 내용을 그대로 반환하는 secret_sink 도구가 있으며, 이를 통해 테스트 스위트는 업스트림이 비식별화되지 않은 인자를 보는 반면 로그는 그렇지 않다는 것을 증명합니다.
관련 프로젝트: toilscan(개발자 도구에 적용된 동일한 쓰기 안전 본능), agent-slots(병렬 에이전트를 위한 런타임 격리), 그리고 agentkeel(프로세스 측면: 에이전트가 작성한 코드에 대한 게이트와 폭발 반경; 진행 중).
다음에 이 프로젝트를 맡게 될 사람을 위해: docs/learning/how-it-works.html은 둘러보기(호출 순서의 코드, 컨트롤, 인터뷰 답변)이고, docs/spec.md는 계약서입니다.
라이선스
MIT.
This server cannot be installed
Maintenance
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
- AlicenseBqualityCmaintenanceSecurity gateway that wraps any MCP server with per-tool policies, approval gates, and optional Ed25519-signed decision receipts. Shadow mode logs every tool call without blocking; enforce mode applies block, rate-limit, and minimum-tier rules. Receipts are independently verifiable offline with no accounts needed.54699MIT
- AlicenseNot gradedqualityBmaintenanceA least-privilege enforcement proxy for MCP servers. It sits between MCP clients and upstream servers, enforcing tool policies, hiding denied tools, requiring human approval for risky actions, and providing a structured audit trail.MIT
- AlicenseAqualityAmaintenanceAn MCP proxy that enforces policy on every tool call, blocking or flagging actions before they reach downstream MCP servers.1249MIT
- AlicenseNot gradedqualityAmaintenanceAn authorizing reverse proxy for MCP servers that enforces per-call policy rules on tool arguments with audit logging, dry-run, and rate limiting.Apache 2.0
Related MCP Connectors
Remote MCP for A2A caller identity, scope policy, verdict receipts, and audit history.
Runtime permission, approval, and audit layer for AI agent tool execution.
A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/hishamalward/mcpclerk'
If you have feedback or need assistance with the MCP directory API, please join our Discord server