An intelligent email filtering system that uses Claude AI to process emails based on natural language rules. Define rules like "if it looks like a cold sales email, archive it" and let AI handle the classification.
- AI-Powered Rules: Write filtering rules in plain English (e.g., "Cold sales emails", "Newsletters I don't read")
- Gmail Integration: Full Gmail API support for reading and managing emails
- Claude AI Classification: Uses Anthropic's Claude 3.5 Haiku for fast, accurate email classification
- Action Execution: Automatically archive, label, or delete emails based on rule matches
- Audit Trail: Track all processed emails and rule matches with confidence scores
- Type-Safe API: Built with tRPC for end-to-end type safety
- Backend: Hono + tRPC + Node.js
- Database: Neon (Postgres) + Drizzle ORM
- Auth: Better Auth with Google OAuth
- AI: Anthropic Claude 3.5 Haiku
- Email: Gmail API (googleapis)
- Monorepo: Turborepo + pnpm
┌──────────────┐
│ Gmail Inbox │
└──────┬───────┘
│
▼
┌──────────────────────┐
│ Gmail API Sync │ ← Fetches emails via IMAP/API
└──────┬───────────────┘
│
▼
┌──────────────────────┐
│ Email Processor │ ← Coordinates processing
└──────┬───────────────┘
│
▼
┌──────────────────────┐
│ Claude AI Classifier │ ← Evaluates against rules
└──────┬───────────────┘
│
▼
┌──────────────────────┐
│ Action Executor │ ← Archives/Labels/Deletes
└──────────────────────┘
- Node.js 18+
- pnpm 9+
- Neon Postgres database
- Anthropic API key
- Google Cloud OAuth credentials
pnpm installCopy .env.example to .env and fill in the values:
cp .env.example .envRequired environment variables:
# Database
DATABASE_URL=postgresql://user:pass@host/db?sslmode=require
# Better Auth
BETTER_AUTH_SECRET=<generate-random-string>
BETTER_AUTH_URL=http://localhost:3000
# Google OAuth (for Gmail access)
GOOGLE_CLIENT_ID=<your-google-client-id>
GOOGLE_CLIENT_SECRET=<your-google-client-secret>
# Anthropic API
ANTHROPIC_API_KEY=<your-anthropic-api-key>- Go to Google Cloud Console
- Create a new project (or select existing)
- Enable the Gmail API:
- Navigate to "APIs & Services" > "Library"
- Search for "Gmail API" and enable it
- Create OAuth 2.0 credentials:
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "OAuth client ID"
- Application type: "Web application"
- Authorized redirect URIs:
http://localhost:3000/api/auth/callback/google
- Configure OAuth scopes:
- Go to "APIs & Services" > "OAuth consent screen"
- Add these scopes:
https://www.googleapis.com/auth/gmail.readonly(Read emails)https://www.googleapis.com/auth/gmail.modify(Modify labels, archive)https://www.googleapis.com/auth/gmail.labels(Manage labels)
- Copy the Client ID and Client Secret to your
.envfile
- Sign up at Anthropic Console
- Create an API key
- Add it to your
.envasANTHROPIC_API_KEY
pnpm db:pushpnpm devThis starts:
- API server on
http://localhost:3002 - Web app on
http://localhost:3000
Use the tRPC API to create filtering rules:
// Example: Create a rule to filter cold sales emails
await trpc.rules.create.mutate({
userId: "user_123",
name: "Cold Sales Filter",
description: "Detect and archive cold sales emails",
systemPrompt:
"Is this email an unsolicited sales outreach (cold email) trying to sell a product or service? Consider indicators like: mentions of products/services, asks for meetings, sender from sales role, marketing language.",
actionType: "ARCHIVE_AND_LABEL",
actionValue: "Cold Sales",
priority: 0,
});Or use the AI to generate the system prompt:
const result = await trpc.rules.generatePrompt.mutate({
description: "Cold sales emails from people I don't know",
});
// result.systemPrompt contains the AI-generated promptManually trigger email processing:
await trpc.emails.processNow.mutate({
userId: "user_123",
maxEmailsPerAccount: 10,
});This will:
- Fetch recent emails from Gmail
- Classify each email against active rules
- Execute actions (archive, label, delete) for matches
- Log results to the
processed_emailtable
Check processed emails:
const processed = await trpc.processed.list.query({
userId: "user_123",
limit: 100,
});Stores connected Gmail accounts with OAuth tokens.
User-defined filtering rules with AI prompts and actions.
Cached emails from Gmail for fast access.
Audit trail of rule executions with confidence scores.
emailAccounts.list- List connected accountsemailAccounts.create- Connect new Gmail accountemailAccounts.delete- Remove account
rules.list- List all rules for userrules.create- Create new filtering rulerules.update- Update existing rulerules.delete- Delete rulerules.generatePrompt- AI-generate system prompt from description
emails.list- List cached emailsemails.processNow- Manually trigger processing
processed.list- View audit trail of processed emails
Claude 3.5 Haiku pricing (as of 2025):
- ~$0.001 per 1000 input tokens
- Processing 100 emails/day ≈ $0.50-2/month
Tips to reduce costs:
- Use simple regex pre-filters before AI classification
- Batch similar emails together
- Cache classification results for duplicate emails
- Only process unread emails
- Real-time processing via Gmail Push Notifications (Pub/Sub)
- Web UI for rule management
- Rule testing/preview mode
- Multiple action support (apply multiple actions per rule)
- Rule conditions (AND/OR logic)
- Scheduled batch processing
- Email analytics dashboard
- Multi-provider support (Outlook, iCloud)
# Generate migration
pnpm db:generate
# Push schema to database
pnpm db:push
# Open Drizzle Studio
pnpm db:studiopnpm buildpnpm lint├── apps/
│ └── web/ # React frontend (future)
├── packages/
│ ├── api/ # Hono + tRPC API
│ │ └── src/
│ │ ├── services/
│ │ │ ├── gmail.ts # Gmail API integration
│ │ │ ├── ai.ts # Claude AI service
│ │ │ └── processor.ts # Email processing logic
│ │ ├── router.ts # tRPC routes
│ │ └── server.ts # Hono server
│ ├── db/ # Drizzle schema + migrations
│ ├── auth/ # Better Auth config
│ └── ui/ # Shared UI components
- OAuth tokens are stored in plain text in the database. In production, encrypt these fields.
- Email bodies are sent to Anthropic's API. Review their privacy policy.
- Consider using local LLMs (Ollama) for sensitive emails.
MIT