关于 mcp-gatehouse
mcp-gatehouse 是一个 Python 库,可在 MCP 服务内部添加权限、审批和审计日志。服务开发者可按风险划分工具、要求审批、隐藏敏感参数,并屏蔽指定工具,无需外部策略服务。
主要功能
- 01READ、WRITE 和 DESTRUCTIVE 权限层级
- 02默认拒绝的审批门控
- 03仅追加的 JSONL 审计记录
- 04敏感参数脱敏
- 05工具拒绝列表
- 06审批超时设置
适用场景
- 01在破坏性工具调用前要求审批
- 02记录允许、拒绝、失败和取消的调用
- 03隐藏日志及审批请求中的机密信息
- 04不论权限层级都屏蔽指定工具
MCP 相关
它包装使用官方 Python MCP SDK 构建的服务中的工具注册流程。在工具边界实施权限控制,同时保留原有模式和传输方式。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
4收录的工具列表 · 更新于 1 周前
此工具无需参数。
详细介绍
mcp-gatehouse
项目主页与文档: nickgeorgeai.com/open-source/mcp-gatehouse · PyPI
为 MCP 服务提供权限等级、审批关卡和审计日志。 该服务是把关者:由你决定 AI 可以读取什么、可以写入什么,以及哪些内容禁止访问;每项操作都会被记录。
大多数 MCP 服务会把所有工具都以完整权限交给模型,却不记录它做了什么。这对演示来说没问题。但如果某个 Agent 获得了 CRM、账簿或订单系统的写入权限,那就不行了。mcp-gatehouse 补上了缺失的关卡,并在服务内部强制执行——无需代理、外部策略服务,也不需要官方 mcp SDK 以外的依赖。
pip install mcp-gatehouse
你将获得
| 权限等级 | 每个工具都声明为 READ、WRITE 或 DESTRUCTIVE;等级还会生成符合规范的 ToolAnnotations(readOnlyHint / destructiveHint),包装器不会允许你覆盖这些标注来伪装权限。 |
| 审批关卡 | 你指定的等级需要在工具运行前获得批准。审批者可以是任何可调用对象——终端提示、Slack 消息或工单。**默认拒绝:**未配置审批者的受控工具将被拒绝,而不会放行。 |
| 审计日志 | 仅追加的 JSONL,每次调用占一行——无论是允许、拒绝、失败还是取消——均记录 UTC 时间戳和耗时。六个月后,你仍能回答“AI 实际做了什么?” |
| 脱敏 | 你指定的参数键(默认包括 api_key、password、token、client_secret 等)在写入日志或发送给审批者之前都会被屏蔽,无论键的拼写方式如何:apiKey、API-Key 和 api_key 都视为同一个键。 |
| 拒绝列表 | 无论工具属于哪个等级,都可以直接禁止它。 |
快速入门
from mcp.server.mcpserver import MCPServer
from mcp_gatehouse import AccessTier, AuditLog, Gatehouse, Policy, terminal_approver
mcp = MCPServer("order-desk")
gatehouse = Gatehouse(
mcp,
policy=Policy(approver=terminal_approver),
audit=AuditLog(path="~/order-desk/audit.jsonl"),
)
@gatehouse.tool(tier=AccessTier.READ)
def lookup_order(order_id: str) -> str:
"""Look up an order's status."""
...
@gatehouse.tool(tier=AccessTier.DESTRUCTIVE)
def cancel_order(order_id: str) -> str:
"""Cancel an order. Runs only if the approver says yes."""
...
mcp.run()
集成就这么简单:按照 SDK 文档中的方式构建 MCPServer,但通过 gatehouse 注册工具。Schema 生成(包括 Annotated[..., Field(description=...)] 参数文档)、传输方式及其他一切都保持不变——守卫会保留函数的签名。同步工具仍在工作线程中运行,与在裸 MCPServer 上运行时完全一样。
terminal_approver 会在控制终端(/dev/tty)上询问,绝不会使用 stdin——通过 stdio 通信时,stdin 就是 协议管道,因此普通的 input() 审批器会破坏它。审批器可以是任意同步或异步可调用对象,接收一个 ApprovalRequest,并返回 True 表示允许;同步审批器会在专用线程池中的工作线程里运行,因此人工审批耗时不会阻塞其他调用,积压的审批请求也不会占用同步工具所需的线程。如果审批器抛出异常(Slack 不可用、工单 API 超时),调用将被拒绝,并记录失败。
为审批设置截止时间,避免无人批准的请求一直挂起:
Policy(approver=terminal_approver, approval_timeout=120)
超过截止时间后,调用将被拒绝,并记录为 approval timed out。审批器可以通过 request.deadline(time.monotonic() 值)查看截止时间,terminal_approver 会在截止时间到达时撤回提示。忽略截止时间的同步审批器会在后台继续运行,其答复会被丢弃。未设置超时时间时,守卫会一直等待审批器完成。
默认策略要求对 DESTRUCTIVE 操作进行审批,并审计所有操作。只需一行即可让守卫也写入日志:
Policy(require_approval=frozenset({AccessTier.WRITE, AccessTier.DESTRUCTIVE}), ...)
添加包含敏感信息的自定义键,同时保留默认配置:
from mcp_gatehouse import DEFAULT_REDACT
Policy(redact=DEFAULT_REDACT | {"card_pin"}, ...)
审计记录如下:
{"ts": "2026-07-16T14:02:11+00:00", "tool": "lookup_order", "tier": "read", "outcome": "ok", "arguments": {"order_id": "4417"}, "duration_ms": 0.42}
{"ts": "2026-07-16T14:02:38+00:00", "tool": "add_note", "tier": "write", "outcome": "ok", "arguments": {"order_id": "4417", "note": "call back", "api_key": "«redacted»"}, "duration_ms": 1.08}
{"ts": "2026-07-16T14:03:05+00:00", "tool": "cancel_order", "tier": "destructive", "outcome": "denied", "reason": "approver refused", "arguments": {"order_id": "4417"}}
{"ts": "2026-07-16T14:05:40+00:00", "tool": "cancel_order", "tier": "destructive", "outcome": "cancelled", "reason": "awaiting approval", "arguments": {"order_id": "4418"}}
outcome 的值为 ok、denied(reason 说明原因)、error(工具抛出了异常;reason 是异常类型)或 cancelled:客户端在调用完成前放弃了请求,或服务器已关闭。reason 说明具体情况。awaiting approval 表示工具尚未运行。tool running 会附带 duration_ms,工具可能已经完成了部分工作。同步工具无法中途停止:其工作线程会一直运行到结束,记录行仍会照常显示 ok 或 error。守卫只负责写入记录;取消操作仍按原本的方式继续进行。
试用演示
软件包附带一个可运行的订单台服务器,已接入全部三个等级,并配有终端提示审批器。将其添加到任何支持 stdio 的 MCP 客户端中——对于 Claude Desktop,可在 claude_desktop_config.json 中添加:
{
"mcpServers": {
"gatehouse-demo": {
"command": "uvx",
"args": ["mcp-gatehouse", "--audit-log", "/tmp/gatehouse-audit.jsonl"]
}
}
}
或者在运行 pip install mcp-gatehouse 后自行运行 mcp-gatehouse-demo。让模型列出订单并取消其中一个,然后观察审计日志中相应的审批结果。审计日志写入 --audit-log 指定的位置,否则使用 $MCP_GATEHOUSE_AUDIT_LOG,再否则使用 ./audit.jsonl——当工作目录不可写时(桌面客户端通常会从 / 启动服务器),则回退到 ~/.mcp-gatehouse/audit.jsonl。服务器会将选定的路径打印到 stderr。
审批提示需要独立的终端:在后台启动服务器的客户端没有终端,而使用全屏终端 UI 的客户端正在占用其终端,因此这两种情况下 cancel_order 都会被拒绝——守卫会按设计采用默认拒绝策略。若要交互式批准,请从未运行全屏程序的普通终端会话中启动客户端。两分钟后仍未响应的提示将被拒绝。examples/orders_server.py 是同一服务器,可作为模板复制使用。
设计说明
- 在服务内部、工具边界处执行管控。 代理无法理解工具的语义,而策略服务又是一个需要部署的组件。一个有 40 人的工厂没有平台团队;这只需要几个小型类和一个 JSONL 文件。
- 默认拒绝。 默默放行的安全默认设置还不如没有。脱敏也一样:清理器无法拆解的参数值(任意对象、字节)会被替换为不透明占位符,而不会直接传递;异常消息不会写入日志——只记录异常类型,因为错误文本很容易包含刚刚脱敏的值。
- 审计日志会记录拒绝、错误和取消,而不只是成功——那些没有发生的调用也是重要信息的一半,而中途被终止的调用可能已经产生了影响。
- 阻塞式终端审批器与 stdio 传输不能混用——stdout/stdin 是协议管道。
terminal_approver正是因此在/dev/tty上提示,并会在没有终端或全屏程序将其设为原始模式时拒绝审批。 实际部署应通过带外方式审批:Slack、工单或队列。 - 本工具不提供: 身份验证、传输加密或沙箱。它是服务内部的关卡,而不是外围防护。请参阅 SECURITY.md。
兼容性
面向官方 mcp Python SDK
v2.x(mcp>=2,<3)和 Python 3.10–3.14。附带类型信息
(py.typed)。版本说明:CHANGELOG.md。
mcp-gatehouse | SDK | 服务类 |
|---|---|---|
0.4.x | mcp>=2,<3 | MCPServer |
0.3.x | mcp>=2,<3 | MCPServer |
0.2.x | mcp>=2,<3 | MCPServer |
0.1.x | mcp>=1.27,<2 | FastMCP |
正如承诺的那样,公开 API(Gatehouse、Policy、AuditLog、AccessTier)在整个版本系列中保持不变。将 v1 服务移植过来只需修改两处导入——FastMCP 已改为 MCPServer,并移至 mcp.server.mcpserver;请参阅 SDK 的
迁移指南。
继续使用 SDK v1 无需任何操作:0.1.x 固定使用 mcp<2,因此 pip 会继续解析到该版本。该版本系列不再添加新功能,但仍会获得安全修复。
开发者
Nick George — 我为一家中型逆向物流科技公司设计并运营生产环境中的 MCP 服务,也通过 nickgeorgeai.com 为企业构建 MCP 服务。这个库提取自这些项目中的权限与审计规范。 我为什么构建它,以及它如何运作的通俗说明,请参阅项目页面。
如果你是企业主或运营者,想了解 MCP 到底是什么,请从这篇通俗指南开始:什么是 MCP 服务?
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。