protect-mcp-setup について
protect-mcp の設定スキルです。Claude Code のツール呼び出しに Cedar ポリシーを適用し、オフライン検証可能な Ed25519 署名付きレシートを作成します。規制対象の環境を含め、ポリシー適用と検証可能な記録を必要とするチーム向けです。
主な機能
- 01Cedar ポリシーによる呼び出し評価
- 02ツール実行後のレシート署名
- 03レシートのオフライン検証
- 04フックとレシートのパス設定
- 05レシート監査コマンドの提供
活用シーン
- 01エージェントツール実行前のポリシー適用
- 02コンプライアンス用の検証可能な記録作成
- 03ネットワーク接続なしでのレシート確認
MCP 対応
README では protect-mcp を Claude Code 向けガバナンスプラグインとして説明し、MCP ホスト向けの実装も挙げています。この設定が MCP クライアントに公開するサーバーツールやリソースについては記載されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wshobson/ agents --skill protect-mcp-setupインストール後、Claude Code で/protect-mcp-setupを入力して読み込まれたか確認します。
同梱ファイルreferences/receipt-format.md
詳細
protect-mcp — ポリシー適用 + 署名付きレシート
すべての Claude Code ツール呼び出しに対する暗号学的ガバナンス。各呼び出しは Cedar ポリシーに対して評価され、誰でもオフラインで検証できる Ed25519 署名付き レシートを生成します。
概要
Claude Code は強力なツールを実行します: Bash、Edit、Write、WebFetch。デフォルトでは
監査証跡も、ポリシー適用も、事後に何が決定されたかを証明する方法もありません。
protect-mcp はこの 3 つのギャップをすべて埋めます:
- Cedar ポリシー(AWS のオープンな認可エンジン)が、実行前にすべてのツール呼び出しを 評価します。Cedar の deny は絶対です。
- Ed25519 レシートは、実行された各ツールの名前を、あなたの鍵で署名して 記録します。
- オフライン検証は
npx @veritasacta/verifyで行えます。サーバーもアカウントも、 運用者への信頼も不要です。
問題
AI エージェントは、お金、安全、権利に影響を与える決定を下します。Claude Code の セッションログは何が起きたかを記録しますが、そのログは:
- 変更可能 — アクセスできる誰もが編集できます
- 署名なし — 完全性を証明する方法がありません
- 運用者依存 — 検証にはログを保持する誰かを信頼する必要があります
コンプライアンスが求められる文脈(金融、医療、規制対象の研究)では、これでは不十分です。 あなたを信頼することなく第三者によって検証できる、改ざん検知可能な証拠が必要です。
解決策
Claude Code プロジェクトに protect-mcp を追加します:
# 1. Install the plugin (adds hooks + skill to your project)
claude plugin install wshobson/agents/protect-mcp
# 2. Create ./protect.cedar (see below). The plugin installs the hooks.
# 3. Create the signing key once (protect-mcp 0.7.4 sign does not create it).
# An existing key is never replaced. See references/receipt-format.md to rotate.
if [ ! -e ./protect-mcp.key ]; then
d=$(mktemp -d) && npx [email protected] init --dir "$d" && mv "$d/keys/gateway.json" ./protect-mcp.key
fi
echo "/protect-mcp.key" >> .gitignore
# 4. Use Claude Code normally. Every tool call is now policy-evaluated
# and produces a signed receipt in ./receipts/
フック設定
プラグインをインストールすると、hooks/hooks.json の両方のフックが追加されます。各フックは
プラグインに同梱されたスクリプトを実行します:
{
"hooks": {
"PreToolUse": [
{
"matcher": ".*",
"hooks": [
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/evaluate.sh" }
]
}
],
"PostToolUse": [
{
"matcher": ".*",
"hooks": [
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/sign.sh" }
]
}
]
}
}
Claude Code はフックイベントを stdin の JSON としてコマンドに渡し、TOOL_NAME や
TOOL_INPUT 変数は設定しません。evaluate.sh はそのペイロードから tool_name と
tool_input を読み取り、それらをフラグとして protect-mcp に渡します。sign.sh は
tool_name のみを読み取ります。0.7.4 の署名ツールはそれ以外を記録しないためです。
デフォルトのパスを変更するには PROTECT_MCP_POLICY、PROTECT_MCP_RECEIPTS、PROTECT_MCP_KEY を
設定します。ポリシーファイルが存在しない場合、PreToolUse フックは stderr に警告を出力し、
呼び出しを許可します。
各フックの動作
PreToolUse — ツールが実行される前に実行されます。ツール呼び出しを
Cedar ポリシーファイルに対して評価します。Cedar が deny を返した場合、フックは終了コード 2 で終了し、
Claude Code はツール呼び出しを完全にブロックします。
PostToolUse はツールの完了後に実行されます。ツール名を記録したレシートに署名し、
./receipts/receipts.jsonl に追記します。protect-mcp 0.7.4 は
ツールの入力や出力を記録しません。
Cedar ポリシーファイル
プロジェクトルートに ./protect.cedar を作成します:
// Read-only tools: one rule can name several tools in `when`. Add WebFetch
// with your own URL rule.
permit (principal, action == Action::"MCP::Tool::call", resource) when {
resource == Tool::"Read" || resource == Tool::"Glob" || resource == Tool::"Grep"
};
// Safe commands only; git limited to read subcommands
permit (principal, action == Action::"MCP::Tool::call", resource == Tool::"Bash") when {
context has input && context.input has command &&
(context.input.command like "git status*" || context.input.command like "git diff*" ||
context.input.command like "git log*" || context.input.command like "git show*" ||
context.input.command like "npm*" || context.input.command like "ls*" ||
context.input.command like "cat*" || context.input.command like "echo*" ||
context.input.command like "pwd*" || context.input.command like "test*")
};
// No chaining (`&` also denies `2>&1`), `$` expansion, redirection (`>` or
// `<`, which covers `<(`), file output (`git diff --output`), or rm -rf
forbid (principal, action == Action::"MCP::Tool::call", resource == Tool::"Bash") when {
context has input && context.input has command &&
(context.input.command like "*;*" || context.input.command like "*&*" ||
context.input.command like "*|*" || context.input.command like "*$*" ||
context.input.command like "*`*" || context.input.command like "*>*" ||
context.input.command like "*<*" || context.input.command like "*\n*" ||
context.input.command like "*--output*" || context.input.command like "*rm -rf*")
};
// Writes only inside the project (paths are absolute), never via `..`
permit (principal, action == Action::"MCP::Tool::call", resource) when {
(resource == Tool::"Write" || resource == Tool::"Edit") &&
context has input && context.input has file_path &&
context.input.file_path like "/path/to/project/*"
};
forbid (principal, action == Action::"MCP::Tool::call", resource) when {
(resource == Tool::"Write" || resource == Tool::"Edit") &&
context has input && context.input has file_path &&
(context.input.file_path like "*/../*" || context.input.file_path like "*/..")
};
文字列マッチングはベストエフォートです: like は解決済みのパスではなく生の文字列を
チェックし、npm* の許可は任意のコードを実行するため、プロジェクトのスクリプトと
同じ程度にしか安全ではありません。
検証
すべてのレシートを ./protect-mcp.key の公開鍵に対して検証します:
PUB=$(node -p 'JSON.parse(require("fs").readFileSync("./protect-mcp.key")).publicKey')
npx @veritasacta/[email protected] --replay-chain ./receipts/receipts.jsonl --key "$PUB"
# Exit 0 = every receipt verified
# Exit 1 = a receipt failed (tampered, wrong key, or malformed line)
# Exit 2 = the file could not be read
プラグインのスラッシュコマンドは Claude Code 内で同じことを行います。/verify-receipt
は独自のファイルに 1 つのレシートを受け取ります。たとえば、
tail -n 1 ./receipts/receipts.jsonl > receipt.json から取得します。
/verify-receipt receipt.json
/audit-chain --last 20
レシート形式
各レシートは ./receipts/receipts.jsonl の 1 行です。サンプルについては
references/receipt-format.md を参照してください。
signature以外のすべてのフィールドに対する Ed25519 署名(RFC 8032)- 署名前の JCS 正規化(RFC 8785)
- レシートに公開鍵を含まないため、
--keyで渡す - 前のレシートへのリンクがないため、削除された行は検知されない
これが重要な理由
| 導入前 | 導入後 |
|---|---|
| 「信じてください、エージェントはファイルを読んだだけです」 | 暗号学的に証明可能: すべての Read が記録され署名される |
| 「ログにそう起きたと表示されている」 | レシートがそれが起きたことを証明し、誰も編集できない |
| 「私たちのシステムを監査する必要があるでしょう」 | 誰でもすべてのレシートをオフラインで検証できる |
| 「ログは今では違っているかもしれません」 | Ed25519 署名が署名時点で記録を固定する |
標準
- Ed25519 — RFC 8032(デジタル署名)
- JCS — RFC 8785(決定論的 JSON 正規化)
- Cedar — AWS のオープンな認可ポリシー言語
- IETF ドラフト — draft-farley-acta-signed-receipts
関連
- npm: protect-mcp
- Verify CLI: @veritasacta/verify
- ソース: github.com/ScopeBlind/scopeblind-gateway
- プロトコル: veritasacta.com
- インテグレーション: Microsoft Agent Governance Toolkit(PR #667)、AWS cedar-policy/cedar-for-agents(PR #64)