Metadata-Version: 2.4
Name: mailmesh
Version: 0.2.0
Summary: Agent-native messaging library with email semantics
Project-URL: Homepage, https://mailmesh.plexital.cc
Project-URL: Repository, https://github.com/plexital/mailmesh
Project-URL: Documentation, https://github.com/plexital/mailmesh/blob/main/docs/API.md
Author-email: Jorge Serrano <jorge@plexital.cc>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: a2a,ai-agents,email,imap,mcp,smtp
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.12
Requires-Dist: aioimaplib>=1.0
Requires-Dist: aiosmtplib>=3.0
Provides-Extra: all
Requires-Dist: mcp>=1.0; extra == 'all'
Requires-Dist: resend>=2.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: mcp>=1.0; extra == 'mcp'
Provides-Extra: resend
Requires-Dist: resend>=2.0; extra == 'resend'
Description-Content-Type: text/markdown

# mailmesh

**Agent-native messaging library with email semantics.**

[![CI](https://github.com/Plexital/mailmesh/actions/workflows/ci.yml/badge.svg)](https://github.com/Plexital/mailmesh/actions)
[![PyPI](https://img.shields.io/pypi/v/mailmesh.svg)](https://pypi.org/project/mailmesh/)
[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](LICENSE)
[![IETF](https://img.shields.io/badge/IETF-draft--ietf--sml--structured--email--05-orange.svg)](https://datatracker.ietf.org/doc/draft-ietf-sml-structured-email/)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)
[![Hermes](https://img.shields.io/badge/integración-Hermes-blueviolet)](https://github.com/NousResearch/hermes-agent)
[![OpenCode](https://img.shields.io/badge/integración-OpenCode-ff69b4)](docs/OPENCODE.md)
[![OpenClaw](https://img.shields.io/badge/integración-OpenClaw-00d4aa)](https://github.com/openclaw/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.

```python
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

```bash
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):

```python
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):

```python
from mailmesh import ResendMailboxBackend

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

### 2. Create an AgentCard

```python
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

```python
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

```bash
# 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)

```bash
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

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

```python
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](https://a2a-protocol.org) AgentCard spec — a self-describing manifest for agents. AgentCards can be exposed as MCP resources.

```python
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](docs/API.md#mailmeshidentity_envelope) 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

```bash
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

```bash
# 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

- [x] W1: Structured email + AgentCard + Mailbox ABC
- [x] W2: SMTP/IMAP adapter + Resend backend
- [x] W3: MCP server
- [x] W4: PyPI release + OSS docs
- [x] 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](https://github.com/NousResearch/hermes-agent)** — Native skill available. `hermes mcp add mailmesh …`
- **[OpenCode](https://github.com/opencode-ai/opencode)** — MCP server config in `docs/OPENCODE.md`
- **[OpenClaw](https://github.com/openclaw/openclaw)** (366k ★) — Native plugin + ClawHub skill. Install with `openclaw plugins install openclaw-mailmesh`. See `integrations/openclaw/`
- **[Claude Code](https://claude.ai/code)** — Connect via MCP (same mailmesh-mcp command)
- **[Any MCP agent](https://modelcontextprotocol.io)** — Standard MCP stdio/HTTP transport

## License

Apache 2.0 — see [LICENSE](LICENSE).

---

Built with ❤️ by [Plexital](https://plexital.cc)
