4.3 KiB
Postal Email Infrastructure & AI Integration Scope
Overview
Vibn requires a scalable, multi-tenant email infrastructure that allows both the core platform and user-generated AI agents to send emails. To support unlimited custom domains without incurring high per-domain or per-email costs, we will self-host Postal, an open-source mail delivery platform, on Coolify.
This document outlines the end-to-end implementation plan, covering infrastructure, backend integration, database modifications, and the AI MCP tool.
Phase 1: Infrastructure (Self-Hosted Postal)
Status: Pending
Postal requires its own dedicated environment with MariaDB and RabbitMQ. We will deploy this via Coolify's Docker Compose feature.
1. Server & DNS Prerequisites
- Clean IP: Ensure the Coolify host (or dedicated VPS) IP is not on any DNSBL (Blacklists).
- Subdomain: Dedicate a subdomain (e.g.,
postal.vibn.comormail.vibn.com). - Reverse DNS (rDNS/PTR): Configure the hosting provider to map the server's IP back to the Postal subdomain.
2. Coolify Deployment
- Create a new Docker Compose application in Coolify.
- Use the official Postal docker-compose configuration, which includes:
postal(The Ruby-based core app)mariadb(Relational database for routing/config)rabbitmq(Message queue for email spooling)
- Configure environment variables within Coolify (signing keys, DNS hostnames).
- Expose ports:
80/443(Web UI/API) and25(SMTP inbound/outbound).
3. Deliverability Foundations
- Generate and configure the global SPF, DKIM, and DMARC records for the Vibn root domain.
- Set up a master "Organization" and "Vibn System" Mail Server inside the Postal UI to generate the first API key.
Phase 2: Backend Integration & Database
Status: Pending
We need to securely store Postal credentials and allow individual Vibn projects to configure their own sender identities.
1. Database Schema Update (lib/db-postgres.ts)
Add an email_config JSONB column to the projects table to handle multi-tenancy.
// Proposed structure for email_config
{
provider: "postal",
postalServerKey: "api_key_for_this_specific_project",
verifiedDomains: ["userapp.com"],
defaultFrom: "hello@userapp.com"
}
2. Environment Variables (.env.local & Coolify)
Add global fallback variables for Vibn system emails:
VIBN_POSTAL_API_URL(e.g.,https://postal.vibn.com/api/v1)VIBN_POSTAL_API_KEY
3. Email Utility Client (lib/email/postal.ts)
Create a robust TypeScript wrapper for the Postal REST API.
- Methods:
sendEmail(),createServer(),addDomain(). - Logic: Must support passing a custom API key (for project-specific routing) or falling back to the global key.
Phase 3: AI Agent Integration (MCP Tool)
Status: Pending
Expose the ability to send emails to the AI via the Model Context Protocol (MCP).
1. Register send_email Tool (vibn-agent-runner/src/tools/vibn-tools.ts)
Define the JSON Schema for the tool:
to: Array of email addresses.subject: String.body: Markdown or Plain Text string.- (Optional)
from: Override sender address (must match a verified domain).
2. Handle MCP Execution (vibn-frontend/app/api/mcp/route.ts)
When the AI invokes send_email:
- Extract the
projectIdfrom the authenticated MCP session. - Query the database for the project's
email_config. - Validate that the requested
fromaddress is authorized for this project. - Call the
lib/email/postal.tsutility. - Return the Postal Message ID to the AI so it can confirm delivery in the chat.
Phase 4: User Interface (Optional but Recommended)
Status: Pending
To achieve true multi-tenancy, users need a way to connect their custom domains to Postal via the Vibn UI.
1. Project Settings -> Email Tab
- A UI where users can click "Add Domain".
- Vibn calls the Postal API to register the domain and retrieve the required DNS records (DKIM, SPF).
- Display these DNS records to the user.
- Add a "Verify DNS" button that queries Postal to confirm the records are active.
Next Steps
To begin, we should tackle Phase 1: Infrastructure.
I can write the exact docker-compose.yml you need to paste into Coolify right now. Do you have a specific subdomain in mind for Postal (e.g., postal.yourdomain.com)?