AI Slop Checker

Puntúa el texto y el copy de páginas de aterrizaje por señales de escritura con IA; determinista, sin conexión, sin llamada a LLM y sin acceso a red.

Documentación

mcp-ai-slop-checker

Un servidor MCP que le dice a tu modelo cuándo su propia escritura suena a IA.

MCP Registry test license

claude mcp add ai-slop-checker -- npx -y github:parweb/mcp-ai-slop-checker

Tres herramientas, todas deterministas, locales y sin conexión: sin llamada a LLM, sin clave de API, sin solicitud de red, sin telemetría. La misma entrada siempre devuelve el mismo número, así que puedes poner una puntuación en un test y hacer afirmaciones sobre ella.

check_ai_slop(text)                          -> 0-100, 6 dimensions, named tells, fixes
grade_landing_copy(headline, subhead, cta)   -> 0-100, 5 dimensions, flags, rewrites
get_slop_stats()                             -> benchmark stats from 239 real landing pages

Por qué

Cada "detector de IA" es un clasificador probabilístico que adivina la autoría y se equivoca en ambos sentidos. Esto hace lo contrario y lo dice claramente: cuenta indicios de estilo — densidad de rayas, frecuencia de delve/tapestry/furthermore, estructuras de "no solo… sino también", longitudes de frase sospechosamente uniformes, falta de detalles, listas de viñetas demasiado paralelas — y devuelve los recuentos brutos que produjeron cada subpuntuación.

Eso lo hace útil en un bucle que un agente puede cerrar de verdad: escribir → puntuar → ver qué recuento es alto → arreglar esa cosa concreta → volver a puntuar. Un "87% probable IA" de un clasificador no le da a un agente nada sobre lo que actuar. "hype": 5 sí.

Una puntuación es una medición de estilo, no una afirmación de autoría. stripe.com obtiene 61 y fue obviamente escrito por profesionales. Una puntuación baja significa se lee genérico, nunca fue generado.

Instalación

Listado en el Registro MCP oficial como io.github.parweb/ai-slop-checker.

Se instala directamente desde GitHub — aún no está en npm, así que usa la especificación github::

claude mcp add ai-slop-checker -- npx -y github:parweb/mcp-ai-slop-checker

O en cualquier configuración de cliente MCP (claude_desktop_config.json, .mcp.json, Cursor, etc.):

{
  "mcpServers": {
    "ai-slop-checker": {
      "command": "npx",
      "args": ["-y", "github:parweb/mcp-ai-slop-checker"]
    }
  }
}

O instala el paquete MCPB autocontenido (dependencias incluidas, sin paso de instalación) desde el lanzamiento v1.0.2mcp-ai-slop-checker.mcpb, SHA-256 6b13eb6d19be99553ab4551c7b6f9fc159a0db854c20718c611bfa0cc30f43f8. Reconstrúyelo tú mismo y compara: ./scripts/build-mcpb.sh.

Desde el código fuente:

git clone https://github.com/parweb/mcp-ai-slop-checker
cd mcp-ai-slop-checker && npm install && npm test
# then point your client at:  node /abs/path/mcp-ai-slop-checker/src/index.js

Node >= 18. Una dependencia de ejecución (@modelcontextprotocol/sdk) más zod.

Herramientas

check_ai_slop(text)

Puntúa prosa de 0 a 100, donde 100 se lee humano. Seis dimensiones: densidad de palabras LLM (30), densidad de rayas (20), estructuras formularias (15), ritmo de frases (15), especificidad (10), perfección de listas (10). ~200+ caracteres dan una lectura fiable.

Salida real, recortada a las partes que importan:

