Free

Membiarkan Claude Mengubah Situs Rails Saya Menjadi AI-Native

Enam langkah praktis untuk melayani pembaca manusia dan agen AI dari satu situs, dengan checklist siap pakai


Dalam empat hari terakhir, saya dan Claude Code mengubah smarts.md dari situs dokumentasi smart contract yang dibuat untuk manusia menjadi situs yang dibuat untuk AI agent.

Kedengarannya sama. Nyatanya tidak. Situs untuk manusia dioptimalkan untuk keterbacaan, pencarian, dan kecepatan loading. Situs untuk AI agent harus menjawab pertanyaan yang berbeda:

  • Apakah AI crawler bisa menemukanmu, atau robots.txt default-mu mengunci mereka di luar?
  • Apakah AI bisa melewati rendering HTML dan langsung mengambil konten yang bersih?
  • Apakah AI bisa memanggil tool-mu tanpa harus "membaca dokumentasi" lebih dulu?
  • Apakah setiap halaman memberi tahu AI persis bagaimana mereferensikan dan menanyakannya?

Ini enam hal yang saya minta Claude bangun. Masing-masing berguna sendiri-sendiri, dan bisa kamu bawa ke situsmu satu per satu.

1. Sambut AI crawler secara eksplisit di robots.txt

Kebanyakan situs mewarisi robots.txt dari template lama yang secara implisit memblokir User-Agent yang tidak dikenal. Tapi setelah 2025, banyak AI crawler adalah User-Agent baru — GPTBot, ClaudeBot, PerplexityBot, Applebot-Extended, Google-Extended, CCBot, meta-externalagent, dan lainnya. Kalau mau mereka masuk, kamu harus eksplisit Allow.

robots.txt smarts diawali catatan kebijakan, lalu mencantumkan User-agent + Allow: / untuk 12 crawler yang mencakup OpenAI, Anthropic, Perplexity, Google Gemini, Apple, Common Crawl, Meta, dan Cohere. Sikapnya jelas: situs ini memang ada untuk dibaca AI.

2. llms.txt — menu untuk LLM

llms.txt adalah konvensi yang diusulkan llmstxt.org: taruh Markdown ringkas di root situs yang memberi tahu LLM situs ini apa, cara pakainya, dan di mana pintu masuk utamanya. Itu elevator pitch situsmu.

llms.txt smarts sekitar 60 baris:

  • Satu kalimat posisi (Live docs for every verified smart contract)
  • Cara memakainya dari AI agent (endpoint MCP, perintah setup satu baris)
  • Pola URL (/{chain}/{address} vs slug pendek)
  • Daftar tool MCP dengan deskripsi satu kalimat
  • Daftar contract terkurasi (memberi LLM "jawaban default")
  • Cakupan dan batasan (chain mana yang tidak didukung, kebijakan cache)

Intinya: LLM membayar dengan token untuk membaca dokumenmu, jadi mereka tidak akan crawl seluruh situs. Beri mereka indeks yang sudah disuling, hit rate akan melonjak.

3. .well-known/mcp.json — taruhan dini

Protokol MCP belum menstandarkan konvensi discovery seperti /.well-known/openid-configuration. Saat ini tidak ada client publik yang crawl path well-known tetap.

Tapi menerbitkan manifest ini cuma 30 baris:

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

Begitu konvensi discovery muncul, saya tidak perlu mengubah satu baris pun. Sekaligus itu self-documentation untuk developer — siapa pun yang penasaran MCP saya bisa langsung curl smarts.md/.well-known/mcp.json.

