Una API abierta para la colección.
Pensada para agentes.

Los metadatos del museo se publican en JSON para que investigadores, periodistas y sistemas de IA los consuman sin tener que raspar HTML. Las peticiones que ves abajo son las mismas que realiza cualquier cliente externo — puedes ejecutarlas en vivo desde esta página.

Base URL
https://art-collection.ent.alphams.work
Todos los endpoints son relativos a esta URL.
Autenticación
Pública · sin API key
Identifica tu cliente con User-Agent descriptivo.
Formato
JSON · UTF-8
HTML en rutas de ficha; SVG en /assets.
Rate limits
Por IP · edge CF
/api/* razonable · /assets/* estricto.

Endpoints disponibles

GET/api/artwork/list
Lista completa de la colección
GET/api/artwork/:id
Detalle de una obra
GET/assets/art-:id.jpg
Imagen procedural de la obra
GET/collection/artwork-:id
Ficha HTML de una obra
GET/robots.txt
Política pública para crawlers
GET/sitemap.xml
Sitemap XML

Model Context Protocol

Un servidor MCP para agentes de IA

Para clientes LLM (Claude Desktop, Workers AI Playground, agentes propios) mantenemos un servidor MCP público. En lugar de componer llamadas HTTP, el agente ve cuatro herramientas diseñadas alrededor de intenciones reales: "dame una vista de la colección", "busca obras impresionistas", "dame el detalle de la obra 7".

collection_overview

Resumen tipo curador: totales, rango de años y movimientos dominantes. Llamar primero: da el vocabulario que necesitan el resto de las tools.

list_movements

Vocabulario controlado de movimientos, ordenado por frecuencia. Úsalo como fuente de valores válidos para el filtro movement.

search_artworks

Búsqueda libre + filtros estructurados (movimiento, rango de años, límite). Devuelve tarjetas compactas listas para citar o encadenar a get_artwork.

get_artwork

Detalle completo de una obra por id numérico. Incluye permalink, ruta de imagen y bloque de derechos (metadata vs imagen).

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "atrium-art-collection": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp-art-collection.ent.alphams.work/mcp"
      ]
    }
  }
}

MCP Inspector — prueba interactiva

npx @modelcontextprotocol/inspector
# Transport:  Streamable HTTP
# URL:        https://mcp-art-collection.ent.alphams.work/mcp
# → connect → list tools → call collection_overview

JSON-RPC por curl

curl -s https://mcp-art-collection.ent.alphams.work/mcp \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"search_artworks",
                 "arguments":{"query":"paisaje","limit":3}}}'

¿Por qué no solo HTTP? Un endpoint REST obliga al agente a razonar sobre N rutas, paginación y shapes. El MCP expone verbos: el LLM elige la tool por su descripción, valida los parámetros con el esquema Zod del servidor, y recibe una respuesta ya adaptada a su contexto. En la práctica: menos tokens, menos alucinaciones, y una superficie que el museo puede versionar sin romper a los agentes. Detrás, estas tools leen la misma API JSON que documentamos aquí arriba — service binding Worker → Worker, dentro de la red de Cloudflare.

Lista completa de la colección§

GET /api/artwork/list Cache 60 sPúblicax-robots-tag: index, noai-imagery

Devuelve el catálogo completo como un array de registros mínimos (id, título, artista, año, movimiento, técnica, enlaces). Útil para indexadores y agentes que necesitan un barrido inicial antes de pedir el detalle de una obra concreta.

Petición ejemplo

curl "https://art-collection.ent.alphams.work/api/artwork/list" \
  -H "Accept: application/json" \
  -H "User-Agent: AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
const res = await fetch("https://art-collection.ent.alphams.work/api/artwork/list", {
  headers: {
    "Accept": "application/json",
    "User-Agent": "AtriumResearchBot/1.0"
  }
});
const data = await res.json();
import requests

r = requests.get(
    "https://art-collection.ent.alphams.work/api/artwork/list",
    headers={
        "Accept": "application/json",
        "User-Agent": "AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
    }
)
data = r.json()
respuesta real desde https://art-collection.ent.alphams.work

Respuesta live

Pulsa Probar en vivo para llamar al endpoint real.

Detalle de una obra§

GET /api/artwork/:id Cache 60 sPúblicaMarca IA si activa

Metadata extendida de una obra concreta, incluyendo enlace canónico a la ficha HTML, ruta de la imagen, y el bloque rights con la licencia de datos vs imagen. Si el marcador de atribución está activo en la capa de defensa, un User-Agent de crawler de IA recibirá una versión de este JSON con un tracker inyectado en attribution, provenance, y el campo artist (marcador Unicode invisible).

Petición ejemplo

curl "https://art-collection.ent.alphams.work/api/artwork/1" \
  -H "Accept: application/json" \
  -H "User-Agent: AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
const res = await fetch("https://art-collection.ent.alphams.work/api/artwork/1", {
  headers: {
    "Accept": "application/json",
    "User-Agent": "AtriumResearchBot/1.0"
  }
});
const data = await res.json();
import requests

r = requests.get(
    "https://art-collection.ent.alphams.work/api/artwork/1",
    headers={
        "Accept": "application/json",
        "User-Agent": "AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
    }
)
data = r.json()
respuesta real desde https://art-collection.ent.alphams.work

Respuesta live

Pulsa Probar en vivo para llamar al endpoint real.

Imagen procedural de la obra§

GET /assets/art-:id.jpg Cache 60 sRate limitedChallenge si abuso

Imagen SVG generada en el Worker y servida con content-type: image/svg+xml. Sujeta a rate limit en el edge (10 req/min por IP) para proteger el ancho de banda. Los agentes no deberían descargar imágenes en masa; si lo intentan, reciben un challenge o 429.

Petición ejemplo

curl "https://art-collection.ent.alphams.work/assets/art-1.jpg" \
  -H "Accept: application/json" \
  -H "User-Agent: AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
const res = await fetch("https://art-collection.ent.alphams.work/assets/art-1.jpg", {
  headers: {
    "Accept": "application/json",
    "User-Agent": "AtriumResearchBot/1.0"
  }
});
const data = await res.json();
import requests

r = requests.get(
    "https://art-collection.ent.alphams.work/assets/art-1.jpg",
    headers={
        "Accept": "application/json",
        "User-Agent": "AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
    }
)
data = r.json()
respuesta real desde https://art-collection.ent.alphams.work

Respuesta live

Pulsa Probar en vivo para llamar al endpoint real.

Ficha HTML de una obra§

GET /collection/artwork-:id IndexableCache 60 sContent negotiation recomendada

Página HTML con la ficha catalográfica completa. Incluye tags <meta name="robots"> y enlace canónico a /api/artwork/:id para que un agente bien educado salte al JSON en lugar de parsear el HTML.

Petición ejemplo

curl "https://art-collection.ent.alphams.work/collection/artwork-1" \
  -H "Accept: application/json" \
  -H "User-Agent: AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
const res = await fetch("https://art-collection.ent.alphams.work/collection/artwork-1", {
  headers: {
    "Accept": "application/json",
    "User-Agent": "AtriumResearchBot/1.0"
  }
});
const data = await res.json();
import requests

r = requests.get(
    "https://art-collection.ent.alphams.work/collection/artwork-1",
    headers={
        "Accept": "application/json",
        "User-Agent": "AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
    }
)
data = r.json()
respuesta real desde https://art-collection.ent.alphams.work

Respuesta live

Pulsa Probar en vivo para llamar al endpoint real.

Política pública para crawlers§

GET /robots.txt PúblicaCache 5 minNegociable por contrato

Política del museo para bots e indexadores. Enumera qué paths son indexables (/collection/*, /api/artwork/*) y cuáles están prohibidos a crawlers de IA (/assets/*, por coste de ancho de banda). También contiene Crawl-delay sugerido y una clave AI-policy con la licencia de uso del contenido.

Petición ejemplo

curl "https://art-collection.ent.alphams.work/robots.txt" \
  -H "Accept: application/json" \
  -H "User-Agent: AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
const res = await fetch("https://art-collection.ent.alphams.work/robots.txt", {
  headers: {
    "Accept": "application/json",
    "User-Agent": "AtriumResearchBot/1.0"
  }
});
const data = await res.json();
import requests

r = requests.get(
    "https://art-collection.ent.alphams.work/robots.txt",
    headers={
        "Accept": "application/json",
        "User-Agent": "AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
    }
)
data = r.json()
respuesta real desde https://art-collection.ent.alphams.work

Respuesta live

Pulsa Probar en vivo para llamar al endpoint real.

Sitemap XML§

GET /sitemap.xml PúblicaAuto-generado

Sitemap derivado automáticamente del catálogo. Incluye la home, /about, y cada ficha de obra. Frecuencia de cambio declarada como anual — la colección está estable, no hay rotación semanal.

Petición ejemplo

curl "https://art-collection.ent.alphams.work/sitemap.xml" \
  -H "Accept: application/json" \
  -H "User-Agent: AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
const res = await fetch("https://art-collection.ent.alphams.work/sitemap.xml", {
  headers: {
    "Accept": "application/json",
    "User-Agent": "AtriumResearchBot/1.0"
  }
});
const data = await res.json();
import requests

r = requests.get(
    "https://art-collection.ent.alphams.work/sitemap.xml",
    headers={
        "Accept": "application/json",
        "User-Agent": "AtriumResearchBot/1.0 (+mailto:curator@museum.example)"
    }
)
data = r.json()
respuesta real desde https://art-collection.ent.alphams.work

Respuesta live

Pulsa Probar en vivo para llamar al endpoint real.
Aviso. Las peticiones a /api/artwork/:id pueden pasar por el Worker de marcado de atribución. Si tu User-Agent parece un crawler de IA y el flag está activo, recibirás una respuesta funcional pero trazable — ver cabecera x-atrium-marker. Los investigadores humanos identificados pasan transparentes.