Skip to content

Instantly share code, notes, and snippets.

@nielsberglund
Created January 31, 2026 10:32
Show Gist options
  • Select an option

  • Save nielsberglund/c4d428d2ec6ec18ee939cf4f7cc9e35f to your computer and use it in GitHub Desktop.

Select an option

Save nielsberglund/c4d428d2ec6ec18ee939cf4f7cc9e35f to your computer and use it in GitHub Desktop.

Email Architecture - Transactional Mode

Overview

This document describes the architecture for sending event communications using Claude Desktop as the conversational interface, with PostgreSQL as the single source of truth and Brevo for email delivery.


Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────────┐
│                           USER INTERFACE LAYER                               │
│                                                                              │
│                          ┌─────────────────────┐                             │
│                          │   Claude Desktop    │                             │
│                          │  (Conversational UI)│                             │
│                          └──────────┬──────────┘                             │
│                                     │                                        │
│   User: "Email all 2024 speakers    │    Claude: "I found 25 speakers.      │
│          about CFP for 2025"        │    Sent 25 emails using the           │
│                                     │    'CFP Announcement' template.        │
│                                     │    All delivered successfully."        │
└─────────────────────────────────────┼───────────────────────────────────────┘
                                      │
                                      │ Natural Language
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          LLM ORCHESTRATION LAYER                             │
│                            (Claude Sonnet/Opus)                              │
│                                                                              │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │                        Workflow Orchestration                          │ │
│  │                                                                        │ │
│  │  1. Parse user intent ("email speakers about CFP")                     │ │
│  │  2. Query PostgreSQL for recipients                                    │ │
│  │  3. For each recipient: Send via Brevo                                 │ │
│  │  4. Log results back to PostgreSQL                                     │ │
│  │  5. Compose response for user                                          │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
│                                                                              │
│                    ┌──────────────┴──────────────┐                          │
│                    │                             │                          │
│                    ▼                             ▼                          │
│         ┌─────────────────────┐       ┌─────────────────────┐              │
│         │   MCP Tool Calls    │       │   MCP Tool Calls    │              │
│         │   (PostgreSQL)      │       │   (Brevo)           │              │
│         └─────────────────────┘       └─────────────────────┘              │
└─────────────────────────────────────────────────────────────────────────────┘
                    │                             │
                    │ MCP Protocol                │ MCP Protocol
                    ▼                             ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                            MCP SERVER LAYER                                  │
│                                                                              │
│  ┌─────────────────────────────┐       ┌─────────────────────────────────┐  │
│  │     Postgres MCP Pro        │       │      @houtini/brevo-mcp         │  │
│  │     (Docker Container)      │       │      (Node.js/npx)              │  │
│  │                             │       │                                 │  │
│  │  Tools:                     │       │  Tools:                         │  │
│  │  • execute_sql              │       │  • get_account_info             │  │
│  │  • list_schemas             │       │  • send_transactional_email     │  │
│  │  • get_object_details       │       │  • get_email_templates          │  │
│  │  • explain_query            │       │  • get_template_content         │  │
│  │  • analyze_db_health        │       │  • create_email_campaign        │  │
│  │                             │       │  • send_campaign_now            │  │
│  │  Used for:                  │       │  • get_campaign_stats           │  │
│  │  • Query contacts           │       │                                 │  │
│  │  • Query events             │       │  Used for:                      │  │
│  │  • Log sent emails          │       │  • Send transactional emails    │  │
│  │  • Check email history      │       │  • Use email templates          │  │
│  │                             │       │  • Track delivery status        │  │
│  └──────────────┬──────────────┘       └──────────────┬──────────────────┘  │
│                 │                                     │                      │
└─────────────────┼─────────────────────────────────────┼──────────────────────┘
                  │                                     │
                  │ SQL (TLS)                           │ HTTPS API
                  ▼                                     ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         DATA & SERVICES LAYER                                │