Triknya: array tools diturunkan dari konstanta MCP_TOOLS, single source of truth. Sebuah test struktural yang sudah ada memaksa setiap app/tools/*_tool.rb untuk muncul di konstanta itu, jadi manifest mewarisi jaminan "tool baru tidak akan terlupa" secara gratis.

4. Varian .md: distilasi yang ramah WebFetch untuk setiap halaman

Ini favorit saya. Tool WebFetch Claude Code harus membersihkan dan mengekstrak konten dari HTML sembarang — mahal di token dan tidak stabil. Bagaimana kalau kamu langsung serahkan .md?

respond_to Rails mendukungnya secara native:

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

https://smarts.md/usdc-eth mengembalikan HTML; https://smarts.md/usdc-eth.md mengembalikan 40 baris Markdown — alamat, chain, klasifikasi, endpoint MCP, cara mengquery via AI agent, link sumber.

# 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"

Satu fetch, semua konten terstruktur yang diinginkan AI agent sudah ada, tanpa butuh DOM parser. Claude menyelesaikan ini cepat — satu controller, dua template .md.erb, (.:format) di routes, selesai.

5. Kartu MCP di setiap halaman: biarkan pengguna mengarahkan AI-nya ke sini

Ini discovery arah sebaliknya: sebagian pengunjung saya sudah pakai Claude Code / Cursor / Windsurf. Mereka mendarat di halaman contract, dan langkah berikutnya biasanya "biar AI saya lihat ini".

Jadi setiap halaman contract merender kartu dengan:

  • Reference: slug yang dikurasi (mis. usdc-eth) atau chain/address, dengan tombol copy
  • Sample prompt: "Tell me the current state of usdc-eth", dengan tombol copy
  • Belum pasang AI?: penunjuk ke mcp.smarts.md untuk setup satu baris

Satu klik friksi antara "saya sedang lihat contract ini" dan "saya sedang tanya AI saya". Kartu ini memakai card DaisyUI dan controller Stimulus copy generik — 50 baris erb. Test regresi mengunci atribut data-copy-text-value supaya refactor di masa depan tidak diam-diam menempelkan string salah ke clipboard pengguna.

6. SEO klasik, tapi pakai schema.org dengan benar

OpenGraph, Twitter Card, JSON-LD — lapisan tradisional untuk pencarian dan social card. Layak dikerjakan, karena AI crawler juga membaca sini.

Pilihan menarik adalah bagaimana JSON-LD mendeskripsikan smart contract. Claude memilih WebPage membungkus SoftwareApplication:

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

operatingSystem diisi nama chain, identifier alamat, additionalType klasifikasi (mis. "Uniswap V3 Pool"). schema.org belum punya tipe SmartContract khusus, tapi SoftwareApplication + field-field ini cukup membuat LLM paham "ini adalah contract di Ethereum dengan alamat spesifik".

Gambar OG adalah summary_large_image 1200×630; Twitter Card, breadcrumbs, softwareVersion, dan field license melengkapinya.

Berapa banyak kerja untuk semua ini

Enam item di atas keluar dari tujuh PR dalam empat hari:

PR Files Ukuran
feat/ai-crawler-discovery 2 ~126 loc
feat/well-known-mcp-manifest 4 ~129 loc
feat/markdown-contract-pages 6 ~298 loc
feat/contract-mcp-card 3 ~126 loc
feat/seo-meta-tags 8 ~292 loc
feat/seo-enrichments 8 ~189 loc
feat/og-card

Masing-masing adalah PR independen dengan test dan pesan commit sendiri. Ritme memotong sekecil ini adalah hal paling bernilai saat berkolaborasi dengan Claude — setiap PR cukup kecil untuk direview diff-nya sekilas, tapi ditumpuk bersama situs menumbuhkan permukaan AI yang lengkap.

Checklist yang bisa langsung disalin

Kalau kamu punya situs berorientasi konten dan ingin membuatnya ramah AI, kerjakan dengan urutan ini:

  1. Izinkan secara eksplisit AI crawler utama di robots.txt
  2. Tulis /llms.txt (menu yang sudah disuling)
  3. Tambahkan varian .md ke halaman konten utamamu
  4. Kalau kamu punya server MCP, terbitkan /.well-known/mcp.json
  5. Taruh kartu "tanya AI-mu tentang halaman ini" di halaman konten
  6. Isi JSON-LD / OpenGraph dengan tipe schema.org yang sesuai dengan kontenmu

Kebanyakan SEO engineer tidak akan memberitahumu lima yang pertama — memang tidak ada di playbook SEO tradisional. Tapi dari empat hari data saya, kurva trafik AI dan kurva trafik manusia adalah dua deret yang sepenuhnya independen. Kamu harus melayani keduanya.