induwara.lk
Opinionopen-sourceai-agentsarchitecture

The open-source agentic CRM that locks its own agent out

A new open-source agentic CRM inverts the usual design: the agent runs on its own schedule, with no database credentials at all. The architecture is worth copying.

Induwara Ashinsana6 min read
GitHub repository page for trycompai/crm showing the project README and stars
Image: GitHub

The most interesting thing about trycompai/crm, a new open-source agentic CRM on GitHub, is not that it's a CRM. It's the sentence in the README that reorders everything: "The agent is not a feature of the CRM; the CRM is where the agent keeps its notes."

That's a structural claim, not a marketing one. And if you're building anything with an LLM in it from a small team in Sri Lanka, the architecture in trycompai/crm is worth more to you than the product itself.


🔁 The inversion that actually matters

Almost every "AI-powered" tool shipped in the last two years follows the same shape: a normal CRUD app, plus a chat sidebar. You open the app, you type at the agent, the agent does a thing, you close the tab and it stops existing.

This repo flips the dependency. The agent runs on its own deployment, on its own schedule, against a work queue. It keeps going when the browser is shut.

Chat-sidebar AI Agentic-first
Trigger User types Work queue + schedule
Lifetime The tab session Continuous
Where logic lives The API The agent
App's job Do the work Record what happened

The README puts the API's role bluntly: no intelligence in the API. The NestJS service reports events; the agent interprets them. That single rule is why the design holds together, and it's the part most teams get wrong when they bolt an LLM onto an existing backend.

Key takeaway: If your agent only exists while a user is watching it, you've built a chat feature. An agent that has its own schedule, its own budget and its own queue is a different system with different failure modes — plan for it up front.


🔒 The agent runs with no database credentials

This is the part I'd copy tomorrow. The agent runs in an isolated sandbox with deny-all egress and no DATABASE_URL. It cannot open a socket to the internet unless explicitly allowed, and it cannot reach the database at all.

Instead it gets 18 authored tools — named, bounded functions like:

  • read_crm_history
  • search_crm
  • identify_contact
  • research_person
  • enrich_company

Every read and write goes through one of those. There is no SELECT the model can improvise, and no shell it can use to curl your data somewhere else.

A model holding database credentials and open egress has, functionally, been granted your entire customer table on a prompt-injection basis. One hostile line of text in an email body is enough. Removing the credential kills the whole class of bug, not just the instance.

If your agent can run arbitrary shell commands and also holds your production connection string, prompt injection isn't a risk you mitigate. It's a shell you've already handed out.


🧭 No confidence scores, evidence tiers instead

The README rejects self-reported confidence outright: models grade their own certainty unreliably, so the system doesn't ask them to. Tools report only what they observe. Nothing is guessed.

What replaces the score is a two-tier evidence rule:

Evidence strength What happens
Strong The record is updated directly
Weak It becomes a suggestion for a human to review

I like this because it's a product decision disguised as an architecture decision. "0.82 confidence" is a number nobody can act on. "This needs a human to look at it" is a queue item somebody clears before lunch.

If you're building an AI feature for a Sri Lankan client and you're tempted to surface a confidence percentage in the UI — don't. Pick the threshold yourself, then show the user a binary: applied, or waiting for you.


💰 What it actually costs to run from here

Self-hosting needs Bun and Docker, and the quickstart is short:

git clone https://github.com/trycompai/crm.git && cd crm
bun install
docker compose up -d
cp .env.example .env
bun run db:deploy
bun run dev

Only four values are strictly required to boot: BETTER_AUTH_SECRET, ALLOWED_SIGN_IN, and a Google OAuth client ID and secret. Auth is Google-only with an allowlist, because the whole thing is single-tenant by design.

Production is heavier. The README describes three independent deployments (app, API, agent) sharing a DATABASE_URL and auth secret, plus Postgres, optionally Redis, and a scheduler that has to POST to /internal/sync/google to keep the mailbox in sync.

Component What it is Free-tier friendly?
Postgres Self-hosted or Neon Yes, at small scale
Redis Upstash, optional Optional, skip it first
App / API / agent Three Vercel deployments Hobby limits apply
Model calls Vercel AI Gateway No — metered
Enrichment Perplexity, RapidAPI, Context Dev No — all optional, all billed

The README doesn't quote prices and I'm not going to invent any. But the honest read is this: the code is MIT and free, the research is not. An agent that autonomously decides to enrich a company is an agent autonomously spending your money in USD while you earn in LKR. The README notes the agent manages its own research budget, which tells you the authors hit this problem too.

That scheduled sync POST is a plain cron job, incidentally. If you're setting one up, our cron expression builder will save you the usual ten minutes of second-guessing the five fields.


🛠️ What's worth stealing even if you never run it

At the time I looked, the repo was at 1.1k stars, 131 forks and 28 commits on main. That's early. Twenty-eight commits is not a codebase with years of edge cases sanded off it, and I would not put a client's sales pipeline on it this month.

Read it anyway. The transferable parts, ranked:

  1. Tools over credentials. Give the model named functions, not a connection string.
  2. Deny-all egress by default. Allowlist what the agent may reach. That's a network policy, not a rewrite.
  3. The agent owns its schedule. Decouple it from the request cycle and the UI.
  4. Evidence tiers, not confidence floats. Strong writes, weak suggests.
  5. Skip multi-tenancy you don't need. The README's line on this is sharp: an organizationId that's always the same value is "a column, an index and a permissions check that buys nothing."

That last one is the most Sri-Lanka-relevant point on the list. A lot of local products get built multi-tenant from day one for a customer base of four, and then carry that tax through every query for years.


What this means for you

If you're a student or a small-team builder here, the practical takeaway isn't "self-host this CRM." It's that a credible reference implementation of a sandboxed, scheduled, tool-only agent now exists under an MIT licence, and you can read all of it in an afternoon.

Clone it, run docker compose up -d, and go read the tool definitions and the sandbox config. That's maybe two hours. What you'll take away is a defensible answer to the question every client eventually asks: "What stops your AI from leaking my data?" — and "we prompted it not to" is not that answer.

If you do end up running sales through something like this, you'll still need the boring bits around it. Our invoice generator and quotation generator are free and need no signup, which covers the paperwork the agent isn't doing for you.

#open-source#ai-agents#architecture
IA

Induwara Ashinsana

Information Systems student at UCSC and Executive Director at Ryzera Technologies. Writes about software, AI, and what it means for builders in Sri Lanka.

About the author →

Keep reading