Free

Claude で Rails サイトを AI ネイティブにする

人間と AI エージェントの両方に仕えるサイトを作る 6 つの実践、コピペ可能なチェックリスト付き


この 4 日間、Claude Code と一緒に smarts.md を「人間が読むスマートコントラクトのドキュメントサイト」から「AI エージェントが使うスマートコントラクトのドキュメントサイト」へ作り変えました。

同じことのように聞こえますが、中身はかなり違います。人間向けのサイトでは、可読性・検索性・表示速度を最適化します。AI エージェント向けのサイトでは、まったく別の問いに答える必要があります。

  • AI クローラーがそもそも到達できるか(デフォルトの robots.txt で締め出していないか)
  • HTML を描画せずに クリーンなコンテンツを取れるか
  • 「ドキュメントを読む」ことなく ツールを呼べるか
  • 個々のページ が AI に「どう参照し、どう問い合わせれば良いか」を伝えているか

Claude に作ってもらった 6 つの仕掛けを紹介します。どれも独立して、あなたのサイトにそのまま持ち込めます。

1. robots.txt で AI クローラーを明示的に歓迎する

多くのサイトの robots.txt は古いテンプレのコピーで、知らない User-Agent は暗黙的にブロックしています。2025 年以降、多くの AI クローラーは 新しい User-Agent です——GPTBot、ClaudeBot、PerplexityBot、Applebot-Extended、Google-Extended、CCBot、meta-externalagent などなど。これらに来てほしければ明示的に Allow する必要があります。

smarts の robots.txt は冒頭で方針を述べ、その後 User-agent + Allow: / を 12 個並べて、OpenAI、Anthropic、Perplexity、Google Gemini、Apple、Common Crawl、Meta、Cohere をカバーしています。スタンスは単純明快——このサイトは AI に読まれるために存在している。

2. llms.txt——LLM 向けのメニュー

llms.txtllmstxt.org が提唱する慣例です。サイトのルートに簡潔な Markdown を置き、LLM に「このサイトは何か、どう使うか、主要な入口はどこか」を教えます。いわばサイトの エレベーターピッチ です。

smarts の llms.txt は約 60 行で、こんな内容です。

  • 一言ポジショニング(Live docs for every verified smart contract)
  • AI エージェントからの使い方(MCP エンドポイント、ワンライナー設定)
  • URL パターン(/{chain}/{address} と短い slug)
  • MCP ツール一覧と一文説明
  • キュレーションされた合約リスト(LLM の「既定の答え」用)
  • スコープと制限(非対応チェーン、キャッシュ戦略)

ポイント:LLM はドキュメントをトークンで読んでいるので、サイト全体をクロールしない。蒸留済みのインデックスを渡すと、当たり率が跳ね上がります。

3. .well-known/mcp.json に早めに賭けておく

MCP プロトコルは /.well-known/openid-configuration のような自動発見の慣例をまだ持っていません。今のところ、決まったパスをクロールする公開クライアントは存在しません。

それでも、マニフェストを公開するのは 30 行で済みます。

def well_known_mcp
  response.set_header("Cache-Control", "public, max-age=3600")
  response.set_header("Access-Control-Allow-Origin", "*")
  render json: {
    name: "smarts",
    version: "0.1.0",
    description: "...",
    protocol_version: "2024-11-05",
    transports: [{ type: "sse", endpoint: "https://smarts.md/mcp/sse" }],
    capabilities: { tools: true, resources: false, prompts: false },
    tools: MCP_TOOLS.map { |t| { name: t[:name], description: t[:blurb] } }
  }
end

将来の発見規約が決まった瞬間、一行も書き換えずに乗れます。同時にこのマニフェストは 開発者向けの自己ドキュメント でもあります——MCP の中身が気になる人は curl smarts.md/.well-known/mcp.json で一発です。

