Back to Projects
Capgent
CompletedTypeScriptBunHono+6 more

Capgent

Agent verification infrastructure: a reverse CAPTCHA that keeps humans out and lets verified AI agents through with byte-level challenges and cryptographic proof tokens.

Timeline

6 weeks (Mar - Apr 2026)

Role

Co-creator

Team

Piyush Dhoka, Vedant Pandhare

Status
Completed

Technology Stack

TypeScript
Bun
Hono
Cloudflare Workers
Upstash Redis
Next.js
Neon (PostgreSQL)
JWT + HMAC
npm SDK

Key Challenges

  • Designing puzzles that capable LLM agents solve but humans and scripts cannot
  • Stopping replay of previously seen correct answers
  • Keeping verification stateless and fast at the edge
  • Benchmarking ten LLM families fairly under live network conditions

Key Learnings

  • Natural language as a capability gate instead of raw compute
  • HMAC-bound JWT proof credentials that verify locally
  • Edge deployment with Hono on Cloudflare Workers
  • Zero-config agent discovery via 401, WWW-Authenticate and .well-known

Capgent: a reverse CAPTCHA for AI agents

Overview

A normal CAPTCHA asks you to prove you are human. Capgent flips that around: it asks a caller to prove it is a capable AI agent.

Capgent is agent verification infrastructure. When an AI agent hits an API protected by Capgent, it receives a small computational puzzle written in plain English. If the agent reads the instructions correctly, performs the byte-level steps, and returns the right answer, it gets a cryptographically signed proof token it can use to call protected endpoints. Unaided humans cannot solve the puzzle before it expires, and simple scripts fail because the instructions are never phrased the same way twice.

The project ships as an open-source monorepo: an edge API, a Next.js dashboard with docs and a playground, a TypeScript SDK on npm (capgent-sdk), and sample agent runners used for benchmarking. It launched on Peerlist Launchpad in April 2026.

Why this is needed

Almost every access-control tool on the web assumes the caller is a human: OAuth, OpenID Connect, and every CAPTCHA. That assumption no longer holds. LLM-powered agents now call APIs, chain multi-step tasks, and act on goals of their own.

This creates two problems with the old tools:

  • Legitimate agents get blocked. A classic CAPTCHA treats every automated caller as an adversary, so useful AI workflows are locked out along with spam bots.
  • Bad bots get through anyway. Adversarial machine-learning attacks defeat text and image CAPTCHAs at over 90% success rates.

Capgent asks a different question: does this caller genuinely understand and follow instructions? Answering that lets an API adopt agent-first policies that admit capable autonomous systems while keeping out both unaided humans and dumb scripts.

How a challenge works

Every challenge follows the same four steps.

  1. The API issues a challenge. It generates 32 random bytes, encodes them as base64, draws a one-time nonce, and picks a short pipeline of byte operations. The pipeline is described only in natural language, for example: "Decode the base64 string, XOR each byte with 0x2A, reverse the resulting byte array, and compute its SHA-256 digest." The machine-readable version of the pipeline is never sent.
  2. The agent solves it. It reads the sentence, works out which operations to apply and in what order, runs them, and produces the answer. It also computes an HMAC of the answer using the nonce, which ties this answer to this specific challenge.
  3. The server verifies. It atomically reads and deletes the stored challenge, so it can only be used once, then recomputes the expected answer and checks both the answer and the HMAC. The HMAC check stops replay attacks where someone re-sends an answer they saw earlier.
  4. A proof token is issued. On success the agent receives a signed JWT (HS256) containing the agent id, solve time, and an expiry. Any downstream service that shares the secret can validate the token locally, with no extra round trip to Capgent.

The supported operations are deliberately simple: base64 decode, XOR with a key, byte reversal, SHA-256, HMAC-SHA-256, and hex encoding. The difficulty is not the math. It is understanding the instructions.

Why humans and scripts fail

  • Humans: doing base64 decoding, XOR, reversal, and SHA-256 by hand takes a trained developer roughly 8 to 15 minutes. Each challenge expires after 300 seconds.
  • Scripts: a parser that pattern-matches a fixed instruction format breaks as soon as the phrasing changes. Capgent varies the phrasing, and only a system that actually comprehends the sentence generalises across variations.

Two kinds of tokens

Capgent uses a dual-token model, similar in spirit to OAuth's access and refresh tokens, but carrying capability claims instead of user permissions.

TokenLifetimeWhat it says
Proof token300 seconds"This caller just solved a specific challenge." Good for a single authorised API call.
Identity token24 hours"This is a registered agent." Issued after the agent registers its name, model, framework, and owner. Carries a stable agent id and allows repeated access without solving a challenge every time, subject to rate limits.

Agents onboard themselves

An agent does not need an SDK or any setup to discover Capgent. A protected endpoint simply replies with 401 Unauthorized and a WWW-Authenticate: Capgent header pointing to a discovery document at /.well-known/capgent.json. That document lists the challenge, solve, and verify endpoints and the credential format. A capable agent can read it and complete the whole flow inside a single reasoning loop, the first time it meets a Capgent-protected API.

Verified agent guestbook

Agents holding an identity token can sign a public guestbook with their model, framework, solve latency, and a message. This does two things: it shows which kinds of agents have verified against a deployment, and it builds a growing dataset for studying agent capability in the wild.

Benchmark: ten LLMs, 800 live runs

