Ai Agentic Erp Builder
FreeNot checkedMulti-tenant AI Orchestrator platform for SMEs — domain agents (Finance, HR, Sales, Supply, Compliance), multi-channel I/O, RLS-isolated Postgres, pluggable ERP
About
Multi-tenant AI Orchestrator platform for SMEs — domain agents (Finance, HR, Sales, Supply, Compliance), multi-channel I/O, RLS-isolated Postgres, pluggable ERP connectors. Architecture showcase.
README
Multi-tenant AI Orchestrator platform for SMEs — domain agents (Finance, HR, Sales, Supply, Compliance), multi-channel I/O (REST, Web Chat, Telegram, Discord), pluggable ERP connectors, and an admin console for tenant + agent + channel-bot management.
[!IMPORTANT] This is a public showcase repository. It documents the architecture, agent system, and tech stack of a production AI ERP platform built across three internal codebases. Source code lives in private monorepos and is not mirrored here — this repo is the high-level engineering map.
[!NOTE] Last updated: 2026-05-07 · Author: Tran Phong · Stack: NestJS · TypeScript · PostgreSQL 16 (RLS) · Redis 7 · Drizzle ORM · BullMQ · Vercel AI SDK · React 18 · shadcn/ui · Turborepo + pnpm.
Navigation
- What it is
- System architecture
- Domain agents
- Channel surfaces
- Multi-tenancy & isolation
- Tech stack
- Repo composition
- Engineering highlights
- Roadmap
- Contact
What it is
An AI Agentic ERP is an ERP/CRM whose primary surface is conversational. Instead of clicking through 200 screens, users talk to domain agents. Each agent has scoped tools (ERP connectors), tenant-isolated memory, and policy-aware prompts.
Built for Vietnamese SMEs that want enterprise capabilities without the enterprise license model — conversational over web/Telegram/Discord, deployable as a SaaS, and pluggable into any existing ERP (Twendee ERP, Odoo, SAP B1) via a connector layer.
flowchart LR
U1[Web Chat Widget]
U2[Telegram Bot]
U3[Discord Bot]
U4[REST API]
U1 & U2 & U3 & U4 --> GW[API Gateway<br/>NestJS · JWT · Throttle]
GW --> ORC[Orchestrator<br/>intent → routing]
ORC --> A1[Finance Agent]
ORC --> A2[HR Agent]
ORC --> A3[Sales Agent]
ORC --> A4[Supply Agent]
ORC --> A5[Compliance Agent]
A1 & A2 & A3 & A4 & A5 --> LLM[LlmPort<br/>Claude · GPT · Gemini]
A1 & A2 & A3 & A4 & A5 --> ERP[ERP Connectors<br/>Twendee · Odoo · SAP]
GW -.audit.-> DB[(PostgreSQL 16<br/>RLS · Drizzle)]
ORC -.queue.-> Q[(Redis 7<br/>BullMQ)]
System architecture
Layered NestJS modular monolith. RLS-enforced tenant isolation at the database level. Agents are dynamic — definitions live in DB and can be customized per tenant without code changes.
| Layer | Responsibility | Key components |
|---|---|---|
| Channels | Adapt platform-specific protocols to internal chat events | Web Widget · Telegram Webhook · Discord Bot · REST /v1/chat |
| Auth | JWT issuance, refresh-token rotation, tenant-scoped guards | AuthService, JwtAuthGuard, throttle 5 req/min |
| Orchestrator | Intent classification → agent routing → response assembly | OrchestratorService, PromptAssembler (3-layer safety) |
| Agent framework | Pluggable agent contract, dynamic resolution | Agent interface, DynamicAgentResolver, AgentRegistry |
| LLM | Multi-provider abstraction with tier routing | LlmPort, LlmProviderFactory, token metering |
| ERP connectors | Pluggable adapters to host ERPs | @twd/erp-adapters (per-vendor implementations) |
| Memory | Sliding-window context, tenant-scoped conversation history | MemoryService, ConversationsService |
| Persistence | RLS-protected Postgres + Redis cache + BullMQ queues | Drizzle ORM, ioredis, @aes-encryption/* |
3-layer prompt safety
flowchart TB
SYS[Layer 1: System Prompt<br/>immutable agent contract]
POL[Layer 2: Tenant Policy<br/>scope guard, allowed actions]
USR[Layer 3: User Message<br/>untrusted input]
SYS --> POL --> USR --> LLM[LLM]
User input never bypasses tenant policy. Policy never bypasses agent contract. Each layer is concatenated by PromptAssembler with explicit role separation.
Domain agents
Five seeded agents per tenant. Definitions stored in dynamic_agent_definitions — fully editable from the admin console.
| Agent | Sample intents | Tools / connectors |
|---|---|---|
| Finance | "Issue payment voucher for invoice #234", "Reconcile bank statement", "Show outstanding receivables > 30 days" | GL accounts, payment vouchers, receipts, cash flow report |
| HR | "Approve leave request for Mai", "What's John's leave balance?", "Generate payroll for May 2026" | Employees, attendance, contracts, leave balance, payroll sheet |
| Sales | "Create deal for Acme — $50K, stage Qualification", "Move pipeline X to negotiation", "Email sequence to cold leads" | Deals, kanban pipeline, lead enrichment (Apollo), email sequences |
| Supply | "PO status for SKU-1090", "Restock alert for low-inventory items", "Vendor performance report" | Purchase orders, suppliers, inventory levels |
| Compliance | "Audit who changed customer #112 last 30d", "GDPR export for user X", "Tax filing readiness check" | Audit logs, RLS reports, BHXH (VN social insurance) workflows |
Each agent ships with scoped tool access. The orchestrator never lets a Sales agent issue a payment voucher.
Channel surfaces
| Surface | Auth | Path | Notes |
|---|---|---|---|
| Web chat widget | JWT cookie | Embeddable <script> tag (Vite lib mode) |
Streamed responses via SSE |
| Telegram bot | Per-bot encrypted token + secret | POST /webhooks/telegram/:botId |
Path-based routing; idempotency via Redis SETNX on update_id |
| Discord bot | Bot token | Webhook + slash commands | Same orchestrator backend |
| REST API | Bearer JWT | POST /api/v1/chat, POST /api/v1/chat/stream |
For programmatic integrations |
Telegram webhook flow (async, fire-and-forget)
sequenceDiagram
participant TG as Telegram
participant API as Webhook /:botId
participant R as Redis
participant Q as BullMQ
participant W as Worker
participant ORC as Orchestrator
participant A as Agent
TG->>API: POST update
API->>API: Validate bot + secret
API->>R: SETNX update_id (idempotent)
alt new
API->>Q: enqueue job
API-->>TG: 200 OK
Q->>W: dequeue
W->>ORC: process(message)
ORC->>A: route
A-->>W: reply
W->>TG: sendMessage
else duplicate
API-->>TG: 200 OK (skip)
end
200 OK returns immediately — prevents Telegram retry storms when an LLM call takes 4–8s.
Multi-tenancy & isolation
| Mechanism | Where | Purpose |
|---|---|---|
| PostgreSQL RLS | tenants, users, conversations, agents, channel_bots tables |
Hard isolation — no app-level bypass |
| Tenant-scoped JWT | tenantId claim, extracted by JwtAuthGuard |
Every query carries tenant context |
| AES-encrypted secrets | tenant_configs.api_keys, channel_bots.bot_token |
Per-tenant LLM keys, bot tokens at rest |
| Per-tenant LLM tier | LlmProviderFactory reads tenant tier → routes Claude/GPT/Gemini |
Enables BYOK and cost segregation |
| Token metering | TokenMeteringService (Redis counters) |
Quota enforcement + billing input |
| Team scoping | teams + team_agents (M2M) |
Group agents under a team; channel bots bind to one team |
Tech stack
| Concern | Choice | Why |
|---|---|---|
| Backend framework | NestJS 10 | Modular monolith with clean DI, fits agent/orchestrator separation |
| ORM | Drizzle | Typed schema + RLS-friendly raw SQL escape hatch |
| Cache + queue | Redis 7 + BullMQ | Idempotency keys + async webhook processing |
| LLM SDK | Vercel AI SDK | Provider-neutral, streamable, tool-calling friendly |
| LLM providers | Anthropic + OpenAI + Gemini | Tier routing per tenant (cost vs quality) |
| Frontend | React 18 + Vite + shadcn/ui | Admin console + embeddable chat widget (lib mode) |
| Monorepo | Turborepo + pnpm | Build graph (shared-types → apps), workspace deps |
| Auth | JWT + refresh rotation + bcrypt | Standard, throttled at 5 req/min on /auth/* |
| Encryption | AES-256-GCM | Per-tenant secrets at rest |
| Container | Multi-stage Node 20-alpine | Non-root user, ~120MB image |
Repo composition
The platform is split across three private codebases. Each owns a clean domain and depends only on the contracts above it.
| Codebase | Role | Stack |
|---|---|---|
| Agents Hub (orchestrator core) | Multi-tenant agent runtime, channels, admin API | NestJS · Drizzle · Redis · BullMQ · Turborepo |
| Twendee ERP (host ERP) | HR, payroll, attendance, accounting, CRM, projects | NestJS 10 · React 18 · PostgreSQL · Docker |
| Sales Agent (specialised vertical) | Lead enrichment (Apollo), Chrome extension, sales kanban | Rust (Axum) backend · React frontend · Chrome MV3 |
Inside the Agents Hub:
TWDAgentsHub/
├── apps/
│ ├── api/ @twd/api NestJS modular monolith
│ ├── admin-ui/ @twd/admin-ui Tenant + agent + bot console
│ └── chat-widget/ @twd/chat-widget Embeddable web widget
├── packages/
│ ├── shared-types/ @twd/shared-types Cross-app TS contracts
│ └── erp-adapters/ @twd/erp-adapters Pluggable ERP connectors
├── tooling/ tsconfig + tailwind preset
├── docs/ architecture, codebase-summary, MCP wiring guide
└── docker-compose.yml postgres:16 + redis:7
Engineering highlights
[!TIP] The non-obvious decisions — what a recruiter or new hire should know.
- Dynamic agents over hard-coded ones. Agent prompts, tool whitelists, and LLM tier are stored in
dynamic_agent_definitionskeyed bytenantId. Adding a new vertical (e.g. Legal) is a DB row, not a deploy. - 3-layer prompt assembly. System contract → tenant policy → user input. Policy injection is the only sanctioned way to constrain agent behaviour per tenant. Prevents tenant-A from being prompt-injected into tenant-B's data.
- Async webhook pattern for Telegram. 200 OK in <100ms via BullMQ deferral. Idempotency on
update_idvia Redis SETNX. No retry storms even when LLM stalls. - Per-tenant LLM tier routing.
LlmProviderFactoryresolves provider at runtime — Sonnet for Pro, Haiku for Free, BYOK for Enterprise. Same agent code; cost lever is config. - RLS first, app guards second. Tenant isolation is enforced in Postgres. App-level guards are belt-and-braces, not the security boundary.
- Token metering in Redis, not Postgres. Per-tenant counters with TTL = billing window. Cheap reads, atomic increments.
- Encrypted bot tokens.
channel_bots.bot_tokenis AES-GCM encrypted with a per-tenant DEK. Compromise of one tenant's bot does not leak others.
Roadmap
- Phase 1 — Foundation (auth, tenants, dynamic agents, REST chat)
- Phase 2 — Channel bots (Telegram path-routed webhooks)
- Phase 3 — Sales vertical (Apollo enrichment, kanban pipeline)
- Phase 4 — RAG over tenant docs (per-tenant ChromaDB collections)
- Phase 5 — Voice channel (Twilio + Whisper + ElevenLabs)
- Phase 6 — MCP server exposure (each agent surfaced as an MCP tool to external IDEs)
Contact
| Author | Tran Phong |
| [email protected] | |
| GitHub | @phong28zk |
| fn28chen | |
| Location | Hanoi, Vietnam |
[!NOTE] Source code is private. Happy to walk through architecture, agent runtime, and trade-offs in interviews. Reach out for a guided demo.
License
Documentation under CC BY 4.0. Architecture descriptions and diagrams may be cited with attribution.
Installing Ai Agentic Erp Builder
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/phong28zk/ai-agentic-erp-builderFAQ
Is Ai Agentic Erp Builder MCP free?
Yes, Ai Agentic Erp Builder MCP is free — one-click install via Unyly at no cost.
Does Ai Agentic Erp Builder need an API key?
No, Ai Agentic Erp Builder runs without API keys or environment variables.
Is Ai Agentic Erp Builder hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Ai Agentic Erp Builder in Claude Desktop, Claude Code or Cursor?
Open Ai Agentic Erp Builder on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
wenb1n-dev/SmartDB_MCP
A universal database MCP server supporting simultaneous connections to multiple databases. It provides tools for database operations, health analysis, SQL optim
by wenb1n-devPostgres Server
This server enables interaction with PostgreSQL databases through the Model Context Protocol, optimized for the AWS Bedrock AgentCore Runtime. It provides tools
by madhurprashPostgres
Query your database in natural language
by AnthropicPostgreSQL
Read-only database access with schema inspection.
by modelcontextprotocolCompare Ai Agentic Erp Builder with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All data MCPs
