Metadata-Version: 2.4
Name: agentmail-oss
Version: 0.1.0
Summary: Python SDK for AgentMail — open-source email server for AI agents
Project-URL: Homepage, https://github.com/iamtouchskyer/agentmail-python
Project-URL: Repository, https://github.com/iamtouchskyer/agentmail-python
Project-URL: Issues, https://github.com/iamtouchskyer/agentmail-python/issues
Author-email: AgentMail <hello@agentmail.dev>
License-Expression: MIT
License-File: LICENSE
Keywords: agentmail,agents,ai,email,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.25.0
Requires-Dist: pydantic<3,>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# AgentMail Python SDK

Python client for [AgentMail](https://github.com/iamtouchskyer/agentmail) — open-source email server for AI agents.

[![PyPI](https://img.shields.io/pypi/v/agentmail-oss)](https://pypi.org/project/agentmail-oss/)
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.9+-green)](https://python.org)

## Install

```bash
pip install agentmail-oss
```

## Quick Start

```python
from agentmail import AgentMail

client = AgentMail(api_key="your-key", base_url="http://localhost:3456")

# Create an inbox
inbox = client.inboxes.create(display_name="My Agent")
print(inbox.email)  # agent-xxx@inbox.agentmail.dev

# Send an email
email = client.emails.send(
    inbox.id,
    to="user@example.com",
    subject="Hello from my agent",
    body="This email was sent by an AI agent.",
)

# List emails
emails = client.emails.list(inbox.id)
for e in emails.emails:
    print(f"{e.direction}: {e.subject}")

# Thread memory (the key differentiator)
memory = client.threads.get_memory(inbox.id, email.thread_id)
print(memory.summary)

# Semantic search
results = client.threads.search_memory(
    inbox.id, email.thread_id, query="revenue report"
)
```

## Async

```python
from agentmail import AsyncAgentMail

async with AsyncAgentMail(api_key="your-key") as client:
    inbox = await client.inboxes.create(display_name="Async Agent")
    email = await client.emails.send(inbox.id, to="user@example.com", body="Hello!")
```

## Attachments

```python
# Upload
attachment = client.attachments.upload(
    file=open("report.pdf", "rb"),
    filename="report.pdf",
)

# Send with attachment
client.emails.send(
    inbox.id,
    to="user@example.com",
    subject="Report attached",
    body="See attached.",
    attachment_ids=[attachment.id],
)

# Download
data = client.attachments.download(attachment.id)
with open("downloaded.pdf", "wb") as f:
    f.write(data)
```

## Authentication

```python
# Option 1: Pass explicitly
client = AgentMail(api_key="your-key")

# Option 2: Environment variable
# export AGENTMAIL_API_KEY=your-key
client = AgentMail()

# Custom server URL
# export AGENTMAIL_BASE_URL=http://your-server:3456
client = AgentMail(base_url="http://your-server:3456")
```

## API Reference

### `client.inboxes`
| Method | Description |
|--------|-------------|
| `.create(display_name?, metadata?)` | Create inbox |
| `.list()` | List all inboxes |
| `.get(inbox_id)` | Get inbox with stats |
| `.delete(inbox_id)` | Delete inbox |

### `client.emails`
| Method | Description |
|--------|-------------|
| `.send(inbox_id, to=, subject?, body?, html_body?, attachment_ids?)` | Send email |
| `.list(inbox_id, direction?, limit?, offset?)` | List emails |
| `.get(inbox_id, email_id)` | Get email |
| `.update(inbox_id, email_id, is_read?, is_archived?)` | Update email |
| `.delete(inbox_id, email_id)` | Delete email |

### `client.threads`
| Method | Description |
|--------|-------------|
| `.list(inbox_id)` | List threads |
| `.get(inbox_id, thread_id)` | Get thread with messages |
| `.reply(inbox_id, thread_id, to=, body?)` | Reply to thread |
| `.update(inbox_id, thread_id, is_archived?, labels?)` | Update thread |
| `.delete(inbox_id, thread_id)` | Delete thread |
| `.get_memory(inbox_id, thread_id)` | Get thread memory for agent prompts |
| `.search_memory(inbox_id, thread_id, query=)` | Semantic search within thread |
| `.refresh_memory(inbox_id, thread_id)` | Refresh rolling summary |

### `client.attachments`
| Method | Description |
|--------|-------------|
| `.upload(file=, filename?, content_type?)` | Upload attachment (25MB max) |
| `.download(attachment_id)` | Download as bytes |
| `.get_metadata(attachment_id)` | Get metadata |
| `.delete(attachment_id)` | Delete attachment |

### `client.webhooks`
| Method | Description |
|--------|-------------|
| `.create(url=, events?, secret?)` | Register webhook |
| `.list()` | List webhooks |
| `.delete(webhook_id)` | Delete webhook |

## Error Handling

```python
from agentmail import AgentMail, NotFoundError, AuthenticationError

try:
    client.inboxes.get("nonexistent-id")
except NotFoundError:
    print("Inbox not found")
except AuthenticationError:
    print("Invalid API key")
```

## Requirements

- Python 3.9+
- [AgentMail server](https://github.com/iamtouchskyer/agentmail) running (self-hosted)

## License

MIT
