Free

Dejar que Claude haga mi sitio Rails AI-native

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:

  • ¿Pueden los crawlers de IA encontrarte o tu robots.txt por defecto los está bloqueando?
  • ¿Puede una IA saltarse el renderizado del HTML y obtener contenido limpio directamente?
  • ¿Puede una IA invocar tus herramientas sin tener que "leer la documentación" antes?
  • ¿Cada página le dice a la IA exactamente cómo referenciarla y consultarla?

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.

1. Dar la bienvenida explícita a los crawlers de IA en robots.txt

La 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.

2. llms.txt — un menú para LLMs

llms.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:

  • Un posicionamiento en una frase (Live docs for every verified smart contract)
  • Cómo usarlo desde un agente de IA (endpoint MCP, comando de configuración de una línea)
  • Patrones de URL (/{chain}/{address} vs slug corto)
  • Herramientas MCP con descripciones de una frase
  • Una lista curada de contratos (dando al LLM "respuestas por defecto")
  • Alcance y límites (qué cadenas no se soportan, política de caché)

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.

3. .well-known/mcp.json — apostar temprano

El 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.

4. Una variante .md: destilación amigable con WebFetch para cada página

Esta 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.

5. Una tarjeta MCP en cada página: que los usuarios apunten su IA aquí

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:

  • Reference: el slug curado (p. ej. usdc-eth) o chain/address, con botón de copiar
  • Sample prompt: "Tell me the current state of usdc-eth", con botón de copiar
  • ¿Aún no tienes IA conectada?: un puntero a mcp.smarts.md con la configuración de una línea

Un 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.

6. SEO clásico, con schema.org bien hecho

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.

Cuánto trabajo es todo esto

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.

Una lista para copiar y pegar

Si tienes un sitio de contenido y quieres que sea amigable para IA, hazlo en este orden:

  1. Permite explícitamente a los principales crawlers de IA en robots.txt
  2. Escribe un /llms.txt (un menú destilado)
  3. Añade una variante .md a tus páginas de contenido principales
  4. Si tienes un servidor MCP, publica /.well-known/mcp.json
  5. Pon una tarjeta "pregunta a tu IA sobre esta página" en las páginas de contenido
  6. Llena JSON-LD / OpenGraph con los tipos schema.org que encajen con tu contenido

Los 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.