mcpField
S
sweep-mcp

sweep-mcp

ローカル
les-k.github.io開発ツール04 週間前に更新

sweep-mcp について

sweep-mcpは、指定したルート内で再生成可能なディレクトリを探して回収する開発者向けMCPサーバーです。ルート許可リスト、スキャンで発行したID、削除直前の再確認、既定のドライランで削除を制限します。

主な機能

  1. 01回収対象のディレクトリ種別を表示
  2. 02スキャン結果にランダムIDとサイズを付与
  3. 03スキャンIDでディレクトリを回収
  4. 04既定はドライラン、削除には明示確認
  5. 05ルート許可リストと削除前の再検証

活用シーン

  1. 01プロジェクト内のnode_modulesを整理
  2. 02不要になった.venvやtargetを回収
  3. 03指定した作業ルート内にAgentの整理範囲を限定

MCP 対応

list_targets、scan、reclaimの3つのMCPツールを提供します。前者2つは読み取り専用で、reclaimはスキャンで得たIDを使う破壊的ツールとして注釈されています。

設定

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

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

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

パッケージ
pypisweep-mcp0.1.1

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

sweep-mcp

CI Python License: MIT

簡単に言うと: 開発者のマシンにたまった不要なフォルダーを AI が片付けられるようにしつつ、それ以外には一切触れられないようにします。指定したフォルダーの中だけで動作し、自ら見つけたものだけを削除し、削除する直前にも再確認します。そのため、直前に別のものへすり替えられることはありません。

ディレクトリを削除する MCP サーバーです。そして、その機能を言語モデルに渡しても無謀なことにならないようにするための安全策を備えています。

Model Context Protocol を通じて sweep を公開するため、エージェントは node_modules、.venv、target、__pycache__ などを見つけて整理できます。重要なのは削除そのものではありません。削除を許可する前に満たすべき条件のすべてです。

2026 年に発表された調査では、スキャンした 1,808 件の MCP サーバーの 66% にセキュリティ上の問題が見つかり、単一の四半期に MCP 実装に対して 30 件以上の CVE が登録されました。このリポジトリは、逆の考え方で書かれたサーバーです。まず拒否の仕組みを作り、機能はその後に追加しています。


脅威モデル

ディレクトリを削除できる MCP サーバーは、プロセスがアクセスできるあらゆる場所に向けられた、弾の装填された銃のようなものです。問題になりうる点は 5 つあり、それぞれに対処策と、その対策が機能することを確認するテストがあります。

リスク対処策テスト
エージェントが / や C:\ をスキャンして、マシン上のものを削除するサーバー起動時に固定されるルートの許可リストを使用します。エージェントが設定、拡張したり、その範囲を越えて読み取ったりすることはできません。ルートが設定されていない場合 → すべてのリクエストを拒否しますtest_empty_allowlist_denies_every_path
../../ やシンボリックリンクを使って許可リストの範囲外に抜けるすべてのパスで、包含チェックの前に resolve() を実行するため、実際の参照先に基づいて判定されますtest_dotdot_traversal_is_denied、test_symlink_pointing_outside_root_is_denied
エージェントがスキャンしていないパスの削除を要求するreclaim が受け付けるのは ID であり、パスではありません。 API のどこにも、パスを指定して削除する経路はありませんtest_there_is_no_way_to_delete_by_path
スキャン後、削除するまでの間にディレクトリが変わる削除時に、検索結果のそれぞれを実際のファイルシステムに対して再確認します。引き続き許可範囲内にあること、ディレクトリであること、リンクではないこと、マーカーファイルが存在することを確認しますtest_revalidate_refuses_a_directory_swapped_for_a_symlink
誤って破壊してしまうデフォルトではドライランです。 削除には confirm="delete" との完全一致が必要です。それ以外はすべて「いいえ」として扱われますtest_a_wrong_confirmation_string_stays_a_dry_run

同じ理由から、さらに小さな対策が 2 つあります。

  • チケット ID は連番ではなくランダムです。 1 ではなく f-3a91c02b77de を使います。連番 ID では、エージェントが何かを削除できるまで順番に試すよう促してしまいます。
  • ツールの説明は文字列リテラルです。 ディスクから読み取った情報を使って組み立てることはありません。そのため、ignore-previous-instructions という名前のディレクトリも、文ではなくデータとしてモデルに渡されます(test_tool_descriptions_are_static)。

