mcpField
M
mcp-gatehouse

mcp-gatehouse

ローカル
nickgeorgeai.comセキュリティ26 日前に更新

mcp-gatehouse について

mcp-gatehouseは、MCPサーバー内部に権限管理、承認、監査ログを加えるPythonライブラリです。サーバー開発者はツールをリスク別に分類し、承認を必須にしたり、引数を秘匿したり、外部ポリシーサービスなしでツールを拒否したりできます。

主な機能

  1. 01READ、WRITE、DESTRUCTIVEの権限階層
  2. 02フェイルクローズの承認ゲート
  3. 03追記専用のJSONL監査記録
  4. 04機密引数のマスキング
  5. 05ツール拒否リスト
  6. 06承認タイムアウト

活用シーン

  1. 01破壊的なツール呼び出し前の承認必須化
  2. 02許可、拒否、失敗、キャンセルの記録
  3. 03ログや承認依頼内の秘密情報の秘匿
  4. 04権限階層に関係なく特定ツールを遮断

MCP 対応

公式Python MCP SDKで構築したサーバーのツール登録をラップします。スキーマとトランスポートを維持しながら、ツール境界で権限を適用します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"nickgeorgeseo-gatehouse": {
"command": "uvx",
"args": [
"mcp-gatehouse"
]
}
}
}
起動コマンドuvx mcp-gatehouse

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypimcp-gatehouse0.4.0

ツール

4

掲載時のツール一覧 · 1 週間前に更新

このツールにパラメーターはありません。

詳細

mcp-gatehouse

プロジェクトページとドキュメント: nickgeorgeai.com/open-source/mcp-gatehouse · PyPI

CI PyPI Python License: MIT mcp-gatehouse MCP server

Gatehouse MCP server

MCP サーバーの権限レベル、承認ゲート、監査ログ。 サーバーがゲートキーパーとなり、AI が読み取れるもの、書き込めるもの、アクセスを禁止するものを決められます。すべての操作が記録されます。

多くの MCP サーバーは、すべてのツールをモデルに無制限で渡し、実行内容を記録しません。デモなら問題ありません。しかし、エージェントに CRM、帳簿、注文システムへの書き込み権限を与える日には、そうはいきません。 mcp-gatehouse は、サーバー内部で強制される、欠けていたゲートです。プロキシも外部ポリシーサービスも不要で、公式の mcp SDK 以外に依存関係はありません。

pip install mcp-gatehouse

得られる機能

権限レベルすべてのツールを READ、WRITE、DESTRUCTIVE のいずれかとして宣言できます。また、各レベルに応じて、仕様に準拠した正確な ToolAnnotations(readOnlyHint / destructiveHint)も出力されます。ラッパー側で上書きして偽ることはできません。
承認ゲート選択したレベルのツールは、実行前に承認を必要とします。承認者には、ターミナルのプロンプト、Slack の通知、チケットなど、任意の呼び出し可能なものを指定できます。フェイルクローズ: 承認者が設定されていない場合、ゲート対象のツールは許可されず、実行を通過しません。
監査ログ追記専用の JSONL 形式で、許可、拒否、失敗、キャンセルの各呼び出しを1行ずつ記録します。UTC タイムスタンプと所要時間も含まれます。半年後に「AI は実際に何をしたのか?」を確認できます。
秘匿化指定した引数キー(デフォルトでは api_key、password、token、client_secret など)は、ログや承認者に渡る前にマスクされます。表記方法にかかわらず、apiKey、API-Key、api_key は同じキーとして扱われます。
拒否リスト権限レベルに関係なく、ツールを全面的にブロックできます。

クイックスタート

from mcp.server.mcpserver import MCPServer
from mcp_gatehouse import AccessTier, AuditLog, Gatehouse, Policy, terminal_approver

mcp = MCPServer("order-desk")
gatehouse = Gatehouse(
    mcp,
    policy=Policy(approver=terminal_approver),
    audit=AuditLog(path="~/order-desk/audit.jsonl"),
)

@gatehouse.tool(tier=AccessTier.READ)
def lookup_order(order_id: str) -> str:
    """Look up an order's status."""
    ...

@gatehouse.tool(tier=AccessTier.DESTRUCTIVE)
def cancel_order(order_id: str) -> str:
    """Cancel an order. Runs only if the approver says yes."""
    ...

mcp.run()

