@aiondadotcom/mail-mcp-client
v0.2.0
Published
Aionda Mail MCP Proxy — E2E encrypted email access for AI agents via stdio
Downloads
97
Readme
@aiondadotcom/mail-mcp-client
TypeScript MCP client for Aionda Mail — E2E encrypted email access for AI agents.
Connects to TrashMail.com's MCP server via JSON-RPC 2.0 over HTTP. Supports full client-side decryption using Hybrid KEM (X25519 + ML-KEM-1024) for post-quantum security.
Install
npm install @aiondadotcom/mail-mcp-clientRequirements: Node.js >= 18
Quick Start
import { AiondaMailClient } from '@aiondadotcom/mail-mcp-client';
const client = new AiondaMailClient({
apiKey: 'tma_...',
vaultKey: '...', // hex-encoded 32-byte master key (optional)
vaultPrivateKeys: '...', // hex-encoded x25519+mlkem private keys (optional)
});
await client.connect();
// List folders
const folders = await client.listFolders();
// List emails
const emails = await client.listEmails('inbox', 20, 0);
// Read + decrypt an email
const email = await client.readEmailDecrypted('email-uuid');
console.log(email.subject, email.from, email.bodyText);
// Send an email
await client.sendEmail({
from_identity: '[email protected]',
to: '[email protected]',
subject: 'Hello',
body: '<p>Hello from AI</p>',
});
await client.disconnect();Features
- 26 MCP tools — folders, emails, DEAs, drafts, send/reply/forward, shared folders, events
- E2E decryption — AES-256-GCM with PHP format translation, HKDF key derivation, gzip decompression, bucket-padding removal
- Post-quantum crypto — Hybrid KEM (X25519 + ML-KEM-1024) via
@noble/post-quantum - Shared folders — list, share, revoke, update permissions, decrypt shared folder keys
- Real-time events — SSE/Mercure subscription with E2E encrypted event payloads
- Dual ESM + CJS — works with import and require
- 2 runtime dependencies — only
@noble/hashesand@noble/post-quantum
API Reference
Constructor
new AiondaMailClient({
apiKey: string; // MCP API key (tma_*)
vaultKey?: string; // Hex-encoded 32-byte vault master key
vaultPrivateKeys?: string; // Hex-encoded x25519(32) + mlkem(3168) private keys
endpoint?: string; // Server URL (default: https://trashmail.com)
timeout?: number; // Request timeout in ms (default: 30000)
})Without vaultKey/vaultPrivateKeys, the client works as a plain MCP transport (encrypted data returned as-is). With keys, *Decrypted() methods become available.
Lifecycle
| Method | Description |
|--------|-------------|
| connect() | Initialize MCP session |
| disconnect() | Close session |
| ping() | Keep-alive |
| isConnected() | Check session state |
Folders
| Method | Description |
|--------|-------------|
| listFolders() | List folders (encrypted names) |
| listFoldersDecrypted() | List folders with decrypted names |
Emails
| Method | Description |
|--------|-------------|
| listEmails(folder, limit, offset) | List emails in folder |
| readEmail(uuid) | Read email (encrypted) |
| readEmailDecrypted(uuid) | Read + decrypt email |
| markRead(uuid) | Mark as read |
| markUnread(uuid) | Mark as unread |
| moveEmail(uuid, folder) | Move to folder |
| deleteEmail(uuid) | Delete email |
Send / Reply / Forward
| Method | Description |
|--------|-------------|
| sendEmail(params) | Send new email |
| replyEmail(params) | Reply to email |
| forwardEmail(params) | Forward email |
Drafts
| Method | Description |
|--------|-------------|
| saveDraft(params) | Save/update draft |
| listDrafts(limit, offset) | List drafts |
| getDraft(id) | Get draft |
| deleteDraft(id) | Delete draft |
DEA Management
| Method | Description |
|--------|-------------|
| listDeas() | List disposable addresses |
| getDea(uid) | Get DEA details |
| createDea(params) | Create new DEA |
| updateDea(params) | Update DEA |
| deleteDea(uid) | Delete DEA |
Shared Folders
| Method | Description |
|--------|-------------|
| listSharedFolders(direction?) | List incoming + outgoing shares ('both', 'incoming', 'outgoing') |
| shareFolder(params) | Share folder with another user |
| revokeShare(uuid) | Revoke a share |
| updateSharePermissions(params) | Update share permissions |
| getRecipientKeys(username) | Get recipient's public keys |
| decryptSharedFolderKey(share) | Decrypt incoming share's folder key |
Events
| Method | Description |
|--------|-------------|
| callTool('event_subscribe', params) | Subscribe to real-time SSE events |
| callTool('get_missed_events', params) | Retrieve events missed while offline |
Low-Level
// Call any MCP tool directly
const result = await client.callTool('tool_name', { param: 'value' });
// List available tools
const tools = await client.listTools();Real-Time Events
Subscribe to E2E encrypted server-sent events via Mercure:
import { AiondaMailClient, AiondaEventClient } from '@aiondadotcom/mail-mcp-client';
import { fromHex } from '@aiondadotcom/mail-mcp-client';
const client = new AiondaMailClient({ apiKey: 'tma_...' });
await client.connect();
const privateKeysRaw = fromHex('...');
const events = new AiondaEventClient(client, {
x25519PrivateKey: privateKeysRaw.slice(0, 32),
mlKemPrivateKey: privateKeysRaw.slice(32),
});
events.on('email.received', (event) => {
console.log('New email:', event.data.email_uuid);
});
events.on('notification.new', (event) => {
console.log('Notification:', event.data);
});
await events.connect(['email.received', 'notification.new']);
// Fetch events missed while offline
const missed = await events.fetchMissedEvents();
// Disconnect
events.disconnect();Supported event types: email.received, notification.new, calendar.event, calendar.invite, chat.message, task.update, file.share
Note: EventSource is available natively in Node.js 22+. For Node.js 18-20, use a polyfill like eventsource.
Error Handling
import {
McpError,
McpAuthError,
McpRateLimitError,
McpSessionExpiredError,
McpToolError,
McpDecryptionError,
} from '@aiondadotcom/mail-mcp-client';
try {
await client.readEmailDecrypted('uuid');
} catch (error) {
if (error instanceof McpAuthError) {
// Invalid API key (error code 61)
} else if (error instanceof McpRateLimitError) {
// Rate limited (429), check error.retryAfter
} else if (error instanceof McpDecryptionError) {
// Decryption failed (wrong key, corrupted data)
}
}Crypto Utilities
For advanced usage, crypto primitives are exported:
import {
decryptEmail,
decryptAesGcm,
decryptPhpAesGcm,
hybridDecapsulate,
deriveFolderKey,
decryptSharedFolderKey,
decompress,
isBucketPadded,
unpadFromBucket,
decodeMimeEncodedWords,
fromHex,
toHex,
fromBase64,
toBase64,
} from '@aiondadotcom/mail-mcp-client';Development
npm install
npm run build # ESM + CJS
npm test # Vitest (56+ tests)
npm run lint # ESLint
npm run lint # ESLintArchitecture
src/
client.ts # AiondaMailClient — high-level typed API
events.ts # AiondaEventClient — SSE/Mercure real-time events
transport.ts # HTTP JSON-RPC 2.0 transport
session.ts # MCP session lifecycle
errors.ts # Error hierarchy
constants.ts # Protocol constants
types/ # TypeScript interfaces (tools, emails, folders, events)
crypto/ # Decryption pipeline
aes-gcm.ts # AES-256-GCM with PHP format reorder
key-derivation.ts # HKDF-SHA256 folder key derivation
hybrid-kem.ts # X25519 + ML-KEM-1024
shared-folder-key.ts # Shared folder key decryption
email-decryptor.ts # Full email decryption pipeline
decompression.ts # Gzip/zlib detection + decompression
bucket-padding.ts # 0xDEAD bucket-padding removal
mime-decoder.ts # RFC 2047 MIME encoded-word decoder
encoding.ts # hex/base64 utilitiesLicense
Proprietary — Aionda GmbH