防げないこと

上記の制御が有効なのは、その対象となる範囲に限られます。それ以上の効果はありません。

  • ルートの設定ミス。 --root / を指定して起動すれば、ファイルシステム全体を問題なく処理します。許可リストの安全性は、そこに何を入れるかにかかっており、この仕組みがその選択を再検討することはありません。
  • 悪意のあるクライアント。 ガードが制限するのは、削除できる対象であり、要求者ではありません。正当にスキャンし、正当に確認するクライアントには、要求したとおりの処理が行われます。
  • 説得されてしまったエージェント。 静的なツールの説明によって、ファイルシステムの内容がモデルへの指示に入り込むことはありません。しかし、エージェントが独自のよからぬ理由で、実際に見つけた本物の node_modules を削除しようと決めた場合に、それを止める方法はありません。
  • 最後の数ミリ秒。 revalidate() はチェックと削除の間の時間を短くしますが、その時間をなくすわけではありません。これを適切になくすには、処理中にディレクトリのファイル記述子を保持する必要がありますが、shutil.rmtree はそれを移植性のある形では提供していません。これは現実に存在する競合状態であり、規模は小さくなりますが、なくなるわけではありません。
  • Python 3.11 の Windows ジャンクション。 os.path.isjunction は 3.12 で追加されました。それより前のバージョンでは、ジャンクションの検出はシンボリックリンクのみに制限されます。これは sweep 自体が採用しているのと同じ妥協点であり、ここでは隠さず明記しています。
  • 権限。 これはサンドボックスではありません。起動したユーザーの権限で実行されます。

スキャナーの結果

2026 年 8 月 18 日に agent-audit 0.19.2 を使って実行しました。

静的スキャン — 検出 0 件、リスクスコア 0.0(低)、7 ファイル。

最初の実行では、低リスクの検出が 1 件ありました。AGENT-110、ソースマップの成果物が配布対象から除外されていないというものです。このパッケージは JavaScript を含まないため、漏えいするソースマップはありませんでしたが、念のため除外設定を pyproject.toml に追加しました。コストはかからず、サプライチェーンのチェックリストと議論するのは時間の無駄だからです。

ツールの検査 — ツールに関する検出 0 件。 3 つの定義のいずれにも、ツールポイズニング、クロスオリジン、ラグプルのパターンは検出されませんでした。

割り当てられたリスク評価は、示唆に富む誤りなので、再掲する価値があります。

ツール評価推定された権限
list_targetsMEDIUMSHELL_EXEC、FILE_READ
scanHIGHFILE_DELETE、SHELL_EXEC、FILE_READ
reclaimHIGHFILE_DELETE、SHELL_EXEC、FILE_READ

scan は何も削除できません。読み取り専用であり、read_only_hint=True として宣言され、その状態を維持することを検証するテストもあります。それにもかかわらず FILE_DELETE 権限を持つとして HIGH と評価されたのは、スキャナーが説明文に含まれるキーワードを照合するためです。このサーバーの scan の説明には、次の文があります。

「読み取り専用:これは何も削除しません。」

deletes という単語は FILE_DELETE のキーワードリストに含まれています。SHELL_EXEC は「それを再生成するコマンド」という表現にある command という単語に由来します。このサーバーはシェルコマンドを一切実行しません。

スコアが上がるように説明を書き換えることはできます。しかし、そうしていないのは、その説明がツールを呼び出すかどうかを判断する言語モデルに向けたものであり、「これは何も削除しません」がその中で最も役に立つ一文だからです。キーワードスキャナーは煙探知器であって、裁判官ではありません。問題のないスキャン結果には価値があり、公開する価値もあります。しかし、文章の文字列照合から導かれた評価は、どちらの方向においても動作を示す証拠にはなりません。

