Mailoo
MCP serverCommunicationMailoo, email MCP server for IMAP, SMTP, and ManageSieve. Multi-account, per-folder profiles.
Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.
Add to setup to save this item as a reference. ahel cannot run it, and signing in will not install it.
Getting started
- Save this item in Your setup as a reference.
- Read the source or reference documentation for its setup requirements. Saving it here does not connect it to your AI.
- Check this page for availability before trying to install it through ahel.
From the project's README
As published by bitfloo/mailoo in README.md.
Mailoo is Bitfloo's IMAP, SMTP, and ManageSieve MCP server: multi-mailbox, with profiles per account and per folder.
This is a public LGPL-3.0-or-later fork of email-mcp. It is not an official codefuturist project. See Upstream / Attribution.
Enables AI assistants to read, search, send, manage, schedule, and analyze emails across multiple accounts. Exposes 56 tools, 7 prompts, and 6 resources over the MCP protocol with OAuth2 support (experimental), email scheduling, calendar extraction, analytics, provider-aware label management, real-time IMAP IDLE watcher with AI-powered triage, customizable presets and static rules, ManageSieve filters, and a guided setup wizard.
Behaviour for Sent copies, IMAP4rev2, Sieve, attachment savePath, and read-only side effects is documented in docs/configuration.md and docs/tools.md.
Highlights
| Feature | In this tree |
|---|---|
| Multi-account IMAP/SMTP | ✅ |
| Send / reply / forward | ✅ |
| Drafts & templates | ✅ |
| Provider-aware labels & bulk ops | ✅ |
| Schedule future emails | ✅ |
| Real-time IMAP IDLE watcher | ✅ |
| AI triage with presets | ✅ |
| Desktop & webhook alerts | ✅ |
| Calendar (ICS) extraction | ✅ |
| Email analytics | ✅ |
| OAuth2 (Gmail / M365) | ✅ experimental |
| Guided setup wizard | ✅ |
| ManageSieve (server-side filters) | ✅ |
| Sender auth headers (SPF/DKIM/DMARC) | ✅ |
Table of Contents
- Highlights
- Security
- Docs
- Background
- Install
- Usage
- Capabilities & data flows
- API
- Maintainers
- Upstream / Attribution
- Contributing
- License
Security
Policy and how to report a vulnerability: SECURITY.md.
tlsis implicit TLS;starttlsfails the connection when the server offers no STARTTLS. With both false, IMAP and SMTP differ — see Security considerations.- The audit log redacts passwords and message bodies. It records send, draft, folder, label, bulk, manage, sieve, template, and schedule writes, not every local write (
src/safety/audit.ts) — SECURITY.md - One global
rate_limit(default 10 per minute) sizes a separate send bucket for each account (src/config/schema.ts) - OAuth2 XOAUTH2 authentication for Gmail and Microsoft 365 (experimental)
savePathwrites a new file only under a specific working directory — Security considerations- Outgoing attachment paths must be regular files under the working directory or home — Security considerations
Docs
| Topic | Where |
|---|---|
Sent APPEND, IMAP4rev2, Sieve, read_only, stdio EOF | docs/configuration.md |
savePath, search dates, get_email_security, sieve tools, send/draft attachments, RFC 2047 | docs/tools.md |
| Performance notes | docs/performance-roadmap.md |
Background
Most MCP email implementations provide only basic read/send. This server aims to be a full-featured email client for AI assistants, covering the entire lifecycle: reading, composing, managing, scheduling, and analyzing email — all from a single MCP server.
Key design decisions:
- XDG-compliant config — TOML at
~/.config/mailoo/config.toml - Multi-account — Operate across multiple IMAP/SMTP accounts simultaneously
- Layered services — Business logic is decoupled from MCP wiring for testability
- Provider auto-detection — Gmail, Outlook, Yahoo, iCloud, Fastmail, ProtonMail, Zoho, GMX
Install
Requires Node.js ≥ 24.
npx -y @bitfloo/mailoo setup
That writes the local config and prints an MCP client snippet. The same package runs the server and the other commands:
npx -y @bitfloo/mailoo
npx -y @bitfloo/mailoo account add
npx -y @bitfloo/mailoo test
npx -y @bitfloo/mailoo with no subcommand starts the MCP server over stdio. Or install the mailoo command:
npm install -g @bitfloo/mailoo
# or
pnpm add -g @bitfloo/mailoo
# or, without a global install:
pnpm dlx @bitfloo/mailoo setup
From a clone
Building this repository needs pnpm 9:
git clone https://github.com/Bitfloo/mailoo.git
cd mailoo
pnpm install && pnpm build
node dist/main.js setup
Docker
The running image needs Docker, not Node on the host. Create the config first with npx -y @bitfloo/mailoo setup (or write the TOML by hand), then mount that directory into the container.
The image is ghcr.io/bitfloo/mailoo, built for linux/amd64 and linux/arm64. Tags are bare semver (no v prefix), for example ghcr.io/bitfloo/mailoo:0.1.7:
docker pull ghcr.io/bitfloo/mailoo:0.1.7
To build from a clone instead (docker-compose.yml uses build: .):
docker build -t ghcr.io/bitfloo/mailoo .
Note: The server uses stdio transport. Config is created on the host (
npx -y @bitfloo/mailoo setup, or a hand-written TOML) and mounted into the container.
Usage
Commands below use npx -y @bitfloo/mailoo. A global install accepts the same subcommands as mailoo. From a clone, after pnpm build, those subcommands are node dist/main.js (see From a clone).
Setup
# Add an email account interactively (recommended)
npx -y @bitfloo/mailoo account add
# Or use the legacy alias
npx -y @bitfloo/mailoo setup
# Or create a template config manually
npx -y @bitfloo/mailoo config init
The setup wizard auto-detects server settings, tests connections, saves config, and outputs the MCP client config snippet.
Test Connections
npx -y @bitfloo/mailoo test # all accounts
npx -y @bitfloo/mailoo test personal # specific account
npx -y @bitfloo/mailoo test / mailoo test is a live-account connection probe, not Vitest. Unit and integration tests are pnpm test / pnpm test:integration (see Contributing).
Configure Your MCP Client
Run the guided installer, or paste a snippet below. There is no VS Code / MCP gallery listing.
npx -y @bitfloo/mailoo install
The installer can register an npx, pnpm dlx, or global mailoo launch. A mailoo binary already on PATH can use "command": "mailoo" with "args": ["stdio"].
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"mailoo": {
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"]
}
}
}
Mailoo is not in the VS Code Extensions gallery. Point Copilot at the npx launch below.
Workspace (.vscode/mcp.json):
{
"servers": {
"mailoo": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"]
}
}
}
User config (settings.json, all workspaces):
Open the Command Palette → Preferences: Open User Settings (JSON) and add:
{
"mcp": {
"servers": {
"mailoo": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"]
}
}
}
}
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"mailoo": {
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"]
}
}
}
Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"mailoo": {
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"]
}
}
}
Edit ~/.config/zed/settings.json:
{
"context_servers": {
"mailoo": {
"command": {
"path": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"]
}
}
}
}
Add to ~/.vibe/config.toml:
[[mcp_servers]]
name = "mailoo"
transport = "stdio"
command = "npx"
args = ["-y", "@bitfloo/mailoo", "stdio"]
To pass credentials directly instead of using a config file, use the env field:
[[mcp_servers]]
name = "mailoo"
transport = "stdio"
command = "npx"
args = ["-y", "@bitfloo/mailoo", "stdio"]
env = { MCP_EMAIL_ADDRESS = "you@example.com", MCP_EMAIL_PASSWORD = "your-app-password", MCP_EMAIL_IMAP_HOST = "imap.example.com", MCP_EMAIL_SMTP_HOST = "smtp.example.com" }
MCP tools are exposed as mailoo_<tool_name> (e.g. mailoo_list_emails). Restart Vibe after editing the config.
Run the server in a container — mount your config directory read-only. The image is ghcr.io/bitfloo/mailoo (pull a tag such as 0.1.7, or build it with docker build -t ghcr.io/bitfloo/mailoo .):
docker run --rm -i \
-v ~/.config/mailoo:/home/node/.config/mailoo:ro \
ghcr.io/bitfloo/mailoo
For MCP client configuration (e.g. Claude Desktop):
{
"mcpServers": {
"mailoo": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "~/.config/mailoo:/home/node/.config/mailoo:ro",
"ghcr.io/bitfloo/mailoo"
]
}
}
}
{
"mcpServers": {
"mailoo": {
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"],
"env": {
"MCP_EMAIL_ADDRESS": "you@example.com",
"MCP_EMAIL_PASSWORD": "your-app-password",
"MCP_EMAIL_IMAP_HOST": "imap.example.com",
"MCP_EMAIL_SMTP_HOST": "smtp.example.com"
}
}
}
}
CLI Commands
npx -y @bitfloo/mailoo [command]
Commands:
stdio Run as MCP server over stdio (default)
http [port] [host] Streamable HTTP (default: port 8080 on 127.0.0.1 and ::1)
account list List all configured accounts
account add Add a new email account interactively
account edit [name] Edit an existing account
account delete [name] Remove an account
setup Alias for 'account add'
test Test connections for all or a specific account
install Register mailoo with MCP clients interactively
install status Show registration status for detected clients
install remove Unregister mailoo from MCP clients
config show Show config (passwords masked)
config edit Edit global settings (rate limit, read-only)
config path Print config file path
config init Create template config
scheduler check Process pending scheduled emails
scheduler list Show all scheduled emails
scheduler install Install OS-level scheduler (launchd/crontab)
scheduler uninstall Remove OS-level scheduler
scheduler status Show scheduler installation status
--version, -v Print the package version
help Show help
HTTP
http listens on 127.0.0.1 and ::1 (port 8080 unless you pass another port). A non-loopback address or a non-loopback name in MCP_EMAIL_HTTP_ALLOWED_HOSTS requires MCP_EMAIL_HTTP_TOKEN. Details, including 0.0.0.0 / :: and the 8 MiB body limit: docs/configuration.md.
npx -y @bitfloo/mailoo http
MCP_EMAIL_HTTP_TOKEN='replace-with-a-long-random-secret' npx -y @bitfloo/mailoo http 8080 192.0.2.10
Clients send Authorization: Bearer <token> when a token is configured.
Configuration
Located at $XDG_CONFIG_HOME/mailoo/config.toml (default: ~/.config/mailoo/config.toml).
[settings]
rate_limit = 10 # max emails per minute per account
read_only = false
save_to_sent = true # see docs/configuration.md — Gmail already files Sent
[[accounts]]
name = "personal"
email = "you@example.com"
full_name = "Your Name"
password = "your-app-password"
[accounts.imap]
host = "imap.example.com"
port = 993
tls = true
# disable_imap4rev2 = true # Strato and similar SEARCH bugs
# sieve_host = "imap.example.com"
# sieve_port = 4190
[accounts.smtp]
host = "smtp.example.com"
port = 465
tls = true
starttls = false
verify_ssl = true
[accounts.smtp.pool]
enabled = true
max_connections = 1
max_messages = 100
OAuth2 (experimental)
Note: OAuth2 support is experimental. Token refresh and provider-specific flows may require additional testing in your environment.
[[accounts]]
name = "work"
email = "you@example.com"
full_name = "Your Name"
[accounts.oauth2]
provider = "google" # or "microsoft"
client_id = "your-client-id"
client_secret = "your-client-secret"
refresh_token = "your-refresh-token"
[accounts.imap]
host = "imap.example.com"
port = 993
tls = true
[accounts.smtp]
host = "smtp.example.com"
port = 465
tls = true
[accounts.smtp.pool]
enabled = true
max_connections = 1
max_messages = 100
Environment Variables
For single-account setups (overrides config file):
| Variable | Default | Description |
|---|---|---|
MCP_EMAIL_ADDRESS | required | Email address |
MCP_EMAIL_PASSWORD | required | Password or app password |
MCP_EMAIL_IMAP_HOST | required | IMAP server hostname |
MCP_EMAIL_SMTP_HOST | required | SMTP server hostname |
MCP_EMAIL_ACCOUNT_NAME | default | Account name |
MCP_EMAIL_FULL_NAME | — | Display name |
MCP_EMAIL_USERNAME | Login username | |
MCP_EMAIL_IMAP_PORT | 993 | IMAP port |
MCP_EMAIL_IMAP_TLS | true | IMAP TLS |
MCP_EMAIL_SMTP_PORT | 465 | SMTP port |
MCP_EMAIL_SMTP_TLS | true | SMTP TLS |
MCP_EMAIL_SMTP_STARTTLS | false | SMTP STARTTLS |
MCP_EMAIL_SMTP_VERIFY_SSL | true | Verify SSL certificates |
MCP_EMAIL_SMTP_POOL_ENABLED | true | Enable SMTP transport pooling |
MCP_EMAIL_SMTP_POOL_MAX_CONNECTIONS | 1 | Max pooled SMTP connections |
MCP_EMAIL_SMTP_POOL_MAX_MESSAGES | 100 | Max messages per pooled connection |
MCP_EMAIL_RATE_LIMIT | 10 | Max sends per minute |
Sent copies, IMAP4rev2, Sieve host/port, and read_only env vars:
docs/configuration.md.
Email Scheduling
The scheduler enables future email delivery with a layered architecture:
- MCP auto-check — Processes the queue on server startup and every 60 seconds while the MCP server is running
- CLI —
npx -y @bitfloo/mailoo scheduler checkfor manual or cron-based processing - OS-level daemon —
npx -y @bitfloo/mailoo scheduler installsets up launchd (macOS) or crontab (Linux) to run every minute, independently of the MCP server
Important — the daemon must be installed for reliable delivery. Without it, scheduled emails only fire while an AI client is actively connected. Your machine also needs to be running at the scheduled time; if it's asleep or off, the daemon will process overdue emails on next wake/startup. Failed sends are retried up to 3 times before being marked
failed.
Setting up the daemon
# Install (macOS launchd / Linux crontab — runs every minute)
npx -y @bitfloo/mailoo scheduler install
# Verify it's running
npx -y @bitfloo/mailoo scheduler status
# View pending / sent / failed scheduled emails
npx -y @bitfloo/mailoo scheduler list
# Trigger a manual check immediately
npx -y @bitfloo/mailoo scheduler check
# Remove the daemon
npx -y @bitfloo/mailoo scheduler uninstall
Scheduled emails are JSON files in ~/.local/state/mailoo/scheduled/. Before sending, a check claims the entry with a lock file next to it and keeps that claim fresh while SMTP runs, so the in-process timer, mailoo scheduler check and other server processes do not send it twice. If the process dies after the server accepted a message but before it was recorded as sent, the entry can be sent again after the claim goes stale (at least once, not exactly once). Each entry tracks attempts (max 3) and the last error, so you can inspect failures with scheduler list.
Real-time Watcher & AI Hooks
The IMAP IDLE watcher monitors configured mailboxes in real-time using persistent IDLE connections (separate from tool connections). When new emails arrive:
- Static rules — Pattern-match on from/to/subject → apply labels, flag, or mark read instantly (no AI)
- AI triage — Remaining emails are analyzed via MCP sampling with a customizable preset prompt
- Notify mode — Falls back to logging if AI triage is disabled
Configure in config.toml:
[settings.watcher]
enabled = true
folders = ["INBOX"]
idle_timeout = 1740 # 29 minutes (IMAP spec max is 30)
[settings.hooks]
on_new_email = "triage" # "triage" | "notify" | "none"
preset = "inbox-zero" # "inbox-zero" | "gtd" | "priority-focus" | "notification-only" | "custom"
auto_label = true # apply AI-suggested labels
auto_flag = true # flag urgent emails
batch_delay = 5 # seconds to batch before triage
# User context — appended to preset's AI prompt
custom_instructions = """
I'm a software engineer. Emails from @example.com are always high priority.
Newsletters I read: TL;DR, Hacker Newsletter.
"""
# Static rules — run BEFORE AI, skip AI if matched
[[settings.hooks.rules]]
name = "GitHub Notifications"
match = { from = "*@example.com" }
actions = { labels = ["Dev"], mark_read = true }
[[settings.hooks.rules]]
name = "Newsletter Archive"
match = { from = "*@example.com|*@example.test" }
actions = { labels = ["Newsletter"] }
[[settings.hooks.rules]]
name = "VIP Contacts"
match = { from = "ceo@example.com|cto@example.test" }
actions = { flag = true, labels = ["VIP"] }
Presets
| Preset | Focus | Suggested Labels |
|---|---|---|
inbox-zero | Aggressive categorization + archiving | Newsletter, Notification, Updates, Finance, Social, Promo |
gtd | Getting Things Done contexts | @Action, @Waiting, @Reference, @Someday, @Delegated |
priority-focus | Simple priority classification (default) | (none — just priority + flag) |
notification-only | No AI triage, just log | (none) |
custom | User defines full system prompt | User-defined |
Static Rules
Static rules use glob-style patterns (*@example.com) with | as OR separator (*@example.com|*@example.test). All conditions within a match are AND'd. First matching rule wins.
Available actions: labels (string array), flag (boolean), mark_read (boolean), alert (boolean — forces desktop notification).
Alerts
Urgency-based multi-channel notification routing — grab attention for important emails even when you're not looking at the chat. All channels are opt-in and disabled by default.
| Priority | Desktop | Sound | MCP Log Level | Webhook |
|---|---|---|---|---|
urgent | ✅ Banner | 🔊 Alert | alert | ✅ |
high | ✅ Banner | 🔇 Silent | warning | ✅ |
normal | ❌ | ❌ | info | ❌ |
low | ❌ | ❌ | debug | ❌ |
[settings.hooks.alerts]
desktop = true # OS-level notifications (macOS/Linux/Windows)
sound = true # play sound for urgent emails
urgency_threshold = "high" # minimum priority to trigger desktop alert
webhook_url = "https://ntfy.sh/my-email-alerts" # optional: Slack, Discord, ntfy.sh, etc.
webhook_events = ["urgent", "high"]
allow_private_webhooks = false # default; true allows a LAN, VPN, or tailnet target
Details: docs/configuration.md.
Supported platforms: macOS (Notification Center via osascript), Linux (notify-send), Windows (PowerShell toast). Zero npm dependencies — uses native OS commands.
Notification setup by platform:
Desktop notifications use osascript (built-in). The terminal app running the MCP server needs notification permission:
- Open System Settings → Notifications & Focus
- Find your terminal app (Terminal, iTerm2, VS Code, Cursor, etc.)
- Enable Allow Notifications and choose Banners or Alerts
- Ensure Focus / Do Not Disturb is not blocking notifications
Use check_notification_setup to diagnose and test_notification to verify.
Requires notify-send from libnotify. For sound alerts, paplay is also needed:
# Ubuntu / Debian
sudo apt install libnotify-bin pulseaudio-utils
# Fedora
sudo dnf install libnotify pulseaudio-utils
# Arch
sudo pacman -S libnotify
Desktop notifications require a running display server (X11/Wayland) — they will not work in headless/SSH sessions.
Uses PowerShell toast notifications (built-in):
- Open Settings → System → Notifications
- Ensure Notifications is turned on
- Set Focus Assist to allow notifications
- If using Windows Terminal, ensure its notifications are enabled
AI-configurable: The AI can check, test, and configure notifications at runtime:
check_notification_setup— diagnose platform support and show setup instructionstest_notification— send a test notification to verify everything worksconfigure_alerts— enable/disable desktop, sound, threshold, webhook (with optional persist to config file)
Webhook payload:
{
"event": "email.urgent",
"account": "work",
"sender": { "name": "John CEO", "address": "ceo@example.com" },
"subject": "Q4 Review Due Today",
"priority": "urgent",
"labels": ["VIP"],
"rule": "VIP Contacts",
"timestamp": "2026-02-18T11:30:00Z"
}
Static rules can force desktop notifications with alert = true, regardless of urgency threshold:
[[settings.hooks.rules]]
name = "VIP Contacts"
match = { from = "ceo@example.com" }
actions = { flag = true, alert = true, labels = ["VIP"] }
Features:
- Auto-reconnect — Exponential backoff (1s → 60s) on connection failures
- Batching — Groups arrivals within a configurable delay to reduce AI calls
- Rate limiting — Max 10 sampling calls per minute
- Graceful degradation — Falls back to notify mode if client doesn't support sampling
System One (opt-in typed filing)
Optional TypeSafe System One classification on residue mail after static rules. Off by default. Both settings.watcher.enabled and settings.system_one.enabled must be on. Set TYPESAFE_API_KEY in the environment (never in TOML).
Shortened here. Read the whole README on GitHub.
Signals
- Last commit
- Sep 2026
- Weekly_downloads
- 322 weekly_downloads
Advanced
- Delivery
- mailoo MCP server → your ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
io-github-bitfloo-mailoo- Source
- github.com/bitfloo/mailoo
More in Communication
MCP server · builderio
More in Communicationagent-native-brain
MCP server · builderio
More in Communicationpalisade
MCP server · palisadeemail
More in Communicationimpreza-mcp
MCP server · imprezahost
More in Communicationqr-generator
MCP server · modelcontextprotocol
More in Communicationshipmail-mcp
MCP server · shipmail-to
More in Communication