統合はこれだけです。SDK のドキュメントに記載されているとおりに MCPServer を構築し、ツールをゲートハウス経由で登録します。Annotated[..., Field(description=...)] によるパラメーターのドキュメントを含むスキーマ生成、トランスポートなど、その他すべては変更なしで動作します。ガードは関数のシグネチャを保持します。同期ツールは、通常の MCPServer をそのまま使う場合と同じく、ワーカースレッドで実行されます。

terminal_approver は標準入力ではなく、制御端末(/dev/tty)に確認を求めます。stdio 経由では、標準入力はプロトコル用のパイプそのものなので、単純な input() を使う承認処理ではパイプが破損してしまいます。承認処理には、ApprovalRequest を受け取り、許可する場合に True を返す任意の呼び出し可能オブジェクトを指定できます。同期処理でも非同期処理でも構いません。同期処理は専用のプールからワーカースレッドで実行されるため、人が承認に時間をかけても他の呼び出しが滞ることはなく、承認待ちが大量に発生しても同期ツールに必要なスレッドを占有しません。承認処理で例外が発生した場合(Slack の停止やチケット API のタイムアウトなど)、呼び出しは拒否され、失敗がログに記録されます。

誰も承認しないまま呼び出しが停止しないよう、承認に期限を設定します。

Policy(approver=terminal_approver, approval_timeout=120)

期限を過ぎると、呼び出しは拒否され、その旨がログに記録されます。承認処理には request.deadline(time.monotonic() の値)で期限が通知され、terminal_approver は期限が過ぎるとプロンプトを取り下げます。期限を無視する同期承認処理はバックグラウンドで実行を続けますが、その結果は破棄されます。タイムアウトを設定しない場合、ゲートは承認処理が完了するまで待機します。

デフォルトのポリシーでは、DESTRUCTIVE には承認が必要で、すべての操作が監査ログに記録されます。ゲートへの書き込みも、次の1行で行えます。

Policy(require_approval=frozenset({AccessTier.WRITE, AccessTier.DESTRUCTIVE}), ...)

デフォルト設定を失わずに、独自のシークレットを含むキーを追加できます。

from mcp_gatehouse import DEFAULT_REDACT
Policy(redact=DEFAULT_REDACT | {"card_pin"}, ...)

監査ログは次のようになります。

{"ts": "2026-07-16T14:02:11+00:00", "tool": "lookup_order", "tier": "read", "outcome": "ok", "arguments": {"order_id": "4417"}, "duration_ms": 0.42}
{"ts": "2026-07-16T14:02:38+00:00", "tool": "add_note", "tier": "write", "outcome": "ok", "arguments": {"order_id": "4417", "note": "call back", "api_key": "«redacted»"}, "duration_ms": 1.08}
{"ts": "2026-07-16T14:03:05+00:00", "tool": "cancel_order", "tier": "destructive", "outcome": "denied", "reason": "approver refused", "arguments": {"order_id": "4417"}}
{"ts": "2026-07-16T14:05:40+00:00", "tool": "cancel_order", "tier": "destructive", "outcome": "cancelled", "reason": "awaiting approval", "arguments": {"order_id": "4418"}}

outcome は ok、denied(理由は reason に記録されます)、error(ツールで例外が発生し、例外の型が reason に記録されます)、または cancelled のいずれかです。cancelled は、呼び出しが完了する前にクライアントが処理を中断したか、サーバーがシャットダウンしたことを示します。reason に理由が記録されます。awaiting approval は、ツールがまだ実行されていないことを意味します。tool running には duration_ms が記録され、ツールが処理の一部を完了している場合があります。同期ツールは処理の途中で停止できません。ワーカースレッドは最後まで実行され、通常どおり ok または error が記録されます。ゲートが書き込むのはログ行だけです。キャンセルの処理は、ゲートがない場合と同じように進みます。

デモを試す

このパッケージには、3つのティアすべてが組み込まれ、ターミナルでプロンプトを表示する承認処理を備えた、すぐに実行できる注文デスクサーバーが同梱されています。stdio に対応する任意の MCP クライアントに追加できます。Claude Desktop の場合は、claude_desktop_config.json に追加します。

{
  "mcpServers": {
    "gatehouse-demo": {
      "command": "uvx",
      "args": ["mcp-gatehouse", "--audit-log", "/tmp/gatehouse-audit.jsonl"]
    }
  }
}

