はじめに — 「URLを渡すだけで完了」の理想と現実
MCP Serverの run_seo_audit は、URLを1つ渡すだけでSEO監査を完了させるワークフローツールです。OGPチェック、alt属性チェック、リンク切れチェック、ページ速度チェック、見出し抽出——5つのTier 1ツールを内部で連鎖実行し、スコア付きレポートを返します。MCP Serverの全体設計は「MCP Server開発記」を参照してください。
しかしPhase 2(v0.2.0)の時点では、16項目中7項目が「手動確認」のままでした。canonical URL、JSON-LD構造化データ、robots.txt、XMLサイトマップ、ファビコン、コントラスト、ブランディング。「URLを渡すだけで全チェック完了」を謳うには、手動項目が多すぎました。
手動確認項目ゼロを目指す理由: SEO監査ワークフロー(
run_seo_audit)の最大の訴求ポイントは「URLを渡すだけで全チェック完了」。canonical、JSON-LD、robots.txt、サイトマップが手動のままだと「結局自分で確認する項目がある」となり、ワンコマンド完結の価値が毀損する
2月17日の開発日記にこう書きました。Phase 2.5では、この手動7項目のうち技術的に自動化可能な4項目を自動化し、SEO監査の手動項目をゼロにしました。
自動化対象の選定 — 何を自動化し、何をしないか
手動7項目すべてを一度に自動化しようとは考えませんでした。まず「技術的に自動化可能か」で振り分けます。
自動化可能(Phase 2.5で対応):
- canonical URL — HTMLの
<link rel="canonical">を解析すれば検出可能 - JSON-LD構造化データ — HTMLの
<script type="application/ld+json">を解析すれば検出可能 - robots.txt — 独立したURLからテキストを取得・解析すれば検出可能
- XMLサイトマップ — 独立したURLからXMLを取得・解析すれば検出可能
自動化困難(将来課題):
- ファビコン —
<link rel="icon">の存在確認は可能だが、Phase 2.7で計画 - コントラスト — PageSpeed InsightsのACCESSIBILITYカテゴリを活用予定
- ブランディング — 人間の判断が必要な領域
PM-AI 対話: 既存APIの拡張 vs 新規API
<link rel="canonical">、JSON-LDは <script type="application/ld+json"> で、どちらもHTMLの <head> 内の要素です。既存のOGPチェッカーを拡張すれば、追加のHTTPリクエストなしで取得できます。OGPチェッカーの「メタ情報ハブ」化: canonical URL、JSON-LD、OGP、Twitter Cardがすべて同じHTMLから取得できる。OGPチェッカーを「ページメタ情報の統合取得ツール」に育てることで、新しいチェック項目を追加するたびに新APIを作る必要がなくなる
この設計判断が、Phase 2.5の実装効率を大きく左右しました。
OGPチェッカーの拡張 — canonical + JSON-LD
OGPチェッカーのAPI routeに2つのフィールドを追加しました。
canonicalフィールドは、HTMLから <link rel="canonical"> のhref属性を抽出します。存在しなければnull。シンプルな追加です。
jsonLdフィールドは少し複雑でした。<script type="application/ld+json"> は1ページに複数存在する可能性があります。各JSON-LDブロックについて、@type(スキーマの種類)とvalid(JSON構文が正しいかどうか)を返す配列として設計しました。
MCP Server側では、ワークフローの buildToolResultSummary() にcanonicalとJSON-LDの情報を追加し、SEO監査レポートに反映させます。
site-config-checker — 新規Tier 1ツール
robots.txtとXMLサイトマップは、HTMLページとは独立したURLに存在します。OGPチェッカーのHTMLフェッチとは別のリクエストが必要なため、check_site_config という新しいTier 1ツールを作りました。
このツールは2つの検査を行います。
robots.txt検査: URLのドメインから /robots.txt を取得し、構文を解析します。ルール数、Sitemapディレクティブの有無、構文上の問題を検出します。
XMLサイトマップ検査: robots.txt内のSitemapディレクティブからURLを自動発見するか、/sitemap.xml にフォールバックします。URL数、サイトマップインデックスかどうか、構造上の問題を検出します。
SSRF対策 — redirect: manual の選択
site-config-checkerの実装で最も注意を払ったのが、SSRF(Server-Side Request Forgery)対策です。
外部URLにHTTPリクエストを送るAPIでは、攻撃者がリダイレクトを利用して内部ネットワークにアクセスさせる攻撃が成り立ちます。たとえば robots.txt のURLとして https://evil.com/redirect を渡し、リダイレクト先が http://169.254.169.254/(クラウドのメタデータAPI)であれば、サーバーの認証情報が漏洩します。
SSRF対策で
redirect: "manual"にした理由:redirect: "follow"だとリダイレクト先のURLを検証できない。攻撃者がリダイレクト経由で内部IPにアクセスさせるSSRF攻撃を防ぐため、リダイレクトごとにisValidUrl()で検証するhop-by-hop方式を採用
fetch() のデフォルトである redirect: "follow" はリダイレクトを自動で追従しますが、途中のURLを検証する機会がありません。redirect: "manual" に設定し、リダイレクトごとに isValidUrl() で内部IPでないことを確認するhop-by-hop方式を採用しました。この対策パターンの詳細は「Next.js APIルートのSSRF対策」で解説しています。
評価関数の設計 — チェックリストデータとの統合
4つの自動化項目それぞれに評価関数を実装しました。
evalCanonical— canonical URL存在チェック(OGPチェッカー経由)evalJsonLd— JSON-LD存在+有効性チェック(OGPチェッカー経由)evalRobotsTxt— robots.txt存在+構文チェック(site-config-checker経由)evalSitemap— XMLサイトマップ存在+URL数チェック(site-config-checker経由)
これらの評価関数をワークフローの checklist-data.ts に組み込むことで、SEO監査ワークフローの自動チェック項目が12→16に増加。手動確認項目が7→0になりました。
段階的自動化のアプローチ
振り返ると、Phase 2(v0.2.0)で「手動項目あり」のままリリースしたのは正しい判断でした。
手動→自動化の段階的アプローチ: Phase 2(v0.2.0)で「手動項目あり」のままリリースし、Phase 2.5で自動化を追加するのは正しい段階的アプローチ。最初から完璧を目指すとリリースが遅れる
PM-AI 対話: 手動項目ありでリリースした判断
Phase 2のデモで「手動項目がある」という違和感を実感し、それがPhase 2.5の動機になりました。最初から完璧を目指していたら、ワークフローツール自体のリリースが大幅に遅れていたでしょう。
バージョン管理の教訓
Phase 2.5の変更をv0.2.1としてCHANGELOGに書いていたところ、npmには既にv0.2.1が公開済みでした。npmレジストリは同じバージョンの再公開を許しません。
v0.2.2にバンプし、CHANGELOGをv0.2.2(今回の修正)とv0.2.1(公開済み内容)に正しく分離しました。50テスト全パス、ビルド成功を確認してnpm公開。npm公開の詳しい手順は「個人開発者がnpmパッケージを公開するまでの全手順」にまとめています。
npm公開のバージョン管理: npm registryは同じバージョンの再公開を許さない。CHANGELOGの分離やバージョンバンプのタイミングは、開発作業とリリース作業を明確に区別する必要がある
学んだこと
既存APIの拡張が新規APIより効率的な場合がある: OGPチェッカーを「メタ情報ハブ」に育てることで、HTTPリクエスト数を削減しつつ新しいチェック項目を追加できました。「すでにHTMLを取得しているAPIはないか?」という問いが設計の出発点です。
段階的自動化は価値のあるパターン: 最初から手動ゼロを目指すとリリースが遅れます。「手動項目あり」でリリースし、実際に使ってみて手動項目の痛みを実感してから自動化する。この段階的アプローチは、リリース速度と品質のバランスを取る有効な方法です。
SSRF対策は外部URLフェッチの基本: redirect: "follow" はリダイレクト先を検証できないため、外部URLにリクエストを送るAPIでは redirect: "manual" + hop-by-hop検証が鉄則です。
npmのバージョン管理は開発と公開を分離して考える: 開発中にCHANGELOGを書き始めると、公開済みバージョンとの衝突が起きやすい。「公開直前にバージョンを決める」運用が安全です。
Zeronova(ゼロノバ)
Product Manager / AI-Native Builder
Web/IT業界19年以上・20以上のWebサービスを担当したPdM。東証プライム上場企業の子会社代表として事業経営を経験。現在はAIを駆使して企画から実装まで完結させる個人開発を実践中。