From zero to a branded, action-taking AI agent embedded in your product.
Three options — pick what fits your stack:
# Clone and run in one command git clone https://github.com/mehedihassanz/concierge.git cd concierge cp .env.example .env # edit secrets docker compose up -d # serving on :3000
git clone https://github.com/mehedihassanz/concierge.git
cd concierge
npm install
npm run build
npm start # serving on :3000
# Set environment variables in your hosting dashboard: # CONCIERGE_SECRET=your-secret-hex-string # OPENAI_API_KEY=sk-... (optional, for real LLM) # Build command: npm ci && npm run build # Start command: npm start
Open http://localhost:3000/api/health — should return {"ok":true}.
Sign in to the dashboard (seed admin: admin@concierge.dev / admin1234) and use the Agent Builder, or do it via API:
curl -X POST http://localhost:3000/api/v1/builder \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt": "An agent for my SaaS that creates tickets, deploys sites, and checks usage", "email": "ceo@myapp.com" }'
This returns:
{
"tenantId": "myapp",
"brandName": "Myapp",
"agentName": "Myappy",
"primaryColor": "#2563eb",
"enabledActions": ["create_ticket", "deploy_site", "check_usage"],
"apiKey": { "keyId": "ck_...", "secret": "cs_..." },
"ownerEmail": "ceo@myapp.com",
"snippet": "<script src=...>"
}
The apiKey.secret is shown once. Store it securely — it authenticates your embedded widget.
Drop two lines into your HTML page. The widget appears as a chat bubble in the bottom-right corner.
<!-- 1. Load the embed SDK (zero deps, 6KB) --> <script src="https://your-concierge.app/concierge-embed.js"></script> <!-- 2. Initialize --> <script> ConciergeEmbed.init({ endpoint: "https://your-concierge.app/api/v1/chat", tenantId: "myapp", apiKey: "cs_...", branding: { brandName: "MyApp", agentName: "Assistant", primaryColor: "#2563eb" } }); </script>
That's it. Your agent is live. Users can chat with it and it will take real actions in your product.
Actions are the real power — they let the agent do things in your product. Register them in TypeScript:
import { AgentRuntime } from "./src/core/runtime"; runtime.registry.register({ name: "create_invoice", title: "Create an invoice", description: "Create and send an invoice to a customer", keywords: ["invoice", "bill", "charge"], requireConfirmation: true, // HITL: user must approve params: [ { name: "customer", type: "string", required: true }, { name: "amount", type: "number", required: true }, ], run(params, ctx) { // Your real business logic here const id = createInvoice(params.customer, params.amount); return { ok: true, action: "create_invoice", message: `Invoice #${id} created for ${params.customer} ($${params.amount})`, }; }, });
The ctx.caller is resolved server-side from the session token or API key — never from the request body. A user cannot impersonate another user or escalate their role.
By default, Concierge uses a local mock LLM (free, deterministic, keyword-based). For production quality, connect OpenAI or Anthropic:
# .env CONCIERGE_LLM_PROVIDER=openai OPENAI_API_KEY=sk-... # Or Anthropic: # CONCIERGE_LLM_PROVIDER=anthropic # ANTHROPIC_API_KEY=sk-ant-...
Concierge uses a fallback ladder: if OpenAI is down, it tries Anthropic, then falls back to the local mock. The widget never returns a 500.
All endpoints are available under /api/v1/ (or /api/ for backward compat).
Authorization: Bearer <token>X-Api-Key: <secret>POST /api/v1/chat # Send a message, get action + reply POST /api/v1/chat/stream # SSE streaming variant POST /api/v1/chat/confirm # Confirm a HITL-staged action POST /api/v1/chat/handoff # Escalate to a human POST /api/v1/builder # Prompt → agent builder (admin) GET /api/v1/widget # Widget config + branding POST /api/v1/kb/query # RAG knowledge base query GET /api/v1/me # Current user profile GET /api/v1/me/memory # What the agent knows about me GET /api/v1/me/conversations # My conversation history # Admin (requires admin role): GET /api/v1/admin/tenants # List all tenants GET /api/v1/admin/analytics # Resolution/containment/CSAT GET /api/v1/admin/audit # Full audit trail PUT /api/v1/admin/tenants/:id/enabled-actions POST /api/v1/admin/tenants/:id/apikeys POST /api/v1/admin/tenants/:id/kb # Index a KB document # Multichannel: POST /api/v1/channels/whatsapp # WhatsApp webhook POST /api/v1/channels/sms # Twilio SMS webhook POST /api/v1/channels/email # Email inbound # Channels: POST /api/v1/channels/whatsapp # WhatsApp webhook POST /api/v1/channels/sms # Twilio SMS webhook POST /api/v1/channels/email # Email inbound