または、pip install mcp-gatehouse の後に mcp-gatehouse-demo を実行してください。モデルに注文の一覧表示とキャンセルを依頼し、どちらの場合も判定が監査ログに記録されることを確認します。監査ログの出力先は --audit-log、次に $MCP_GATEHOUSE_AUDIT_LOG、それらが指定されていない場合は ./audit.jsonl です。作業ディレクトリに書き込めない場合(デスクトップクライアントはサーバーを / から起動することがよくあります)は、~/.mcp-gatehouse/audit.jsonl にフォールバックします。サーバーは選択したパスを標準エラー出力に表示します。

承認プロンプトには専用のターミナルが必要です。サーバーをバックグラウンドで起動するクライアントにはターミナルがなく、全画面のターミナル UI を使用するクライアントでは、そのターミナルがすでに使用中です。そのため、どちらの場合も cancel_order は拒否されます。これは設計どおり、ゲートが安全側に倒れているためです。対話形式で承認するには、全画面プログラムを実行していない通常のターミナルセッションから、サーバーを起動するクライアントを開始してください。プロンプトに2分以内に回答がない場合、拒否されます。examples/orders_server.py は、コピーして使えるテンプレートとして同じサーバーを収録したものです。

設計上の注意点

  • 強制適用はサーバー内部のツール境界で行います。 プロキシではツールの意味を把握できず、ポリシーサービスはデプロイするものがもう1つ増えることになります。従業員40人の工場にはプラットフォームチームはありません。必要なのは、いくつかの小さなクラスとJSONLファイルだけです。
  • フェイルクローズにします。 何も通知せず許可するセキュリティのデフォルト設定は、何もしないより悪いものです。これにはマスキングも含まれます。スクラバーで分解できない引数値(任意のオブジェクトやバイト列)は、そのまま渡さず不透明なプレースホルダーに置き換えます。また、例外のメッセージはログに記録しません。記録するのは例外の型だけです。エラーテキストには、たった今マスキングした値そのものが埋め込まれやすいためです。
  • 監査ログには、成功だけでなく拒否、エラー、キャンセルも記録します。 実行されなかった呼び出しも全体像の半分を占めます。また、途中で打ち切られた呼び出しでも、何らかの処理が行われている可能性があります。
  • ブロック中に端末で承認を求める方式とstdioトランスポートは併用できません。 stdout/stdinはプロトコルのパイプです。terminal_approverが/dev/ttyでプロンプトを表示するのはそのためです。端末がない場合や、全画面プログラムが端末をrawモードで使用している場合は拒否します。 実運用環境では、Slack、チケット、キューなどを通じて帯域外で承認してください。
  • これは認証でも、トランスポートの暗号化でも、サンドボックスでもありません。 サーバーの内側にあるゲートであり、サーバーを取り囲む境界ではありません。SECURITY.mdをご覧ください。

互換性

公式のmcp Python SDK v2.x(mcp>=2,<3)とPython 3.10~3.14を対象としています。型情報 (py.typed)を同梱しています。リリースノート:CHANGELOG.md。

mcp-gatehouseSDKサーバークラス
0.4.xmcp>=2,<3MCPServer
0.3.xmcp>=2,<3MCPServer
0.2.xmcp>=2,<3MCPServer
0.1.xmcp>=1.27,<2FastMCP

公開API(Gatehouse、Policy、AuditLog、AccessTier)は、この系列を通じて変更されていません。これは当初のお約束どおりです。v1サーバーの移行で必要なのは、インポートを2か所変更することだけです。FastMCPがMCPServerになり、mcp.server.mcpserverに移動しました。SDKの 移行ガイドをご覧ください。

SDK v1を使い続ける場合、対応は不要です。0.1.xはmcp<2に固定されているため、pipは引き続きそれを解決します。この系列への機能追加は終了していますが、セキュリティ修正は引き続き提供されます。

開発者

Nick George — 私は中堅のリバース・ロジスティクス・テクノロジー企業で、本番環境のMCPサーバーを設計・運用し、nickgeorgeai.comでは企業向けの開発も行っています。このライブラリは、そうした開発から権限管理と監査の規律を取り出したものです。開発の経緯と仕組みを平易な言葉で説明した内容は、プロジェクトページをご覧ください。

MCPとは何か疑問に思っている経営者や運用担当者の方は、まず平易な言葉で書かれたガイドをご覧ください:MCPサーバーとは?

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。