2 つのスキャナーを試し、1 つは実行できませんでした。Invariant Labs の mcp-scan は Snyk による買収後に snyk-agent-scan へ改名され、現在は SNYK_TOKEN が必要です。Cisco の mcp-scanner は PyPI に公開されていません。また、agent-audit 自身の stdio トランスポートは、Windows ではこのサーバーに接続するとタイムアウトします。一方、同じバイナリに対して手動でハンドシェイクを行うと数ミリ秒で応答します。そのため、分析器には実際の tools/list 出力を直接渡しました。トランスポートはバイパスしましたが、分析はバイパスしていません。

インストール

pip install sweep-mcp

ソースチェックアウトからインストールする場合:pip install -e .

設定

サーバーには、1つ以上の --root ディレクトリを指定します。デフォルトはありません。 ルートを指定せずに起動すると、すべてをスキャンするのではなく、エラーになります。

{
  "mcpServers": {
    "sweep": {
      "command": "sweep-mcp",
      "args": ["--root", "/home/you/code", "--root", "/home/you/work"]
    }
  }
}

ツール

ツール破壊的内容
list_targetsいいえ再利用の対象として認識しているディレクトリの種類と、それぞれを再生成するコマンドを表示します
scanいいえルート内のパスを対象に、再利用可能なディレクトリを見つけます。ID、サイズ、再生成コマンドを返します
reclaimはいIDで指定された検出項目を削除します。confirm="delete" を指定しない限り、ドライランです

3つのツールすべてにMCPの ToolAnnotations が付いているため、破壊的なツールの実行前に確認プロンプトを表示するクライアントに必要な情報が揃っています。reclaim は destructive_hint=True を宣言し、ほかの2つは read_only_hint=True を宣言します。これもテストスイートで検証しています。ヒントが気付かれないまま機能しなくなるくらいなら、ないほうがましです。

セッション

scan(path="/home/you/code")
  → 12 finds, 3.4 GB
    f-3a91c02b77de  /home/you/code/api/node_modules   1.9 GB  npm install
    f-8e0244fd1b6c  /home/you/code/ml/.venv           842 MB  python -m venv .venv

reclaim(ids=["f-3a91c02b77de"])
  → dry_run: true
    would_delete: 1 path, 1.9 GB
    note: Nothing was deleted. Call again with confirm='delete'.

reclaim(ids=["f-3a91c02b77de"], confirm="delete")
  → deleted: 1 path, reclaimed 1.9 GB

テスト

テストは38件です。Windowsでは34件、Linuxでは38件すべてを実行します。

ローカルでスキップされる4件ではシンボリックリンクの作成が必要ですが、Windowsでは開発者モードが有効になっていないと作成できません。そのうち1件は、スキャンと削除の間に対象をすり替える攻撃を扱うもので、ここで最も重要なテストです。これをひそかにスキップするとテストスイートが飾りになってしまうため、CIはLinuxで実行し、これらのテストがスキップされた場合はビルドを失敗させます。

pytest -q --cov=sweep_mcp

カバレッジは**83%**です。未カバーの大部分は main() とargparseの設定です。テストスイートでは代わりに build_server を通して実行しています。トランスポートはモックする価値が最も低く、被害の原因になる可能性も最も低い部分だからです。

このテストスイートでは、ファイルシステムを一切モックしていません。Path をモックすれば、サーバーが依然として間違ったディレクトリを削除する状態でも、ここにあるテストはすべて通ってしまいます。

構成

src/sweep_mcp/
  guard.py    212 lines - the allowlist, the tickets, the re-check. Imports no MCP.
  server.py   280 lines - three tools. Translation only.
tests/
  test_guard.py    23 tests - one per rule, each named for the attack it stands in for
  test_server.py   15 tests - driven through call_tool, the way a client would

guard.py は意図的にMCPについて何も知りません。データを失う可能性がある判断はすべて、クライアントもトランスポートもエージェントも介さずにテストできます。ルールが server.py で適用されているように見えるなら、それはバグです。テストで確認できるように、1つ下のレイヤーに配置する必要があります。

ライセンス

MIT。

作者

Leslie Kadenge が作成しました。MCPサーバーのセキュリティレビューを独立して行っており、本番環境で稼働する13のサーバーを対象にした公開調査は、les-k.github.io/field-notes.html でご覧いただけます。

コメント

MCP は初めてですか?

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

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