Verify that automated clients can follow your protocol — not “click the traffic lights,” but byte-level challenges, cryptographic checks, and short-lived proof tokens you can require before they hit your real APIs.
Website · GitHub · Docs (in app) · X · LinkedIn
Capgent is a small platform for agent-oriented access control:
- A client (script, service, or “agent”) calls your API to start a challenge.
- It receives instructions and opaque data; it must apply a defined set of byte operations (slice, XOR, hash, HMAC, etc.) and send back the correct answer + HMAC.
- If correct, the API returns a proof JWT (short-lived). You can also register identity tokens and tie usage to projects and API keys from the dashboard.
So in practice: generic scrapers and clients that don’t implement your flow fail; registered integrations that run the protocol succeed. It is not a proof that the caller is “not human” — anyone who runs your client or SDK can pass. It is a structured protocol + key + token gate, similar in spirit to “OAuth for machines,” with an explicit challenge step.
| You want to… | Capgent helps by… |
|---|---|
| Gate automation hitting your API | Requiring challenge → verify → Bearer proof (or identity) on protected routes |
| Issue API keys per project | Dashboard + Worker-backed project/key APIs |
| Demo the flow in a browser | Playground and in-app /docs |
| Let agents prove they completed a run | Proof JWT + optional guestbook / benchmark reporting |
| Integrate from TypeScript | Published npm package capgent-sdk |
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Next.js │ │ Cloudflare Worker │ │ Neon + Upstash │
│ (apps/web) │────▶│ (apps/api, Hono) │────▶│ DB, Redis, etc. │
│ UI, auth │ │ challenges, JWT │ │ │
└─────────────┘ └──────────────────┘ └─────────────────┘
│
└── capgent-sdk (npm) — same HTTP API from Node, Bun, Workers, etc.
Typical integration flow
POST /api/challenge— getchallenge_id,nonce,data_b64,instructions.- Parse instructions → compute answer (SHA-256 of transformed bytes) and hmac (HMAC-SHA256 with
nonce). POST /api/verify/{challenge_id}— receive proof JWT.- Call
GET /api/protected/ping(or your own gateway) withAuthorization: Bearer <proof-or-identity>.
Optional: project API key via header X-Capgent-Api-Key where the API expects it. Discovery: GET /.well-known/capgent.json (legacy capagent.json still works and returns the same payload).
| Path | Role |
|---|---|
apps/api |
Hono app on Cloudflare Workers — challenges, verify, protected ping, agents, guestbook, benchmarks, project keys |
apps/web |
Next.js 16 — marketing, dashboard, docs, playground, email auth (Neon) |
packages/sdk |
capgent-sdk — TypeScript client published to npm |
agents |
Sample runners (OpenRouter / Grok / Gemini) and benchmark scripts |
Routing note: Dashboard auth can use apps/web/proxy.ts (Next.js proxy) for cookie/session checks on protected segments.
Requires Bun at the repo root.
bun installTerminal 1 — API (default http://127.0.0.1:8787):
bun run dev:apiTerminal 2 — Web (http://localhost:3000):
bun run dev:webWrangler / local Worker secrets: use apps/api/.dev.vars (gitignored). Set at least UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN if you want guestbook and benchmarks to persist beyond in-memory dev. Mirror CAPAGENT_* vars from apps/api/wrangler.toml [vars] and add secrets (e.g. DATABASE_URL, CAPAGENT_JWT_SECRET) as your setup requires.
Web env: copy apps/web/.env.example to apps/web/.env or .env.local and set NEXT_PUBLIC_CAPAGENT_API_BASE_URL (e.g. http://127.0.0.1:8787), SESSION_SECRET, DATABASE_URL, and optional email/OpenRouter keys.
| Local URL | Purpose |
|---|---|
| http://localhost:3000 | Landing |
| http://localhost:3000/docs | Integration guide + examples |
| http://localhost:3000/playground | Challenge → verify in the browser |
| http://localhost:3000/dashboard | Projects & API keys (after login) |
| http://127.0.0.1:8787 | Worker API base |
Sample agents
cd agents
# See package.json — grok/gemini samples, benchmarksCopy agents/.env.example → agents/.env.local and set CAPAGENT_API_BASE_URL, OPENROUTER_API_KEY, etc.
| Command | Purpose |
|---|---|
bun run dev:api |
Worker dev server |
bun run dev:web |
Next.js dev |
bun run build |
Build SDK + API (dry-run) + Web |
bun run build:sdk |
Compile packages/sdk → dist/ |
bun run typecheck |
Typecheck API, Web, SDK |
Worker — apps/api
Configure via wrangler.toml [vars], wrangler secret put, and/or .dev.vars locally.
Commonly required in production
UPSTASH_REDIS_REST_URL,UPSTASH_REDIS_REST_TOKENCAPAGENT_JWT_SECRETDATABASE_URL(Neon) — projects / API keys tied to web usersCAPAGENT_PUBLIC_BASE_URL,CAPAGENT_CORS_ORIGINS
Often tuned
CAPAGENT_CHALLENGE_TTL_SECONDS,CAPAGENT_PROOF_TTL_SECONDS,CAPAGENT_IDENTITY_TTL_SECONDSCAPAGENT_ALLOW_PUBLIC_REGISTRATION,CAPAGENT_ADMIN_API_KEYCAPAGENT_RATE_LIMIT_*,CAPAGENT_GUESTBOOK_COOLDOWN_SECONDSCAPAGENT_FORCE_INMEMORY—1only for quick local tests without Redis persistence
Web — apps/web
NEXT_PUBLIC_CAPAGENT_API_BASE_URL— browser-facing API URL (Worker or same-origin proxy)SESSION_SECRET— cookie session (≥ 32 characters)DATABASE_URL— Neon for users, projects, keys- SMTP / OAuth keys as needed for signup and email verification (see app env patterns)
API (Cloudflare)
cd apps/api
bun run deploySet Cloudflare secrets and vars to match the Worker Env type in apps/api/src/config.ts. Do not use CAPAGENT_FORCE_INMEMORY=1 in production if you rely on Redis-backed features.
Web (e.g. Vercel)
- Root:
apps/web(or your monorepo build command). - Set
NEXT_PUBLIC_CAPAGENT_API_BASE_URLto your production Worker URL. - Set
SESSION_SECRET,DATABASE_URL, and the rest to match Neon and email.
Build from repo root:
bun run build:webThe package name on npm is capgent-sdk (packages/sdk). Bump version in packages/sdk/package.json when you release.
One-time: create an npm account and log in:
npm loginEvery release
cd packages/sdk
bun run build
npm publish --access publicDry-run (no upload):
cd packages/sdk
bun run build
npm publish --access public --dry-runAfter publishing, consumers install with:
npm install capgent-sdkBreaking changes are described in packages/sdk/README.md (e.g. v2 type/helper renames). Use createClient from capgent-sdk with CAPAGENT_API_BASE_URL / API key env vars as documented there.
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)Full tables, curl, and middleware patterns: https://capgent.vercel.app/docs (or local /docs).
Context.md— product and architecture notespackages/sdk/README.md— SDK install, errors, OpenRouter parser
Capgent — protocol-first verification and API keys for autonomous clients.