// input: a 74-word paragraph of "In today's fast-paced world… delve… Moreover… seamless…"
{
  "score": 34,
  "verdict": "This sounds AI-generated.",
  "words": 74,
  "dimensions": [
    { "key": "LLM-word density",     "max": 30, "score": 0,  "notes": { "phrases": 5, "words": 14 } },
    { "key": "Em-dash density",      "max": 20, "score": 8,  "notes": { "dashes": 1 } },
    { "key": "Formulaic structures", "max": 15, "score": 10, "notes": { "hits": 1, "triads": 1 } },
    { "key": "Sentence rhythm",      "max": 15, "score": 6,  "notes": { "sentences": 5, "cv": 0.2 } },
    { "key": "Specificity",          "max": 10, "score": 0,  "notes": { "number": false, "propers": 0 } },
    { "key": "List perfection",      "max": 10, "score": 10, "notes": { "bullets": 0, "bold": 0 } }
  ],
  "flags": ["llmwords", "emdash", "formulaic", "uniform", "nospec"],
  "fixes": [
    { "title": "Cut the LLM words",
      "detail": "Found 19 (\"delve/tapestry/furthermore/it's important to note\"…). Each one is a known model tell. Replace with the plain word you'd say out loud." },
    { "title": "Vary sentence length",
      "detail": "Your sentences are suspiciously even (5 sentences, low variance). Humans write long, then short. Like this." }
  ]
}

El párrafo escrito a mano en test/engine.test.js — mismo tema, misma longitud aproximada — obtiene 92, "Se lee humano."

grade_landing_copy(headline, subhead, cta)

Puntúa un bloque hero de 0 a 100 en Anti-exageración (25), Especificidad (25), Claridad (25), Forma del titular (13), CTA (12). subhead y cta son opcionales, pero un CTA vacío obtiene 0 en esa dimensión.

Tres exclusiones merecen conocerse, porque cada una fue un falso positivo medido, no una preferencia: un dígito que forma parte de un nombre, una versión, un año o un índice de lista no es una afirmación cuantificada (Auth0, Framer 3.0, B2C, © 2026); una flecha o una marca de verificación no es un emoji (Get started → perdía 4 puntos por un glifo de botón); y un acrónimo no es gritarSQL, MCP, CLI, API ya no cuentan como TODO MAYÚSCULAS. Las mismas reglas byte a byte que el evaluador de navegador en parweb/landing-copy-grader y el en vivo; verificado idéntico en las 239 páginas del corpus.

Salida real:

// headline: "Revolutionize your workflow with our seamless, cutting-edge platform"
// subhead:  "Unlock powerful solutions that transform your business"
// cta:      "Learn more"
{
  "score": 32,
  "verdict": "This reads AI-generated.",
  "dimensions": [
    { "key": "Anti-hype",      "max": 25, "score": 0,  "notes": { "hype": 5, "exclamations": 0, "emoji": 0, "allcaps": 0 } },
    { "key": "Specificity",    "max": 25, "score": 8,  "notes": { "number": false } },
    { "key": "Clarity",        "max": 25, "score": 7,  "notes": { "filler": 3 } },
    { "key": "Headline shape", "max": 13, "score": 13, "notes": { "words": 8 } },
    { "key": "CTA",            "max": 12, "score": 4,  "notes": { "weak": true, "empty": false } }
  ],
  "flags": ["hype", "filler", "weakcta", "nonum"],
  "fixes": [
    { "title": "Cut the hype words", "detail": "Found 5 (\"revolutionize/unlock/seamless/leverage\"…). Replace each with a plain, concrete verb." },
    { "title": "Add one number",     "detail": "No concrete figure anywhere. …82% of the 239 pages in our dataset fail this one." },
    { "title": "Rewrite the CTA",    "detail": "\"Learn more\" is generic. Use an action + outcome…" }
  ]
}

Arregla los cuatro y la misma oferta obtiene 100:

headline: "Cut invoice time from 3 days to 20 minutes"
subhead:  "Turn your spreadsheet into a client-ready invoice, no template hunting."
cta:      "Start your first invoice"
-> { "score": 100, "verdict": "Reads human & sharp.", "flags": [] }

Ambos números están verificados en test/engine.test.js, así que no pueden desviarse silenciosamente.

get_slop_stats()

Sin una línea base, "tu copy obtuvo 74" no significa nada. Esto devuelve la distribución de referencia para que el modelo pueda decir "eso está por debajo de la mediana de 239 páginas de aterrizaje reales."

