SafeNode MCP Gateway について
SafeNode MCP Gatewayは、MCPツールを利用するチーム向けのポリシープロキシです。各ツール呼び出しを転送前に評価し、拒否またはレビューが必要な呼び出しは下流サーバーに渡しません。
主な機能
- 01転送前の呼び出し評価
- 02許可、警告、レビュー、拒否の判定
- 03ペイロードのマスキングや制限
- 04デフォルトのフェイルクローズ
- 05ローカルJSONL判定ログ
活用シーン
- 01ファイルシステムやデータベースのツール呼び出しを制御
- 02機密性の高い操作にレビューを要求
- 03評価用に送る機密値をマスキング
- 04ポリシー判定のローカル記録を保持
MCP 対応
MCPクライアントと設定済みMCPサーバーの間に配置されます。ツール一覧はそのまま渡し、各呼び出しを評価します。拒否またはレビュー対象の呼び出しは下流サーバーに届きません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y safenode-mcp-gatewaySAFENODE_API_KEYシークレットSafeNode API key. Free tier at https://safenode.tech — no card required.SAFENODE_BASE_URLOverride the SafeNode API base URL. Defaults to https://safenode.tech.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
SafeNode MCP Gateway
すべてのツール呼び出しにポリシーを適用する MCP プロキシです。エージェントが回避することはできません。
npx safenode-mcp-gateway
プロキシを使う理由
evaluate_action ツールを公開する MCP サーバーは、見せかけにすぎません。モデルはそのツールを呼び出さないことを選べるため、何も強制できません。
これはプロキシです。MCP クライアント(Claude Desktop、Claude Code、Cursor など、あらゆる MCP ホスト)と、すでに使用している MCP サーバーの間に配置されます。tools/list はそのまま通過するため、モデルには以前とまったく同じツールが表示されます。すべての tools/call は、まず SafeNode による評価を受けます。拒否された場合、呼び出しが下流のサーバーに到達することはありません。
Claude Desktop ──► safenode-mcp-gateway ──► filesystem server
│ github server
▼ postgres server
SafeNode API
allow/warn/review/deny
エージェントのコードを変更する必要はありません。ゲートウェイの存在を知ることもありません。
API キーを取得 — 無料プラン、カード不要 · ドキュメント · Python SDK
セットアップ
1. API キーを取得する
safenode.techで無料で取得できます。キーは sn_... の形式です。
2. 設定ファイルを作成する
safenode-gateway.json — 既存の MCP クライアント設定からサーバーをそのままコピーします。
{
"failMode": "fail_closed",
"payloadMode": "redacted",
"logFile": "./safenode-decisions.jsonl",
"servers": [
{
"name": "filesystem",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"]
}
],
"tools": {
"read_file": { "failMode": "fail_open" },
"write_file": { "payloadMode": "metadata_only" }
}
}
このファイルに API キーを記載しないでください。環境変数に SAFENODE_API_KEY を設定します。環境変数は設定ファイルより優先されるため、このファイルを安全にコミットできます。
3. 送信する前に、送信内容を確認する
SAFENODE_API_KEY=sn_... npx safenode-mcp-gateway --dry-run
評価のために POST される正確な JSON 本文を出力します。ネットワーク呼び出しは行いません。マシンから何が送信されるかを確認する最も手早い方法です。
4. MCP クライアントの接続先をゲートウェイにする
Claude Desktop — claude_desktop_config.json:
{
"mcpServers": {
"safenode": {
"command": "npx",
"args": ["-y", "safenode-mcp-gateway", "--config", "/absolute/path/to/safenode-gateway.json"],
"env": { "SAFENODE_API_KEY": "sn_..." }
}
}
}
Claude Code — プロジェクト内の .mcp.json:
{
"mcpServers": {
"safenode": {
"command": "npx",
"args": ["-y", "safenode-mcp-gateway", "--config", "./safenode-gateway.json"],
"env": { "SAFENODE_API_KEY": "sn_..." }
}
}
}
Cursor — ~/.cursor/mcp.json。Claude Desktop と同じ形式です。
既存のサーバーエントリーを、この設定に置き換えてください。ゲートウェイがサーバーを自ら起動するため、両方の場所に記載すると各サーバーが二重に起動します。
各判定の動作
| 判定 | 動作 |
|---|---|
allow | 転送されます。下流の結果が変更されずに返されます。 |
warn | [SafeNode warning] の行が先頭に追加されてから転送されるため、モデルと人の両方に警告が表示されます。 |
review | 転送されません。 承認が必要であることを示すメッセージを返します。 |
deny | 転送されません。 人が読める理由と trace_id を返します。 |
拒否はトランスポートの失敗ではなく、MCP ツールのエラーとして返されます。そのため、ホストに原因不明のクラッシュを表示させる代わりに、モデルが理由を確認して別の方法を試せます。
失敗時の動作
SafeNode 自体に接続できない場合の動作は、failMode で決まります。
fail_closed (デフォルト) | 呼び出しをブロックします。 |
fail_open | 評価せずに転送します。 |
raise | ゲートウェイをクラッシュさせます。 |
SafeNode SDK のデフォルトが fail_open なのに対し、ゲートウェイのデフォルトは fail_closed です。 この違いは意図的なものです。SDK は開発者自身のコードをラップするもので、SafeNode の停止中に本番環境を停止させると、ユーザーを永久に失うおそれがあります。一方、ゲートウェイはファイルシステムへの書き込み、シェルコマンド、支払いなど、内容を把握していない任意の MCP ツールの前段に置かれます。SafeNode に接続できなくなった瞬間に、それらすべてを黙って通過させてしまっては、導入する意味がありません。
読み取り専用のツールについては、ツールごとに制限を緩められます。
"tools": {
"read_file": { "failMode": "fail_open" },
"list_files": { "failMode": "fail_open" }
}
縮退時の判定は stderr に記録され、判定ログでは "degraded": true および null の traceId として示されます。そのため、実際のポリシー判定として数えられることはありません。
マシンから送信されるデータ
ツール呼び出しごとに、ゲートウェイはツール名、下流サーバー名、セッション ID、設定に含まれる静的コンテキスト、そしてペイロードとしてツールの引数を送信します。
引数の扱いは payloadMode で制御します。
full | そのまま送信されます。 |
redacted (デフォルト) | クライアント側で事前に秘匿化されます。 |
metadata_only | 値は一切含まれず、キー名とハッシュのみ送信されます。 |
秘匿化の対象は、メールアドレス、Luhn アルゴリズムで検証されたクレジットカード番号、米国の SSN、プロバイダーの API キーのプレフィックス(sk-、ghp_、xoxb-、AKIA、AIza)、ベアラートークン、PEM 形式の秘密鍵ブロックです。値は [REDACTED:<type>] に置き換えられます。
なぜ秘匿化件数は常に送信されるのか
秘匿化されたペイロードとともに、ゲートウェイは削除したデータの件数を送信します。
"safenode_redactions": { "email": 2, "credit_card": 1 }
これはセキュリティ上、重要な意味を持ちます。SafeNode のサーバー側 sensitive_data ルールは、ペイロードの値に対してパターンを照合します。ゲートウェイが値をスクラブして何も伝えなければ、「カード番号を含むすべてのアクションを拒否する」というポリシーが、気付かないうちに適用されなくなります。つまり、クライアント側のプライバシー機能がサーバー側のセキュリティ制御を無効にしてしまいます。件数を報告すれば、この問題を解消できます。カード番号を一切受け取らずに、カード番号の存在に基づいてポリシーを適用できます。
patterns を指定して sensitive_data を使う場合は、redaction_metadata ルールも併用してください。
これらの件数は自己申告です。誠実なクライアントに対する最低限の保護にはなりますが、悪意のあるクライアントへの防御にはなりません。
テレメトリーなし
ゲートウェイが通信する相手は、設定した下流の MCP サーバーと SafeNode API の 2 つだけです。分析データの送信、ホームへの通信、postinstall スクリプトはありません。
ローカル決定ログ
logFile を設定すると、サーバー側の監査証跡とは別に、すべての判断を JSONL 形式で記録できます。ネットワークがダウンしても、エージェントが何を実行しようとしたかを確認できます。
{"timestamp":"2026-08-08T04:12:09.412Z","server":"filesystem","tool":"write_file","decision":"deny","degraded":false,"traceId":"9f1c…","reasons":["Path is outside the approved workspace."],"forwarded":false,"durationMs":143,"sessionId":"a3f1…"}
設定リファレンス
| キー | デフォルト | 意味 |
|---|---|---|
apiKey | — | 環境変数の SAFENODE_API_KEY を推奨します |
baseUrl | https://safenode.tech | ステージング用 |
failMode | fail_closed | fail_closed | fail_open | raise |
payloadMode | redacted | full | redacted | metadata_only |
timeoutMs | 5000 | 評価リクエストのタイムアウト |
logFile | null | JSONL 決定ログのパス |
prefixTools | false | <server>__<tool> 形式の命名を強制します |
servers[] | 必須 | 下流の MCP サーバー |
tools{} | {} | ツールごとの上書き設定 |
context{} | {} | すべての評価に適用する静的コンテキスト |
failMode、payloadMode、context は、グローバル、サーバーごと、またはツールごとに設定できます。最も具体的な設定が優先されます。
tools.<name>.bypass: true を設定すると、1 つのツールについて評価を完全にスキップします。設定どおり、ポリシーチェックなしで呼び出しを転送します。
ツール名の衝突
2 つの下流サーバーが同じツール名を公開している場合、ゲートウェイはすべてのツールに <server>__ を付け、警告を記録します。黙って一方を選ぶと、あるサーバーのポリシーが別のサーバーのツールに適用される可能性があります。これは見た目の問題ではなく、セキュリティ上のバグです。
この機能の対象外
- サンドボックスではありません。 呼び出しを転送するかどうかを判断します。下流サーバーを隔離したり、システムコールを制限したり、呼び出しが届いた後にそのサーバーができることを制限したりはしません。
- プロンプトインジェクション検出器ではありません。 判断の根拠となった推論ではなく、アクションを評価します。エージェントがテーブルを削除するよう説得されていた場合、削除を阻止することはできますが、エージェントが操作されたことを知らせることはできません。
- オフラインでは使えません。 ツールを呼び出すたびに SafeNode API との往復通信が必要です。ローカルでのポリシー評価はありません。
- 基盤となるサーバーのアクセス範囲を限定する代わりにはなりません。 ファイルシステムサーバーには、目的を達成できる最も狭いルートディレクトリを引き続き指定してください。
- 副作用がないわけではありません。 すべての評価がサーバー側に記録され、月間クォータに加算されます。
レイテンシー
保護対象のツール呼び出しごとに、デフォルトで 5000ms のタイムアウトが設定された SafeNode API との往復通信が 1 回追加されます。バイパスされたツールでは追加されません。
evaluate エンドポイントの実測 p99 は、現実的な負荷のもとでまだ測定されていないため、現時点では公開されていません。測定されたら、推定値ではなく、ここおよびドキュメントに掲載します。
Docker
docker build -t safenode-mcp-gateway .
引数を指定せずに実行すると、同梱のデモ設定を使って起動し、付属の echo サーバーへのプロキシとして動作するため、セットアップなしでプロキシの動作を確認できます。
docker run -i --rm safenode-mcp-gateway
デモキーはプレースホルダーのため、tools/list はそのまま通過しますが、実際のツール呼び出しは fail_closed ポリシーによってすべて拒否されます。実際に使用する場合は、独自の設定をマウントし、キーを指定してください。
docker run -i --rm \
-e SAFENODE_API_KEY=sn_... \
-v /path/to/safenode-gateway.json:/app/config.json \
safenode-mcp-gateway --config /app/config.json
-i は必須です。MCP は stdio 経由で JSON-RPC を使用するため、stdin を接続しないとゲートウェイは通信できません。
エージェントスキル
SKILL.md では、エージェントがゲートウェイをセットアップし、既存のサーバーをゲートウェイの背後に移す方法と、呼び出しがブロックされた場合やレビュー待ちになった場合の対応方法を説明しています。エージェントのスキルディレクトリ内のフォルダーにコピーしてください(Claude Code の場合は ~/.claude/skills/safenode-mcp-gateway/)。ポリシー作成の補助資料は skill/safenode-policies/ にあります。
要件
Node 18 以上。実行時依存関係は @modelcontextprotocol/sdk の 1 つです。
コントリビューション
CONTRIBUTING.md を参照してください。適用の抜け穴に関するバグ報告(ブロックされるべきなのに下流サーバーに到達するもの)は、最も役立つ報告です。
セキュリティ
SECURITY.md を参照してください。脆弱性について、公開 issue を作成しないでください。
ライセンス
MIT。LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。