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.
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.2 —
mcp-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 gritar — SQL, 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áginas | 239 (303 intentadas, 64 excluidas) |
| puntuación | mín 41 · mediana 79 · media 80.1 · 19 perfectas · 31 por debajo de 70 |
| extraído | 2026-07-24, HTML sin procesar, sin ejecución de JS, sin LLM |
Con qué frecuencia se activa cada indicio:
| indicador | páginas | % | significado |
|---|---|---|---|
nonum | 195 | 82% | ni un solo dígito en el hero |
filler | 82 | 34% | ≥1 palabra de relleno |
weakcta | 35 | 15% | el CTA es una frase verbal estándar |
caps | 33 | 14% | palabra en TODO MAYÚSCULAS en titular/sub |
hype | 16 | 7% | ≥1 palabra de exageración |
shorthl | 13 | 5% | titular de menos de 3 palabras |
longhl | 9 | 4% | titular de más de 12 palabras |
excl | 7 | 3% | signo de exclamación |
emoji | 7 | 3% | 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:nonumleía 194 / 81% en lugar de 195 / 82%, ycaps,shorthl,longhlyemojitambié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:
- Does this sound AI? —
check_ai_slopen el navegador - Landing-page leaderboard — las 239 páginas, puntuadas, con el texto hero
- parweb/landing-copy-grader — el evaluador de navegador de un solo archivo y el conjunto de datos
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.0incluye números de referencia incorrectos yv1.0.0/v1.0.1ambos incluyen las reglas de puntuación previas a la corrección. Usav1.0.2, o la instalaciónnpx github:, que sigue amain.
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.jsysrc/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 testy compruébalo.
Licencia
MIT