│                                                                              │
│  ┌─────────────────────────────┐       ┌─────────────────────────────────┐  │
│  │   PostgreSQL (Neon Cloud)   │       │      Brevo Email Service        │  │
│  │                             │       │         (FREE Plan)             │  │
│  │  ┌───────────────────────┐  │       │                                 │  │
│  │  │ contacts              │  │       │  • 300 emails/day               │  │
│  │  │ • email, name, phone  │  │       │  • 109,500 emails/year          │  │
│  │  │ • company, type       │  │       │  • Drag-and-drop templates      │  │
│  │  └───────────────────────┘  │       │  • Transactional API            │  │
│  │  ┌───────────────────────┐  │       │  • Delivery tracking            │  │
│  │  │ events                │  │       │  • Open/click analytics         │  │
│  │  │ • name, date, year    │  │       │                                 │  │
│  │  └───────────────────────┘  │       │  Templates (created in Brevo):  │  │
│  │  ┌───────────────────────┐  │       │  • Registration Confirmation    │  │
│  │  │ contact_roles         │  │       │  • Event Reminder               │  │
│  │  │ • speaker, attendee   │  │       │  • CFP Announcement             │  │
│  │  └───────────────────────┘  │       │  • Speaker Rating Results       │  │
│  │  ┌───────────────────────┐  │       │  • Post-Event Thank You         │  │
│  │  │ email_log             │  │       │                                 │  │
│  │  │ • sent_date, subject  │  │       │                                 │  │
│  │  │ • recipient_count     │  │       │                                 │  │
│  │  │ • template_used       │  │       │                                 │  │
│  │  │ • brevo_message_id    │  │       │                                 │  │
│  │  └───────────────────────┘  │       │                                 │  │
│  │                             │       │                                 │  │
│  │  SINGLE SOURCE OF TRUTH     │       │  EMAIL DELIVERY ONLY            │  │
│  │  (No contacts in Brevo)     │       │  (No contact storage)           │  │
│  └─────────────────────────────┘       └─────────────────────────────────┘  │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

Data Flow: Send Email to Speakers

┌─────────────────────────────────────────────────────────────────────────────┐
│  User: "Email all 2024 speakers about CFP for 2025"                         │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│  Step 1: QUERY RECIPIENTS (PostgreSQL MCP)                                   │
│                                                                              │
│  SELECT c.id, c.email, c.first_name, c.last_name                            │
│  FROM contacts c                                                             │
│  JOIN contact_roles cr ON c.id = cr.contact_id                              │
│  JOIN events e ON cr.event_id = e.id                                        │
│  WHERE cr.role_type = 'speaker' AND e.year = 2024                           │
│                                                                              │
│  Result: 25 speakers                                                         │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│  Step 2: PREVIEW & CONFIRM                                                   │
│                                                                              │
│  Claude: "I found 25 speakers from 2024 events:                             │
│           - John Smith (john@example.com)                                    │
│           - Jane Doe (jane@example.com)                                      │
│           ... and 23 more.                                                   │
│                                                                              │
│           Send CFP announcement using 'CFP 2025' template?"                  │
│                                                                              │
│  User: "Yes, send it"                                                        │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│  Step 3: SEND EMAILS (Brevo MCP) - Loop through recipients                  │
│                                                                              │
│  for each speaker:                                                           │
│      send_transactional_email(                                               │
│          to: speaker.email,                                                  │
│          template_id: 5,  // CFP 2025 template                              │
│          params: {                                                           │
│              first_name: speaker.first_name,                                 │
│              event_name: "Data & AI Community Day 2025"                      │
│          }                                                                   │
│      )                                                                       │
│                                                                              │
│  Result: 25 emails sent, message IDs returned                                │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│  Step 4: LOG RESULTS (PostgreSQL MCP)                                        │
│                                                                              │
│  INSERT INTO email_log (sent_date, subject, template_used,                   │
│                         recipient_count, brevo_message_ids)                  │
│  VALUES (NOW(), 'CFP 2025 Announcement', 'cfp-2025',                        │
│          25, '{msg1, msg2, ...}')                                           │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│  Claude: "Done! Sent 25 emails using 'CFP 2025' template.                   │
│           All delivered successfully. Logged to email_log."                  │
└─────────────────────────────────────────────────────────────────────────────┘

