关于 chp-mcp
chp-mcp 是用于支出控制和工具授权的 MCP 服务,面向需要为 AI Agent 操作设置人工审批和审计记录的团队。它将预算门槛与绑定具体调用的签名收据、结构化拒绝账本结合起来。
主要功能
- 01支出上限与阈值门控
- 02人工审批与签名收据
- 03绑定参数的工具授权
- 04结构化链式审计账本
- 05需收据的模拟金融工具
适用场景
- 01为高额支出设置审批
- 02阻止参数变更或重放收据的调用
- 03审计被拒绝及已授权的金融操作
MCP 相关
向 MCP 客户端提供支出评估、审批、收据授权、审计及参考金融工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
4收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | object | 是 | 拟议的交易/支出/授权操作 |
| action.asset | string | 是 | |
| action.action | string | 是 | |
| action.notional | number | 是 | |
| action.rationale | string | 否 | |
| action.confidence | number|null | 否 | |
| policy | object | 是 | 门控策略(限额、HITL 阈值、置信度下限) |
| policy.version | string | 否 | |
| policy.daily_cap | number | 是 | |
| policy.max_notional | number | 是 | |
| policy.hitl_threshold | number | 是 | |
| policy.min_confidence | number | 是 | |
| policy.allowed_actions | array | 否 | |
| policy.per_asset_limits | object | 否 | |
| committed_today | number | 否 | 今日已计入 daily_cap 的名义金额(默认值为 0) |
详细介绍
@cubiczan/chp-mcp
一键安装 MCP,支持 CHP Profile B 支出 / 资本门槛和 工具审批回执(允许列表并不等于授权),还提供 结构化拒绝账本和回执门控的金融工具。
封装 @cubiczan/chp,让 Cursor、
Claude Code 或任何 MCP 客户端都能调用 evaluate_spend_gate,而无需将协议代码 vendoring
到项目中。引擎摘要与规范黄金向量一致
(Profile B 30/30)。
各部分如何协同工作
MCP client (Cursor / Claude / …)
│ tools/call
▼
┌───────────────────────────┐
│ MCP server (transport) │ ← you are here (@cubiczan/chp-mcp)
│ evaluate_spend_gate │
│ approve_spend │
│ evaluate_tool_approval │ allowlist ≠ authorization
│ issue_approval_receipt │
│ authorize_tool_call │
│ request_authorization │ finance-tool receipt / HITL / deny
│ place_equity_order │ scoped + receipt-gated (synthetic)
│ wire_treasury_transfer │
│ rebalance_portfolio │
│ inspect_audit_ledger │ CHP-signed deny / authorize / execute
│ chp_content_hash │
└─────────────┬─────────────┘
│ depends on
▼
┌───────────────────────────┐
│ Published CHP packages │
│ npm: @cubiczan/chp (Profile B)
│ PyPI: consensus-hardening-protocol (Profile A)
└───────────────────────────┘
如需 AGENTS.md + skills + Profile A decision_gate / decision_adversary,请改用
agent-conductor。
安装
npm install -g @cubiczan/chp-mcp
# or one-shot
npx -y @cubiczan/chp-mcp
Cursor / Claude Desktop
{
"mcpServers": {
"chp": {
"command": "npx",
"args": ["-y", "@cubiczan/chp-mcp"]
}
}
}
Claude Code
claude mcp add chp -- npx -y @cubiczan/chp-mcp
工具
| 工具 | 对应项 | 用途 |
|---|---|---|
evaluate_spend_gate | evaluateGate | LOCKED / HITL_REQUIRED / BLOCKED + 声明 + 内容哈希。BLOCKED 也会作为 policy_deny 记录到账本。 |
approve_spend | approveHuman | HITL_REQUIRED 时由人工锁定(无法覆盖硬性失败)。可选的 tool + bound_args 会生成签名回执。 |
evaluate_tool_approval | evaluateToolApproval | 允许列表是预筛选;与主机绑定的字段会合并到 args_hash;仍然需要回执 |
issue_approval_receipt | issueApprovalReceipt | 人工允许 / 拒绝 → HMAC 签名回执 + 决策日志 |
authorize_tool_call | authorizeToolCall | 使用回执;发生漂移、覆盖主机绑定字段、过期、重放或 MAC 错误时拒绝 |
request_authorization | runtime | 生成绑定到限定范围参考工具的回执,或返回 HITL / 结构化拒绝 |
place_equity_order | reference | 合成股票订单 — 范围 trading:equities:place,需要回执 |
wire_treasury_transfer | reference | 合成资金库电汇 — 范围 treasury:wire,始终需要 HITL |
rebalance_portfolio | reference | 合成投资组合再平衡 — 范围 portfolio:rebalance |
inspect_audit_ledger | ledger | 最近的 CHP 链式拒绝 / 授权 / 执行记录 |
chp_content_hash | contentHash | 考虑浮点数的规范 SHA-256 |
chp_version | — | 服务端 + 协议版本 + 拒绝原因代码 + 回执架构 |
示例 — 评估支出
// tools/call evaluate_spend_gate
{
"action": { "action": "LONG", "asset": "ETH", "notional": 300, "confidence": 0.9 },
"policy": {
"max_notional": 500,
"daily_cap": 2500,
"hitl_threshold": 250,
"min_confidence": 0.55,
"allowed_actions": ["LONG", "SHORT"]
}
}
食谱 — Claude / Cursor 工具审批
托管的 MCP 允许列表(Cursor mcpServers、Claude Desktop、Claude Code)
只回答*“是否已安装此工具名称?”*。它们不会绑定租户、参数、风险或人工决策。本服务会将这一缺口视为必须拒绝,除非仍有一份已签名的审批凭证与即将执行的调用匹配。
凭证是对 CHP 规范 JSON执行 HMAC-SHA256(采用与 Profile B contentHash / audit-ledger sig 相同的载荷规范)。MAC 覆盖:
| 字段 | 作用 |
|---|---|
actor | 允许或拒绝的人员 |
tool | 具体工具名称(不能是 *) |
resource | 租户 / 资源绑定(不能是 *) |
args_hash | contentHash(host ∪ model arguments, { floatAware: true }) |
policy_version | 人员所查看的策略 |
risk | 该工具的策略风险 |
issued_at / expiry | 有效期 |
decision | allow 或 deny |
nonce | 一次性使用;重放将被拒绝 |
signature | HMAC-SHA256 十六进制值 |
在 MCP 服务环境中设置 CHP_RECEIPT_KEY(或 AUDIT_LEDGER_KEY)。
如果未设置,进程会回退到有文档说明的不安全默认值——适用于本地食谱,但不适用于生产环境。
示例策略:examples/tool-approval-policy.json。
stripe.create_charge 在允许列表中,但没有绑定到 acct_live_acme 和确切交易参数的凭证,仍然无法运行。
主机注入的租户 / 索引绑定使用
examples/host-injected-policy.json
(参见下文的主机注入参数食谱)。
{
"mcpServers": {
"chp": {
"command": "npx",
"args": ["-y", "@cubiczan/chp-mcp"],
"env": { "CHP_RECEIPT_KEY": "replace-me" }
}
}
}
1. 仅有允许列表 — 拒绝
Claude/Cursor 已启用 stripe.create_charge。这并不构成授权。
// tools/call evaluate_tool_approval
{
"call": {
"tool": "stripe.create_charge",
"resource": "acct_live_acme",
"arguments": { "amount": 2500, "currency": "usd", "customer": "cus_123" }
},
"policy": { "$ref": "examples/tool-approval-policy.json" }
}
结果:RECEIPT_REQUIRED,deny_code: "allowlist_is_not_authorization"。
使用相同载荷且不提供凭证调用 authorize_tool_call,
会返回 DENIED / allowlist_is_not_authorization。
2. 人工允许 — 然后授权
// tools/call issue_approval_receipt
{
"actor": "[email protected]",
"decision": "allow",
"reason": "invoice INV-104 matches amount",
"ttl_seconds": 120,
"call": { /* same as above */ },
"policy": { /* same as above */ }
}
响应中包含 receipt(请传入整个对象)和
decision_log(actor、decision、args hash、nonce)。将该凭证
与相同调用一起传给 authorize_tool_call。结果:AUTHORIZED。
3. 人工拒绝
使用 "decision": "deny" 签发。该决策会被记录。使用该凭证进行授权时,
将返回 DENIED / human_denied。不能通过编辑 decision 将拒绝凭证改为允许——MAC 会失效。
4. 审批后参数发生变化 — 拒绝
审批 { "amount": 2500, ... },然后使用
{ "amount": 2500000, ... } 进行授权。结果:DENIED / changed_arguments。
键的顺序无关紧要;哈希采用 CHP 规范形式。原始凭证对已审批的参数仍然有效(直到过期或成功使用)。
5. 凭证已过期 — 拒绝
使用 ttl_seconds: 30 签发。过期时刻之后,
authorize_tool_call 会返回 DENIED / expired_receipt。nonce
会被消耗,因此回拨时钟也无法使其恢复有效。
6. 重放凭证 — 拒绝
成功以 AUTHORIZED 使用后,nonce 即被销毁。再次出示同一凭证会返回 DENIED / replayed_receipt。
7. 存在歧义 — 拒绝
以下情况均不会生成可用的允许凭证:
resource: "*"、any、all或空字符串- 缺少
arguments - 策略没有具体的
version - actor / tool 通配符
- 凭证包含额外键(严格解析)
失败时默认拒绝:无法关闭 deny_on_ambiguity。
操作指南 — 宿主注入参数与网关 _meta
Semantic Kernel 和其他宿主需要传递 索引、密钥和租户
而不让模型选择它们
(SO 风格的路由)。
将这些字段放到工具架构中,让 LLM 来“决定”,就是
问题所在。MCP 允许列表无法解决这个问题:工具名称可以继续
位于允许列表中,但模型仍可将 index_name 替换为另一个租户。
宿主(或位于此服务前面的网关)会注入绑定字段。 此软件包会将 宿主 ∪ 模型 参数哈希到回执中, 并在模型覆盖宿主绑定字段时拒绝请求。允许列表 仍然只是预筛选。
契约 — _meta.cubiczan(无硬依赖)
@cubiczan/governed-mcp-gateway
已经会在每次 tools/call 和 SSE 帧中注入身份信息:
{
"_meta": {
"cubiczan": {
"principal": {
"id": "agt_search",
"kind": "agent",
"orgId": "org_acme",
"displayName": "Search Runner"
}
}
}
}
此服务不会导入该软件包,而是读取相同的
信封。宿主可以在 principal 旁添加 host_bound。可信的
网关应覆盖 _meta.cubiczan,以防模型自行声明身份。
{
"_meta": {
"cubiczan": {
"principal": { "id": "agt_search", "kind": "agent", "orgId": "org_acme" },
"host_bound": { "tenant_id": "acme", "index_name": "prod-docs" }
}
}
}
库调用方也可以在拟议调用中传递 host_bound
(显式键会覆盖 _meta)。策略文件
examples/host-injected-policy.json
声明了 host_bound_fields,因此 index_name 和 tenant_id 必须由
宿主注入且具有具体值。如果声明了 tenant_id 但未提供,
可使用 _meta.cubiczan.principal.orgId 填充。
model args ──┐
├─ override check ─→ deny host_bound_override
host_bound ──┘ │
▼
merged args → args_hash → receipt MAC
│
allowlist ──── pre-filter only (never a grant)
1. 宿主注入索引和租户 — 仍被允许列表拒绝
模型选择了 query / top_k。宿主选择了索引。
// tools/call evaluate_tool_approval
{
"call": {
"tool": "search.azure_ai",
"resource": "tenant:acme",
"arguments": { "query": "Q3 revenue", "top_k": 5 },
"_meta": {
"cubiczan": {
"principal": { "id": "agt_search", "kind": "agent", "orgId": "org_acme" },
"host_bound": { "tenant_id": "acme", "index_name": "prod-docs" }
}
}
},
"policy": { "$ref": "examples/host-injected-policy.json" }
}
结果:RECEIPT_REQUIRED,deny_code: "allowlist_is_not_authorization"。
args_hash 是
{ query, top_k, tenant_id, index_name } 的 contentHash,而非仅对模型对象进行哈希。
2. 模型更改宿主绑定字段 — 拒绝
使用相同的宿主 _meta,但模型添加了 "index_name": "other-index"。
"arguments": { "query": "Q3 revenue", "top_k": 5, "index_name": "other-index" }
evaluate_tool_approval、issue_approval_receipt(decision: "allow")
和 authorize_tool_call 都会返回 DENIED /
host_bound_override。与宿主值相同不算覆盖。
3. 人工允许 — 然后授权合并后的参数
为宿主注入的调用签发回执。使用相同的
arguments 和 _meta 进行授权。结果:AUTHORIZED。批准后更改
query → changed_arguments。在模型参数中更改 index_name →
host_bound_override。省略已声明的宿主字段 → ambiguous。
4. Semantic Kernel / 宿主接线
在宿主中进行路由,而不是交给模型:禁用自动调用,然后在调用
evaluate_tool_approval /
authorize_tool_call 之前注入索引/租户(或在前面添加一个网关,
由其写入 _meta.cubiczan.host_bound)。API 密钥等机密应保存在宿主或
网关保管库中,而不是放在 LLM 可见的工具架构中。
操作指南 — 拒绝遥测与回执
MCP 拒绝通常只是一个简单的错误字符串。客户端断开连接后,这个 字符串就会消失。此服务将拒绝视为一种结构化事件,必须先写入 CHP 签名账本,之后调用方才能看到它。
金融工具(place_equity_order、wire_treasury_transfer、
rebalance_portfolio)是合成工具,不连接任何实时交易场所或银行通道,
并使用单独的 kind: "authorization" 回执,该回执绑定到工具、范围和参数哈希。
它与 chp.tool_approval_receipt 不是同一种对象。
原因代码
| 代码 | 情况 |
|---|---|
policy_deny | 未通过 CHP 硬性规则(max_notional、每日上限等) |
expired | 收据的 expires_at 已过期 |
replay | 收据已被成功执行使用 |
args_changed | 工具、范围或参数哈希与收据不再匹配 |
missing_receipt | 没有收据,或内容哈希验证失败 |
ambiguous_policy | 未知工具、范围不匹配或策略不完整 |
签名采用现有的 Profile B 基元:收据/账本载荷上的 contentHash,以及账本行之间的 chainHash。
将 CHP_AUDIT_LEDGER 设置为 JSONL 路径(默认为 ./data/chp-audit.jsonl),测试时也可设置为 :memory:。
1. 请求绑定收据
低于 HITL 阈值时,门控会自动锁定并签发收据。达到或超过阈值时,请传入 approver(或使用 tool + bound_args 调用 approve_spend)。
// tools/call request_authorization
{
"tool": "place_equity_order",
"args": {
"symbol": "AAPL",
"side": "BUY",
"quantity": 10,
"notional": 300,
"confidence": 0.9
},
"approver": "[email protected]"
}
Treasury 接线使用 hitl_threshold: 0。不带 approver 的请求会返回 HITL_REQUIRED,且不会返回收据——这是审批门控,不是天气 API 演示。
2. 仅凭该收据执行
接线时 receipt 为可选项,因此缺少令牌会被记录为 missing_receipt 拒绝,而不会变成无法写入账本的架构 400 错误。
// tools/call place_equity_order
{
"symbol": "AAPL",
"side": "BUY",
"quantity": 10,
"notional": 300,
"confidence": 0.9,
"receipt": { "kind": "authorization", "receipt_id": "…", "content_hash": "…" }
}
审批后更改 notional 或 quantity → args_changed,账本中会记录拒绝。使用同一收据再次调用 → replay。不带收据调用 → missing_receipt。这三种情况都会持久记录。
3. 检查链
// tools/call inspect_audit_ledger
{ "limit": 20 }
每行都包含 content_hash 和 sig = chainHash(prev_sig, { seq, ts, event, content_hash })。
如果有人改写历史记录,chain.ok 会变为 false。
测试
npm test
此 Cubiczan 镜像可能不包含 GitHub Actions;请在本地运行测试套件。
npm test 会先构建,然后运行 node --test dist/*.test.js(审批收据 + 主机注入绑定)以及 node --import tsx --test test/**/*.test.ts(拒绝账本)。覆盖的不变量:不可能出现未记录的拒绝(账本失败会抛出异常,而非返回拒绝对象);审批后参数变更会导致拒绝;每个受门控的引用工具都必须提供收据;允许列表不等于授权;模型无法覆盖由主机绑定的租户/索引;收据的 args_hash 涵盖主机参数 ∪ 模型参数。
相关项目
| 软件包/仓库 | 作用 |
|---|---|
@cubiczan/chp | Profile B 库(此服务的依赖项) |
consensus-hardening-protocol | Profile A + 规范性规范 |
@cubiczan/agent-conductor | 完整 MCP:合约、技能、Profile A 门控 |
@cubiczan/governed-mcp-gateway | HTTP MCP 控制平面 |
@cubiczan/codesentinel-mcp | 代码库健康状况 MCP |
cubiczan-resilience / @cubiczan/resilience | 共享的重试/超时/审计基元 |
许可证
MIT。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。