Skip to main content

AI-native email & calendar client over JMAP and CalDAV

Project description

Courier

AI-native email & calendar client over JMAP and CalDAV.

Your AI agent deserves its own email client — not an adapter wrapping a human one.

The Problem

Every AI agent framework connects to email and calendar by wrapping human-facing apps. MCP servers adapt web UIs. Osascript automates native mail clients. Browser tools click through webmail. Each introduces friction because the agent is fighting an interface designed for someone else.

Courier takes a different approach: connect directly to the open protocols (JMAP for email, CalDAV for calendar) as a first-class client — a peer alongside your human apps, not a wrapper around them.

What Makes It Different

  • Context-window-optimized output — emails are structured for AI consumption, not HTML rendering
  • Session state & watermarks — "what's new?" is a first-class operation that persists between sessions
  • Triage classification — emails arrive pre-sorted: urgent, needs_reply, actionable, fyi, bulk
  • Batch-first operations — archive 15 emails in one call, not 15 separate requests
  • Sane timezone handling — CalDAV with proper TZID normalization and recurrence expansion
  • Composable — higher-order operations like "find all emails from this person and summarize the thread"

Quick Start

pip install ai-courier

# Configure your Fastmail account
courier setup

# Check your inbox (triaged by priority)
courier inbox

# What's new since last check?
courier new

# Today's calendar
courier today

# Find free time
courier free

As an MCP Server

Add to your Claude configuration:

{
  "mcpServers": {
    "courier": {
      "command": "courier-mcp"
    }
  }
}

Available tools:

Tool Description
email_inbox Triaged inbox (urgent → bulk)
email_new New emails since last check (watermark-based)
email_search Flexible email search
email_sent_since Recent sent messages (queries Sent mailbox directly)
email_read Read full email by ID
email_thread Get full thread
email_thread_digest Quote-stripped, token-budgeted thread payload
email_archive Archive emails (batch)
email_trash Trash emails (batch)
email_mark_read Mark read (batch)
email_draft Create draft
email_send Send email
email_mailboxes List folders/labels with IDs, paths, roles
email_move Move emails to a folder (by ID, name, or path)
email_label Add/remove labels without touching other memberships
email_reply Threaded reply (In-Reply-To + References); draft or send
email_forward Forward an email, re-attaches original as .eml; draft or send
calendar_today Today's events
calendar_week This week's events
calendar_events Events in date range
calendar_free Find free time slots
calendar_create Create event
calendar_rsvp Respond to an invite (accepted / tentative / declined)
courier_status Connection & watermark status

Customizing Triage Rules

Triage rules are defined in YAML. The defaults ship with Courier (see src/courier/default_rules.yaml). To customize, create ~/.config/courier/triage-rules.yaml:

# Force specific senders to a classification (checked first, confidence 1.0)
sender_overrides:
  "ceo@mycompany.com": { classification: urgent, reason: "VIP sender" }
  "deals@spammy.com": { classification: bulk, reason: "always bulk" }

# Custom rules — if you define any, they REPLACE the defaults entirely.
# Omit this section to keep defaults and only add sender overrides.
rules:
  - name: my-custom-rule
    classification: urgent
    confidence: 0.9
    reason: "keyword: '{match}'"
    subject_pattern: "\\b(fire|outage|p0)\\b"

Each rule supports regex match conditions (from_pattern, subject_pattern, body_pattern, domain_pattern) and guard conditions (requires_known_contact, requires_unknown_contact, max_size, requires_thread, requires_flagged). Rules are evaluated top-to-bottom; first match wins.

See src/courier/default_rules.yaml for the full schema documentation and all default rules.

Architecture

AI Agent (Claude, GPT, etc.)
    │
    ▼
Courier MCP Server ← the novel layer
    ├── Email (JMAP)     ├── Calendar (CalDAV)
    │   ├── Watermarks   │   ├── TZID normalization
    │   ├── Triage       │   ├── Recurrence expansion
    │   └── Batch ops    │   └── Free/busy
    └────────────────────┘
    │
    ▼
SQLite (state, watermarks, contact signals)
    │
    ▼
JMAP API ──── CalDAV API
(Fastmail)    (Fastmail)

Courier talks to the same backend your human apps do. It's a parallel client, not a wrapper.

Requirements

  • Python 3.11+
  • A Fastmail account with an API token (get one here)
  • Scopes needed: Mail, Calendars (Contacts optional)

Development

git clone https://github.com/iamdadzilla/courier.git
cd courier
pip install -e ".[dev]"
pytest

Why "Courier"?

A courier delivers messages directly. No intermediary, no adapter, no wrapper. Just the message.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ai_courier-0.5.2.1.tar.gz (247.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ai_courier-0.5.2.1-py3-none-any.whl (63.0 kB view details)

Uploaded Python 3

File details

Details for the file ai_courier-0.5.2.1.tar.gz.

File metadata

  • Download URL: ai_courier-0.5.2.1.tar.gz
  • Upload date:
  • Size: 247.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ai_courier-0.5.2.1.tar.gz
Algorithm Hash digest
SHA256 ccb49bc7141f0b15216f0c0fe11b3bec6714d38727ba72ef5b2751e478d66861
MD5 e1146197223ad1aa8c2dd2e0bceba0d4
BLAKE2b-256 32e0ca154e8472e79af7da717785e927cdfb62256ded4ea35689c71fe1b62930

See more details on using hashes here.

File details

Details for the file ai_courier-0.5.2.1-py3-none-any.whl.

File metadata

  • Download URL: ai_courier-0.5.2.1-py3-none-any.whl
  • Upload date:
  • Size: 63.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ai_courier-0.5.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1bc4273299ee98f37d7d96ab2b7c8ac98e4b5b58929a624fb11e1c66f40e9af8
MD5 a713e7f4d595d2e86b8f87a3ba06fa7b
BLAKE2b-256 8c89631cc2d60f5089e47d4b3a65db46b5d646fb2e53b9836d874268c8d445f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page