Open-source, self-hosted autonomous AI recruiting agent. Sources, engages, vets, and books meetings with engineering candidates — fully autonomously. Bring your own API keys, run it anywhere.
- AI-personalized email outreach (OpenAI + Resend)
- Conversational voice calls (Gemini Live + Twilio)
- Autonomous interview booking (Google Calendar + Meet)
- Unified talent pool, Kanban pipeline, agent activity log
- No SaaS, no subscriptions, no success fees
📺 60-second walkthrough: see
docs/assets/walkthrough-script.mdfor the recording script — embed the recorded video here once captured.
Full docs live in docs/ and are also browsable inside the running app at /docs.
- Quickstart · Self-hosting · Configuration
- Architecture · Agent Behavior
- Integrations: OpenAI · Gemini · Twilio · Resend · Google Calendar · Hunter.io
- Troubleshooting · FAQ
Requires Docker 24+ and Docker Compose v2.
git clone <your-fork-url> sudohired
cd sudohired
cp .env.example .env
# (optional) edit .env to add your OpenAI / Twilio / Resend / etc. keys
docker compose up --buildOpen http://localhost:5000. The first account you sign up becomes the admin.
To stop: docker compose down. To wipe data: docker compose down -v.
Requires Node.js 20+ and a running PostgreSQL 14+ instance.
git clone <your-fork-url> sudohired
cd sudohired
cp .env.example .env
# Edit .env: set DATABASE_URL and SESSION_SECRET at minimum
npm install
npm run db:push # creates / updates tables in your Postgres
npm run dev # starts on http://localhost:5000For production, use npm run build && npm start.
Sudohired supports three sign-in backends, selected at startup via LOCAL_AUTH:
LOCAL_AUTH |
When to use it | How it works |
|---|---|---|
password |
Self-hosted on a laptop, VPS, or your own server | Built-in email + password. The very first signup becomes the admin. |
dev |
Local development | No login screen — every request is auto-attached to a single local admin user. Never use in production. |
replit |
Deploying on Replit | Uses Replit's OpenID Connect (requires REPL_ID). |
If LOCAL_AUTH is not set, Sudohired defaults to replit when REPL_ID is present and dev otherwise.
The full list lives in .env.example. The essentials:
| Variable | Required? | Purpose |
|---|---|---|
DATABASE_URL |
✅ | Postgres connection string |
SESSION_SECRET |
✅ (prod) | Random string used to sign session cookies |
LOCAL_AUTH |
– | password | dev | replit (see above) |
PORT |
– | HTTP port (default 5000) |
SESSION_COOKIE_SECURE |
– | Set to true to require HTTPS cookies |
OPENAI_API_KEY |
– | Email generation |
GEMINI_API_KEY |
– | Conversational voice |
TWILIO_ACCOUNT_SID / TWILIO_AUTH_TOKEN / TWILIO_PHONE_NUMBER |
– | Voice + SMS |
RESEND_API_KEY / RESEND_FROM_EMAIL |
– | Outbound email delivery |
HUNTER_API_KEY |
– | Email enrichment |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / GOOGLE_REFRESH_TOKEN / GOOGLE_CALENDAR_ID |
– | Calendar + Meet |
PUBLIC_BASE_URL |
– | Public HTTPS URL of this deployment, required for Twilio voice/SMS callbacks |
All integration keys are optional — the corresponding feature is disabled when its keys are missing.
Replit-only vars. When deployed on Replit, the platform also injects
REPL_ID,ISSUER_URL,REPLIT_DOMAINS,REPLIT_DEV_DOMAIN,REPLIT_CONNECTORS_HOSTNAME, andREPL_IDENTITY/WEB_REPL_RENEWAL. These powerLOCAL_AUTH=replitand the Replit-hosted Resend / Twilio / Google Calendar connectors. Do not set them yourself when self-hosting — use the standard provider keys above instead.
Admin bootstrap in
LOCAL_AUTH=passwordmode. The very first account created on an empty database becomes the admin. If you switch an existing database fromreplit/devtopasswordmode and users already exist, no signup is auto-promoted; promote one manually withUPDATE users SET role='admin' WHERE email='you@example.com';.
- Install Docker + Docker Compose on your server.
git clonethis repo andcp .env.example .env.- Set
SESSION_SECRETto a long random value, setLOCAL_AUTH=password, and add any integration keys you have. - Put a TLS-terminating reverse proxy (Caddy, Nginx, Traefik) in front of port
5000and setSESSION_COOKIE_SECURE=true. docker compose up -d --build.
Database, schema migration, and the app process are all handled by the compose stack.
flowchart LR
subgraph Client
UI[React + Vite SPA]
end
subgraph Server[Node.js / Express]
API[REST API + /api/docs]
WS[/media-stream WebSocket/]
AGENT[Agent worker loop]
QUEUE[(agent_jobs queue)]
end
subgraph DB[(PostgreSQL)]
SCHEMA[users · job_searches · candidates · agent_logs · meetings · …]
end
subgraph External[External services bring-your-own-key]
OPENAI[OpenAI]
GEMINI[Gemini Live]
TWILIO[Twilio]
RESEND[Resend]
GCAL[Google Calendar]
HUNTER[Hunter.io]
end
UI -->|HTTPS| API
API --> SCHEMA
AGENT --> QUEUE
QUEUE --> SCHEMA
AGENT --> OPENAI
AGENT --> RESEND
AGENT --> TWILIO
AGENT --> HUNTER
AGENT --> GCAL
TWILIO -->|audio| WS
WS --> GEMINI
A PNG fallback lives at docs/assets/architecture.png; regeneration instructions are in docs/assets/architecture.md.
![]() |
![]() |
| Dashboard — campaign summary, KPIs, active searches | Talent Pool — unified, filterable, bulk actions |
![]() |
![]() |
| Activity — every agent action, in real time | Setup wizard — keys + live connection probes |
Screenshots live in
docs/screenshots/. Replace the placeholders by capturing your own and saving with the same filenames.
Pull requests, bug reports, and feature ideas are very welcome. Read CONTRIBUTING.md and our CODE_OF_CONDUCT.md before opening a PR.
client/ React + Vite frontend
server/ Express + Drizzle backend
auth/ Pluggable auth backends (replit | password | dev)
shared/ Shared Zod / Drizzle schema
db/ Drizzle Postgres connection
docker/ Container entrypoint
See replit.md for a deeper architecture overview.
MIT — see LICENSE.



