mcpField
B
bulk-url-checker

bulk-url-checker

リモート
github.com/carlosofscience開発ツール02 週間前に更新
リポジトリ

bulk-url-checker について

bulk-url-checkerは、大量のURLチェックをBulk URL Checker APIに送信するPythonクライアントとコマンドラインツールです。ステータスコード、リダイレクト、リンク切れの結果を返し、長時間のジョブ管理や安全な再試行にも対応します。

主な機能

  1. 01URLの一括チェックとステータスコード取得
  2. 02リダイレクトチェーンとリンク切れの確認
  3. 03ジョブの送信、ポーリング、ページ取得
  4. 04冪等性を備えた再試行と署名付きWebhook
  5. 05CSV、JSON、JSONL形式のCLI出力

活用シーン

  1. 01大量のURLリストからリンク切れを確認
  2. 02長時間のチェックを再開または監視
  3. 03チェック結果をレポートとして出力

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://mcp.bulkurlchecker.com/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

5
パラメーター型必須説明
urlsarrayはいチェックする URL。各 URL には http:// または https:// スキームを含めてください。

詳細

bulkurlchecker

PyPI version Python versions License: MIT

Bulk URL Checker API 用の Python クライアントです。

通常なら構築に2週間かかるプロキシローテーション、レート制限、ソフト404検出、再試行分類器を省けます。 数千件の URL を送信すると、ステータスコード、リダイレクトチェーン、リンク切れの検出結果が Python オブジェクトとして返されます。住宅用プロキシとドメインごとのスロットリングを備えた、マネージドクラウドサービスを利用しています。

インストール

pip install bulkurlchecker

5行の例

from bulkurlchecker import Client

client = Client(api_key="uck_live_...")
results = client.check_urls(["https://example.com", "https://example.org"])
for r in results.results:
    print(r.url, r.status_code, "BROKEN" if r.is_broken else "ok")

API キーは https://app.bulkurlchecker.com/dashboard/api-keys で取得できます。最初の300件の URL は無料で、カード情報も不要です。

取得できるデータ

results = client.check_urls(urls)

results.status            # 'completed' | 'paused' | 'failed' | 'cancelled'
results.timed_out         # True if the wait deadline passed (job still running)
results.total_urls        # how many URLs the engine accepted
results.completed_urls    # how many it finished checking
results.duplicates_removed
results.invalid_urls_rejected

for r in results.results:
    r.url                # the original URL you submitted
    r.final_url          # after redirects
    r.status_code        # 200, 301, 404, 429, 500, ...
    r.redirect_chain     # list of intermediate URLs
    r.is_broken          # True if the engine flagged this as broken
    r.is_soft_404        # True if 200 OK but page content says "not found"
    r.response_time_ms

# Convenience properties:
results.broken           # list of URLResult where is_broken == True
results.soft_404s        # list where is_soft_404 == True

コマンドラインの使用方法

bulkurlchecker コマンドを使うには、[cli] エクストラを指定してインストールします。

pip install 'bulkurlchecker[cli]'
export BULKURLCHECKER_API_KEY=uck_live_...

# One URL per line in urls.txt → CSV on stdout
bulkurlchecker check urls.txt > report.csv

# Pipe from anywhere
sitemap-extractor mydomain.com | bulkurlchecker check - --output jsonl > report.jsonl

# Only show broken URLs, ad-hoc input
bulkurlchecker check --urls "https://example.com,https://example.org" --only-broken

# Two-step (submit, then poll & fetch later)
JOB=$(bulkurlchecker submit urls.txt)
bulkurlchecker status "$JOB"
bulkurlchecker results "$JOB" --output csv > report.csv

出力形式は csv(デフォルト)、json、jsonl です。すべてのフラグについては bulkurlchecker check --help を実行してください。

大規模なジョブ:送信してポーリングする

check_urls() はサーバー側で最大15分間ブロックします。待機がタイムアウトするようなリストには、次の2段階の方法を使ってください。

job = client.submit(my_500k_urls)
print(f"Submitted {job.job_id}, {job.total_urls} URLs queued")

# Poll explicitly, or use the convenience method
done = client.wait_until_done(job.job_id, timeout=3600)

# Stream results in pages
for batch in client.iter_results(job.job_id, page_size=1000):
    for r in batch:
        if r.is_broken:
            print(r.url, r.status_code)

idempotency_key による安全な再試行

ネットワーク障害時の再試行を安全にするには、submit() または check_urls() に冪等性キーを渡します。サーバーはレスポンスを24時間キャッシュします。同じキーと同じ本文で再試行すると、重複したジョブを作成せず、元の結果が返されます。

import uuid

key = str(uuid.uuid4())  # generate once per logical request

# First call: creates a new job.
job = client.submit(urls, idempotency_key=key)

# Network blip, no clean response received? Just retry with the same
# key -- you'll get the SAME job summary back, no duplicate submission.
same_job = client.submit(urls, idempotency_key=key)
# job.job_id == same_job.job_id

