Kloakt について
KloaktはAIエージェント向けのRust製ヘッドレスブラウザー兼コマンドラインツールです。JavaScriptの実行、ページ内容の抽出、永続セッションに対応し、MCPサーバーは抽出、クロール、ページ構造、スクリーンショット、セッション操作の12ツールを公開します。
主な機能
- 01クリーンなMarkdownと構造化データの抽出
- 02JavaScript実行とページ取得
- 03並列スクレイピング、検索、クロール
- 04アクセシビリティ構造と操作要素のスナップショット
- 05永続セッションとページ操作
- 06MCPツールとCDPサーバー
活用シーン
- 01JavaScriptを多用するページから主要コンテンツを抽出
- 02複数URLのデータを並行して収集
- 03ページ操作の前にクリック可能な要素を確認
- 04ブラウザー操作をまたいでCookieとページ状態を保持
MCP 対応
MCPサーバーを内蔵し、抽出、取得、スクレイピング、検索、クロール、スナップショット、スクリーンショット、永続セッション管理の12ツールを公開します。PuppeteerやPlaywrightのクライアント向けにCDPサーバーも提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | はい | コンテンツを抽出する URL |
| delay | integer | いいえ | 読み込み後に非同期コンテンツを待機する追加時間(ミリ秒、デフォルト:0) |
| format | enum | いいえ | 出力形式(デフォルト:markdown)markdown | text | links |
| stealth | boolean | いいえ | 検出回避モードを有効にする |
| selector | string | いいえ | 抽出前に待機する CSS セレクター |
| main_only | boolean | いいえ | ナビゲーション、ヘッダー、フッター、サイドバーを削除します(デフォルト:true) |
| max_chars | integer | いいえ | コンテンツをN文字に切り詰めます(0 = 無制限、デフォルト:0) |
| wait_until | enum | いいえ | ページの読み込み完了と見なすタイミング(デフォルト:load)load | domcontentloaded | networkidle0 |
詳細
Kloakt
AI エージェント向けの、クローキングされたヘッドレスブラウザー。
軽量で検出されにくく、Rust で構築されています。Obscuraをベースにしています。
Kloakt は、AI エージェント向けに構築されたヘッドレスブラウザーです。V8 を介して JavaScript を実行し、あらゆるページ(SPA を含む)からクリーンな Markdown を抽出して、Claude Code などの AI システム向けに MCP 経由でツールを公開します。
単発の抽出に加えて、永続的なステートフルセッション(クリック、入力、移動が可能で、Cookie とページ/JS の状態を呼び出し間で保持)を操作したり、エージェントの視覚機能の代替としてアクセシビリティ/構造スナップショットを出力したり、システム Chrome 経由で実際のスクリーンショットを撮影したりできます。MCP ツールは全部で 12 種類です。
Kloakt を選ぶ理由
| 指標 | Kloakt | ヘッドレス Chrome |
|---|---|---|
| メモリ | 30 MB | 200+ MB |
| バイナリーサイズ | 70 MB | 300+ MB |
| 検出回避 | 組み込み | なし |
| ページ読み込み | 85 ms | ~500 ms |
| 起動 | 即時 | ~2s |
| SPA の抽出 | 対応 | 手動 |
インストール
ビルド済みバイナリー(推奨)
ワンライナーでインストールできます(Linux と macOS)。最新の GitHub Release からお使いの OS/アーキテクチャに合ったバイナリーをダウンロードし、~/.local/bin(root で実行した場合は /usr/local/bin)にインストールします。
curl -fsSL https://raw.githubusercontent.com/KultMember6Banger/kloakt/main/install.sh | sh
バージョンを指定したり、インストール先ディレクトリを変更したりできます。
KLOAKT_VERSION=v0.1.2 INSTALL_DIR=/usr/local/bin \
sh -c "$(curl -fsSL https://raw.githubusercontent.com/KultMember6Banger/kloakt/main/install.sh)"
Windows: Releases ページから kloakt-x86_64-windows.zip をダウンロードし、kloakt.exe を PATH 上に展開してください。
Homebrew(macOS)
brew install KultMember6Banger/kloakt/kloakt
# or, from a local checkout:
brew install --formula ./Formula/kloakt.rb
(専用の tap ができるまでは、brew tap KultMember6Banger/kloakt https://github.com/KultMember6Banger/kloakt を実行してから、brew install kloakt を実行してください。)
cargo install
crates.io から CLI をビルドします(Rust ツールチェーンが必要です。初回ビルドでは V8 がコンパイルされ、約 5 分かかります)。
cargo install obscura-cli
これにより kloakt バイナリーがインストールされます。ステルスモードを有効にしてビルドするには、--features stealth を追加してください。
ソースからビルド
git clone https://github.com/KultMember6Banger/kloakt.git
cd kloakt
cargo build --release
# With stealth mode (anti-detection + tracker blocking)
cargo build --release --features stealth
Rust 1.75 以降が必要です(rustup.rs)。初回ビルドには約 5 分かかります(V8 はソースからコンパイルされ、以降はキャッシュされます)。
クイックスタート
コンテンツを抽出する(AI エージェントでの使用)
# Clean markdown from any page
kloakt extract https://example.com --main
# Structured JSON with metadata
kloakt extract https://example.com --main --json
# Cap output for agent context windows
kloakt extract https://en.wikipedia.org/wiki/Rust --main --json --max-chars 3000
# Wait for SPA hydration
kloakt extract https://example.com --delay 2000 --json
ページを取得する
# Get the page title
kloakt fetch https://example.com --eval "document.title"
# Extract all links
kloakt fetch https://example.com --dump links
# Render JavaScript and dump markdown
kloakt fetch https://news.ycombinator.com --dump markdown
# Wait for dynamic content
kloakt fetch https://example.com --wait-until networkidle0
CDP サーバーを起動する
kloakt serve --port 9222
# With stealth mode
kloakt serve --port 9222 --stealth
並列でスクレイピングする
kloakt scrape url1 url2 url3 ... \
--concurrency 25 \
--eval "document.querySelector('h1').textContent" \
--format json
ページ構造のスナップショットを取得する(エージェントの視覚機能)
# Indexed accessibility/structure tree — tags, text, roles, what's clickable, visibility
kloakt snapshot https://example.com
# Only the actionable elements (links, buttons, inputs), with id/name/label for targeting
kloakt snapshot https://example.com --interactive
kloakt にはラスタライザーがないため、これはピクセルではなく構造に基づいて作業するエージェント向けに、「ページに何があり、何を操作できるか」を軽量に把握するための表示です。
スクリーンショット(システム Chrome 経由)
# Real PNG — delegates to a locally-installed Chrome/Chromium/Edge
kloakt screenshot https://example.com --output shot.png --width 1280 --height 800
永続セッション
実行中の kloakt serve デーモンをバックエンドとして、Cookie とページ/JS の状態を個別の呼び出し間で保持する名前付きセッションを操作できます。
kloakt serve --port 9222 & # start the daemon once
kloakt session open shop --url https://example.com
kloakt session snapshot shop --interactive # see the page structure
kloakt session type shop 'input[name=q]' 'hello' # fill a field
kloakt session click shop 'button[type=submit]' # click an element
kloakt session text shop # read the body text
kloakt session eval shop 'document.title' # run JS, get the value back
kloakt session close shop # tear down (drops cookies + page)
スマート抽出
extract コマンドは、AI エージェント向けに最適化された複数フェーズのパイプラインを使用します。
- ノイズ除去 — Cookie バナー、広告、ポップアップ、ナビゲーション、ソーシャルウィジェットを取り除きます
- コンテンツのスコアリング — テキスト密度アルゴリズム(Readability に類似)で主要なコンテンツブロックを検出します
- Markdown への変換 — DOM を絶対 URL の解決に対応した Markdown に変換します
- SPA フォールバック — JavaScript のレンダリングに失敗した場合、メタタグ、Open Graph、JSON-LD、noscript のコンテンツから抽出します
静的 HTML、サーバーサイドレンダリングされたページ、純粋なクライアントサイド SPA(React、Vue など)で動作します。
Python API
from kloakt import (
extract, extract_fields, fetch, scrape, search, crawl,
snapshot, screenshot, session_open, session_close,
)
# Extract clean markdown
page = extract("https://example.com")
print(page.title, page.content, page.meta)
# Cap output length
page = extract("https://example.com", max_chars=3000)
# Wait for SPA content
page = extract("https://example.com", delay=2000)
# Structured field extraction via CSS selectors
data = extract_fields("https://news.ycombinator.com", {
"title": "title",
"stories": ".titleline > a[]", # [] => list of all matches
"links": ".titleline > a[]@href" # @href => an attribute
})
print(data["data"]["stories"])
# Raw fetch
html = fetch("https://example.com", dump="html")
title = fetch("https://example.com", eval_js="document.title")
# Parallel scrape
results = scrape(["https://a.com", "https://b.com"], concurrency=5)
# Discover links, or breadth-first crawl a small section of a site
links = search("https://news.ycombinator.com", same_domain=True)
pages = crawl("https://example.com", max_pages=5, max_depth=1)
# Structure snapshot (agent vision) and a real screenshot via system Chrome
snap = snapshot("https://example.com", interactive=True)
screenshot("https://example.com", output="shot.png")
# Persistent session — auto-starts a daemon if one isn't running; cookies + page
# state persist across calls. (session_nav / _click / _type / _eval / _text / _snapshot)
session_open("shop", url="https://example.com")
# ... drive the page across calls ...
session_close("shop")
MCP サーバー(Claude Code)
Kloakt には、Claude Code のツールとして使用できる MCP サーバーが含まれています。
{
"mcpServers": {
"kloakt": {
"command": "python3",
"args": ["/path/to/kloakt/mcp_server.py"]
}
}
}
12 個のネイティブツールを公開します。
| ツール | 機能 |
|---|---|
kloakt_extract | Markdown を整形するか、schema で構造化フィールドを取得します |
kloakt_fetch | 低レベルの取得(html/text/links/markdown、または JS の評価) |
kloakt_scrape | 複数の URL を並列処理します |
kloakt_search | ページ上の外部リンクを検出します |
kloakt_crawl | 予算と深さを制限した幅優先クロール |
kloakt_snapshot | アクセシビリティ/構造ツリー(エージェントの視覚機能) |
kloakt_screenshot | システムの Chrome を使用して実際の PNG を取得します |
kloakt_session_open | 名前付きの永続セッションを開きます |
kloakt_session_act | セッション内で navigate / click / type / eval を実行します |
kloakt_session_read | セッションのページをテキストまたはスナップショットとして読み取ります |
kloakt_session_list | 開いているセッションの一覧を表示します |
kloakt_session_close | セッションを閉じます(Cookie とページを破棄します) |
Puppeteer / Playwright
Puppeteer
CDP サーバーは、Chrome と同様に、セッションごとのトークンを WebSocket パスに埋め込みます。browserURL 経由で接続すると、クライアントは /json/version からトークンを自動的に検出するため、ws://.../devtools/browser パスをハードコードしないでください。
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserURL: 'http://127.0.0.1:9222', // discovers the tokenized ws endpoint
});
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com');
const stories = await page.evaluate(() =>
Array.from(document.querySelectorAll('.titleline > a'))
.map(a => ({ title: a.textContent, url: a.href }))
);
await browser.disconnect();
Playwright
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP({
endpointURL: 'http://127.0.0.1:9222', // discovers the tokenized ws endpoint
});
const page = await browser.newContext().then(ctx => ctx.newPage());
await page.goto('https://en.wikipedia.org/wiki/Web_scraping');
console.log(await page.title());
await browser.close();
ステルスモード
--features stealth で有効にします。
- セッションごとのフィンガープリントのランダム化(GPU、画面、キャンバス、音声、バッテリー)
- リアルな
navigator.userAgentData(Chrome 145、高エントロピー値) - ディスパッチされたイベントの
event.isTrusted = true - ネイティブ関数のマスキング(
Function.prototype.toString()→[native code]) navigator.webdriver = undefined- リアルな
Accept-Languageおよび Client Hints(Sec-CH-UA)リクエストヘッダー - セッションごとにランダム化される
navigator.languages - Chrome 145 の Linux/Windows/macOS プロファイル間で TLS フィンガープリント(JA3)をローテーション
- 3,520 個のトラッカードメインをブロック
CLI リファレンス
kloakt extract <URL>
| フラグ | デフォルト | 説明 |
|---|---|---|
--format | markdown | 出力形式:markdown、text、links |
--main | off | ナビゲーション、ヘッダー、フッター、サイドバーを除去します |
--json | off | 構造化 JSON:title、URL、content、meta |
--max-chars | unlimited | コンテンツを N 文字に切り詰めます |
--delay | 0 | 読み込み後に待機する追加時間(ミリ秒) |
--stealth | off | 検出回避モード |
--selector | — | CSS セレクターを待機します |
--wait-until | load | load、domcontentloaded、networkidle0(--wait による上限あり) |
--schema | — | 構造化フィールドを JSON として抽出します(以下を参照) |
--har | — | キャプチャしたネットワークアクティビティを HAR ファイルに書き込みます |
--cache-ttl | 0 | 結果をディスクにキャッシュし、N 秒間再利用します |
--schema による構造化抽出
フィールド名を CSS セレクターに対応付ける JSON オブジェクトを渡します。セレクターの末尾に [] を付けると一致するすべての要素をリストとして返し、@attr を付けるとテキストの代わりに属性を返します。
kloakt extract https://news.ycombinator.com \
--schema '{"title":"title","stories":".titleline > a[]","first_link":".titleline > a@href"}'
# => { "url": ..., "data": { "title": "...", "stories": [...], "first_link": "..." }, "elapsed_ms": ... }
これは、オプションの schema 引数を使用して MCP の kloakt_extract ツールからも利用できます。
kloakt fetch <URL>
| フラグ | デフォルト | 説明 |
|---|---|---|
--dump | html | 出力形式:html、text、links、markdown |
--eval | — | 評価する JavaScript 式 |
--wait-until | load | 待機条件 |
--selector | — | CSS セレクターを待機します |
--stealth | off | 検出回避モード |
--quiet | off | バナーを非表示にします |
kloakt serve
| フラグ | デフォルト | 説明 |
|---|---|---|
--port | 9222 | WebSocket ポート |
--proxy | — | HTTP/SOCKS5 プロキシ URL |
--stealth | off | 検出回避とトラッカーブロック |
--workers | 1 | 並列ワーカー数 |
kloakt scrape <URL...>
| フラグ | デフォルト | 説明 |
|---|---|---|
--concurrency | 10 | 並列ワーカー数 |
--eval | — | ページごとの JS 式 |
--format | json | 出力形式:json または text |
kloakt snapshot <URL>
インデックス付きのアクセシビリティ/構造ツリー(常に JSON)を出力します。エージェントの視覚機能を代替します。
各ノードはコンパクトで、i(インデックス)、tag、depth、vis(表示状態)と、存在する場合は click、
role、text、type/value、href、id、name、label が含まれます。
| フラグ | デフォルト | 説明 |
|---|---|---|
--interactive | off | 操作可能な要素(リンク、ボタン、入力欄)のみを対象にします |
--max-nodes | 1500 | 出力するノード数の上限 |
--stealth | off | 検出回避モード |
--delay | 0 | 読み込み後に追加で待機する時間(ミリ秒) |
--wait-until | load | 待機条件 |
kloakt screenshot <URL>
ローカルにインストールされた Chrome/Chromium/Edge に処理を委ねて、実際の PNG を取得します(kloakt にはラスター化機能がありません)。該当するブラウザーが見つからない場合は明確なエラーを表示します。検出結果は --chrome <path> または環境変数 KLOAKT_CHROME で上書きできます。
| フラグ | デフォルト | 説明 |
|---|---|---|
--output | screenshot.png | 出力する PNG のパス |
--width | 1280 | ビューポートの幅 |
--height | 800 | ビューポートの高さ |
--chrome | 自動検出 | Chrome/Chromium/Edge バイナリーへのパス |
kloakt session <COMMAND>
稼働中の kloakt serve デーモンに対して、名前付きの永続セッションを操作します。Cookie と
ページ/JS の状態は、個別の呼び出しをまたいで保持されます(クライアントの状態は ~/.kloakt/sessions/<name>.json に保存されます)。
| コマンド | 説明 |
|---|---|
open <name> [--url URL] [--port] | セッションを開く(または再接続する)とともにページを作成します |
nav <name> <url> | セッションのページに移動します |
eval <name> <expr> | JS 式を評価し、JSON 値を出力します |
text <name> | document.body.innerText を出力します |
snapshot <name> [--interactive] | セッションのページの構造スナップショット |
click <name> <selector> | 最初に一致した要素をクリックします |
type <name> <selector> <text> | 要素にフォーカスし、値を設定して、input/change を発火させます |
list [--port] | デーモン上で開いているセッションを一覧表示します |
close <name> | セッションを閉じます(ページと Cookie を破棄します) |
evalに渡した複数ステートメントの JS はnullを返します(デーモンは単一の 式を評価します)。値を返すには、IIFE —(function(){ ...; return v })()— で囲みます。
kloakt benchmark <URL...>
URL ごとに読み込みパフォーマンス(読み込み時間の平均/最小/最大、リクエスト数、バイト数、DOM
ノード数)を測定し、表または --json で出力します。
kloakt benchmark https://example.com https://news.ycombinator.com --runs 3
| フラグ | デフォルト | 説明 |
|---|---|---|
--runs | 1 | URL ごとの実行回数(平均を報告します) |
--json | off | 表の代わりに JSON を出力します |
--wait-until | load | load、domcontentloaded、または networkidle0 |
チャレンジ/ボットウォールの検出
kloakt extract --json には、検出された CAPTCHA またはボットウォール(recaptcha、hcaptcha、turnstile、cloudflare、datadome、perimeterx)を報告する "challenge" フィールドが含まれます。該当しない場合は null です。これは検出のみを行います。kloakt はページにアクセス制限があることをエージェントに知らせ、処理を停止して待機できるようにしますが、チャレンジの解決や回避は試みません。(MCP の kloakt_extract 出力と Python の Page.challenge フィールドからも確認できます。)
グローバルフラグ
| フラグ | デフォルト | 説明 |
|---|---|---|
--obey-robots | off | robots.txt を尊重し、取得が許可されていないパスへのアクセスを拒否します |
--allow-private | off | プライベート/内部/ループバックホストへのアクセスを許可します(SSRF ガードを無効にします) |
セキュリティに関する注意: デフォルトでは、kloakt はプライベート、ループバック、リンクローカル、クラウドメタデータの各アドレスへのアクセスを拒否し(SSRF 保護)、
file://URL も拒否します。内部サービスへのアクセスが意図的に必要な場合に限り、--allow-privateを使用してください。CDP サーバーは127.0.0.1にバインドし、DNS リバインディングを防ぐためにHostヘッダーを検証します。
CDP API
Puppeteer/Playwright との互換性を実現する、Chrome DevTools Protocol の完全なサポートです。
| ドメイン | メソッド |
|---|---|
| Session | open、close、list — Cookie を保持する、名前付きの永続的なブラウザーコンテキスト |
| Target | createTarget(browserContextName はページをセッションに関連付けます)、closeTarget、attachToTarget、createBrowserContext、disposeBrowserContext |
| Page | navigate、getFrameTree、addScriptToEvaluateOnNewDocument、lifecycleEvents |
| Runtime | evaluate、callFunctionOn、getProperties、addBinding |
| DOM | getDocument、querySelector、querySelectorAll、getOuterHTML、resolveNode |
| Network | enable、setCookies、getCookies、setExtraHTTPHeaders、setUserAgentOverride |
| Fetch | enable、continueRequest、fulfillRequest、failRequest |
| Storage | getCookies、setCookies、deleteCookies |
| Input | dispatchMouseEvent、dispatchKeyEvent |
ライセンス
Apache 2.0 — h4ckf0r0day による Obscura をベースにしています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。