
CAPTCHA demuestra que eres humano. HATCHA demuestra que no.
CAPTCHA demuestra que eres humano. HATCHA demuestra que no lo eres.
HATCHA (Hyperfast Agent Test for Computational Heuristic Assessment) es un CAPTCHA inverso que restringe el acceso mediante desafíos triviales para agentes de IA pero tediosos para humanos: multiplicación de números grandes, inversión de cadenas, decodificación binaria y más.
npm install @mondaycom/hatcha-react @mondaycom/hatcha-server
// app/api/hatcha/[...hatcha]/route.ts
import { createHatchaHandler } from "@mondaycom/hatcha-server/nextjs";
const handler = createHatchaHandler({
secret: process.env.HATCHA_SECRET!,
});
export const GET = handler;
export const POST = handler;
// app/layout.tsx
import { HatchaProvider } from "@mondaycom/hatcha-react";
import "@mondaycom/hatcha-react/styles.css";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<HatchaProvider>{children}</HatchaProvider>
</body>
</html>
);
}
"use client";
import { useHatcha } from "@mondaycom/hatcha-react";
function AgentModeButton() {
const { requestVerification } = useHatcha();
return (
<button
onClick={() =>
requestVerification((token) => {
console.log("Agent verified!", token);
})
}
>
Enter Agent Mode
</button>
);
}
# .env.local
HATCHA_SECRET=your-random-secret-here
Client Server
│ │
│ GET /api/hatcha/challenge │
│────────────────────────────────►│
│ │ Generate challenge
│ │ Hash answer
│ │ HMAC-sign { hash, expiry }
│ { challenge (no answer), token }
│◄────────────────────────────────│
│ │
│ Agent solves the challenge │
│ │
│ POST /api/hatcha/verify │
│ { answer, token } │
│────────────────────────────────►│
│ │ Verify HMAC signature
│ │ Check expiry
│ │ Compare answer hash
│ { success, verificationToken } │
│◄────────────────────────────────│
La respuesta nunca llega al cliente. El token firmado es opaco y contiene solo una respuesta hash + fecha de expiración. La verificación no tiene estado — no necesita base de datos.
import { registerChallenge } from "@mondaycom/hatcha-server";
registerChallenge({
type: "hex",
generate() {
const n = Math.floor(Math.random() * 0xffffff);
return {
display: {
type: "hex",
icon: "0x",
title: "Hex Decode",
description: "Convert this hex number to decimal.",
prompt: `0x${n.toString(16).toUpperCase()}`,
timeLimit: 30,
answer: String(n),
},
answer: String(n),
};
},
});
HATCHA utiliza propiedades personalizadas CSS con ámbito bajo --hatcha-*. Sobrescríbelas en cualquier elemento padre:
[data-hatcha-theme] {
--hatcha-accent: #3b82f6;
--hatcha-accent-light: #60a5fa;
--hatcha-bg: #060b18;
--hatcha-fg: #e4eaf6;
--hatcha-success: #22c55e;
--hatcha-danger: #ef4444;
}
Pasa theme="dark", theme="light" o theme="auto" a <HatchaProvider> o <Hatcha>.
import express from "express";
import { hatchaRouter } from "@mondaycom/hatcha-server/express";
const app = express();
app.use(express.json());
app.use("/api/hatcha", hatchaRouter({ secret: process.env.HATCHA_SECRET! }));
app.listen(3000);
git clone https://github.com/mondaycom/HATCHA.git
cd HATCHA
pnpm install
pnpm build
cd examples/nextjs-app
pnpm dev
¡Las contribuciones son bienvenidas! Consulta CONTRIBUTING.md para instrucciones de configuración y pautas.
| Tipo | Icono | Qué hace | Límite de tiempo |
|---|
math | × | Multiplicación de 5 dígitos × 5 dígitos | 30 s |
string | ↔ | Invertir una cadena aleatoria de 60–80 caracteres | 30 s |
count | # | Contar un carácter específico en ~250 caracteres | 30 s |
sort | ⇅ | Ordenar 15 números, devolver el k-ésimo más pequeño | 30 s |
binary | 01 | Decodificar octetos binarios a ASCII | 30 s |
@mondaycom/hatcha-core| Generación de desafíos y verificación criptográfica |
@mondaycom/hatcha-react | Componente React, proveedor y estilos |
@mondaycom/hatcha-server | Manejadores de servidor para Next.js y Express |