Skip to main content

Agent-native messaging library with email semantics

Project description

mailmesh

Agent-native messaging library with email semantics.

CI Python 3.12+ License IETF

⚠️ Private alpha — public launch W10. Currently in active development.

mailmesh turns any email backend into an agent-native messaging endpoint. Send structured JSON-LD emails, receive machine-readable messages (MRM), and expose email operations to AI agents via MCP — all through a single unified API.

from mailmesh import AgentMailbox, SMTPIMAPBackend

backend = SMTPIMAPBackend(
    imap_host="mail.example.com", imap_port=993,
    smtp_host="mail.example.com", smtp_port=465,
    username="agent@example.com", password="...",
)
box = AgentMailbox(backend)

# Send a fully machine-readable message
await box.send(
    to=["ops@company.com"],
    subject="New deploy",
    structured_data={"@type": "Event", "action": "deploy", "app": "api"},
)

# Read MRM-only messages from inbox
mrm_messages = await box.list(filter_mrm=True)

Why email?

Email is the only truly federated, self-hostable, IETF-standardized messaging protocol. Agents don't need Slack webhooks or vendor-locked APIs — they need a protocol that works across organizational boundaries, with built-in identity (DKIM), delivery guarantees, and decades of infrastructure.

mailmesh puts that protocol in a Python package.


Architecture

┌──────────────────────────────────────────────────┐
│  AgentMailbox (high-level API)                   │
│  ┌────────────┐  ┌──────────┐  ┌─────────────┐  │
│  │ Structured │  │ Identity │  │ Mailbox     │  │
│  │ Email      │  │ Envelope │  │ Abstraction │  │
│  └────────────┘  └──────────┘  └──────┬──────┘  │
│                          ┌────────────┼───────┐  │
│                          │ Backends   │       │  │
│                          │ SMTP/IMAP  Resend │  │
│                          └───────────────────┘  │
│  ┌─────────────────────────────────────────────┐ │
│  │ MCP Server (expose to AI agents)            │ │
│  └─────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘

Installation

pip install mailmesh

# With MCP server support
pip install mailmesh[mcp]

# With Resend backend
pip install mailmesh[resend]

# Development
pip install mailmesh[dev]

Quick start

1. Pick a backend

SMTP/IMAP (any mail server — Mailu, Postfix, Gmail, Fastmail):

from mailmesh import SMTPIMAPBackend

backend = SMTPIMAPBackend(
    imap_host="mail.plexital.cc", imap_port=993,
    smtp_host="mail.plexital.cc", smtp_port=465,
    username="agent@example.com", password="...",
)

Resend (API-first, best deliverability):

from mailmesh import ResendMailboxBackend

backend = ResendMailboxBackend(
    api_key="re_xxx",
    domain="mailmesh.example.com",
)

2. Create an AgentCard

from mailmesh import AgentCard, AgentInterface, AgentSkill

card = AgentCard(
    name="deploy-bot",
    description="CI/CD deployment agent",
    version="1.0.0",
    interfaces=[AgentInterface(url="https://bots.example.com/mcp", protocol_binding="JSONRPC")],
    skills=[AgentSkill(id="deploy", name="Deploy", description="Deploy services")],
)

3. Start messaging

from mailmesh import AgentMailbox

box = AgentMailbox(backend, identity_card=card)

# Send with structured data
await box.send(
    to=["ops@company.com"],
    subject="Deploy: api v2.3",
    structured_data={"@type": "DeployRequest", "app": "api", "version": "v2.3"},
    text="Deploying API v2.3 to production",
)

# List machine-readable messages
mrm = await box.list(filter_mrm=True)
for msg in mrm:
    print(f"[MRM] {msg.subject} from {msg.from_addr}")

# Search
results = await box.search("deploy")

4. Run as MCP server

# Expose email to any MCP-compatible AI agent
mailmesh-mcp --backend smtp-imap \
  --imap-host mail.plexital.cc --imap-port 993 \
  --smtp-host mail.plexital.cc --smtp-port 465 \
  --username agent@plexital.cc --password ...

Self-hosting

Docker Compose (dev)

git clone https://github.com/Plexital/mailmesh
cd mailmesh
cp .env.example .env
# Edit .env with your mail server credentials