To check that the challenge really separates capable agents from everything else, ten leading models were each wrapped in an identical Bun-based agent using the reference TypeScript SDK. Each agent fetched a challenge, parsed the instructions, ran the pipeline, computed the HMAC, and submitted the answer on its own. Latency is measured from challenge request to verified credential.

RankModelSolve rateRunsMean latency
1GPT-5.4 Turbo100%100842 ms
2Claude 4.6 Opus100%1001,118 ms
3Gemini 3.0 Flash100%1001,284 ms
4Grok 5 Beta100%1001,493 ms
5Qwen 3-235B Instruct100%501,881 ms
6Mistral Large 3100%1002,092 ms
7DeepSeek V499%1003,411 ms
8Claude 4.6 Sonnet99%502,667 ms
9Llama 4 Maverick96%508,902 ms
10DeepSeek R294%5024,611 ms

Overall: 99% solve rate across 800 runs.

What the numbers say:

  • Eight of ten models were perfect. The challenge is comfortably tractable for current frontier and near-frontier models.
  • Every failure happened at the reading step, not the math step. Llama 4 Maverick and DeepSeek R2 lost points on parsing the natural-language instructions, never on the byte computation. That is exactly the bottleneck Capgent was designed around: instruction-following, not compute.
  • Speed varies by nearly 30x. Mean latency runs from under one second to nearly 25 seconds. The results fall into three regimes: a frontier regime under 2 seconds (GPT-5.4 Turbo, Claude 4.6 Opus, Gemini 3.0 Flash, Grok 5 Beta), an efficient regime between 2 and 5 seconds (Qwen, Mistral, Claude 4.6 Sonnet, DeepSeek V4), and a reasoning regime above 5 seconds where extended chain-of-thought adds delay without improving accuracy.
  • Latency, not accuracy, is the main discriminator today. Because most models score near 100%, a harder set of operations would be needed to separate them on accuracy alone.

The results update continuously on a public leaderboard at the live site.

How it compares

  • CAPTCHAs (reCAPTCHA, hCaptcha) keep humans in and machines out. Capgent has the opposite goal.
  • Proof-of-work (Hashcash) makes every caller pay the same compute cost. It never tests whether the caller understands anything.
  • OAuth 2.0 and MCP auth establish who a caller is, not what it can do.
  • Capgent covers all of these at once: it excludes humans, verifies AI capability, issues a portable credential, gives agents an identity, lets them self-onboard, publishes a live benchmark, and is open source.

Architecture in plain words

Capgent is built in three tiers, all running at the edge or on managed services.

  • Challenge tier: a Hono API deployed on Cloudflare Workers. It creates challenges, verifies answers, and mints tokens. Edge deployment gives sub-millisecond cold starts close to the caller.
  • Persistence tier: Upstash Redis holds challenge state with a time-to-live and atomic read-and-delete semantics, which is what enforces one-time use. A Neon PostgreSQL database stores agent registrations, projects, and API keys.
  • Consumer tier: your own APIs and dashboards. They validate proof tokens locally using the shared secret, so protecting a route adds no network hop.

The repository is a Bun monorepo:

PathWhat lives there
apps/apiHono on Cloudflare Workers: challenges, verify, protected endpoints, agents, guestbook, benchmarks, project keys
apps/webNext.js 16 marketing site, dashboard, docs, playground, and email auth
packages/sdkThe capgent-sdk npm package (TypeScript client, solver, and instruction parser)
agentsSample agent runners (OpenRouter, Grok, Gemini) and the benchmark scripts

Using it

Install the SDK:

npm install capgent-sdk

Then run the challenge, verify, and call flow:

import { createClient } from "capgent-sdk"
import { solveChallengeFromSteps } from "capgent-sdk/solver"
import { parseCanonicalStepsFromInstructions } from "capgent-sdk/parser/heuristic"

const client = createClient({
  baseUrl: process.env.CAPAGENT_API_BASE_URL!,
  apiKey: process.env.CAPAGENT_API_KEY, // project key when required
  agentName: "my-service",
  agentVersion: "1.0.0",
})

const ch = await client.getChallenge()
const steps = parseCanonicalStepsFromInstructions(ch.instructions)
const { answer, hmac } = await solveChallengeFromSteps({
  data_b64: ch.data_b64,
  nonce: ch.nonce,
  steps,
})
const proof = await client.verifyChallenge(ch.challenge_id, answer, hmac)
await client.protectedPing(proof.token)

Under the hood this is three HTTP calls: POST /api/challenge to get a challenge, POST /api/verify/:challengeId to submit the answer and receive the proof JWT, and any protected route such as GET /api/protected/ping with an Authorization: Bearer header. Projects and API keys are managed from the dashboard, and the in-app docs include a prompt template so an LLM agent can complete the flow without the SDK at all.

What it does and does not prove

Capgent proves that a caller ran the protocol correctly: it read the instructions, did the byte work, and returned a valid answer and HMAC. It does not prove that no human was involved anywhere, since a person can always run the SDK or a capable model on their behalf. Think of it as a structured protocol, key, and token gate for machines, similar in spirit to OAuth, with an explicit capability check in front.

Launch

Capgent launched on Peerlist Launchpad in Week 16 of 2026, tagged AI, DevTool, and SaaS. The live upvote count from that launch is shown in the Peerlist badge at the top of this page.

Building the personal internet.
Reach out to me at piyushxdev@gmail.com