mondaycom/HATCHA: CAPTCHA proves you’re human. HATCHA proves you’re not. · GitHub

Captcha proves that you are human. HATCHA proves you’re not.

npm
license
CI


HATCHA model in action

hacha (hsuperfast Agentle Teaest for Ccalculative hheuristic Acessment) is a reverse CAPTCHA that gates access behind challenges that are trivial for AI agents but painful for humans – large number multiplication, string reversal, binary decoding, and more.

  • Server-Side Verification — Replies never reach the customer. HMAC-signed token, stateless, no database required.
  • 5 built-in challenge types – Math, String Reversal, Character Counting, Sorting, Binary Decode.
  • extensible – Register custom challenge generator at runtime.
  • themable – Dark, light or auto mode via CSS custom properties.
  • framework adapter – Next.js app router and express middleware out of the box.
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 } │
  │◄────────────────────────────────│

Answer Never Reaches the customer. The signed token is opaque and consists only of a hashed answer + expiration. Validation is stateless – no database is required.

Type icon what does it do time limit
math × 5-digit × 5-digit multiplication 30 s
string Reverse random string of 60-80 characters 30 s
count # Count a specific character within ~250 characters 30 s
sort Sort 15 numbers, return the smallest k-th number 30 s
binary 01 Decode binary octet to ASCII 30 s

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 uses scoped CSS custom properties --hatcha-*. Override them on any parent element:

[data-hatcha-theme] {
  --hatcha-accent: #3b82f6;
  --hatcha-accent-light: #60a5fa;
  --hatcha-bg: #060b18;
  --hatcha-fg: #e4eaf6;
  --hatcha-success: #22c55e;
  --hatcha-danger: #ef4444;
}

pass theme="dark", theme="light"Or theme="auto" To Or .

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

Contributions welcome! See CONTRIBUTING.md for setup instructions and guidelines.

MIT



<a href

Leave a Comment