# Dev mode: Mailpit catches all emails (nothing leaves your machine)
docker compose -f docker-compose.dev.yml up -d
# Open http://localhost:8025 → see captured emails
# MCP server running on stdio — connect any MCP agent

# Production: connects to your real mail server
docker compose up -d

Manual

pip install mailmesh[mcp]
mailmesh-mcp --backend smtp-imap \
  --imap-host mail.example.com --imap-port 993 \
  --smtp-host mail.example.com --smtp-port 465 \
  --username agent@example.com --password ...

Core concepts

Structured Email (IETF draft-ietf-sml-structured-email-05)

mailmesh implements the IETF SML working group draft for structured email. Emails can carry JSON-LD as a dedicated MIME part (application/ld+json) with custom headers for efficient filtering.

from mailmesh import StructuredEmail

email = StructuredEmail.from_email(raw_bytes)
print(email.is_mrm)          # True if fully machine-readable
print(email.structured_data) # {"@type": "Order", "orderNumber": "123"}

Machine-Readable Messages (MRM)

An MRM is an email with no human-readable content — only structured JSON-LD data. IMAP servers can filter MRM messages with the $MRM header flag.

Header Value Meaning
$MRM true Fully machine-readable
$hasStructuredData true Contains JSON-LD attachment

AgentCard (A2A v1.0)

mailmesh implements the Agent2Agent AgentCard spec — a signed identity card for agents. AgentCards can be exposed as MCP resources.

from mailmesh import AgentCard, AgentCardSignature

card = AgentCard(name="my-agent", ...)
signed = AgentCardSignature.sign(card, private_key_pem)

MCP Server

Expose mail operations as MCP tools for any AI agent:

Tool Description
send_email Send an email with optional structured data
read_email Read a single email by ID
list_emails List inbox with MRM filtering
search_emails Full-text search across inbox

Resources:

  • agent-card://identity — AgentCard JSON

Development

git clone https://github.com/Plexital/mailmesh
cd mailmesh
uv pip install -e ".[dev]"
uv run pytest                 # 93 tests
uv run ruff check src/        # Lint

Running with real Mailu

# Create test account (requires Mailu admin API)
curl -X POST http://127.0.0.1:8080/api/v1/user \
  -H "Authorization: Bearer $API_TOKEN" \
  -d '{"email": "test-agent@plexital.cc", "raw_password": "..."}'

# Smoke test
python -c "
from mailmesh import SMTPIMAPBackend, AgentMailbox
import asyncio

async def test():
    b = SMTPIMAPBackend('mail.plexital.cc', 993, 'mail.plexital.cc', 465, 'test-agent@plexital.cc', '...')
    box = AgentMailbox(b)
    await box.send(to=['test-agent@plexital.cc'], subject='Test', text='Hello')
    msgs = await box.list(limit=5)
    print(f'{len(msgs)} messages in inbox')

asyncio.run(test())
"

Roadmap

  • W1: Structured email + AgentCard + Mailbox ABC
  • W2: SMTP/IMAP adapter + Resend backend
  • W3: MCP server
  • W5-7: TypeScript SDK, docs, docker-compose
  • W8-10: Landing page, integration tests
  • W11: Public release, Show HN

License

Apache 2.0 — see LICENSE.


Built with ❤️ by Plexital

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

mailmesh-0.1.0.tar.gz (80.3 kB view details)

Uploaded Source

Built Distribution

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

mailmesh-0.1.0-py3-none-any.whl (26.2 kB view details)

Uploaded Python 3

File details

Details for the file mailmesh-0.1.0.tar.gz.

File metadata

  • Download URL: mailmesh-0.1.0.tar.gz
  • Upload date:
  • Size: 80.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for mailmesh-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f6c68ea28d102b22260a4c32fac49b309bfa097663e816cc9abb8458fcb47bb1
MD5 a142a7c48c2e5c69b701cdc246c939b2
BLAKE2b-256 9d388931b52ca5ccc92021ec8549e443215dff449641e4faee131c3588e3ad92

See more details on using hashes here.

File details

Details for the file mailmesh-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mailmesh-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for mailmesh-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8cb1025ffb3245151dcbcdb95746de005b93652d2ccb9bca21169e104abeaf84
MD5 945b4fad51d453b5a0be8c091078ce1d
BLAKE2b-256 e0397cb462d882ac7c5c55cdbc174cf3c6601d1c3db8be38ce3b051547f1f617

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