Skip to main content

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
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.

# 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.

Release files for email-clerk 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for email-clerk 0.7.0
File Size Uploaded
email_clerk-0.7.0.tar.gz 118.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for email-clerk 0.7.0
File Interpreter ABI Platform
email_clerk-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 166.5 kB

Release files / email_clerk-0.7.0.tar.gz

Download URL email_clerk-0.7.0.tar.gz
Size 118.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ea18d9ceda78ae1cfd5050cecf2905caa8380e744091db5e972c12308df8732d
BLAKE2b-256 checksum
How to use checksums
fc26cecfabef109a290ba678441d0639e21f79e314e545a0f17b0a91ac4359d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release files / email_clerk-0.7.0-py3-none-any.whl

Download URL email_clerk-0.7.0-py3-none-any.whl
Size 47.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7da3a3c21b7174c81995eb43c8a7733e70f2aadf40eaf8c360f1b0a1f9a0828b
BLAKE2b-256 checksum
How to use checksums
ee25bb1f4512c376d9bcd0407c3f118af7e9bf00a23b9a4d942dcbd471fafcb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page