chp-mcp について
chp-mcpは、AIエージェントの操作に人間の承認と監査記録を設けたいチーム向けの、支出管理・ツール認可用MCPサーバーです。予算ゲートに加え、呼び出しに紐づく署名付きレシートと構造化された拒否台帳を備えています。
主な機能
- 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
CHP Profile Bの支出/資本ゲートと ツール承認の証跡(許可リストは認可ではありません)、さらに 構造化された拒否台帳および証跡でゲートされた金融ツールを、1つのコマンドでMCPにインストールできます。
@cubiczan/chpをラップしているため、Cursor、
Claude Code、または任意のMCPクライアントから、プロトコルコードをベンダー化することなくevaluate_spend_gateを呼び出せます。エンジンのダイジェストは、規範的なゴールデンベクトルと一致します
(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、スキル、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 | ランタイム | スコープ指定の参照ツールにバインドされた証跡を発行するか、HITLまたは構造化された拒否を返します |
place_equity_order | 参照実装 | 合成株式注文 — スコープはtrading:equities:place、証跡が必要です |
wire_treasury_transfer | 参照実装 | 合成トレジャリー送金 — スコープはtreasury:wire、常にHITLです |
rebalance_portfolio | 参照実装 | 合成ポートフォリオのリバランス — スコープはportfolio:rebalance |
inspect_audit_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 / 監査台帳の sig と同じペイロード規則です)。MAC の対象は次のとおりです。
| フィールド | 役割 |
|---|---|
actor | 許可または拒否した人間 |
tool | 具体的なツール名(* は不可) |
resource | テナント / リソースの紐付け(* は不可) |
args_hash | contentHash(host ∪ model arguments, { floatAware: true }) |
policy_version | 人間が確認したポリシー |
risk | そのツールに対するポリシー上のリスク |
issued_at / expiry | 有効期間 |
decision | allow または deny |
nonce | 1 回限り。再利用すると拒否されます |
signature | HMAC-SHA256 の 16 進数表記 |
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(実行者、判断、引数ハッシュ、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 フレームにすでに ID を注入します。
{
"_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、1 日あたりの上限など) |
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 はワイヤ上では省略可能です。そのため、トークンがない場合は、台帳に記録されないスキーマエラー 400 ではなく、missing_receipt の拒否としてログに記録されます。
// 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 つはすべて永続的に記録されます。
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 サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。