Six actions concrètes pour servir à la fois lecteurs humains et agents IA depuis un seul site, avec checklist à copier
Ces quatre derniers jours, Claude Code et moi avons transformé smarts.md d'un site de documentation de smart contracts pensé pour les humains en un site pensé pour les agents IA.
Ça sonne pareil. Ça ne l'est pas. Un site pour humains optimise la lisibilité, la recherche et le temps de chargement. Un site pour agents IA doit répondre à d'autres questions :
robots.txt par défaut les enferme dehors ?Voici les six choses que j'ai demandées à Claude. Chacune est utile isolément, tu peux la prendre pour ton propre site à part.
robots.txtLa plupart des sites héritent d'un robots.txt issu d'un vieux template qui bloque implicitement tout User-Agent qu'il ne connaît pas. Mais après 2025, beaucoup de crawlers IA sont de nouveaux User-Agents — GPTBot, ClaudeBot, PerplexityBot, Applebot-Extended, Google-Extended, CCBot, meta-externalagent et d'autres. Pour les laisser entrer, il faut les autoriser explicitement.
Le robots.txt de smarts s'ouvre par une note de politique, puis liste User-agent + Allow: / pour 12 crawlers couvrant OpenAI, Anthropic, Perplexity, Google Gemini, Apple, Common Crawl, Meta et Cohere. La posture est directe : ce site existe pour être lu par des IA.
llms.txt — un menu pour LLMsllms.txt est une convention proposée par llmstxt.org : tu déposes un Markdown concis à la racine qui indique au LLM ce qu'est ce site, comment l'utiliser et où sont les points d'entrée clés. C'est le pitch ascenseur de ton site.
Le llms.txt de smarts fait environ 60 lignes :
/{chain}/{address} vs slug court)L'idée : les LLMs paient en tokens pour lire ta doc, donc ils ne crawleront pas tout le site. Donne-leur un index distillé et le taux de pertinence bondit.
.well-known/mcp.json — parier tôtLe protocole MCP n'a pas encore standardisé de convention de découverte façon /.well-known/openid-configuration. Aucun client public ne crawle aujourd'hui un chemin well-known fixe.
Mais publier le manifeste coûte 30 lignes :
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
Le jour où une convention de découverte apparaît, je n'ai pas une ligne à changer. Et c'est une auto-documentation pour les développeurs — quiconque curieux de mon MCP n'a qu'à faire curl smarts.md/.well-known/mcp.json.
L'astuce : le tableau tools dérive de la constante MCP_TOOLS, source unique de vérité. Un test structurel existant oblige chaque app/tools/*_tool.rb à apparaître dans cette constante, donc le manifeste hérite gratuitement de la garantie "pas d'outil oublié".
.md : une distillation WebFetch-friendly pour chaque pageMa favorite. L'outil WebFetch de Claude Code doit nettoyer et extraire du contenu depuis du HTML arbitraire — coûteux en tokens et peu fiable. Et si tu servais directement du .md ?
Le respond_to de Rails le gère nativement :
# config/routes.rb
get ":slug(.:format)", to: "contracts#show",
constraints: { slug: ContractSlugs::ROUTE_PATTERN, format: /html|md/ }
https://smarts.md/usdc-eth renvoie du HTML ; https://smarts.md/usdc-eth.md renvoie 40 lignes de Markdown — adresse, chaîne, classification, endpoint MCP, comment interroger via un agent IA, liens sources.
# 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"
Un fetch, tout le contenu structuré qu'un agent IA veut, pas de parseur DOM. Claude a expédié ça vite — un controller, deux templates .md.erb, (.:format) dans les routes, terminé.
Découverte inverse : une partie de mes visiteurs utilisent déjà Claude Code / Cursor / Windsurf. Ils arrivent sur une page de contrat et la suite naturelle est "laisse mon IA y jeter un œil".
Chaque page de contrat affiche donc une carte avec :
usdc-eth) ou chain/address, avec un bouton Copiermcp.smarts.md (setup en une ligne)Un clic de friction entre « je regarde ce contrat » et « je demande à mon IA ». La carte utilise une card DaisyUI et un contrôleur Stimulus copy générique — 50 lignes d'erb. Un test de régression verrouille les attributs data-copy-text-value pour qu'un refactor futur ne colle pas silencieusement la mauvaise chaîne dans le presse-papiers des utilisateurs.
OpenGraph, Twitter Card, JSON-LD — la couche traditionnelle de recherche et de cartes sociales. Ça vaut le coup, parce que les crawlers IA lisent aussi là.
Le choix intéressant : comment JSON-LD doit décrire un smart contract. Claude a opté pour un WebPage enveloppant une SoftwareApplication :
{
"@type": "WebPage",
"about": {
"@type": "SoftwareApplication",
"name": "USD Coin",
"applicationCategory": "SmartContract",
"operatingSystem": "Ethereum",
"identifier": "0xa0b8..."
}
}
operatingSystem reçoit le nom de la chaîne, identifier l'adresse, additionalType la classification (p. ex. « Uniswap V3 Pool »). schema.org n'a pas de type dédié SmartContract, mais SoftwareApplication + ces champs suffit à ce qu'un LLM comprenne « c'est un contrat sur Ethereum avec une adresse précise ».
L'image OG est un summary_large_image 1200×630 ; Twitter Card, fil d'Ariane, softwareVersion et license complètent le tout.
Les six points ci-dessus sortent de sept PRs en quatre jours :
| PR | Fichiers | Taille |
|---|---|---|
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 |
— | — |
Chacun est un PR indépendant avec ses tests et son message de commit. Ce rythme de découpe fin est ce qu'il y a de plus précieux en travaillant avec Claude — chaque PR est assez petit pour relire le diff d'un coup d'œil, mais empilés ensemble, le site a fait pousser une surface IA complète.
Si tu as un site orienté contenu et que tu veux le rendre AI-friendly, procède dans cet ordre :
robots.txt/llms.txt (un menu distillé).md à tes pages de contenu principales/.well-known/mcp.jsonLa plupart des ingénieurs SEO ne te parleront pas des cinq premiers — ce n'est pas dans le playbook traditionnel. Mais d'après quatre jours de données chez moi, la courbe de trafic IA et la courbe de trafic humain sont deux séries complètement indépendantes. Il faut servir les deux.