Skip to main content

email-agent

Unified email client with LLM agent. Supports IMAP/SMTP, Outlook COM, CalDAV, and Microsoft Graph API backends.

Backends

Backend Email Calendar Platform Provider
COM Yes Yes Windows only M365/Exchange
IMAP/SMTP Yes No Any Any
CalDAV No Yes Any Google, Nextcloud, iCloud
Graph API No No Any M365 (Phase 3)

Email and calendar backends are independent (for example, IMAP for email plus CalDAV for calendar).

Auto-detection priority:

  1. Explicit BACKEND=com|imap|graph overrides
  2. IMAP_HOST + AZURE_CLIENT_ID + EMAIL_ADDRESS → IMAP
  3. GRAPH_CLIENT_ID → Graph API
  4. Windows → COM

Setup

uv sync              # base (IMAP + LLM agent)
uv sync --extra com  # + Outlook COM (Windows)

Copy .env.example to .env and configure.

IMAP/SMTP (any OS)

AZURE_CLIENT_ID=your-azure-app-client-id
AZURE_TENANT_ID=your-tenant-id
EMAIL_ADDRESS=user@example.com
IMAP_HOST=outlook.office365.com
SMTP_HOST=smtp.office365.com

COM (Windows, no config needed)

Outlook must be running. Auto-detected on Windows if no IMAP config is set.

@mailgent agent

MODEL=anthropic/claude-sonnet-4-5
AZURE_API_KEY=your-api-key
AZURE_API_BASE=https://your-endpoint.openai.azure.com

CLI

uv run python run.py                    # show help

# Email
uv run python run.py search-emails <query>
uv run python run.py read-email <query>
uv run python run.py read-email <query> --save-att
uv run python run.py draft <to> <subject> <body> [--cc=...] [--att=file1,file2]
uv run python run.py send <to> <subject> <body>

# Calendar
uv run python run.py events [days]
uv run python run.py free-slots [days]
uv run python run.py create-event <subject> <start> <end>

# @mailgent agent
uv run python run.py agent [interval]   # polling loop (default 30s)
uv run python run.py agent-once         # process pending and exit

# Archive
uv run python run.py archive            # incremental dump to SQLite
uv run python run.py archive-stats
uv run python run.py archive-search <query>

@mailgent

Write @mailgent: in a draft or incoming email to trigger the LLM agent:

Dear colleague,
@mailgent: What are my free slots next week?

Best regards

The agent processes the prompt, calls tools (search emails, check calendar, etc.), and inserts the response directly below the prompt with a unique ID:

Dear colleague,
@mailgent[a1b2c3d4]: What are my free slots next week?
------------ mailgent[a1b2c3d4] ------------
Monday: 10:00-12:00, 14:00-17:00
Tuesday: 8:00-10:00, 13:00-17:00
------------ mailgent[a1b2c3d4] ------------

Best regards

Re-run: Delete the response block and remove the [id] from the prompt.

Multiple prompts per email are supported, and each gets its own ID.

Tools available to @mailgent

  • search_emails: search by subject
  • read_email: read full email content
  • list_events: calendar events for next N days
  • free_slots: free meeting slots
  • create_draft: create email draft
  • draft_reply / send_reply: reply to an email
  • draft_event / send_event: create calendar event

Config

MAILGENT_TAG=@mailgent
MAILGENT_MODEL=anthropic/claude-sonnet-4-5    # or use MODEL=
MAILGENT_AUTO_REPLY=false                      # reply to inbox emails
MAILGENT_AUTO_SEND=false                       # send replies immediately
MAILGENT_TRUSTED_REPLY=*@company.com           # auto-reply trust list
MAILGENT_TRUSTED_SEND=me@company.com           # auto-send trust list

Tests

uv run pytest tests/ -v                        # all tests
uv run pytest tests/test_backend.py -v         # unit tests (mocked, no backend needed)
uv run pytest tests/test_integration.py -v     # integration tests (needs real backend)

Architecture

src/email_agent/
  config.py        Settings (Pydantic BaseSettings)
  models.py        EmailMessage, Attachment, EventInfo
  exceptions.py    Exception hierarchy
  auth.py          OAuth2 (MSAL device code flow)
  imap_client.py   IMAP read/search/draft
  smtp_client.py   SMTP send
  client.py        MailClient facade (IMAP + SMTP)
  backend.py       EmailBackend + CalendarBackend protocols, IMAPBackend, COMBackend, factory
  com_client.py    Outlook COM wrapper (Windows)
  tools.py         LLM tool definitions + executor
  mailgent.py      @mailgent agent loop
  formatting.py    Markdown ↔ plain/HTML conversion
  archive.py       Incremental SQLite archive

Download files

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

Source Distribution

semos_agentura_email-1.0.0.tar.gz (46.3 kB view details)

Uploaded Source

Built Distribution

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

semos_agentura_email-1.0.0-py3-none-any.whl (43.5 kB view details)

Uploaded Python 3

File details

Details for the file semos_agentura_email-1.0.0.tar.gz.

File metadata

  • Download URL: semos_agentura_email-1.0.0.tar.gz
  • Upload date:
  • Size: 46.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for semos_agentura_email-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0d784e62034088ff0f20bd5aec34d21d2d46546275f4a0ad7ad59b19bd479e9f
MD5 b7baaf785c8e2da9a94173cf6f0d0a25
BLAKE2b-256 c0c5538d23e45b42f07a89ef874f8fbec709929575c030ac9bd2b564abf27dbd

See more details on using hashes here.

File details

Details for the file semos_agentura_email-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: semos_agentura_email-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 43.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for semos_agentura_email-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ff9ffd4e82a07ff134d98ed5bc7c37703936553fe2ee3c0969d2726a232108a
MD5 850afd60ef87c35044ece2c1f9fccef5
BLAKE2b-256 de36c68a3169b2e7b62b6c38ae4bc7cacda0979ff9a23cb80fa0a6c3bc2f3195

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

0.5.0

2 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