mcpclerk
mcpclerk
一个用于 MCP 服务器的治理代理:它位于任何 MCP 服务器之前,强制执行按工具划分的允许列表,将写类工具挂起等待人工批准,应用按工具划分的配额,对看起来像秘密的参数进行脱敏,并记录每次调用的哈希链审计日志。
AI 代理在 MCP 服务器上可以调用它们暴露的任何工具,想调用多少次就调用多少次,使用任何参数,而且没有任何东西以任何人都能审计的形式记录它做了什么。在企业环境中,问题不是“代理能否完成工作”,而是它被允许做什么,谁批准了危险的部分,以及它实际做了什么?
mcpclerk 用代码回答这三个问题。它本身就是一个 MCP 服务器:代理连接到它,它连接到真实的服务器,并将它们的工具重新暴露为 upstream.tool。每次调用都经过一个管道:允许列表、配额、脱敏、批准、转发、记录。未列出的工具会被拒绝。写类工具会等待人类回答 y。拒绝以可读的错误形式返回。日志是仅追加的 JSON Lines,每个条目与前一个条目进行哈希链接,因此任何地方的编辑都会破坏链条。
演示包装了官方的文件系统服务器:读取通过,写入被挂起并批准,移动被拒绝,一分钟内的第四次搜索因配额被拒绝,日志验证通过。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
五分钟
编写一个策略。这是演示中的那个(
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以 0 退出并显示OK n entries, chain intact,或以 1 退出并显示FAIL at line N: <what>。试试: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 解析器)。
它不做什么(尚未)
身份和按用户策略。假定只有一个操作员;日志记录的是有人类批准,而不是哪个人类。
Web UI 或远程审批渠道(Slack、email)。
mcpclerk approve是本地终端。跨上游的策略继承或模板化。
资源和提示。v0.1 仅代理工具;
resources/list和prompts/list为空。需要请求头的 HTTP 上游。此版本中 SDK 的 HTTP 传输不接受任何请求头;设置
headers的策略会大声失败,而不是静默地不发送任何内容。Windows:文件队列和
mcpclerk approve可用;进程内终端提示不可用(没有/dev/tty)。CI 尽力运行 Windows。
威胁模型,坦诚地说
攻击者如果占据代理的位置,首先会尝试调用一个不在列表中的工具名称。这会被拒绝并记录(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