URL analizada
https://www.rivalr.app/
Puntuación AI-Ready
Aceptable
de 100
Ahorro de tokens
Desglose de la puntuación
Protocolos emergentes
0 de 3 detectadosEndpoints well-known que los AI agents buscan. Detectados significa que un agente puede descubrir y conectar con tu servicio automáticamente.
-
OAuth Discovery RFC 8414
/.well-known/oauth-authorization-server -
MCP Server Card Anthropic
/.well-known/mcp.json -
A2A Agent Card Google
/.well-known/agent.json
Tu página no usa elementos <article> o <main>. Estos contenedores semánticos ayudan a los AI agents a identificar el área de contenido principal e ignorar navegación, barras laterales y pies de página.
Cómo implementarlo
Añade un elemento <main> alrededor del contenido principal de tu página, y usa <article> para bloques de contenido independientes como entradas de blog o descripciones de productos.
La estructura de encabezados tiene problemas (niveles saltados o múltiples etiquetas h1). Una jerarquía limpia ayuda a los AI agents a comprender la organización del contenido.
Cómo implementarlo
Asegúrate de tener exactamente un <h1> por página y que los encabezados sigan un orden secuencial: h1 > h2 > h3. No saltes niveles (por ejemplo, de h1 directamente a h3).
No se encontró un sitemap. Un sitemap ayuda a los AI agents a descubrir todas las páginas de tu sitio.
Cómo implementarlo
Crea un /sitemap.xml con todas tus páginas públicas. La mayoría de los CMS pueden generarlo automáticamente.
Tu página depende en gran medida de elementos <div>. Los elementos semánticos como <section>, <nav>, <header>, <footer> y <aside> proporcionan una estructura significativa para los AI agents.
Cómo implementarlo
Reemplaza los contenedores <div> genéricos con los elementos semánticos apropiados. Usa <section> para grupos temáticos, <nav> para navegación, <header>/<footer> para cabeceras y pies de página o sección.
Tu sitio no soporta Markdown for Agents. Este estándar de Cloudflare permite a los agentes IA solicitar contenido en formato markdown, reduciendo el uso de tokens en ~80%.
Cómo implementarlo
Implementa uno o más: (1) Responder a Accept: text/markdown con contenido markdown. (2) Servir URLs .md (ej: /pagina.md). (3) Añadir etiquetas <link rel="alternate" type="text/markdown">. (4) Añadir cabeceras HTTP Link para descubrimiento markdown.
No se encontró URL canónica. Esto ayuda a los AI agents a identificar la versión preferida de una página y evitar contenido duplicado.
Cómo implementarlo
Añade una etiqueta <link rel="canonical" href="..."> apuntando a la URL canónica de la página.
Muchos elementos tienen atributos de estilo en línea. Estos añaden ruido para los AI agents al extraer contenido.
Cómo implementarlo
Mueve todos los estilos en línea a clases CSS en tu hoja de estilos. Usa frameworks de CSS utilitario como Tailwind si necesitas muchos estilos únicos.
Rivalr — Find Players & Join Activity Groups Near You
Sube este archivo como /index.md en tu servidor para que los AI agents puedan acceder a una versión limpia de tu página. También puedes configurar la negociación de contenido Accept: text/markdown para servirlo automáticamente.
Nuestra recomendación
# rivalr.app > Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed. ## Main - [Rivalr — Find Players & Join Activity Groups Near You](https://www.rivalr.app/): Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one…
El llms.txt completo requiere un análisis de todo el dominio (próximamente)
Sube este archivo a https://www.rivalr.app/llms.txt en la raíz de tu dominio. Los AI agents como ChatGPT, Claude y Perplexity consultan este archivo para comprender la estructura de tu sitio.
Este sitio ya tiene un archivo llms.txt.
Formato no válido — debería empezar con un encabezado # y tener contenido significativo<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed." />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.rivalr.app/" />
<meta property="og:title" content="Rivalr — Find Players & Join Activity Groups" />
<meta property="og:description" content="Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed." />
<meta property="og:image" content="https://www.rivalr.app/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Rivalr — Find Players & Join Activity Groups" />
<meta property="og:site_name" content="Rivalr" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Rivalr — Find Players & Join Activity Groups" />
<meta name="twitter:description" content="Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed." />
<meta name="twitter:image" content="https://www.rivalr.app/og-image.png" />
<title>Rivalr — Find Players & Join Activity Groups Near You</title>
<!-- Schema.org JSON-LD -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.rivalr.app/#organization",
"name": "Rivalr",
"url": "https://www.rivalr.app/",
"logo": {
"@type": "ImageObject",
"url": "https://www.rivalr.app/og-image.png",
"width": 1200,
"height": 630
},
"description": "Rivalr connects people for shared activities — football, basketball, padel, concerts, dinners, hikes and more."
},
{
"@type": "WebSite",
"@id": "https://www.rivalr.app/#website",
"url": "https://www.rivalr.app/",
"name": "Rivalr",
"publisher": { "@id": "https://www.rivalr.app/#organization" }
},
{
"@type": "SoftwareApplication",
"@id": "https://www.rivalr.app/#app",
"name": "Rivalr",
"operatingSystem": ["iOS", "Android"],
"applicationCategory": "SocialNetworkingApplication",
"description": "Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "EUR"
},
"url": "https://www.rivalr.app/"
}
]
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=DM+Serif+Display:ital@0;1&display=swap" rel="stylesheet" />
<script type="module" crossorigin src="/assets/index-DekaQV6t.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Bv57ANoo.css">
</head>
<body style="background:#0B0F19;color:#F1F5F9">
<div id="root"></div>
<noscript>
<h1>Find Players & Join Activity Groups Near You</h1>
<p>Rivalr connects you with people for football, basketball, padel, tennis, concerts, dinners, hiking and more. Post open spots or join an existing group — no group chat needed.</p>
<nav aria-label="Activity pages">
<a href="/activities/football/athens/">Football in Athens</a>
<a href="/activities/basketball/athens/">Basketball in Athens</a>
<a href="/activities/padel/athens/">Padel in Athens</a>
<a href="/activities/tennis/athens/">Tennis in Athens</a>
<a href="/activities/concert/athens/">Concerts in Athens</a>
<a href="/activities/hiking/athens/">Hiking in Athens</a>
<a href="/activities/dinner/athens/">Dinner in Athens</a>
<a href="/activities/football/thessaloniki/">Football in Thessaloniki</a>
<a href="/activities/basketball/thessaloniki/">Basketball in Thessaloniki</a>
<a href="/activities/padel/thessaloniki/">Padel in Thessaloniki</a>
</nav>
</noscript>
<!-- WebMCP: expose Rivalr tools to AI agents via the browser -->
<script>
(function () {
if (!navigator.modelContext || typeof navigator.modelContext.registerTool !== 'function') return;
const ac = new AbortController();
const BASE = 'https://api.rivalr.app';
navigator.modelContext.registerTool({
name: 'rivalr_list_postings',
description: 'List open match postings and pickup game slots on Rivalr, optionally filtered by activity type, city, or date.',
inputSchema: {
type: 'object',
properties: {
activity: { type: 'string', description: 'Activity type, e.g. football, basketball, padel, tennis, concert, dinner, hiking' },
city: { type: 'string', description: 'City name, e.g. athens, thessaloniki' },
date: { type: 'string', format: 'date', description: 'ISO 8601 date to filter by' }
}
},
execute: async ({ activity, city, date } = {}) => {
const params = new URLSearchParams();
if (activity) params.set('activity', activity);
if (city) params.set('city', city);
if (date) params.set('date', date);
const res = await fetch(`${BASE}/postings?${params}`);
return res.json();
},
signal: ac.signal
});
navigator.modelContext.registerTool({
name: 'rivalr_get_posting',
description: 'Get full details about a specific Rivalr match posting including spots left, date, venue, and participants.',
inputSchema: {
type: 'object',
required: ['id'],
properties: {
id: { type: 'string', description: 'Match posting ID' }
}
},
execute: async ({ id }) => {
const res = await fetch(`${BASE}/postings/${encodeURIComponent(id)}`);
return res.json();
},
signal: ac.signal
});
navigator.modelContext.registerTool({
name: 'rivalr_list_venues',
description: 'List sports venues on Rivalr with location, supported activities, and availability.',
inputSchema: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name to filter venues' },
activity: { type: 'string', description: 'Activity type supported by the venue' }
}
},
execute: async ({ city, activity } = {}) => {
const params = new URLSearchParams();
if (city) params.set('city', city);
if (activity) params.set('activity', activity);
const res = await fetch(`${BASE}/venues?${params}`);
return res.json();
},
signal: ac.signal
});
window.addEventListener('unload', () => ac.abort(), { once: true });
})();
</script>
</body>
</html>
HTML semántico
Missing <article> and <main> elements
No headings found
0 semantic elements, 1 divs (ratio: 0%)
No images found
Avg div depth: 0.0, max: 0
Eficiencia del contenido
100% token reduction (HTML→Markdown)
Content ratio: 43.1% (3395 content chars / 7876 HTML bytes)
1/30 elements with inline styles (3.3%)
HTML size: 8KB
Visibilidad para IA
llms.txt exists but appears empty or invalid
robots.txt exists
All major AI bots allowed
No sitemap found
Datos estructurados
JSON-LD found: Organization, WebSite, SoftwareApplication
All OG tags present
Meta description: 149 chars
No canonical URL
lang="en"
Accesibilidad
Content available without JavaScript
Page size: 8KB
Main content starts at 49% of HTML
{
"url": "https://www.rivalr.app/",
"timestamp": 1778798510409,
"fetch": {
"mode": "simple",
"timeMs": 775,
"htmlSizeBytes": 7876,
"supportsMarkdown": true,
"markdownAgents": {
"contentNegotiation": true,
"mdUrl": {
"found": false,
"url": null
},
"linkTag": {
"found": false,
"url": null
},
"linkHeader": {
"found": false,
"url": null
},
"responseHeaders": {
"contentSignal": "ai-train=yes, search=yes, ai-input=yes",
"xMarkdownTokens": "486",
"vary": "Accept"
},
"frontmatter": {
"present": true,
"fields": [
"title",
"description",
"image"
],
"level": "enriched"
},
"level": "application"
},
"statusCode": 200
},
"extraction": {
"title": "Rivalr — Find Players & Join Activity Groups Near You",
"excerpt": "Find Players & Join Activity Groups Near You\n Rivalr connects you with people for football, basketball, padel, tennis, concerts, dinners, hiking and more. Post open spots or join an existing grou",
"byline": null,
"siteName": null,
"lang": "en",
"contentLength": 3395,
"metadata": {
"description": "Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.",
"ogTitle": "Rivalr — Find Players & Join Activity Groups",
"ogDescription": "Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed.",
"ogImage": "https://www.rivalr.app/og-image.png",
"ogType": "website",
"canonical": null,
"lang": "en",
"schemas": [
{
"@type": "Organization",
"@id": "https://www.rivalr.app/#organization",
"name": "Rivalr",
"url": "https://www.rivalr.app/",
"logo": {
"@type": "ImageObject",
"url": "https://www.rivalr.app/og-image.png",
"width": 1200,
"height": 630
},
"description": "Rivalr connects people for shared activities — football, basketball, padel, concerts, dinners, hikes and more."
},
{
"@type": "WebSite",
"@id": "https://www.rivalr.app/#website",
"url": "https://www.rivalr.app/",
"name": "Rivalr",
"publisher": {
"@id": "https://www.rivalr.app/#organization"
}
},
{
"@type": "SoftwareApplication",
"@id": "https://www.rivalr.app/#app",
"name": "Rivalr",
"operatingSystem": [
"iOS",
"Android"
],
"applicationCategory": "SocialNetworkingApplication",
"description": "Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "EUR"
},
"url": "https://www.rivalr.app/"
}
],
"robotsMeta": null,
"author": null,
"generator": null,
"markdownAlternateHref": null
}
},
"markdown": "\n",
"fullPageMarkdown": "Rivalr — Find Players & Join Activity Groups Near You\n",
"markdownStats": {
"images": 0,
"links": 10,
"tables": 0,
"codeBlocks": 0,
"headings": 1
},
"tokens": {
"htmlTokens": 1936,
"markdownTokens": 1,
"reduction": 1935,
"reductionPercent": 100
},
"score": {
"score": 71,
"grade": "C",
"dimensions": {
"semanticHtml": {
"score": 35,
"weight": 20,
"grade": "F",
"checks": {
"uses_article_or_main": {
"score": 0,
"weight": 20,
"details": "Missing <article> and <main> elements"
},
"proper_heading_hierarchy": {
"score": 0,
"weight": 25,
"details": "No headings found"
},
"semantic_elements": {
"score": 0,
"weight": 20,
"details": "0 semantic elements, 1 divs (ratio: 0%)"
},
"meaningful_alt_texts": {
"score": 100,
"weight": 15,
"details": "No images found"
},
"low_div_nesting": {
"score": 100,
"weight": 20,
"details": "Avg div depth: 0.0, max: 0"
}
}
},
"contentEfficiency": {
"score": 93,
"weight": 25,
"grade": "A",
"checks": {
"token_reduction_ratio": {
"score": 100,
"weight": 40,
"details": "100% token reduction (HTML→Markdown)"
},
"content_to_noise_ratio": {
"score": 100,
"weight": 30,
"details": "Content ratio: 43.1% (3395 content chars / 7876 HTML bytes)"
},
"minimal_inline_styles": {
"score": 50,
"weight": 15,
"details": "1/30 elements with inline styles (3.3%)"
},
"reasonable_page_weight": {
"score": 100,
"weight": 15,
"details": "HTML size: 8KB"
}
}
},
"aiDiscoverability": {
"score": 61,
"weight": 25,
"grade": "C",
"checks": {
"has_llms_txt": {
"score": 50,
"weight": 20,
"details": "llms.txt exists but appears empty or invalid"
},
"has_robots_txt": {
"score": 100,
"weight": 10,
"details": "robots.txt exists"
},
"robots_allows_ai_bots": {
"score": 100,
"weight": 15,
"details": "All major AI bots allowed"
},
"has_sitemap": {
"score": 0,
"weight": 10,
"details": "No sitemap found"
},
"supports_markdown_negotiation": {
"score": 40,
"weight": 25,
"details": "Application level — Content negotiation"
},
"has_content_signals": {
"score": 80,
"weight": 20,
"details": "robots.txt: ai-train=no, search=yes, ai-input=no | Policy included"
}
}
},
"structuredData": {
"score": 85,
"weight": 15,
"grade": "B",
"checks": {
"has_schema_org": {
"score": 100,
"weight": 30,
"details": "JSON-LD found: Organization, WebSite, SoftwareApplication"
},
"has_open_graph": {
"score": 100,
"weight": 25,
"details": "All OG tags present"
},
"has_meta_description": {
"score": 100,
"weight": 20,
"details": "Meta description: 149 chars"
},
"has_canonical_url": {
"score": 0,
"weight": 15,
"details": "No canonical URL"
},
"has_lang_attribute": {
"score": 100,
"weight": 10,
"details": "lang=\"en\""
}
}
},
"accessibility": {
"score": 85,
"weight": 15,
"grade": "B",
"checks": {
"content_without_js": {
"score": 100,
"weight": 40,
"details": "Content available without JavaScript"
},
"reasonable_page_size": {
"score": 100,
"weight": 30,
"details": "Page size: 8KB"
},
"fast_content_position": {
"score": 50,
"weight": 30,
"details": "Main content starts at 49% of HTML"
}
}
}
}
},
"recommendations": [
{
"id": "add_article_main",
"priority": "critical",
"category": "semanticHtml",
"titleKey": "rec.add_article_main.title",
"descriptionKey": "rec.add_article_main.description",
"howToKey": "rec.add_article_main.howto",
"effort": "quick-win",
"estimatedImpact": 8,
"checkScore": 0,
"checkDetails": "Missing <article> and <main> elements"
},
{
"id": "fix_heading_hierarchy",
"priority": "critical",
"category": "semanticHtml",
"titleKey": "rec.fix_heading_hierarchy.title",
"descriptionKey": "rec.fix_heading_hierarchy.description",
"howToKey": "rec.fix_heading_hierarchy.howto",
"effort": "quick-win",
"estimatedImpact": 6,
"checkScore": 0,
"checkDetails": "No headings found"
},
{
"id": "add_sitemap",
"priority": "critical",
"category": "aiDiscoverability",
"titleKey": "rec.add_sitemap.title",
"descriptionKey": "rec.add_sitemap.description",
"howToKey": "rec.add_sitemap.howto",
"effort": "quick-win",
"estimatedImpact": 5,
"checkScore": 0,
"checkDetails": "No sitemap found"
},
{
"id": "add_semantic_elements",
"priority": "critical",
"category": "semanticHtml",
"titleKey": "rec.add_semantic_elements.title",
"descriptionKey": "rec.add_semantic_elements.description",
"howToKey": "rec.add_semantic_elements.howto",
"effort": "moderate",
"estimatedImpact": 5,
"checkScore": 0,
"checkDetails": "0 semantic elements, 1 divs (ratio: 0%)"
},
{
"id": "add_markdown_negotiation",
"priority": "high",
"category": "aiDiscoverability",
"titleKey": "rec.add_markdown_negotiation.title",
"descriptionKey": "rec.add_markdown_negotiation.description",
"howToKey": "rec.add_markdown_negotiation.howto",
"effort": "significant",
"estimatedImpact": 6,
"checkScore": 40,
"checkDetails": "Application level — Content negotiation"
},
{
"id": "add_canonical_url",
"priority": "high",
"category": "structuredData",
"titleKey": "rec.add_canonical_url.title",
"descriptionKey": "rec.add_canonical_url.description",
"howToKey": "rec.add_canonical_url.howto",
"effort": "quick-win",
"estimatedImpact": 3,
"checkScore": 0,
"checkDetails": "No canonical URL"
},
{
"id": "remove_inline_styles",
"priority": "medium",
"category": "contentEfficiency",
"titleKey": "rec.remove_inline_styles.title",
"descriptionKey": "rec.remove_inline_styles.description",
"howToKey": "rec.remove_inline_styles.howto",
"effort": "moderate",
"estimatedImpact": 3,
"checkScore": 50,
"checkDetails": "1/30 elements with inline styles (3.3%)"
}
],
"llmsTxtPreview": "# rivalr.app\n\n> Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.\n\n## Main\n- [Rivalr — Find Players & Join Activity Groups Near You](https://www.rivalr.app/): Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one…\n\n",
"llmsTxtExisting": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"description\" content=\"Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.\" />\n\n <!-- Open Graph -->\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:url\" content=\"https://www.rivalr.app/\" />\n <meta property=\"og:title\" content=\"Rivalr — Find Players & Join Activity Groups\" />\n <meta property=\"og:description\" content=\"Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed.\" />\n <meta property=\"og:image\" content=\"https://www.rivalr.app/og-image.png\" />\n <meta property=\"og:image:width\" content=\"1200\" />\n <meta property=\"og:image:height\" content=\"630\" />\n <meta property=\"og:image:alt\" content=\"Rivalr — Find Players & Join Activity Groups\" />\n <meta property=\"og:site_name\" content=\"Rivalr\" />\n\n <!-- Twitter Card -->\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content=\"Rivalr — Find Players & Join Activity Groups\" />\n <meta name=\"twitter:description\" content=\"Connect with people for football, basketball, padel, concerts, dinners, hikes and more. Post open spots or join an existing group — no group chat needed.\" />\n <meta name=\"twitter:image\" content=\"https://www.rivalr.app/og-image.png\" />\n\n <title>Rivalr — Find Players & Join Activity Groups Near You</title>\n\n <!-- Schema.org JSON-LD -->\n <script type=\"application/ld+json\">\n {\n \"@context\": \"https://schema.org\",\n \"@graph\": [\n {\n \"@type\": \"Organization\",\n \"@id\": \"https://www.rivalr.app/#organization\",\n \"name\": \"Rivalr\",\n \"url\": \"https://www.rivalr.app/\",\n \"logo\": {\n \"@type\": \"ImageObject\",\n \"url\": \"https://www.rivalr.app/og-image.png\",\n \"width\": 1200,\n \"height\": 630\n },\n \"description\": \"Rivalr connects people for shared activities — football, basketball, padel, concerts, dinners, hikes and more.\"\n },\n {\n \"@type\": \"WebSite\",\n \"@id\": \"https://www.rivalr.app/#website\",\n \"url\": \"https://www.rivalr.app/\",\n \"name\": \"Rivalr\",\n \"publisher\": { \"@id\": \"https://www.rivalr.app/#organization\" }\n },\n {\n \"@type\": \"SoftwareApplication\",\n \"@id\": \"https://www.rivalr.app/#app\",\n \"name\": \"Rivalr\",\n \"operatingSystem\": [\"iOS\", \"Android\"],\n \"applicationCategory\": \"SocialNetworkingApplication\",\n \"description\": \"Find players for football, basketball, padel and tennis. Join concerts, dinners and hikes. Post open spots or claim one — free, no group chat needed.\",\n \"offers\": {\n \"@type\": \"Offer\",\n \"price\": \"0\",\n \"priceCurrency\": \"EUR\"\n },\n \"url\": \"https://www.rivalr.app/\"\n }\n ]\n }\n </script>\n\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link href=\"https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=DM+Serif+Display:ital@0;1&display=swap\" rel=\"stylesheet\" />\n <script type=\"module\" crossorigin src=\"/assets/index-DekaQV6t.js\"></script>\n <link rel=\"stylesheet\" crossorigin href=\"/assets/index-Bv57ANoo.css\">\n </head>\n <body style=\"background:#0B0F19;color:#F1F5F9\">\n <div id=\"root\"></div>\n <noscript>\n <h1>Find Players & Join Activity Groups Near You</h1>\n <p>Rivalr connects you with people for football, basketball, padel, tennis, concerts, dinners, hiking and more. Post open spots or join an existing group — no group chat needed.</p>\n <nav aria-label=\"Activity pages\">\n <a href=\"/activities/football/athens/\">Football in Athens</a>\n <a href=\"/activities/basketball/athens/\">Basketball in Athens</a>\n <a href=\"/activities/padel/athens/\">Padel in Athens</a>\n <a href=\"/activities/tennis/athens/\">Tennis in Athens</a>\n <a href=\"/activities/concert/athens/\">Concerts in Athens</a>\n <a href=\"/activities/hiking/athens/\">Hiking in Athens</a>\n <a href=\"/activities/dinner/athens/\">Dinner in Athens</a>\n <a href=\"/activities/football/thessaloniki/\">Football in Thessaloniki</a>\n <a href=\"/activities/basketball/thessaloniki/\">Basketball in Thessaloniki</a>\n <a href=\"/activities/padel/thessaloniki/\">Padel in Thessaloniki</a>\n </nav>\n </noscript>\n <!-- WebMCP: expose Rivalr tools to AI agents via the browser -->\n <script>\n (function () {\n if (!navigator.modelContext || typeof navigator.modelContext.registerTool !== 'function') return;\n const ac = new AbortController();\n const BASE = 'https://api.rivalr.app';\n\n navigator.modelContext.registerTool({\n name: 'rivalr_list_postings',\n description: 'List open match postings and pickup game slots on Rivalr, optionally filtered by activity type, city, or date.',\n inputSchema: {\n type: 'object',\n properties: {\n activity: { type: 'string', description: 'Activity type, e.g. football, basketball, padel, tennis, concert, dinner, hiking' },\n city: { type: 'string', description: 'City name, e.g. athens, thessaloniki' },\n date: { type: 'string', format: 'date', description: 'ISO 8601 date to filter by' }\n }\n },\n execute: async ({ activity, city, date } = {}) => {\n const params = new URLSearchParams();\n if (activity) params.set('activity', activity);\n if (city) params.set('city', city);\n if (date) params.set('date', date);\n const res = await fetch(`${BASE}/postings?${params}`);\n return res.json();\n },\n signal: ac.signal\n });\n\n navigator.modelContext.registerTool({\n name: 'rivalr_get_posting',\n description: 'Get full details about a specific Rivalr match posting including spots left, date, venue, and participants.',\n inputSchema: {\n type: 'object',\n required: ['id'],\n properties: {\n id: { type: 'string', description: 'Match posting ID' }\n }\n },\n execute: async ({ id }) => {\n const res = await fetch(`${BASE}/postings/${encodeURIComponent(id)}`);\n return res.json();\n },\n signal: ac.signal\n });\n\n navigator.modelContext.registerTool({\n name: 'rivalr_list_venues',\n description: 'List sports venues on Rivalr with location, supported activities, and availability.',\n inputSchema: {\n type: 'object',\n properties: {\n city: { type: 'string', description: 'City name to filter venues' },\n activity: { type: 'string', description: 'Activity type supported by the venue' }\n }\n },\n execute: async ({ city, activity } = {}) => {\n const params = new URLSearchParams();\n if (city) params.set('city', city);\n if (activity) params.set('activity', activity);\n const res = await fetch(`${BASE}/venues?${params}`);\n return res.json();\n },\n signal: ac.signal\n });\n\n window.addEventListener('unload', () => ac.abort(), { once: true });\n })();\n </script>\n </body>\n</html>",
"emergingProtocols": {
"oauthDiscovery": {
"exists": false,
"url": "https://www.rivalr.app/.well-known/oauth-authorization-server"
},
"mcpServerCard": {
"exists": false,
"url": "https://www.rivalr.app/.well-known/mcp.json"
},
"a2aAgentCard": {
"exists": false,
"url": "https://www.rivalr.app/.well-known/agent.json"
},
"count": 0
},
"snippets": [
{
"id": "fix_heading_hierarchy",
"title": "Fix heading hierarchy",
"description": "Your page has no <h1>. Every page needs exactly one <h1> as the main heading. Add it inside your <main> or <article>.",
"language": "html",
"code": "<h1>Rivalr — Find Players & Join Activity Groups Near You</h1>",
"filename": "<main> or <article>"
},
{
"id": "add_canonical_url",
"title": "Add canonical URL",
"description": "The canonical URL tells AI agents which version of the page is the \"official\" one, avoiding duplicate content issues.",
"language": "html",
"code": "<link rel=\"canonical\" href=\"https://www.rivalr.app/\">",
"filename": "<head>"
},
{
"id": "add_sitemap",
"title": "Create /sitemap.xml",
"description": "A sitemap helps AI agents discover all your pages. Most CMS platforms generate one automatically.",
"language": "xml",
"code": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n <url>\n <loc>https://www.rivalr.app/</loc>\n <lastmod>2026-05-14</lastmod>\n </url>\n</urlset>",
"filename": "/sitemap.xml"
},
{
"id": "add_article_main",
"title": "Wrap content in <main> and <article>",
"description": "Semantic HTML landmarks help AI agents identify the main content of your page.",
"language": "html",
"code": "<main>\n <article>\n <h1>Your Page Title</h1>\n <p>Your content here...</p>\n </article>\n</main>",
"filename": "<body>"
},
{
"id": "add_markdown_negotiation",
"title": "Support Markdown for Agents",
"description": "Let AI agents request a clean Markdown version of any page via content negotiation, .md alternate URLs, link tags or Link headers.",
"language": "html",
"code": "<!-- Mechanism 3: link tag advertising the .md alternate -->\n<link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">",
"filename": "<head>",
"stacks": [
{
"id": "html",
"label": "HTML <head>",
"language": "html",
"filename": "<head>",
"code": "<!-- Mechanism 3: link tag advertising the .md alternate -->\n<link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">"
},
{
"id": "express",
"label": "Express",
"language": "javascript",
"filename": "server.js",
"code": "// Mechanisms 1 + 4: content negotiation + Link header\napp.get('/page', (req, res) => {\n res.setHeader('Vary', 'Accept');\n res.setHeader('Link', '</page.md>; rel=\"alternate\"; type=\"text/markdown\"');\n if ((req.headers.accept || '').includes('text/markdown')) {\n res.type('text/markdown; charset=utf-8');\n return res.send(renderMarkdown('page'));\n }\n res.render('page');\n});"
},
{
"id": "fastify",
"label": "Fastify",
"language": "javascript",
"filename": "server.js",
"code": "// Mechanisms 1 + 4: content negotiation + Link header\nfastify.get('/page', async (req, reply) => {\n reply.header('Vary', 'Accept');\n reply.header('Link', '</page.md>; rel=\"alternate\"; type=\"text/markdown\"');\n if ((req.headers.accept || '').includes('text/markdown')) {\n return reply.type('text/markdown; charset=utf-8').send(renderMarkdown('page'));\n }\n return reply.view('/page.ejs');\n});"
},
{
"id": "nextjs",
"label": "Next.js",
"language": "typescript",
"filename": "app/page/route.ts",
"code": "// Next.js App Router — Route Handler returning Markdown\nimport { NextRequest } from 'next/server';\nimport { renderMarkdown } from '@/lib/md';\nexport async function GET(req: NextRequest) {\n const accept = req.headers.get('accept') || '';\n if (accept.includes('text/markdown')) {\n return new Response(await renderMarkdown('page'), {\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Vary': 'Accept',\n },\n });\n }\n // Fall through to the page component\n return new Response(null, { status: 404 });\n}"
},
{
"id": "wordpress",
"label": "WordPress",
"language": "php",
"filename": "functions.php",
"code": "<?php\n// Mechanism 1: respond to Accept: text/markdown on the same URL\nadd_action('template_redirect', function () {\n if (!is_singular()) return;\n $accept = $_SERVER['HTTP_ACCEPT'] ?? '';\n if (strpos($accept, 'text/markdown') === false) return;\n header('Content-Type: text/markdown; charset=utf-8');\n header('Vary: Accept');\n $post = get_queried_object();\n echo \"# \" . get_the_title($post) . \"\\n\\n\";\n echo wp_strip_all_tags(apply_filters('the_content', $post->post_content));\n exit;\n});"
},
{
"id": "static",
"label": "Hugo / Jekyll / Astro",
"language": "txt",
"filename": "static/page.md",
"code": "# Mechanism 2: serve .md alongside .html\n# Hugo: place page.md in /static/ — built unchanged\n# Jekyll: drop page.md in /assets/ — copied as-is\n# Astro: src/pages/page.md.ts that exports a GET returning markdown\n\n# Then advertise with mechanism 3 in <head>:\n# <link rel=\"alternate\" type=\"text/markdown\" href=\"/page.md\">"
}
]
}
]
}
Usa nuestra API para obtener esto de forma programática (próximamente)
Este JSON es para uso interno — a diferencia del Markdown y llms.txt, no está pensado para subirse a tu web. Guárdalo como referencia para seguir la evolución de tu puntuación, compártelo con tu equipo de desarrollo o intégralo en tu pipeline CI/CD.
Incrusta tu badge
Añade este badge a tu sitio. Se actualiza automáticamente cuando cambie tu puntuación.
<script src="https://agentready.md/badge.js" data-id="869e97d4-81ec-4e34-948b-49149a42d94e" data-domain="www.rivalr.app"></script>
[](https://agentready.md/es/r/869e97d4-81ec-4e34-948b-49149a42d94e)
Próximamente: Análisis de dominio completo
Rastrea todo tu dominio, genera llms.txt y monitoriza tu puntuación de preparación para IA a lo largo del tiempo. Únete a la lista de espera para recibir notificaciones.