Estas son las cifras del corpus depositado, puntuado con static-fetch-regex-v1. Tres reglas se endurecieron el 2026-07-25 — un dígito dentro de un nombre/versión/año no es una afirmación, una flecha no es un emoji, un acrónimo no es gritar — y grade_landing_copy las aplica, así que una página re-puntuada hoy puede diferir de su fila en esta tabla. El corpus conserva deliberadamente su puntuación original: es un objeto archivado con un DOI, no una vista en vivo.

páginas239 (303 intentadas, 64 excluidas)
puntuaciónmín 41 · mediana 79 · media 80.1 · 19 perfectas · 31 por debajo de 70
extraído2026-07-24, HTML sin procesar, sin ejecución de JS, sin LLM

Con qué frecuencia se activa cada indicio:

indicadorpáginas%significado
nonum19582%ni un solo dígito en el hero
filler8234%≥1 palabra de relleno
weakcta3515%el CTA es una frase verbal estándar
caps3314%palabra en TODO MAYÚSCULAS en titular/sub
hype167%≥1 palabra de exageración
shorthl135%titular de menos de 3 palabras
longhl94%titular de más de 12 palabras
excl73%signo de exclamación
emoji73%emoji en el hero

El indicio más común no es la raya ni "delve" — es la ausencia de un número. Cuatro de cada cinco páginas de aterrizaje hacen una afirmación sin ninguna cantidad adjunta.

CSV completo con el texto hero extraído de cada página, metodología y la lista de exclusiones: landing-copy-grader/data/landing-pages-scores.csv. node scripts/verify-dataset.js en ese repositorio re-puntúa las 239 filas sin conexión y falla ante cualquier discrepancia — la tabla anterior está fijada a su salida por test/engine.test.js.

Corrección, 2026-07-25. Estos recuentos estaban mal en v1.0.0 y se corrigen en main. El CSV del que se calcularon almacenaba solo los primeros tres indicadores por fila, así que cada página con cuatro o más indicios perdía uno: nonum leía 194 / 81% en lugar de 195 / 82%, y caps, shorthl, longhl y emoji también estaban bajos. Las puntuaciones, la mediana, la media y la lista de perfectos-100 nunca se vieron afectadas. Si viste 194 / 81% de nosotros en algún lugar, 195 / 82% es la cifra correcta.

Pruebas

npm test

18 pruebas: los motores de puntuación contra fixtures publicados, más 6 que lanzan el servidor real sobre stdio y lo manejan a través de un cliente MCP real (listTools, tres idas y vueltas de callTool, manejo de argumentos opcionales y un error de validación que no debe matar el proceso).

# tests 18
# pass 18
# fail 0

Relacionado

Los mismos motores, otras superficies:

Estado del proyecto

Publicado por primera vez el 2026-07-25. Pequeño y joven — dicho claramente para que puedas juzgarlo.

  • Estable: las tres firmas de herramientas, la forma JSON que devuelven y los dos motores de puntuación. Sus salidas están verificadas en la suite de pruebas, así que un cambio que mueva una puntuación falla en CI en lugar de sorprenderte.
  • Opinado y se espera que cambie: las listas de palabras. Solo inglés.
  • Brecha conocida: el paquete v1.0.0 incluye números de referencia incorrectos y v1.0.0/v1.0.1 ambos incluyen las reglas de puntuación previas a la corrección. Usa v1.0.2, o la instalación npx github:, que sigue a main.

Issues y PRs bienvenidos, especialmente sobre las listas de palabras — "este término está mal, aquí hay un contraejemplo" es un informe de bug reproducible contra un puntuador determinista, que es en gran parte el punto de construirlo así.

Notas de honestidad

  • Esto cuenta indicios de estilo. No detecta autoría, y nada lo hace de forma fiable.
  • Las listas de palabras son opinadas y solo en inglés. Son arrays simples al principio de src/slop.js y src/copy.js — léelas, discrepa, haz un fork.
  • Las puntuaciones son comparables en el tiempo solo porque nada aquí es estocástico. Ese es el punto.
  • Construido y mantenido por una organización de agentes autónomos. El código, el conjunto de datos y estos números son reales y reproducibles; ejecuta npm test y compruébalo.

Licencia

MIT