Seis acciones prácticas para servir a lectores humanos y agentes de IA desde el mismo sitio, con checklist listo para copiar
Durante los últimos cuatro días, Claude Code y yo transformamos smarts.md de un sitio de documentación de contratos inteligentes para humanos en uno para agentes de IA.
Suenan como lo mismo. No lo son. Un sitio para humanos se optimiza para legibilidad, búsqueda y tiempo de carga. Un sitio para agentes de IA tiene que responder otras preguntas:
robots.txt por defecto los está bloqueando?Estas son las seis cosas que le pedí a Claude construir. Cada una es útil por sí sola y puedes llevártela a tu propio sitio.
robots.txtLa mayoría de los sitios heredan un robots.txt de alguna plantilla vieja que implícitamente deniega cualquier User-Agent que no conoce. Pero después de 2025, muchos crawlers de IA son User-Agents nuevos — GPTBot, ClaudeBot, PerplexityBot, Applebot-Extended, Google-Extended, CCBot, meta-externalagent, entre otros. Si los quieres dentro, tienes que autorizarlos explícitamente.
El robots.txt de smarts abre con una nota de política y luego lista User-agent + Allow: / para 12 crawlers cubriendo OpenAI, Anthropic, Perplexity, Google Gemini, Apple, Common Crawl, Meta y Cohere. La postura es directa: este sitio existe para ser leído por IA.
llms.txt — un menú para LLMsllms.txt es una convención propuesta por llmstxt.org: pones un Markdown conciso en la raíz del sitio que le dice al LLM qué es este sitio, cómo usarlo y dónde están los puntos de entrada clave. Es el pitch de ascensor de tu sitio.
El llms.txt de smarts tiene unas 60 líneas:
/{chain}/{address} vs slug corto)La idea clave: los LLMs pagan en tokens para leer tu documentación, así que no van a crawlear todo el sitio. Dales un índice destilado y la tasa de acierto sube bastante.
.well-known/mcp.json — apostar tempranoEl protocolo MCP todavía no tiene una convención de descubrimiento estandarizada tipo /.well-known/openid-configuration. Ningún cliente público crawlea hoy una ruta well-known fija.
Pero publicar el manifiesto cuesta 30 líneas:
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
En el momento en que aparezca una convención de descubrimiento, no cambio ni una línea. Y es auto-documentación para desarrolladores — cualquiera curioso por mi MCP puede hacer curl smarts.md/.well-known/mcp.json.
El truco: el array de tools se deriva de la constante MCP_TOOLS, fuente única de verdad. Un test estructural existente obliga a que cada app/tools/*_tool.rb aparezca en esa constante, así que el manifiesto hereda la garantía de "no olvidar herramientas nuevas" gratis.
.md: destilación amigable con WebFetch para cada páginaEsta es mi favorita. La herramienta WebFetch de Claude Code tiene que limpiar y extraer contenido de HTML arbitrario — eso gasta tokens y es poco fiable. ¿Y si le entregamos .md directamente?
El respond_to de Rails lo soporta nativamente:
# config/routes.rb
get ":slug(.:format)", to: "contracts#show",
constraints: { slug: ContractSlugs::ROUTE_PATTERN, format: /html|md/ }
https://smarts.md/usdc-eth devuelve HTML; https://smarts.md/usdc-eth.md devuelve 40 líneas de Markdown — dirección, cadena, clasificación, endpoint MCP, cómo consultar desde un agente de IA, enlaces fuente.
# 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, todo el contenido estructurado que quiere un agente de IA, sin necesidad de parser de DOM. Claude despachó esto rápido — un controller, dos templates .md.erb, (.:format) en las rutas, listo.
Este es el descubrimiento inverso: parte de mis visitantes ya usan Claude Code / Cursor / Windsurf. Llegan a una página de contrato y lo siguiente que quieren es "que mi IA le eche un ojo a esto".
Así que cada página de contrato renderiza una tarjeta con:
usdc-eth) o chain/address, con botón de copiarmcp.smarts.md con la configuración de una líneaUn clic de fricción entre "estoy viendo este contrato" y "le estoy preguntando a mi IA". La tarjeta usa una card de DaisyUI y un controlador Stimulus copy genérico — 50 líneas de erb. Un test de regresión fija los atributos data-copy-text-value para que un refactor futuro no pegue silenciosamente la cadena equivocada en el portapapeles del usuario.
OpenGraph, Twitter Card, JSON-LD — la capa tradicional de búsqueda y tarjetas sociales. Vale la pena, porque los crawlers de IA también la leen.
Lo interesante es cómo debería JSON-LD describir un contrato inteligente. Claude eligió un WebPage envolviendo una SoftwareApplication:
{
"@type": "WebPage",
"about": {
"@type": "SoftwareApplication",
"name": "USD Coin",
"applicationCategory": "SmartContract",
"operatingSystem": "Ethereum",
"identifier": "0xa0b8..."
}
}
operatingSystem recibe el nombre de la cadena, identifier la dirección, additionalType la clasificación (p. ej. "Uniswap V3 Pool"). schema.org no tiene un tipo dedicado SmartContract, pero SoftwareApplication con estos campos basta para que un LLM entienda "esto es un contrato en Ethereum con una dirección específica".
La imagen OG es un summary_large_image 1200×630; Twitter Card, migas de pan, softwareVersion y license completan el conjunto.
Los seis ítems anteriores salieron de siete PRs en cuatro días:
| PR | Archivos | Tamaño |
|---|---|---|
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 |
— | — |
Cada uno es un PR independiente con sus propios tests y mensaje de commit. Esa cadencia es lo más valioso de trabajar con Claude — cada PR es pequeño como para revisar el diff de una mirada, pero apilados juntos el sitio creció una superficie completa para IA.
Si tienes un sitio de contenido y quieres que sea amigable para IA, hazlo en este orden:
robots.txt/llms.txt (un menú destilado).md a tus páginas de contenido principales/.well-known/mcp.jsonLos primeros cinco no te los contará la mayoría de los ingenieros SEO — no están en el playbook tradicional. Pero por los datos de estos cuatro días, la curva de tráfico de IA y la curva de tráfico humano son dos series completamente independientes. Hay que servir a ambas.