active tool

clerk

Started 2026 Python

Resources & Distribution

Source Code

Package Registries

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 unread                    # Unread counts by folder
# 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

OperatorExampleDescription
from:from:aliceSender contains
to:to:bob@example.comRecipient contains
subject:subject:meetingSubject contains
body:body:quarterlyBody contains
has:attachmenthas:attachmentHas attachments
is:unreadis:unreadUnread messages
is:readis:readRead messages
is:flaggedis:flaggedStarred/flagged
after:after:2025-01-01After date
before:before:2025-01-15Before date
date:date:2025-01-10On 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

ToolDescription
clerk_inboxList conversations
clerk_showGet message details
clerk_conversationGet full thread
clerk_searchSearch messages
clerk_search_sqlRaw SQL search
clerk_draftCreate draft
clerk_draftsList drafts
clerk_sendSend draft
clerk_delete_draftDelete draft
clerk_foldersList folders
clerk_unreadUnread counts
clerk_moveMove message
clerk_attachmentsList/download attachments

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
ruff check src tests

License

MIT License - see LICENSE for details.

Discussion