Moperator Moperator Docs

Moperator Documentation

Moperator is email infrastructure for AI agents. It provides a REST API, MCP server, and webhooks to let your AI assistants send and receive email.

Base URL: https://api.moperator.work

Quickstart

  1. 1. Sign up at app.moperator.work
  2. 2. Get your API key from the dashboard (format: mop_xxx_yyy)
  3. 3. Your email address is [email protected]
  4. 4. Query emails using the REST API or connect via MCP

Authentication

All API requests require a Bearer token in the Authorization header:

Authorization: Bearer mop_yourtenantid_yoursecret

Your API key is available in the dashboard after signing up.

List Emails

GET /api/v1/emails

Retrieve a list of emails with optional filtering.

Query Parameters

Parameter Type Description
labels string Filter by label (comma-separated for multiple)
status string unread or read
limit number Max emails to return (default: 20)
offset number Pagination offset

Example Request

curl "https://api.moperator.work/api/v1/emails?status=unread&labels=finance" \
  -H "Authorization: Bearer mop_yourkey"

Response

{
  "emails": [
    {
      "id": "1704067200000-abc123",
      "email": {
        "from": "[email protected]",
        "to": "[email protected]",
        "subject": "Invoice #1234",
        "textBody": "Please find attached...",
        "receivedAt": "2024-01-01T00:00:00.000Z"
      },
      "labels": ["finance", "important"],
      "status": "unread",
      "processedAt": "2024-01-01T00:00:01.000Z"
    }
  ],
  "total": 1,
  "unreadCount": 1
}

Get Email

GET /api/v1/emails/:id

Retrieve a single email by ID.

Query Parameters

markRead boolean Set to true to automatically mark as read

Example

# Get email without marking as read
curl "https://api.moperator.work/api/v1/emails/1704067200000-abc123" \
  -H "Authorization: Bearer mop_yourkey"

# Get email and mark as read
curl "https://api.moperator.work/api/v1/emails/1704067200000-abc123?markRead=true" \
  -H "Authorization: Bearer mop_yourkey"

Update Email Status

PATCH /api/v1/emails/:id

Update the read/unread status of an email.

Request Body

{
  "status": "read"  // or "unread"
}

Example

curl -X PATCH "https://api.moperator.work/api/v1/emails/1704067200000-abc123" \
  -H "Authorization: Bearer mop_yourkey" \
  -H "Content-Type: application/json" \
  -d '{"status": "read"}'

Search Emails

GET /api/v1/emails/search

Search emails by sender, subject, or labels.

Query Parameters

from string Filter by sender (partial match)
subject string Filter by subject (partial match)
labels string Filter by labels

Example

curl "https://api.moperator.work/api/v1/emails/search?from=stripe&subject=invoice" \
  -H "Authorization: Bearer mop_yourkey"

Labels

Labels are used by Claude to automatically classify incoming emails. Define labels with descriptions to help Claude understand what each label means.

List Labels

curl "https://api.moperator.work/api/v1/labels" \
  -H "Authorization: Bearer mop_yourkey"

Create Label

curl -X POST "https://api.moperator.work/api/v1/labels" \
  -H "Authorization: Bearer mop_yourkey" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "finance",
    "name": "Finance",
    "description": "Invoices, receipts, bank statements, payment confirmations"
  }'

Claude Desktop (MCP)

Connect Moperator to Claude Desktop using the Model Context Protocol (MCP).

Configuration

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "moperator": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://api.moperator.work/mcp",
        "--header", "Authorization: Bearer mop_yourkey"
      ]
    }
  }
}

Available Tools

  • list_emails - List emails with optional filters
  • get_email - Get a specific email by ID
  • search_emails - Search emails by sender/subject
  • mark_as_read - Mark an email as read

Example Prompts

  • "Check my email"
  • "Do I have any unread emails?"
  • "Show me emails labeled finance"
  • "Search for emails from Stripe"

ChatGPT (OpenAPI)

Connect Moperator to ChatGPT using OpenAPI Actions.

Setup

  1. 1. Go to ChatGPT → Create a GPT → Configure → Actions
  2. 2. Click "Import from URL"
  3. 3. Enter: https://api.moperator.work/openapi.json
  4. 4. Set authentication to "API Key" with header Authorization
  5. 5. Enter your API key as Bearer mop_yourkey

Webhooks

Receive real-time notifications when emails arrive. Configure webhooks in the dashboard to get POST requests to your endpoint.

Webhook Payload

{
  "email": {
    "from": "[email protected]",
    "to": "[email protected]",
    "subject": "Hello",
    "textBody": "Email content...",
    "receivedAt": "2024-01-01T00:00:00.000Z"
  },
  "labels": ["important"],
  "matchedLabel": "important",
  "timestamp": "2024-01-01T00:00:01.000Z",
  "signature": "sha256=..."
}

Verifying Signatures

Webhooks include an HMAC-SHA256 signature for verification:

import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Python Example

import requests

API_KEY = "mop_yourkey"
BASE_URL = "https://api.moperator.work"

headers = {"Authorization": f"Bearer {API_KEY}"}

# List unread emails
response = requests.get(
    f"{BASE_URL}/api/v1/emails",
    headers=headers,
    params={"status": "unread"}
)
emails = response.json()

print(f"You have {emails['unreadCount']} unread emails")

for email in emails['emails']:
    print(f"- {email['email']['subject']} from {email['email']['from']}")

# Get and mark as read
if emails['emails']:
    email_id = emails['emails'][0]['id']
    detail = requests.get(
        f"{BASE_URL}/api/v1/emails/{email_id}",
        headers=headers,
        params={"markRead": "true"}
    ).json()
    print(f"\nRead: {detail['email']['textBody'][:200]}...")

JavaScript / Node.js Example

const API_KEY = 'mop_yourkey';
const BASE_URL = 'https://api.moperator.work';

const headers = {
  'Authorization': `Bearer ${API_KEY}`,
  'Content-Type': 'application/json'
};

// List unread emails
async function getUnreadEmails() {
  const response = await fetch(
    `${BASE_URL}/api/v1/emails?status=unread`,
    { headers }
  );
  const data = await response.json();

  console.log(`You have ${data.unreadCount} unread emails`);

  for (const email of data.emails) {
    console.log(`- ${email.email.subject} from ${email.email.from}`);
  }

  return data.emails;
}

// Mark email as read
async function markAsRead(emailId) {
  await fetch(`${BASE_URL}/api/v1/emails/${emailId}`, {
    method: 'PATCH',
    headers,
    body: JSON.stringify({ status: 'read' })
  });
}

getUnreadEmails();