Skip to main content

An MCP server for LLM agents to interact with email via IMAP/SMTP

Project description

clerk

A thin CLI for LLM agents to interact with email via IMAP/SMTP.

License: MIT Python 3.11+

Philosophy

Clerk is intentionally dumb. It's a bridge, not a brain.

┌─────────────────────────────────────┐
│         Claude Code (LLM)           │
│  • Decides what's important         │
│  • Summarizes conversations         │
│  • Drafts replies                   │
│  • Orchestrates workflows           │
└─────────────────────────────────────┘
                 │ uses
                 ▼
┌─────────────────────────────────────┐
│              clerk                   │
│  • Fetches email (IMAP)             │
│  • Sends email (SMTP)               │
│  • Returns structured JSON          │
│  • Knows nothing about content      │
└─────────────────────────────────────┘

Installation

pip install clerk

Or install from source:

git clone https://github.com/spinoza/clerk.git
cd clerk
pip install -e .

Quick Start

1. Add an account

# Interactive setup for IMAP/SMTP
clerk accounts add --name personal

# Or for Gmail with OAuth
clerk accounts add-gmail work

2. Check your inbox

clerk inbox
clerk inbox --unread --json

3. Read a conversation

clerk show <conv-id>
clerk show <conv-id> --json

4. Search

clerk search "from:alice project deadline"
clerk search "has:attachment after:2025-01-01"

5. Compose and send

# Create a draft
clerk draft new --to bob@example.com --subject "Hello" --body "Hi there!"

# Review it
clerk draft show <draft-id>

# Send it (requires confirmation)
clerk send <draft-id>

CLI Reference

Inbox & Messages

clerk inbox                     # List conversations
clerk inbox --limit 50          # More results
clerk inbox --unread            # Only unread
clerk inbox --fresh             # Bypass cache
clerk inbox --json              # JSON output

clerk show <conv-id>            # Show conversation
clerk show <message-id>         # Show single message
clerk show abc123               # Prefix matching (if unambiguous)

clerk unread                    # Unread counts by folder

Conversation IDs are 12-character SHA256 prefixes. Shorter prefixes work if unambiguous — if multiple conversations match, clerk shows them for disambiguation.

Search

# Basic search (FTS on cached messages)
clerk search "quarterly report"

# Advanced search with operators
clerk search "from:alice subject:meeting has:attachment"

# Raw SQL for power users
clerk search-sql "SELECT * FROM messages WHERE from_addr LIKE '%@example.com'"

Search Operators

Operator Example Description
from: from:alice Sender contains
to: to:bob@example.com Recipient contains
subject: subject:meeting Subject contains
body: body:quarterly Body contains
has:attachment has:attachment Has attachments
is:unread is:unread Unread messages
is:read is:read Read messages
is:flagged is:flagged Starred/flagged
after: after:2025-01-01 After date
before: before:2025-01-15 Before date
date: date:2025-01-10 On specific date

Drafts & Sending

clerk draft new --to bob@example.com --subject "Hi" --body "Hello!"
clerk draft new --reply-to <conv-id> --body "Thanks!"
clerk draft list
clerk draft show <draft-id>
clerk draft delete <draft-id>

clerk send <draft-id>           # Preview and confirm

Attachments

clerk attachment <message-id> --list
clerk attachment <message-id> document.pdf --save ./downloads/

Folders

clerk folders                   # List folders
clerk move <message-id> Archive
clerk archive <message-id>      # Move to Archive

Interactive Shell

clerk shell

The shell provides all CLI commands with tab completion and history:

clerk> inbox --limit 5
clerk> search from:alice
clerk> sql SELECT * FROM messages LIMIT 10
clerk> exit

Account Management

clerk accounts list
clerk accounts add --name work
clerk accounts add-gmail personal
clerk accounts test work
clerk accounts remove work

Cache

clerk cache status
clerk cache clear
clerk cache refresh

Configuration

Config file: ~/.config/clerk/config.yaml

default_account: personal

