{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "name": "EmailEngine",
  "description": "Self-hosted email API gateway providing REST API access to email accounts via IMAP, SMTP, Gmail API, and Microsoft Graph API",
  "version": "2.79.5",
  "documentationUrl": "https://learn.emailengine.app/",
  "openApiSpec": "https://go.emailengine.app/swagger.json",
  "authentication": {
    "type": "bearer",
    "header": "Authorization",
    "format": "Bearer {token}",
    "alternativeQueryParam": "access_token"
  },
  "baseUrl": "http://localhost:3000/v1",
  "capabilities": {
    "accountManagement": {
      "description": "Register, configure, and manage email account connections",
      "features": ["oauth2", "imap", "smtp", "gmail-api", "ms-graph", "service-accounts"],
      "endpoints": [
        {"method": "POST", "path": "/v1/account", "description": "Register new email account"},
        {"method": "GET", "path": "/v1/accounts", "description": "List all accounts (paginated)"},
        {"method": "GET", "path": "/v1/account/{account}", "description": "Get account details"},
        {"method": "PUT", "path": "/v1/account/{account}", "description": "Update account configuration"},
        {"method": "DELETE", "path": "/v1/account/{account}", "description": "Delete account (pass ?revoke=true to also revoke the upstream OAuth2 grant; supported for individual Gmail OAuth grants, no-op otherwise)"},
        {"method": "PUT", "path": "/v1/account/{account}/reconnect", "description": "Force reconnection"},
        {"method": "PUT", "path": "/v1/account/{account}/flush", "description": "Reset sync state"},
        {"method": "PUT", "path": "/v1/account/{account}/sync", "description": "Trigger immediate sync"},
        {"method": "GET", "path": "/v1/account/{account}/oauth-token", "description": "Get OAuth2 access token"},
        {"method": "POST", "path": "/v1/verifyAccount", "description": "Test account credentials"},
        {"method": "POST", "path": "/v1/authentication/form", "description": "Generate hosted auth form URL. Optional expectedEmail restricts the setup to one address"},
        {"method": "GET", "path": "/v1/autoconfig", "description": "Auto-detect IMAP/SMTP settings"},
        {"method": "GET", "path": "/v1/account/{account}/server-signatures", "description": "List server signatures"}
      ]
    },
    "messageOperations": {
      "description": "Read, search, update, and delete email messages",
      "features": ["list", "search", "read", "update-flags", "move", "delete", "download-attachments"],
      "endpoints": [
        {"method": "GET", "path": "/v1/account/{account}/messages", "description": "List messages in mailbox"},
        {"method": "GET", "path": "/v1/account/{account}/message/{message}", "description": "Get message details. Pass textType=* for bodies; webSafeHtml=true returns sanitized HTML ready to display, with inline images embedded (pass embedAttachedImages=false to keep the cid: references instead) and quoted thread history wrapped in <details class=\"ee-collapsed-thread\">"},
        {"method": "GET", "path": "/v1/account/{account}/message/{message}/source", "description": "Get raw RFC822 source"},
        {"method": "PUT", "path": "/v1/account/{account}/message/{message}", "description": "Update flags/labels"},
        {"method": "DELETE", "path": "/v1/account/{account}/message/{message}", "description": "Delete message"},
        {"method": "PUT", "path": "/v1/account/{account}/message/{message}/move", "description": "Move to mailbox"},
        {"method": "POST", "path": "/v1/account/{account}/message", "description": "Upload message"},
        {"method": "POST", "path": "/v1/account/{account}/search", "description": "Search messages"},
        {"method": "GET", "path": "/v1/account/{account}/text/{text}", "description": "Get text part"},
        {"method": "GET", "path": "/v1/account/{account}/attachment/{attachment}", "description": "Download attachment"}
      ]
    },
    "bulkOperations": {
      "description": "Perform operations on multiple messages at once",
      "endpoints": [
        {"method": "PUT", "path": "/v1/account/{account}/messages", "description": "Update flags/labels for all messages matching a search"},
        {"method": "PUT", "path": "/v1/account/{account}/messages/move", "description": "Move multiple messages"},
        {"method": "PUT", "path": "/v1/account/{account}/messages/delete", "description": "Delete multiple messages"}
      ]
    },
    "mailboxManagement": {
      "description": "List, create, and delete mailbox folders",
      "endpoints": [
        {"method": "GET", "path": "/v1/account/{account}/mailboxes", "description": "List all mailboxes"},
        {"method": "POST", "path": "/v1/account/{account}/mailbox", "description": "Create mailbox"},
        {"method": "PUT", "path": "/v1/account/{account}/mailbox", "description": "Rename mailbox or change subscription status"},
        {"method": "DELETE", "path": "/v1/account/{account}/mailbox", "description": "Delete mailbox"}
      ]
    },
    "emailSending": {
      "description": "Send emails with attachments, templates, and tracking",
      "features": ["html", "attachments", "templates", "mail-merge", "scheduling", "tracking", "replies", "forwards", "drafts"],
      "endpoints": [
        {"method": "POST", "path": "/v1/account/{account}/submit", "description": "Send/queue email"},
        {"method": "POST", "path": "/v1/account/{account}/message/{message}/submit", "description": "Send a stored draft by message ID"},
        {"method": "GET", "path": "/v1/outbox", "description": "List queued emails"},
        {"method": "GET", "path": "/v1/outbox/{queueId}", "description": "Get queued email"},
        {"method": "DELETE", "path": "/v1/outbox/{queueId}", "description": "Cancel queued email"}
      ],
      "submitParameters": {
        "required": ["to"],
        "optional": [
          {"name": "to", "type": "array", "description": "Recipients [{address, name}]"},
          {"name": "cc", "type": "array", "description": "CC recipients"},
          {"name": "bcc", "type": "array", "description": "BCC recipients"},
          {"name": "subject", "type": "string", "description": "Email subject"},
          {"name": "text", "type": "string", "description": "Plain text body"},
          {"name": "html", "type": "string", "description": "HTML body"},
          {"name": "from", "type": "object", "description": "Override sender {address, name}"},
          {"name": "replyTo", "type": "object", "description": "Reply-to address"},
          {"name": "attachments", "type": "array", "description": "Attachments [{filename, content, contentType}]"},
          {"name": "headers", "type": "object", "description": "Custom email headers"},
          {"name": "reference", "type": "object", "description": "For replies/forwards {message, action}"},
          {"name": "template", "type": "string", "description": "Template ID to use"},
          {"name": "mailMerge", "type": "array", "description": "Bulk personalized sending"},
          {"name": "sendAt", "type": "string", "description": "Schedule sending (ISO 8601)"},
          {"name": "trackOpens", "type": "boolean", "description": "Enable open tracking"},
          {"name": "trackClicks", "type": "boolean", "description": "Enable click tracking"},
          {"name": "copy", "type": "boolean", "description": "Save to Sent folder (default: true)"},
          {"name": "dryRun", "type": "boolean", "description": "Preview without sending"},
          {"name": "gateway", "type": "string", "description": "Use specific SMTP gateway"},
          {"name": "deliveryAttempts", "type": "number", "description": "Max retry attempts"}
        ]
      }
    },
    "templates": {
      "description": "Create and manage reusable email templates",
      "endpoints": [
        {"method": "GET", "path": "/v1/templates", "description": "List templates"},
        {"method": "POST", "path": "/v1/templates/template", "description": "Create template"},
        {"method": "GET", "path": "/v1/templates/template/{template}", "description": "Get template"},
        {"method": "PUT", "path": "/v1/templates/template/{template}", "description": "Update template"},
        {"method": "DELETE", "path": "/v1/templates/template/{template}", "description": "Delete template"},
        {"method": "DELETE", "path": "/v1/templates/account/{account}", "description": "Delete all templates for an account"}
      ]
    },
    "webhooks": {
      "description": "Real-time notifications for email events",
      "endpoints": [
        {"method": "GET", "path": "/v1/webhookRoutes", "description": "List webhook routes"},
        {"method": "GET", "path": "/v1/webhookRoutes/webhookRoute/{webhookRoute}", "description": "Get a webhook route. Webhook routes are read-only via the API; create and edit them in the EmailEngine dashboard"}
      ],
      "configurationViaSettings": {
        "endpoint": "POST /v1/settings",
        "parameters": ["webhooks", "webhooksEnabled", "webhookEvents"]
      }
    },
    "oauth2Apps": {
      "description": "Configure OAuth2 applications for Gmail, Outlook, and Mail.ru",
      "endpoints": [
        {"method": "GET", "path": "/v1/oauth2", "description": "List OAuth2 apps"},
        {"method": "POST", "path": "/v1/oauth2", "description": "Register app"},
        {"method": "GET", "path": "/v1/oauth2/{app}", "description": "Get app"},
        {"method": "PUT", "path": "/v1/oauth2/{app}", "description": "Update app"},
        {"method": "DELETE", "path": "/v1/oauth2/{app}", "description": "Delete app"},
        {"method": "POST", "path": "/v1/oauth2/{app}/verify", "description": "Verify app setup step by step (read-only diagnostic; optional account address enables live mailbox checks for service-account apps)"}
      ]
    },
    "smtpGateway": {
      "description": "Configure SMTP gateways for sending via external services",
      "endpoints": [
        {"method": "GET", "path": "/v1/gateways", "description": "List gateways"},
        {"method": "POST", "path": "/v1/gateway", "description": "Register gateway"},
        {"method": "GET", "path": "/v1/gateway/{gateway}", "description": "Get gateway"},
        {"method": "PUT", "path": "/v1/gateway/edit/{gateway}", "description": "Update gateway"},
        {"method": "DELETE", "path": "/v1/gateway/{gateway}", "description": "Delete gateway"}
      ]
    },
    "accessTokens": {
      "description": "Create and manage API access tokens",
      "endpoints": [
        {"method": "GET", "path": "/v1/tokens", "description": "List tokens (each includes id, the SHA-256 hash identifying the token)"},
        {"method": "POST", "path": "/v1/token", "description": "Create token"},
        {"method": "DELETE", "path": "/v1/token/{token}", "description": "Delete token (accepts the token value or its id hash)"},
        {"method": "GET", "path": "/v1/tokens/account/{account}", "description": "List account tokens"}
      ]
    },
    "blocklists": {
      "description": "Manage email address blocklists",
      "endpoints": [
        {"method": "GET", "path": "/v1/blocklists", "description": "List blocklists"},
        {"method": "GET", "path": "/v1/blocklist/{listId}", "description": "Get entries"},
        {"method": "POST", "path": "/v1/blocklist/{listId}", "description": "Add to blocklist"},
        {"method": "DELETE", "path": "/v1/blocklist/{listId}", "description": "Remove from blocklist"}
      ]
    },
    "settings": {
      "description": "Configure EmailEngine runtime settings",
      "endpoints": [
        {"method": "GET", "path": "/v1/settings", "description": "Get all settings"},
        {"method": "POST", "path": "/v1/settings", "description": "Update settings"},
        {"method": "GET", "path": "/v1/settings/queue/{queue}", "description": "Get queue configuration"},
        {"method": "PUT", "path": "/v1/settings/queue/{queue}", "description": "Update queue configuration"}
      ]
    },
    "monitoring": {
      "description": "Access statistics, logs, and system information",
      "endpoints": [
        {"method": "GET", "path": "/v1/stats", "description": "Get usage statistics"},
        {"method": "GET", "path": "/v1/logs/{account}", "description": "Get account logs"},
        {"method": "GET", "path": "/v1/changes", "description": "Get recent changes"},
        {"method": "GET", "path": "/v1/license", "description": "Get license info"},
        {"method": "POST", "path": "/v1/license", "description": "Register a license key"},
        {"method": "DELETE", "path": "/v1/license", "description": "Remove the registered license"},
        {"method": "GET", "path": "/v1/pubsub/status", "description": "List Pub/Sub subscription status"}
      ]
    },
    "deliverabilityTesting": {
      "description": "Test email deliverability and authentication",
      "endpoints": [
        {"method": "POST", "path": "/v1/delivery-test/account/{account}", "description": "Start test"},
        {"method": "GET", "path": "/v1/delivery-test/check/{deliveryTest}", "description": "Check results"}
      ]
    },
    "adminAuthentication": {
      "description": "Admin interface authentication methods",
      "features": ["password", "totp", "passkey-webauthn", "oidc-sso", "okta-sso"],
      "notes": "Passkey (WebAuthn) authentication requires serviceUrl to be configured. Passkeys bypass TOTP requirement. Audit logging covers all authentication methods."
    },
    "exportOperations": {
      "description": "Bulk export email messages from accounts (Beta)",
      "features": ["create", "list", "status", "download", "delete", "encryption"],
      "endpoints": [
        {"method": "POST", "path": "/v1/account/{account}/export", "description": "Create bulk message export"},
        {"method": "GET", "path": "/v1/account/{account}/exports", "description": "List exports (paginated)"},
        {"method": "GET", "path": "/v1/account/{account}/export/{exportId}", "description": "Get export status"},
        {"method": "GET", "path": "/v1/account/{account}/export/{exportId}/download", "description": "Download export file"},
        {"method": "DELETE", "path": "/v1/account/{account}/export/{exportId}", "description": "Delete/cancel export"}
      ]
    }
  },
  "mcp": {
    "description": "Model Context Protocol server that lets AI agents work with the connected email accounts. Off by default; an admin enables it under Configuration > MCP",
    "documentationUrl": "https://learn.emailengine.app/docs/mcp",
    "endpoint": {"method": "POST", "path": "/mcp", "transport": "Streamable HTTP", "payload": "JSON-RPC 2.0"},
    "stateless": true,
    "protocolVersions": ["2026-07-28", "2025-11-25", "2025-06-18"],
    "settings": [
      {"name": "mcpEnabled", "default": false, "description": "Runtime switch for the MCP endpoint. While off, /mcp answers 404"},
      {"name": "mcpOAuthEnabled", "default": false, "description": "Built-in OAuth 2.1 authorization server for MCP clients that cannot use a static token. Requires mcpEnabled and serviceUrl"}
    ],
    "authentication": {
      "scopes": ["mcp", "api", "*"],
      "recommendedScope": "mcp",
      "description": "Bearer access token. A token with the mcp scope opens this endpoint only and is refused by /v1. Every tool call is dispatched as the equivalent REST request with the same credential, so scopes, permissions, account binding, restrictions and the audit log all apply"
    },
    "accessLevels": [
      {"level": "read", "permissions": {"actions": ["read"], "groups": ["account", "mailbox", "message", "outbox", "template"]}, "description": "Default. List, search and read mail"},
      {"level": "mail", "permissions": {"actions": ["read", "write", "send"], "groups": ["account", "mailbox", "message", "submit", "outbox", "template"]}, "description": "Read, organize, draft and send. No delete tool"},
      {"level": "full", "permissions": null, "description": "Every MCP tool, including delete_message. The mcp scope is the bound"}
    ],
    "methods": ["initialize", "server/discover", "ping", "tools/list", "tools/call", "resources/list", "resources/read", "resources/templates/list", "subscriptions/listen"],
    "toolSchemas": "Narrower than the endpoints they wrap: operator-level fields are hidden, rendering options are pinned by the server, and paged listings cap pageSize at 100. A token bound to one account gets tools with no account argument - the binding is applied on dispatch",
    "tools": [
      {"name": "list_accounts", "behavior": "read-only", "wraps": "GET /v1/accounts", "description": "List accounts on the instance, paged"},
      {"name": "get_account", "behavior": "read-only", "wraps": "GET /v1/account/{account}", "description": "Account details, connection state and sync status"},
      {"name": "list_mailboxes", "behavior": "read-only", "wraps": "GET /v1/account/{account}/mailboxes", "description": "Folder tree with counters and special-use roles"},
      {"name": "list_messages", "behavior": "read-only", "wraps": "GET /v1/account/{account}/messages", "description": "Messages in one folder, newest first, paged"},
      {"name": "search_messages", "behavior": "read-only", "wraps": "POST /v1/account/{account}/search", "description": "Structured search inside one folder"},
      {"name": "get_message", "behavior": "read-only", "wraps": "GET /v1/account/{account}/message/{message}", "description": "Envelope, flags, attachment list and the body inline as sanitized web-safe HTML"},
      {"name": "get_message_text", "behavior": "read-only", "wraps": "GET /v1/account/{account}/text/{text}", "description": "The rest of a body that did not fit in get_message, as sanitized web-safe HTML"},
      {"name": "get_attachment", "behavior": "read-only", "wraps": "GET /v1/account/{account}/attachment/{attachment}", "description": "One attachment inline as base64, up to 1 MB"},
      {"name": "update_message", "behavior": "write", "wraps": "PUT /v1/account/{account}/message/{message}", "description": "Add or remove flags and Gmail labels"},
      {"name": "move_message", "behavior": "write", "wraps": "PUT /v1/account/{account}/message/{message}/move", "description": "Move a message to another folder"},
      {"name": "delete_message", "behavior": "destructive", "wraps": "DELETE /v1/account/{account}/message/{message}", "description": "Move to Trash, or delete permanently from Trash"},
      {"name": "create_draft", "behavior": "write", "wraps": "POST /v1/account/{account}/message", "description": "Store a message in a folder without sending"},
      {"name": "send_message", "behavior": "sends-email", "wraps": "POST /v1/account/{account}/submit", "description": "Queue an email for delivery to real recipients. Replies and forwards via the reference block (message, action reply|reply-all|forward, inline, forwardAttachments)"},
      {"name": "get_outbox", "behavior": "read-only", "wraps": "GET /v1/outbox", "description": "Sending queue, including scheduled messages"},
      {"name": "list_templates", "behavior": "read-only", "wraps": "GET /v1/templates", "description": "Stored email templates"}
    ],
    "resources": {"uriTemplate": "emailengine://account/{account}", "description": "Each connected account the credential can see, readable as JSON", "maxListed": 500},
    "limits": {"toolResultBytes": 131072, "messageBodyCharacters": 32768, "messageTextCharacters": 65536, "listingPageSize": 100, "inlineAttachmentBytes": 1048576, "resourceSubscriptionsPerRequest": 20, "listenStreamsPerCredential": 4},
    "oauth": {
      "protectedResourceMetadata": "/.well-known/oauth-protected-resource/mcp",
      "authorizationServerMetadata": "/.well-known/oauth-authorization-server",
      "registrationEndpoint": "POST /mcp/oauth/register",
      "authorizationEndpoint": "GET /admin/mcp/authorize",
      "tokenEndpoint": "POST /mcp/oauth/token",
      "grantTypes": ["authorization_code"],
      "codeChallengeMethods": ["S256"],
      "clientAuthentication": "none",
      "refreshTokens": false,
      "description": "Dynamic client registration (RFC 7591) plus authorization code with mandatory PKCE. Issues an ordinary access token with the mcp scope, revocable on the Access Tokens page"
    }
  },
  "webhookEvents": [
    {"event": "messageNew", "category": "message", "description": "New email received in mailbox"},
    {"event": "messageDeleted", "category": "message", "description": "Email deleted from mailbox"},
    {"event": "messageUpdated", "category": "message", "description": "Email flags/labels changed"},
    {"event": "messageMissing", "category": "message", "description": "Expected message not found"},
    {"event": "messageSent", "category": "delivery", "description": "Email successfully sent via SMTP"},
    {"event": "messageDeliveryError", "category": "delivery", "description": "Delivery attempt failed (will retry)"},
    {"event": "messageFailed", "category": "delivery", "description": "Delivery permanently failed"},
    {"event": "messageBounce", "category": "delivery", "description": "Bounce notification received"},
    {"event": "messageComplaint", "category": "delivery", "description": "Spam complaint (ARF) received"},
    {"event": "accountAdded", "category": "account", "description": "New account registered"},
    {"event": "accountDeleted", "category": "account", "description": "Account removed"},
    {"event": "accountInitialized", "category": "account", "description": "Account ready for use"},
    {"event": "authenticationError", "category": "account", "description": "Authentication failed"},
    {"event": "authenticationSuccess", "category": "account", "description": "Authentication succeeded"},
    {"event": "connectError", "category": "account", "description": "Connection to server failed"},
    {"event": "mailboxNew", "category": "mailbox", "description": "New folder created"},
    {"event": "mailboxDeleted", "category": "mailbox", "description": "Folder deleted"},
    {"event": "mailboxReset", "category": "mailbox", "description": "Folder UIDVALIDITY changed"},
    {"event": "trackOpen", "category": "tracking", "description": "Email opened (tracking pixel loaded)"},
    {"event": "trackClick", "category": "tracking", "description": "Tracked link clicked"},
    {"event": "listUnsubscribe", "category": "tracking", "description": "User unsubscribed"},
    {"event": "listSubscribe", "category": "tracking", "description": "User re-subscribed"},
    {"event": "exportCompleted", "category": "export", "description": "Bulk message export completed successfully"},
    {"event": "exportFailed", "category": "export", "description": "Bulk message export failed"}
  ],
  "accountTypes": [
    {"type": "imap", "description": "Standard IMAP/SMTP with username/password", "protocols": ["imap", "smtp"]},
    {"type": "gmail", "description": "Gmail via OAuth2 (IMAP or API)", "protocols": ["imap", "smtp", "gmail-api"]},
    {"type": "gmailService", "description": "Google Workspace via service account", "protocols": ["gmail-api"]},
    {"type": "outlook", "description": "Microsoft 365/Outlook via OAuth2", "protocols": ["imap", "smtp", "ms-graph"]},
    {"type": "outlookService", "description": "Microsoft 365 via application credentials (client credentials)", "protocols": ["ms-graph"]},
    {"type": "mailRu", "description": "Mail.ru via OAuth2", "protocols": ["imap", "smtp"]},
    {"type": "delegated", "description": "Reported only: Microsoft 365 shared mailbox borrowing another account's OAuth2 grant (oauth2.auth.delegatedAccount)", "protocols": ["ms-graph"]},
    {"type": "sending", "description": "Reported only: SMTP-only account with no IMAP or OAuth2 configuration", "protocols": ["smtp"]},
    {"type": "oauth2", "description": "Reported only: the account references an OAuth2 application that no longer exists", "protocols": []},
    {"type": "invalid", "description": "Reported only: delegated account whose parent account is missing or broken", "protocols": []}
  ],
  "accountStates": [
    {"state": "init", "description": "Being initialized", "operational": false},
    {"state": "syncing", "description": "Initial sync in progress", "operational": false},
    {"state": "connecting", "description": "Establishing connection", "operational": false},
    {"state": "connected", "description": "Active and operational", "operational": true},
    {"state": "disconnected", "description": "Connection lost (will auto-reconnect)", "operational": false},
    {"state": "authenticationError", "description": "Invalid credentials", "operational": false},
    {"state": "connectError", "description": "Network/server error", "operational": false},
    {"state": "paused", "description": "Syncing paused through the API", "operational": false},
    {"state": "unset", "description": "Not syncing: either no IMAP or OAuth2 configuration is set, or syncing was switched off, by the operator (imap.disabled) or automatically after repeated authentication failures (authFailureDisabledAt is set; re-authorizing or saving new IMAP settings resumes syncing)", "operational": false}
  ],
  "errorCodes": [
    {"code": "AccountNotFound", "status": 404, "retryable": false, "description": "Account doesn't exist"},
    {"code": "MessageNotFound", "status": 404, "retryable": false, "description": "Message doesn't exist"},
    {"code": "InvalidRequest", "status": 400, "retryable": false, "description": "Request validation failed"},
    {"code": "InvalidToken", "status": 401, "retryable": false, "description": "Missing or invalid API access token"},
    {"code": "RateLimitExceeded", "status": 429, "retryable": true, "description": "Too many requests"},
    {"code": "ConnectionError", "status": 503, "retryable": true, "description": "Mail server connection failed"},
    {"code": "AccountAlreadyExists", "status": 400, "retryable": false, "description": "An account with the same ID (or OAuth2 user) already exists"}
  ],
  "searchParameters": [
    {"name": "from", "type": "string", "description": "Sender address or name"},
    {"name": "to", "type": "string", "description": "Recipient address or name"},
    {"name": "subject", "type": "string", "description": "Subject contains"},
    {"name": "body", "type": "string", "description": "Body contains"},
    {"name": "unseen", "type": "boolean", "description": "Unread messages only"},
    {"name": "flagged", "type": "boolean", "description": "Starred/flagged only"},
    {"name": "since", "type": "string", "description": "After date (YYYY-MM-DD)"},
    {"name": "before", "type": "string", "description": "Before date (YYYY-MM-DD)"},
    {"name": "header", "type": "object", "description": "Custom header match"},
    {"name": "emailId", "type": "string", "description": "Specific message ID"},
    {"name": "threadId", "type": "string", "description": "Specific thread ID"},
    {"name": "labels", "type": "object", "description": "{has: [...], not: [...]} - filter by Gmail labels or Outlook categories; has matches messages with ALL listed labels, not excludes messages with ANY of them. Gmail and MS Graph accounts only; HTTP 422 if unsupported"}
  ],
  "environmentVariables": [
    {"name": "EENGINE_REDIS", "required": true, "description": "Redis connection URL", "example": "redis://localhost:6379/8"},
    {"name": "EENGINE_SECRET", "required": "production", "description": "Encryption key (32+ hex chars)", "example": "openssl rand -hex 32"},
    {"name": "EENGINE_PORT", "required": false, "default": "3000", "description": "API port"},
    {"name": "EENGINE_HOST", "required": false, "default": "127.0.0.1", "description": "Bind address"},
    {"name": "EENGINE_WORKERS", "required": false, "default": "4", "description": "IMAP worker thread count"},
    {"name": "EENGINE_WORKERS_WEBHOOKS", "required": false, "default": "1", "description": "Webhook delivery worker threads"},
    {"name": "EENGINE_WORKERS_SUBMIT", "required": false, "default": "1", "description": "Email submission worker threads"},
    {"name": "EENGINE_WORKERS_EXPORT", "required": false, "default": "1", "description": "Bulk export worker threads"},
    {"name": "EENGINE_EXPORT_QC", "required": false, "default": "1", "description": "Concurrent export jobs per worker"},
    {"name": "EENGINE_EXPORT_PATH", "required": false, "description": "Directory for export files (default: OS temp dir)"},
    {"name": "EENGINE_EXPORT_MAX_AGE", "required": false, "default": "86400000", "description": "Export file retention time in ms (default: 24h)"},
    {"name": "EENGINE_EXPORT_TIMEOUT", "required": false, "description": "Export operation timeout in ms"},
    {"name": "EENGINE_LOG_LEVEL", "required": false, "default": "trace", "description": "Log level"},
    {"name": "EENGINE_CORS_ORIGIN", "required": false, "description": "CORS allowed origins (space or comma separated)"},
    {"name": "EENGINE_CORS_MAX_AGE", "required": false, "default": "60", "description": "CORS preflight cache duration in seconds"},
    {"name": "EENGINE_HTTP_PROXY_ENABLED", "required": false, "default": "false", "description": "Enable HTTP proxy for outbound requests"},
    {"name": "EENGINE_HTTP_PROXY_URL", "required": false, "description": "HTTP/SOCKS proxy URL for outbound requests"},
    {"name": "EENGINE_DISABLE_THREAD_COLLAPSE", "required": false, "default": "false", "description": "Stop web-safe HTML from folding quoted thread history into a collapsible block (EmailEngine 2.75.0+)"},
    {"name": "EENGINE_MCP_ENABLED", "required": false, "default": "true", "description": "Register the MCP endpoint routes. The mcpEnabled setting is the runtime switch"}
  ]
}
