SM

shalimov04/mcp-airlock

Developer tools

このページは AI により自動翻訳されています。技術的な詳細は原文をご確認ください。 原文を見る

15 stars 7 forks 品質 74 トレンド 41MIT

Stateless governance proxy for MCP (2026-07-28): policy, dry-run, human confirmation, audit, tracing

概要

mcp-airlock is a proxy you put between an AI agent and an MCP server when the server can do things you don't want an agent doing on its own. It speaks the 2026-07-28 revision of the protocol (the stateless one: no session, no initialize, one POST per request) and adds the parts the protocol leaves to you: who is allowed to call what, dry runs by default, a human in the loop for dangerous calls, an audit trail and tracing. It is deliberately small. There is no UI, no policy language beyond flat YAML, no MCP SDK of its own. The whole proxy is one Starlette app plus a few helper modules. The agent sends a normal tools/call to the proxy instead of the server. The proxy: 1. Works out who is calling. That comes from a JWT (Authorization: Bearer) or, if you run it behind a gateway that already did the authentication, from an X-Airlock-Principal header. It is never taken from the request body. No principal, no call.

README

以下は原文 README の抜粋です。原文を見る。

mcp-airlock

Краткий обзор по-русски

mcp-airlock is a proxy you put between an AI agent and an MCP server when the server can do things you don’t want an agent doing on its own. It speaks the 2026-07-28 revision of the protocol (the stateless one: no session, no initialize, one POST per request) and adds the parts the protocol leaves to you: who is allowed to call what, dry runs by default, a human in the loop for dangerous calls, an audit trail and tracing.

It is deliberately small. There is no UI, no policy language beyond flat YAML, no MCP SDK of its own. The whole proxy is one Starlette app plus a few helper modules.

How a call goes through

The agent sends a normal tools/call to the proxy instead of the server. The proxy:

  1. Works out who is calling. That comes from a JWT (Authorization: Bearer) or, if you run it behind a gateway that already did the authentication, from an X-Airlock-Principal header. It is never taken from the request body. No principal, no call. A name that is blank or has whitespace around it is no principal either, from either source: trimmed, alice would be alice.
  2. Looks the tool up in the policy. Tools that are not listed are refused. Listed tools have a risk tier per environment, so the same delete_service can be free in dev and gated in prod.
  3. Depending on the tier:
    • L0 (read) goes straight through.
    • L1 (suggest) always goes through with dry_run: true, whatever the agent asked for.
    • L2 (confirm) goes through with dry_run: true first, and the result comes back to the agent as input_required with a description of what would happen and a signed requestState. When a person says yes, the agent repeats the call with that state and the proxy executes it for real, once. Repeating it again is refused.
    • L3 (auto) goes through as sent.
  4. Checks the blast radius: how many objects one call touches (the length of a list argument you name in the policy) and how many a principal has touched in the last hour or day.
  5. Forwards the call, cuts the response down to the output cap if it is too big, and marks anything in it that smells like a prompt injection. Marking only; it does not change what the agent gets to see.
  6. Writes two audit records, one before the upstream call and one after, whatever happened. The JSONL file gets each one before the proxy goes on; the Postgres table, when there is one, is written from a queue a moment later.

Refusals come back as tool results with isError: true, not as protocol errors, so the model sees why and can do something else. Every tools/call result, a pending one included,

GitHub で README 全文を見る

インストール

uvx mcp-airlock --help
MCP 初心者?mcpskill.org のガイドから始めましょう →