仕掛けの肝:tools 配列は MCP_TOOLS 定数から派生、シングルソースオブトゥルース。既存の構造テストが app/tools/*_tool.rb を全てその定数に出現させることを強制するので、マニフェストは「新しいツールを書き忘れない」保証をタダで継承します。

4. .md バリアント:すべてのページに WebFetch 向けの蒸留版

これが一番の収穫。Claude Code の WebFetch ツールは HTML を取得してから自分でクリーンアップと抽出をしますが、トークン消費が多くて不安定です。では、最初から .md を提供したらどうでしょう?

Rails の respond_to が素で対応しています。

# config/routes.rb
get ":slug(.:format)", to: "contracts#show",
    constraints: { slug: ContractSlugs::ROUTE_PATTERN, format: /html|md/ }

https://smarts.md/usdc-eth は HTML を返し、https://smarts.md/usdc-eth.md は 40 行の Markdown を返します——アドレス、チェーン、分類、MCP エンドポイント、AI エージェントからの問い合わせ方、元リンク。

# USD Coin on Ethereum

- **Address:** `0xa0b8...`
- **Chain:** Ethereum
- **Classification:** ERC-20 Token

## Query via AI agent

- **MCP endpoint:** `https://smarts.md/mcp/sse`
- **Reference:** `usdc-eth`
- **Sample prompt:** "Tell me the current state of usdc-eth"

AI エージェントが .md を一発 fetch すれば、欲しい構造化情報は全部入り、DOM パーサー不要。これは Claude が速くこなしました——controller 一つ、.md.erb テンプレート二つ、routes に (.:format) を追加、それだけ。

5. ページ内の MCP カード:ユーザーに AI をこのページへ向けさせる

逆向きの発見です。サイトの訪問者のうち、すでに Claude Code / Cursor / Windsurf を使っている人が一定数います。合約ページを見た次の行動は「この件、俺の AI に調べさせよう」です。

なので各合約ページにカードを描画しました。

  • Reference:キュレーション済み slug(例:usdc-eth)または chain/address と、コピーボタン
  • Sample prompt:「Tell me the current state of usdc-eth」と、コピーボタン
  • MCP まだ繋いでない人へmcp.smarts.md への案内(ワンライナー設定)

「この合約を見ている」から「AI に聞いている」までの摩擦がクリック 1 回。カードは DaisyUI の card と汎用 Stimulus copy コントローラーで 50 行の erb、さらに回帰テストで data-copy-text-value 属性を固定し、将来の refactor がユーザーのクリップボードに間違った文字列を黙って貼り付けないようにしてあります。

6. 伝統的な SEO を、schema.org でちゃんと書く

OpenGraph、Twitter Card、JSON-LD——従来の検索とソーシャルカード向けのレイヤーですが、やる価値はあります。AI クローラーもここを読むからです。

興味深いのは JSON-LD がスマートコントラクトをどう記述するか。Claude は WebPageSoftwareApplication をくるむ形を選びました。

{
  "@type": "WebPage",
  "about": {
    "@type": "SoftwareApplication",
    "name": "USD Coin",
    "applicationCategory": "SmartContract",
    "operatingSystem": "Ethereum",
    "identifier": "0xa0b8..."
  }
}

operatingSystem にチェーン名、identifier にアドレス、additionalType に分類(例:「Uniswap V3 Pool」)。schema.org には専用の SmartContract 型がありませんが、SoftwareApplication + これらのフィールドで「Ethereum 上でアドレス識別されたコントラクト」と LLM に理解させるのに十分です。

OG 画像は 1200×630 の summary_large_image。Twitter Card、パンくず、softwareVersion、license も一通り埋めました。

全部でどれくらいの作業量か

上記 6 項目は、4 日間の 7 つの PR に収まっています。

PR ファイル数 大きさ
feat/ai-crawler-discovery 2 約 126 行
feat/well-known-mcp-manifest 4 約 129 行
feat/markdown-contract-pages 6 約 298 行
feat/contract-mcp-card 3 約 126 行
feat/seo-meta-tags 8 約 292 行
feat/seo-enrichments 8 約 189 行
feat/og-card

どれも独立した PR、独立したテスト、独立したコミットメッセージ。この細かく刻むリズムこそが Claude との協業で最も価値が高い部分 です——PR 一つ一つは一目で diff を追えるサイズに抑えつつ、積み上げるとサイトには完全な AI 対応面が生えている。

そのまま使えるチェックリスト

コンテンツ型サイトを AI フレンドリーにしたいなら、この順番でどうぞ。

  1. robots.txt で主要 AI クローラーを明示的に Allow
  2. /llms.txt を書く(蒸留メニュー)
  3. 主要コンテンツページに .md バリアントを足す
  4. MCP サーバーがあるなら /.well-known/mcp.json を公開
  5. コンテンツページに「このページについて AI に聞く」カードを置く
  6. JSON-LD / OpenGraph をコンテンツ種別に合った schema.org 型で埋める

最初の 5 つは従来の SEO プレイブックに載っていないので、多くの SEO エンジニアは教えてくれません。けれどこの 4 日間のデータを見る限り、AI トラフィックの成長曲線と人間のトラフィック曲線は完全に独立した 2 本の線です。両方に仕えないと片手落ちになります。