Repository navigation
Releases: Kandid-ai/AgentSDR
Release list
AgentSDR 0.3.1
Install
mkdir agentsdr && cd agentsdr
curl -O https://raw.githubusercontent.com/Kandid-ai/AgentSDR/main/docker-compose.yml
docker compose up -dImage: ghcr.io/kandid-ai/agentsdr:0.3.1
Fixed
docker-compose.ymlnames its release's image (0.3.1) instead of
latest. A server that had pulled an earlierlatestkept running it with
the new file: 0.2.0's image does not create the schema, so every query
failed withrelation … does not exist. Upgrade by downloading the new
file;AGENTSDR_VERSIONstill overrides the tag.- First-run setup no longer loops. On a fresh install the page bounced
between/sign-inand/setupforever: the signed-in frame wrapped
/setupand sent the session-less visitor to sign-in, which sent them back. - A rejected database password is explained at startup: the bundled
database keeps the password its volume was first created with, and the log
now says so, with the two ways out.
AgentSDR 0.3.0
Install
mkdir agentsdr && cd agentsdr
curl -O https://raw.githubusercontent.com/Kandid-ai/AgentSDR/main/docker-compose.yml
docker compose up -dThen open http://localhost:3000 and create your admin account. Guide: https://docs.agentsdr.ai/self-hosting/docker-compose
Image: ghcr.io/kandid-ai/agentsdr:0.3.0
Changed
- Scheduled jobs run inside the app. There is no cron container any more:
Docker Compose is two containers,dbandapp. The jobs run in
production only (never inDEMO_MODE);INTERNAL_SCHEDULER=falseturns
them off for an external cron, which calls the endpoints as before. - Database schema is created when the app starts. The image creates it in
an empty database before the server starts (there is no setup container). An
existing database is only read, never changed. If this step fails the app
does not start;AGENTSDR_SKIP_DB_SETUP=trueskips it. - The daily rollover is per organization. Each organization's email send
queues, Gmail push watch renewal and LinkedIn daily-limit reset run at the
start of its own day, set in Settings, Organization, Defaults (Time zone,
defaultUTC, and New day starts at, default00:00). The first-run
setup page stores the browser's time zone for the first organization. - LinkedIn outreach now runs every 30 minutes, and the LinkedIn webhook replay
every 10. The LinkedIn search queue is no longer scheduled: it runs when
someone clicks Run. CRON_SECRETandOUTREACH_TICK_SECRETare optional: they are only needed
to call the job endpoints from outside, and are no longer in
docker-compose.yml. Unset, the endpoints refuse every secret call.- The job endpoints skip work the in-app scheduler already did (organizations
whose rollover ran today; a slot that already ran).?force=1skips that
check.
Fixed
- LinkedIn job logs: concurrent jobs no longer leave the console patched, so
later lines landed in an old run's log. Log capture is now per run
(AsyncLocalStorage).
Migrations
bun scripts/create-scheduled-job-runs.tscreatesscheduled_job_runs,
where each scheduled run is claimed. With Docker Compose:
docker compose exec app agentsdr-entrypoint bun scripts/create-scheduled-job-runs.ts.
A fresh install gets the table automatically. Until the migration runs, no
scheduled jobs run in-process (the app logs a
[scheduler] Table scheduled_job_runs is missingwarning); the endpoints
keep working.
Upgrading a Docker Compose install from 0.2.0:
- Replace
docker-compose.ymlwith the new one. docker compose up -d --remove-orphans(removes the oldsetupandcron
containers).- Run the migration above.
On Dokploy, nothing needs creating or scheduling any more; existing Schedule
Jobs are harmless and can be deleted. Keep CRON_SECRET and
OUTREACH_TICK_SECRET only if you keep calling the endpoints.
AgentSDR 0.2.0
Install
mkdir agentsdr && cd agentsdr
curl -O https://raw.githubusercontent.com/Kandid-ai/AgentSDR/main/docker-compose.yml
docker compose up -dThen open http://localhost:3000 and create your admin account. Guide: https://docs.agentsdr.ai/self-hosting/docker-compose
Image: ghcr.io/kandid-ai/agentsdr:0.2.0
Upgrading a Docker Compose install from 0.1.0 (breaking): the new
docker-compose.yml no longer loads your whole .env into the containers;
it passes only the settings it lists by name. Before docker compose up -d:
- Add
APP_URL=<your public address>to.env. It replaces
BETTER_AUTH_URL/NEXT_PUBLIC_APP_URL, which the new file does not
read. Without it the app assumeshttp://localhost:3000. - Keep
POSTGRES_PASSWORD,BETTER_AUTH_SECRET,
INTEGRATION_CREDENTIALS_KEY,UNSUBSCRIBE_SECRET,CRON_SECRETand
OUTREACH_TICK_SECRETin.envexactly as they are. - Any other variable you relied on (a
PAUSE_*switch, worker tuning,
Apollo) must be added to theenvironmentblock ofdocker-compose.yml.
Added
- First-run setup page. On a fresh install every visitor is sent to
/setup: one form (name, organization, email, password) creates the first
admin, already verified, and their organization, then signs them in. No
email service is needed to get started. The page closes for good once an
account exists. - Copy-and-run Docker Compose.
docker-compose.ymlruns the published
image (ghcr.io/kandid-ai/agentsdr), with no repository checkout and no
files to mount. Every setting is listed by name in the file; the ones to
replace are marked# CHANGEMEand can be edited in place or set in a
.env. It starts as-is onlocalhost; on any otherAPP_URLit refuses
to start while a secret still has its placeholder. The scheduler runs from
the same image.docker-compose.build.ymlbuilds from source instead.
The Docker guide is rewritten as numbered steps. - Public demo.
DEMO_MODE=trueturns a separate deployment into a
read-only AgentSDR anyone can open without signing in, and
bun run db:seed:demonow fills it with Northwind, a fictional company's
three months of email, LinkedIn and WhatsApp outbound, calls with
transcripts, a full CRM pipeline with AI drafts awaiting review, Tables and
Analytics. See docs/self-hosting/demo.mdx.
Changed
- License: MIT (was AGPL-3.0-only). Anyone may use, modify, self-host,
distribute and sell AgentSDR, including in closed-source products and
hosted services, as long as the copyright and license notice is kept. - Email recipients: inbound Gmail keeps every To and Cc, replies can go
to all, and a colleague's reply joins the lead's thread.
scripts/backfill-email-recipients.ts(optional, dry run by default)
restores recipients on messages stored before. - Tables: about 70 fixes across columns, AI and enrichment runs and the
grid. - The app is only the app. The marketing website, blog theme and launch
film moved to their own repository (agentsdr.ai)./now opens the
workspace (sign-in first), and the app asks search engines not to index it. - Call recorder 0.15.0: the built-in hosted address is now
https://app.agentsdr.ai. Self-hosted addresses are still added on the
extension's Options page.
AgentSDR 0.1.0
The first public release of AgentSDR, the open-source AI SDR: email sequences, LinkedIn and WhatsApp outreach, enrichment tables, and an AI CRM that classifies every reply and drafts the answer. Self-hosted, with your own AI key.
Get started
git clone https://github.com/Kandid-ai/AgentSDR.git && cd AgentSDR
cp .env.example .env # fill in the required values
docker compose up -dOr pull the image: docker pull ghcr.io/kandid-ai/agentsdr:0.1.0. The full guide is in docs/self-hosting.md; the website is agentsdr.ai.
Upgrading an existing install
Fresh installs need nothing beyond the steps above. Installations that ran before this release must apply the migrations listed at the end of these notes, in order.
What's in 0.1.0
Added
- Accounts, organizations and teams with Better Auth: email and
password sign-up with verification, Google sign-in, password reset,
invitations, owner / admin / member roles, an organization switcher.
Sign-up is invite-only by default (AUTH_SIGNUP=openopens it); the first
account on a fresh install can always be created. - Multi-tenancy: every record belongs to an organization; an isolation
test suite (scripts/e2e/tenancy-isolation.ts) proves one organization
cannot see, change or count another's data. - Per-organization integrations configured in Settings — Unipile
(LinkedIn and WhatsApp), Google Workspace (Gmail), Cloudflare R2,
OpenRouter — with credentials encrypted at rest. - Lead database with custom fields, email outreach with sequences and
mailbox rotation, LinkedIn campaigns and search, WhatsApp messaging and
recorded calls, an AI-assisted CRM inbox with reply classification and
drafted responses, Tables with enrichment providers. - Fresh installs:
bun run db:setupcreates the schema in an empty
database fromdb/schema.sql;bun run db:seed:demoadds a demo
organization with fictional data. - Unipile webhooks register themselves: saving the Unipile integration
registers the LinkedIn and WhatsApp webhooks in your Unipile workspace,
each carrying your organization and a generated secret. - Settings by channel: Email, LinkedIn and WhatsApp each have their
accounts, their Connection (the integration they run on) and their
Sending rules — the limits that used to be hardcoded (emails a day and
the gap between them, sending hours, LinkedIn invitations a day and per run,
delays, search leads a day, WhatsApp warm-up, new chats a day, seconds
between sends) — with today's values as defaults, hard ceilings and a
warning past the safe edge. A LinkedIn account or WhatsApp number can set
its own daily limit; the default phone country is per organization.
/settings/integrationsredirects to the new pages. - Call recorder Options page: add your own AgentSDR address in the
extension; a self-hosted deployment no longer needs its own build. - Docker Compose self-hosting, CI, and the project's community documents,
including responsible use. - Public website at agentsdr.ai: product pages for
each channel, the AI CRM and the data tools, solutions for founders,
agencies and sales teams, comparisons, guides and this changelog, with a
sitemap and structured data for search.
Migrations
- Existing single-workspace installations: follow
docs/multi-tenancy/cutover.md
(scripts/create-auth-tables.ts,scripts/add-organization-scope.ts,
thenscripts/finalize-organization-scope.tsafter deploying). - Sending rules:
bun run scripts/add-channel-settings.ts(additive; run it
before deploying). TheWHATSAPP_*sending variables are no longer read —
set those limits in Settings → WhatsApp → Sending rules.