同じ idempotency_key に異なる urls を指定すると、409 Conflict(ValidationError として発生)が返されます。キーを新しいペイロードに使い回すクライアントのバグを、誤ったキャッシュ結果にひそかに対応付けるのではなく、明確に検出できます。

Webhook の受信

ジョブが完了すると、署名付きペイロードを登録済みのエンドポイントに POST します。本文を信頼する前に署名を検証してください。そうしないと、エンドポイント URL を知っている人なら誰でも偽のイベントを送信できます。

from flask import Flask, request
from bulkurlchecker import verify_signature, InvalidSignatureError

SECRET = os.environ["MY_WEBHOOK_SECRET"]  # the signing_secret we showed once

app = Flask(__name__)

@app.route("/webhook/bulkurlchecker", methods=["POST"])
def webhook():
    try:
        verify_signature(
            request.get_data(),  # RAW bytes — not request.get_json()
            request.headers.get("Bulkurlchecker-Signature", ""),
            SECRET,
        )
    except InvalidSignatureError:
        return "", 401
    event = request.get_json()
    if event["type"] == "job.completed":
        job_id = event["data"]["job_id"]
        # ... fetch results, update your DB, ping Slack, etc ...
    return "", 200

エンドポイントの登録とシークレットの取得は https://app.bulkurlchecker.com/dashboard/webhooks(または POST /api/v2/webhooks/endpoints)から行えます。

verify_signature() はリプレイ攻撃を防ぐため、デフォルトで5分のタイムスタンプ許容範囲を適用します。tolerance_seconds= で調整できます。

エラー処理

すべてのエラーは BulkURLCheckerError を継承します。失敗の種類に応じて処理を分岐する場合は、具体的なサブクラスを捕捉してください。

from bulkurlchecker import (
    Client,
    BulkURLCheckerError,
    AuthenticationError,
    RateLimitError,
    QuotaError,
    ValidationError,
)

try:
    results = client.check_urls(urls)
except QuotaError as e:
    print(f"Out of credits. Top up at https://app.bulkurlchecker.com/billing")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s.")
except AuthenticationError:
    print("API key rejected — check it's not revoked.")
except ValidationError as e:
    print(f"Bad request: {e}")  # bad URLs, too many URLs, etc.
except BulkURLCheckerError as e:
    print(f"Other error: {e} (request_id={e.request_id})")

各エラーには status_code、code(サーバーの機械可読な文字列)、request_id(サポートへの問い合わせ用)、および details(サーバーから提供される場合)が含まれます。

httpx + asyncio で独自のチェッカーを書く代わりに、これを使う理由

正直に言うと、500件以下の URL なら必要ありません。標準の requests/httpx ツールチェーンで十分に対応できます。

規模が大きくなると、次のような問題に直面します。

問題自作する場合この SDK
並行処理asyncio + 慎重なセマフォ管理対応済み
住宅用 IP 間のプロキシローテーションWebshare / Bright Data の月額90ドル以上のサブスクリプション + 独自コード対応済み
ドメインごとのレート制限(1つのホストに負荷をかけないため)自分で実装対応済み
本物の403と「ブロックされた」403の見分け推測して試す対応済み
ソフト404(200 OK + 「見つかりません」という本文)の検出テンプレートごとに正規表現/ヒューリスティックを用意対応済み
再試行の分類(一時的か永続的か)何週間もかけて調整対応済み
長時間実行するジョブの状態管理(クラッシュ後の再開)Redis + キュー + ワーカーのインフラ対応済み
エンジニアの作業時間、1〜4週目$$$不要。今日からリリース可能

httpx + プロキシローテーションに週末を費やしたことがあるなら、言いたいことはおわかりでしょう。

料金プラン

  • 最初の1か月は無料です: Starterプランでは、クレジットカード不要でURLチェックを15,000件ご利用いただけます。 APIまたはSDKの連携が初めて正常に実行されると、トライアルはProプランの1か月分に拡張されます:URLチェック50,000件。アカウントごとに1回限りです。
  • その後: すべてのアカウントに、毎月URLチェック300件が含まれます。
  • Starter: 月額$9または年額$90、月間URL数15,000件
  • Pro: 月額$29または年額$290、月間URL数50,000件
  • Agency: 月額$99または年額$990、月間URL数200,000件

メール、Slack、Webhookによるアラート付きの定期チェックは、すべてのプランに含まれます。買い切りのクレジットパックは3,000件分が$5からご利用いただけます。パックのクレジットは繰り越されます。現在の料金:https://bulkurlchecker.com/#pricing

リンク

安定性

SDKはセマンティックバージョニングに従います。バージョンが0.xの間は、マイナーリリースで破壊的変更が入る場合があります(変更は必ずCHANGELOG.mdに記載します)。バージョン1.0以降は、メジャーバージョンを固定して安心してご利用いただけます。

ライセンス

MITです。LICENSEをご覧ください。

コメント

MCP は初めてですか?

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

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