mcpField
C
chp-mcp

chp-mcp

本地服务
github.com/icohangar-ops金融数据07 周前更新

关于 chp-mcp

chp-mcp 是用于支出控制和工具授权的 MCP 服务,面向需要为 AI Agent 操作设置人工审批和审计记录的团队。它将预算门槛与绑定具体调用的签名收据、结构化拒绝账本结合起来。

主要功能

  1. 01支出上限与阈值门控
  2. 02人工审批与签名收据
  3. 03绑定参数的工具授权
  4. 04结构化链式审计账本
  5. 05需收据的模拟金融工具

适用场景

  1. 01为高额支出设置审批
  2. 02阻止参数变更或重放收据的调用
  3. 03审计被拒绝及已授权的金融操作

MCP 相关

向 MCP 客户端提供支出评估、审批、收据授权、审计及参考金融工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"icohangar-ops-chp": {
"command": "npx",
"args": [
"-y",
"@cubiczan/chp-mcp"
]
}
}
}
启动命令npx -y @cubiczan/chp-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@cubiczan/chp-mcp0.1.2

工具

4

收录的工具列表 · 更新于 2 周前

参数类型必填说明
actionobject是拟议的交易/支出/授权操作
action.assetstring是
action.actionstring是
action.notionalnumber是
action.rationalestring否
action.confidencenumber|null否
policyobject是门控策略(限额、HITL 阈值、置信度下限)
policy.versionstring否
policy.daily_capnumber是
policy.max_notionalnumber是
policy.hitl_thresholdnumber是
policy.min_confidencenumber是
policy.allowed_actionsarray否
policy.per_asset_limitsobject否
committed_todaynumber否今日已计入 daily_cap 的名义金额(默认值为 0)

详细介绍

@cubiczan/chp-mcp

icohangar-ops/cubiczan-chp-mcp MCP server

一键安装 MCP,支持 CHP Profile B 支出 / 资本门槛和 工具审批回执(允许列表并不等于授权),还提供 结构化拒绝账本和回执门控的金融工具。

MCP Registry npm Conformance

封装 @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_gateevaluateGateLOCKED / HITL_REQUIRED / BLOCKED + 声明 + 内容哈希。BLOCKED 也会作为 policy_deny 记录到账本。
approve_spendapproveHumanHITL_REQUIRED 时由人工锁定(无法覆盖硬性失败)。可选的 tool + bound_args 会生成签名回执。
evaluate_tool_approvalevaluateToolApproval允许列表是预筛选;与主机绑定的字段会合并到 args_hash;仍然需要回执
issue_approval_receiptissueApprovalReceipt人工允许 / 拒绝 → HMAC 签名回执 + 决策日志
authorize_tool_callauthorizeToolCall使用回执;发生漂移、覆盖主机绑定字段、过期、重放或 MAC 错误时拒绝
request_authorizationruntime生成绑定到限定范围参考工具的回执,或返回 HITL / 结构化拒绝
place_equity_orderreference合成股票订单 — 范围 trading:equities:place,需要回执
wire_treasury_transferreference合成资金库电汇 — 范围 treasury:wire,始终需要 HITL
rebalance_portfolioreference合成投资组合再平衡 — 范围 portfolio:rebalance
inspect_audit_ledgerledger最近的 CHP 链式拒绝 / 授权 / 执行记录
chp_content_hashcontentHash考虑浮点数的规范 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_hashcontentHash(host ∪ model arguments, { floatAware: true })
policy_version人员所查看的策略
risk该工具的策略风险
issued_at / expiry有效期
decisionallow 或 deny
nonce一次性使用;重放将被拒绝
signatureHMAC-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/chpProfile B 库(此服务的依赖项)
consensus-hardening-protocolProfile A + 规范性规范
@cubiczan/agent-conductor完整 MCP:合约、技能、Profile A 门控
@cubiczan/governed-mcp-gatewayHTTP MCP 控制平面
@cubiczan/codesentinel-mcp代码库健康状况 MCP
cubiczan-resilience / @cubiczan/resilience共享的重试/超时/审计基元

许可证

MIT。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。