accounts:
  personal:
    protocol: imap
    imap:
      host: imap.fastmail.com
      port: 993
      username: user@fastmail.com
    smtp:
      host: smtp.fastmail.com
      port: 587
      username: user@fastmail.com
    from:
      address: user@fastmail.com
      name: "User Name"

  work:
    protocol: gmail
    oauth:
      client_id_file: ~/.config/clerk/gmail_client.json

cache:
  window_days: 7
  inbox_freshness_min: 5
  body_freshness_min: 60

send:
  require_confirmation: true
  rate_limit: 20

Credential Storage

Passwords are stored in your system keyring (libsecret, macOS Keychain, Windows Credential Manager).

Alternative methods:

  • password_cmd: "pass email/fastmail" - command that outputs password
  • password_file: ~/.secrets/email.txt - file containing password

MCP Server

Clerk includes an MCP (Model Context Protocol) server for LLM integration:

clerk mcp-server

Add to Claude Code's MCP configuration:

{
  "mcpServers": {
    "clerk": {
      "command": "clerk",
      "args": ["mcp-server"]
    }
  }
}

Available Tools

Tool Description
clerk_inbox List conversations
clerk_show Get conversation/message details (prefix matching)
clerk_search Search messages (FTS + operators)
clerk_sql Readonly SQL queries on message database
clerk_search_sql SQL search returning Message objects
clerk_draft Create draft
clerk_drafts List drafts
clerk_send Send draft (two-step confirmation)
clerk_delete_draft Delete draft
clerk_mark_read Mark message as read
clerk_mark_unread Mark message as unread
clerk_archive Archive message
clerk_move Move message to folder
clerk_flag Flag/unflag message
clerk_attachments List attachments
clerk_status Connection status

Claude Code Skill

Install the clerk skill for Claude Code:

clerk skill install            # Install globally (~/.claude/skills/clerk/)
clerk skill install --local    # Install for current project only
clerk skill status             # Check installation status
clerk skill uninstall          # Remove

The skill teaches Claude Code how to use clerk commands effectively.

Data Locations

~/.config/clerk/
  config.yaml           # Configuration
  gmail_client.json     # Gmail OAuth client (optional)

~/.local/share/clerk/
  cache.db              # Message cache (ephemeral)
  drafts/               # Pending drafts
  sent.log              # Audit log

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run integration tests (requires Docker)
docker-compose -f docker-compose.test.yml up -d
pytest tests/integration/
docker-compose -f docker-compose.test.yml down

# Lint and type check
ruff check src tests
mypy src

Demo Environment

A Docker-based demo with a mock email server (Greenmail):

cd demo
make start        # Start Greenmail mail server
make setup        # Configure clerk for demo
make send-test    # Populate with 18 test emails
make stop         # Tear down

Then use clerk normally: clerk inbox --fresh

See demo/README.md for details on test accounts and email content.

License

MIT License - see LICENSE for details.

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

email_clerk-0.7.0.tar.gz (118.9 kB view details)

Uploaded Source

Built Distribution

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

email_clerk-0.7.0-py3-none-any.whl (47.6 kB view details)

Uploaded Python 3

File details

Details for the file email_clerk-0.7.0.tar.gz.

File metadata

  • Download URL: email_clerk-0.7.0.tar.gz
  • Upload date:
  • Size: 118.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for email_clerk-0.7.0.tar.gz
Algorithm Hash digest
SHA256 ea18d9ceda78ae1cfd5050cecf2905caa8380e744091db5e972c12308df8732d
MD5 cb315b088da3837f0d77e67b56085962
BLAKE2b-256 fc26cecfabef109a290ba678441d0639e21f79e314e545a0f17b0a91ac4359d7

See more details on using hashes here.

File details

Details for the file email_clerk-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: email_clerk-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 47.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for email_clerk-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7da3a3c21b7174c81995eb43c8a7733e70f2aadf40eaf8c360f1b0a1f9a0828b
MD5 e2aa380a2c6fb444991beaefae4efcae
BLAKE2b-256 ee25bb1f4512c376d9bcd0407c3f118af7e9bf00a23b9a4d942dcbd471fafcb4

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