Key Design Decisions

1. PostgreSQL as Single Source of Truth

  • Contacts stored only in PostgreSQL
  • Email history logged in PostgreSQL (email_log table)
  • No contact sync to Brevo required
  • Brevo is a delivery service only

2. Transactional Mode Only

  • Each email sent individually via Brevo API
  • Templates stored in Brevo (drag-and-drop editor)
  • Personalization via template parameters
  • Suitable for ~300 recipients per event

3. Confirmation Before Bulk Send

  • Claude previews recipients before sending
  • User must confirm for sends > 10 recipients
  • Prevents accidental mass emails

4. Complete Audit Trail

  • Every email logged with:
    • Timestamp
    • Recipients
    • Template used
    • Brevo message IDs (for tracking)

Example Conversations

Send Event Reminder

User: "Send a reminder to all registered attendees for the March 2025 event"

Claude: "I found 287 attendees registered for 'Data & AI Community Day - March 2025'.

         Should I send the 'Event Reminder' template to all 287 attendees?

         Preview of email:
         Subject: See you tomorrow at Data & AI Community Day!
         Template: event-reminder-1day"

User: "Yes, send it"

Claude: "Sending... ████████████████ 100%

         ✓ Sent 287 emails successfully
         ✓ Logged to email_log (ID: 45)

         Note: 3 emails had soft bounces (temporary failures).
         These recipients can be retried."

Check Email History

User: "What emails have we sent to speakers this year?"

Claude: "Email history for speakers in 2025:

         | Date       | Subject                    | Recipients | Template      |
         |------------|----------------------------|------------|---------------|
         | 2025-01-15 | CFP 2025 Announcement      | 25         | cfp-2025      |
         | 2025-02-01 | CFP Deadline Reminder      | 25         | cfp-reminder  |
         | 2025-03-01 | Speaker Confirmation       | 18         | speaker-conf  |
         | 2025-03-10 | Event Logistics            | 18         | speaker-info  |

         Total: 4 campaigns, 86 emails sent"

Configuration

Claude Desktop Config (claude_desktop_config.json)

{
  "mcpServers": {
    "postgres": {
      "command": "docker",
      "args": ["run", "-i", "--rm",
               "-e", "DATABASE_URI=postgresql://...",
               "crystaldba/postgres-mcp"],
      "env": {}
    },
    "brevo": {
      "command": "npx",
      "args": ["-y", "@houtini/brevo-mcp"],
      "env": {
        "BREVO_API_KEY": "xkeysib-..."
      }
    }
  }
}

Templates to Create in Brevo

Template Name Use Case Key Parameters
registration-confirmation After ticket purchase first_name, event_name, ticket_type
event-reminder-1day Day before event first_name, event_name, venue
event-reminder-1week Week before event first_name, event_name, date
cfp-announcement Call for papers first_name, deadline_date
speaker-confirmation Talk accepted first_name, talk_title, time_slot
speaker-rating-results Post-event feedback first_name, talk_title, avg_rating
post-event-thankyou After event first_name, event_name

Rate Limits & Constraints

Constraint Value Impact
Brevo free tier 300 emails/day Max 300 recipients per day
Transactional API No explicit limit Recommended: 10 req/sec
Template params 50 max Enough for personalization
Email size 20MB max Attachments included

For your use case (~300 attendees, ~20 speakers, 4-5 events/year):

  • Daily limit: Sufficient (one event's attendees = one day's limit)
  • Annual volume: ~1,500 emails << 109,500 limit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment