Skip to main content

Agent-native messaging library with email semantics

Project description

mailmesh

Agent-native messaging library with email semantics.

CI PyPI Python 3.12+ License IETF Contributor Covenant Hermes OpenCode OpenClaw

⚠️ Alpha — public launch W10. Currently in active development. 112 tests passing.

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

# Build a structured email
se = StructuredEmail()
se.add_human_text("Your order #1234 has shipped!")
se.set_structured_data({"@type": "Order", "orderNumber": "1234"})
mime_msg = se.to_mime()

# Inspect an incoming MIME message
data = StructuredEmail.parse_structured_data(mime_msg)  # dict | None
StructuredEmail.is_structured(mime_msg)                 # bool
StructuredEmail.is_mrm(mime_msg)                        # bool — machine-only

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 self-describing manifest for agents. AgentCards can be exposed as MCP resources.

from mailmesh import AgentCard, AgentInterface, AgentSkill, AgentCardSignature

card = AgentCard(
    name="my-agent",
    description="Example agent",
    version="1.0.0",
    interfaces=[AgentInterface(url="https://bots.example.com/mcp")],
    skills=[AgentSkill(id="ping", name="Ping", description="Health check")],
)

# Sign the card payload with a PEM-encoded RSA private key (RS256).
# `private_key_pem` is required; create() raises ValueError if it can't be loaded.
sig = AgentCardSignature.create(card.to_json(), private_key_pem=private_key_pem)

⚠️ AgentCardSignature is sign-only — there is no verify() method yet. See API.md for the exact surface and limitations.

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                 # 112 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
  • W4: PyPI release + OSS docs
  • W5: OpenClaw plugin + SKILL.md, HumanBridge
  • W6: Polish + Show HN prep (docs, tests, landing)
  • W11: Public release, Show HN

Ecosystem

mailmesh integrates with agent frameworks via MCP:

  • Hermes Agent — Native skill available. hermes mcp add mailmesh …
  • OpenCode — MCP server config in docs/OPENCODE.md
  • OpenClaw (366k ★) — Native plugin + ClawHub skill. Install with openclaw plugins install openclaw-mailmesh. See integrations/openclaw/
  • Claude Code — Connect via MCP (same mailmesh-mcp command)
  • Any MCP agent — Standard MCP stdio/HTTP transport

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.2.0.tar.gz (121.5 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.2.0-py3-none-any.whl (32.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for mailmesh-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b9487891472b5fc2299ca2aafd91195b3a0bb13e1179d374a17c3e86aa987f13
MD5 326f73e6efd94c189d45868f12cc888a
BLAKE2b-256 af8a29b5da2a93570f8093bca91faa51158c5d354ea46b0dd4e32551459c38e2

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for mailmesh-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 11b6054aaa651f9fd435c54cb66528546bbbc91cf785cd0a0f710184680f540b
MD5 86ffd7578890fa5f3afaa81e459e8932
BLAKE2b-256 3b2fbb1544cf8f5878a120487c9e08ef76c564abacc112f019718a97313399fc

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