mcp-capability-guard
mcp-capability-guard
大多数 MCP 服务器会递给模型一把上了膛的枪,并附带一个共享的 Bearer 令牌:一个凭据,就能调用所有工具、所有请求。而这个服务器会让模型为每一颗子弹都请求许可。
这是一个小巧而完整的 MCP 服务器,构建于一个虚构的内存 CRM(Larkspur Supply Co.,七个虚构联系人)之上,演示了能力令牌(capability-token)的写入授权——这个模式提取自一个我在真实 12,000+ 联系人通讯录上运行的生产级 CRM 代理。这里的数据是虚构的;要交付的是其中的强制机制。
设计,分为五层
分层工具面。 读取操作(
list_contacts、get_contact)是免费的。写入操作不存在于单一工具中——没有add_note工具,也没有delete_contact工具。每次变更都恰好经过两次调用:先propose_write,再execute_write。能力令牌(核心)。
propose_write会铸造一个一次性、带 TTL 的授权凭证,绑定到恰好一个精确的变更上——令牌内嵌了变更本身,而不是指向某个变更,因此没有查找表可被投毒,也没有 id 可被重新定向。execute_write将令牌与变更一起提交,守卫会逐字段校验相等性。用不同的变更提交凭证不仅会失败——还会烧毁该令牌,把攻击者合法的写入也一并带走。破坏性层级的人工确认。
change_stage、remove_tag和delete_contact还额外要求操作员通过 MCP 表单引导(elicitation)明确同意,提示语会用一句话说明操作、联系人和负载。询问发生在守卫被咨询之前,因此拒绝不会消耗凭证——而没有引导通道的客户端会得到破坏性写入被拒绝的结果,而不是静默执行。双向失败关闭(fail closed)。上层无法覆盖的底线。 处于
Closed-Lost-DNC阶段(请勿联系、法律保留)的联系人会在存储层内部拒绝所有写入,而存储层对令牌或 MCP 一无所知。一个完全批准的流程——有效凭证、匹配的变更、已确认的人工——仍然会在那里碰壁。这就是纵深防御,而不是一个挂着三块牌子的单一闸门。只能追加且不会泄露凭证的审计日志。 每次提议、确认、执行和拒绝都会被记录。令牌 id 只以 8 字符指纹的形式进入日志——而这是一个编译时保证:指纹字段持有一个品牌化 TypeScript 类型,只有截断函数才能产生该类型。自由文本也会按值擦除,因为守卫自身的拒绝消息会点名被拒绝的令牌。(这与我的 webhook-guard 采用相同的按值脱敏纪律——那里针对 HTTP 凭据,这里针对实时凭证。)
read_audit默认拒绝:除非服务器以exposeAudit: true构建,否则该工具根本不会被注册。
Related MCP server: tenant-scoped-crm
查看运行效果
npm install
npm run demo该演示将真实服务器通过内存 MCP 传输连接到脚本化客户端,并叙述八个步骤:两次落地的写入(一次可逆,一次破坏性且已确认),然后是五次攻击——重放、偷梁换柱、被拒绝的确认、目标转移,以及对冻结记录的一次完全批准的写入——每一次都遇到其类型化的拒绝,而存储保持逐字节不变。最后读取审计跟踪,并检查其中是否出现任何完整的令牌 id。演示内联断言每个期望,任何未命中都会以非零退出码退出,因此它兼作冒烟测试,并在每次推送时于 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让一个敌意模型对抗完全接线的服务器:跳过提议、重放、带烧毁验证的偷梁换柱、将凭证重新指向不同联系人、对冻结记录发起完全批准的进攻、通过注入时钟使凭证过期、绕过确认,以及使用攻击者选择的令牌 id 进行审计完整性检查。每次攻击都必须遇到其精确的类型化拒绝,而在所有这些之后,存储必须保持不变。
其余约 140 个测试逐单元覆盖存储、守卫、审计和工具面,包括确认必须在凭证可被消耗之前运行的顺序不变量。
版本与范围
基于 @modelcontextprotocol/sdk 1.30.0 构建,目标为 MCP 修订版 2025-11-25。2026-07-28 修订版将服务器铸造的、作为普通工具参数传递的句柄确立为跨调用状态(SEP-2567)的规范机制——本仓库中的能力令牌正是该模式,用作授权原语,因此该设计无需更改即可延续到无状态协议中。
两个运行时依赖:SDK 本身,以及 zod,后者是 SDK 自身的对等依赖模式语言——工具输入模式按 SDK 设计就是 zod 模式,因此它与其说是额外依赖,不如说是 SDK 的另一半。没有其他内容进入依赖树。存储、守卫和审计模块是纯 TypeScript,除了 node:crypto 和彼此的类型外零导入,这使得 158 个测试可以在半秒内离线运行。
这不是什么。 本仓库不实现 OAuth 或 MCP 授权规范中的资源服务器角色。那些解决的是另一个问题:在传输边界证明客户端是谁。能力令牌管理的是经过身份验证的会话可以做什么,一次一个写入——两者是组合而非竞争关系,而混淆它们正是服务器最终只有一个授权一切的 Bearer 令牌的原因。传输身份在这里被刻意排除在范围之外,以便授权模式保持清晰。
明确说明的限制
CRM 是虚构且基于内存的。持久化、并发和多用户会话是本演示未涉及的真实问题。
令牌存在于服务器内存中;重启即遗忘。在生产环境中,同一模式在持久化存储上运行,并具有相同的单次使用语义。
引导确认的有效性取决于客户端对其的渲染。向用户显示一个光秃秃的“允许?”而不是服务器句子的客户端会削弱保证——这支持将完整句子放入请求中的做法(正如本服务器所做),而不是跳过询问。
存储的备注时间戳使用墙钟,因此演示输出中的一行会因运行而异。守卫和审计日志使用注入的时钟,是确定性的。
适配
该模式可迁移到任何写入有后果的 MCP 服务器:用你的系统替换存储层,保留提议/执行分离,自行决定层级,并将底线规则放在数据层而不是工具层。守卫和审计模块不导入 MCP 的任何内容,可以整体提取出来。
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
- AlicenseAqualityAmaintenanceSecurity-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 hierarchical2112Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA 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
- FlicenseNot gradedqualityCmaintenanceA 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.
- AlicenseBqualityAmaintenanceA 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.3Apache 2.0
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.
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/adamabdo-xynora/mcp-capability-guard'
If you have feedback or need assistance with the MCP directory API, please join our Discord server