AIエージェントにリコン用ツール群を渡す:30以上のセキュリティツールをMCPサーバーに接続する

Dev.to / 2026/5/4

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical UsageModels & Research

要点

  • この記事は、セキュリティ・リコンでAIエージェントを使う際の主なボトルネックは、個々のツールではなく「つなぎ(glue)」作業だと述べています。具体的には、ツールの統合、リトライ/タイムアウト、認証、レート制限などです。
  • そこで、リコンのツール群をMCP(Model Context Protocol)のツールとして公開し、MCP対応クライアント(Claude Desktop、Cursor、LangGraphエージェント等)が同じツールセットを単一のサーバー側契約で操作できるようにすることを提案しています。
  • リコンの性質として、列挙→解決→スキャン→サービスの指紋化→狙い撃ちの脆弱性チェック→新資産へピボット→ループ、のように反復的かつ分岐するワークフローが、LLMによる「いつ・何を実行するか」のオーケストレーションと相性が良い点を強調しています。
  • 実装例として、HailBytes ASMではMCPサーバーがREST API相当の機能をラップし、発見(ディスカバリー)、脆弱性スキャン、インベントリ管理、レポート出力を扱えると説明しています。またログ解析ではなく、安定したJSONスキーマを返すとしています。
  • 全体として、このアプローチはMCP層でツールのインターフェースとデータ契約を標準化することで、チームやフレームワークごとの作り直しを減らすことを狙っています。

ジュニアのペネトレーションテスターが月曜の午前に、同じ
6つのコマンドを新しいEC2ボックスに打ち込むのを見たことがあるなら、リコンのセットアップ税がどれほど身近なものかを見てきたはずです。
amass enum -passive -d $TARGETsubfinder -d $TARGET -silent、パイプでhttpxへ、さらにパイプでnaabuへ、nucleiに生き残ったホストを投入し、JSONをどこかにダンプして、
次の四半期にはスコープが変わるのでまた繰り返す——。

仕事自体は難しくありません。難しいのはその「つなぎ」です。私が話を聞いたどのチームも、このつなぎを少なくとも2回は作り直していて、しかも毎回、別の言語で作り直しています。

この記事は、別の形の問題についてです。つまり、あなた自身がつなぎを書き続けるのをやめて、そのリコン用ツールボックスをMCP toolsとして公開し、AIエージェントに呼び出させるとどうなるのか?

Why MCP, specifically

エージェントによる「ツール利用」はここ数年、専用の
関数呼び出しアダプタを通じて行われてきました。これらのアダプタの問題は、どの
エージェントのフレームワークも独自のJSON形を要求し、すべてのツールが独自の認証を必要とし、そして
あらゆるチームが独自のリトライ/タイムアウト/レート制限のミドルウェアを書いていることです。

MCP (Model Context Protocol)は、それらを
サーバー側の1つの契約にまとめてしまいます。ツールがMCPツールになれば、
あらゆる準拠クライアント——Claude Desktop、Cursor、あなた自身のLangGraphエージェントなど——
がそれらを駆動できます。

リコンにおける価値は非対称です。リコンは、まれなセキュリティの
ワークフローの一つであり、反復かつ分岐するからです。

サブドメイン列挙 → 解決 → ライブホストのポートスキャン → サービスのフィンガープリント → 標的化した脆弱性チェックの実行 → 新しいアセットへピボット → ループ

このループは、LLMがオーケストレーションするのが得意なまさにその形です。
ツールが構造化データを返し、エージェントがインベントリを
状態として保持できるなら、LLMはきっちり回せます。LLMにnmapをそのまま走らせたいわけではありません。
LLMにいつ
nmapを実行するのか、そして何に対して実行するのかを判断させたいのです。

What we wrapped

HailBytes ASM(完全開示:これは私たちの製品で、ペンテスト企業やMSSPのために特化して
作られています)では、MCPサーバーがREST APIと同じ表面を公開します:

  • Discovery: start_subdomain_scan, start_port_scan, start_dns_scan
  • Vulnerability: start_nuclei_scan, start_template_scan
  • Inventory: list_assets, get_asset_history, diff_scans
  • Reporting: export_findings, get_scan_summary

それぞれのツールは、ログのスクレイプではなく、安定したスキーマでJSONを返します。そのためエージェントは、
モデルがstderrを解析する必要なしに、マルチステップのワークフローを計画できます。

A working loop

実際のセッションは次のようになります(私たちの社内評価実行の一つから要約):

User: "example.com の外部攻撃対象領域をマップし、露出している staging 環境に見えるものを何でも検知して。"

Agent → start_subdomain_scan(domain="example.com")
Agent → list_assets(scan_id=...)  // 312ホスト
Agent → start_port_scan(targets=[...], top_ports=1000)
Agent → start_nuclei_scan(targets=live_hosts, severity=["medium","high"])
Agent → list_assets(filter="hostname matches /staging|stg|dev|qa/")
Agent → get_asset_history(asset_id=...)  // 出現は6日前
Agent → "stagingっぽいパターンに一致するホストが4つ見つかりました。そのうち
        (stg-admin.example.com) は6日前に出現しており、既知のCVEを持つ Jenkins
        インスタンスを公開しています…"

面白いのは、エージェントがやらないことです。シェルを起動しません。
AWSの認証情報を管理しません。レート制限を気にしません。
スキャンの差分検出を再実装もしません。MCPツールがそれらをすべて面倒見ます。エージェントの役割は、
本当に難しい部分——次のアクションを選ぶこと——だけです。

What broke (and what we changed)

この取り組みを顧客サイトで実行してみて見えた、率直なメモをいくつか:

  1. ページネーションがエージェントを殺す。 最初の試作では、すべてのアセットを 単一のレスポンスで返していました。実案件ではサブドメインが3万件超になることがあり、その場合、エージェントのコンテキストが分析ステップに到達する前に埋まってしまいました。そこでカーソルによるページネーションを追加し、summarize_assetsツールを用意して集計結果を返すようにしました。
  2. 暗黙の状態は敵対的。 エージェントは「直近のスキャン」を覚えるのが苦手です。
    そのため、scan_idを受け取るすべてのツールは、たとえ実行中のスキャンが常に1つだけであっても、今ではそれを明示的に要求するようにしました。
  3. 長時間実行のスキャンにはステータスプロトコルが必要。 リコンスキャンは数分から数時間かかります。そこでwait_for_scan(scan_id, timeout)を追加し、エージェントがきついループでポーリングする代わりに、丁寧に待機できるようにしました。

Where this fits

もしすでに社内でリコンを回しているなら、このパターンを試すために何かを買う必要はありません。
自分のスクリプトをMCPサーバーでラップすれば、
価値の70%を得られます。難しいのは、プロダクション規模で現れてくる部分です。つまり、スキャンの差分検出、実行をまたいだアセットの重複排除、マルチテナントの隔離、スケジュールされた実行頻度、コンプライアンスのための監査証跡——。
私たちは、この部分に過去1年を費やしてきました。

エンドツーエンドで見てみたいなら、プラットフォームは
hailbytes.com/asmです。AWSまたは
Azure Marketplaceからデプロイでき、あなたのアカウント上で動作し、そしてMCPエンドポイントを
そのまま箱から出した状態で公開します。

いずれにせよ、私はMCPネイティブなセキュリティツールが
18か月以内にデフォルトになると思います。「エージェントがSplunk
ダッシュボードを読める」から「エージェントがリコンの一連の実行を駆動できる」までのギャップは急速に縮まっており、
自分たちのツールボックスを早期に組み上げたチームは、確かな優位性を持つことになるでしょう。