こんにちは、みねです。
AIワーカーに「何でもできる権限」を与えると、事故が起きます。本番DBを触る、秘密鍵を読む、意図しないファイルを削除する——経験ありませんか?
今回は**MCP(Model Context Protocol)**を使って、AIワーカーの権限を「技術的に」制限する方法を解説します。
この記事でできるようになること
- MCPの基本構造を理解し、ツール連携を標準化できる
- ALLOWLISTベースのガードレールを設計し、禁止領域アクセスを防げる
- Root/Worker分離の設計パターンを自社に適用できる
対象読者
- AIワーカーの「やらかし」を経験済み(または心配している)
- 毎回プロンプトを調整する"手作り地獄"から抜け出したい
- チームにAIを導入する際のセキュリティガイドラインを作りたい
この記事でやらないこと
- MCPサーバーの詳細な実装手順(公式ドキュメントを参照)
- 特定ツール(Cursor、VS Code等)の設定方法
1. MCPが解く問題:ツール連携の"毎回手作り地獄"を終わらせる
1.1 現状の問題
┌─────────────────────────────────────────┐
│ 従来のAIワーカー連携 │
├─────────────────────────────────────────┤
│ プロンプトA: 「ファイルを読んで...」 │
│ プロンプトB: 「shellで実行して...」 │
│ プロンプトC: 「APIを叩いて...」 │
│ │
│ → 毎回、権限・手順・制約を書き直す │
│ → 人によって書き方がバラバラ │
│ → 「禁止」を忘れると事故 │
└─────────────────────────────────────────┘
1.2 MCPのアプローチ
Model Context Protocolは、AIがツールを呼び出す「インターフェース」を標準化します。
┌─────────────────┐ ┌─────────────────┐
│ AI Client │────▶│ MCP Server │
│ (Claude, etc) │ MCP │ (Tool Provider) │
└─────────────────┘ └────────┬────────┘
│
┌────────▼────────┐
│ 実際のツール │
│ (FS/Git/API/DB) │
└─────────────────┘
ポイント:MCPサーバーが「何を許可するか」を決める。AIクライアントは許可された操作しかできない。
2. 役割設計(Root/Sub/Worker)とMCPの相性
2.1 3層構造
┌─────────────────┐
│ Root Planner │ ← 人間 or 上位AI
│ 全体計画・承認 │
│ MCPツール:なし │ ← 直接操作しない
└───────┬─────────┘
│ handoff
┌───────▼─────────┐
│ Sub Planner │ ← AI(オプション)
│ タスク分解 │
│ MCPツール:検索 │ ← Read-only
└───────┬─────────┘
│ handoff
┌───────▼─────────┐
│ Worker │ ← AI
│ 実装・テスト │
│ MCPツール:限定 │ ← ALLOWLIST
└─────────────────┘
2.2 なぜ分離するのか
| 役割 | 権限 | 理由 |
|---|---|---|
| Root | なし | 判断に集中。操作しないから事故しない |
| Sub | Read-only | 情報収集。書き込まないから壊さない |
| Worker | ALLOWLIST | 必要最小限の操作だけ許可 |
3. 最小構成:Read-only repo + テスト実行 + PR作成(だけ)
3.1 Workerに許可するツール
# mcp-server-config.yaml(概念例)
allowed_tools:
# ファイルシステム(Read-only)
- name: fs_read
paths:
- "src/**"
- "tests/**"
- "docs/**"
deny_paths:
- "secrets/**"
- ".env*"
- "**/*.lock"
# ファイルシステム(Write - 限定)
- name: fs_write
paths:
- "src/**"
- "tests/**"
max_files: 5
max_lines_per_file: 300
# コマンド実行(Allowlist)
- name: shell_exec
allowed_commands:
- "pnpm test"
- "pnpm lint"
- "pnpm typecheck"
deny_commands:
- "rm -rf"
- "git push --force"
# Git操作(限定)
- name: git
allowed_operations:
- "branch"
- "commit"
- "push" # protected branchでブロック
deny_operations:
- "push --force"
- "rebase"
3.2 禁止の明示
[!CAUTION] ブラックリストではなくホワイトリスト 「これは禁止」ではなく「これだけ許可」で設計する
# Bad: ブラックリスト
deny_paths:
- "secrets/**"
- ".env"
- "database/production/**"
# → 漏れが発生しやすい
# Good: ホワイトリスト
allow_paths:
- "src/**"
- "tests/**"
# → 明示的に許可したものだけ
4. ガードレール設計(Allowlistが正義)
4.1 原則
┌────────────────────────────────────────────────┐
│ ガードレール設計の3原則 │
├────────────────────────────────────────────────┤
│ 1. 最小権限(Least Privilege) │
│ → 必要最小限のツール・パスだけ許可 │
│ │
│ 2. 段階的解放(Progressive Unlock) │
│ → 信頼が積み上がったら権限を追加 │
│ │
│ 3. フェイルセーフ(Fail-Safe Defaults) │
│ → 設定ミスは「拒否」にフォールバック │
└────────────────────────────────────────────────┘
4.2 段階的解放の例
Week 1: 超保守的
├── fs_read: src/, tests/ のみ
├── shell_exec: pnpm test のみ
└── git: branch のみ(commit/pushなし)
Week 2: テストが安定したら
├── fs_write: src/, tests/
├── shell_exec: + pnpm lint, pnpm typecheck
└── git: + commit
Week 4: CI pass rateが安定したら
├── git: + push(protected branchでガード)
└── PR作成ツール追加
5. 失敗例と対策
5.1 ツールが増えるほど事故る
「便利だから」とツールを追加し続け、気づいたら何でもできる状態に
対策: 四半期ごとにツール棚卸し。3ヶ月使われていないツールは削除
5.2 設定の属人化
「このプロジェクトは〇〇さんが設定した」で誰も触れない
対策: mcp-server-config.yaml をリポジトリにコミット、コードレビュー対象に
5.3 回避経路の発生
MCPを通さずに直接ツールを呼ぶ抜け道ができる
対策: AIクライアント側でMCP以外のツール呼び出しを無効化
測れる仮説と検証
仮説
- H1: MCPで許可ツールを固定すると、禁止領域アクセス発生率が0に近づく
- H2: ツール呼び出しが安定し、Rework countが減少する
KPI
| 指標 | 測定方法 | 目標 |
|---|---|---|
| 禁止領域アクセス | MCPサーバーのdenyログ | 0回/週 |
| Rework count | ai/metrics.md | 2回以下 |
| CI pass rate | CI履歴 | 80%以上 |
今日から一歩
まずは今日、Workerに許可するツールを3つだけ書き出してください。
# ai/allowed-tools.md
## Worker許可ツール(v1)
1. ファイル読み取り: src/, tests/
2. テスト実行: pnpm test
3. 差分表示: git diff
## 禁止(明示)
- secrets/, .env*, *.lock
- rm, git push --force
このリストが「MCP設定」の原型になります。
シリーズ記事
- AI自動運転を"ベンチマーク思考"で検証する
- MCPで"運転席と作業者"を分離して事故率を下げる(本記事)
- LLM/AI開発のObservabilityを"eBPF × OTel"で最小実装する
- WASM Component Modelで"安全な拡張"を作る
- 2026年の「AIコーディング自動運転」最前線
参考リンク
シリーズ全体に戻る: 親記事
