Mailoo
Mailoo (@bitfloo/mailoo) is a Model Context Protocol (MCP) server for email (IMAP/SMTP), calendar, reminders, and ManageSieve automation developed and maintained by .
에이전트 강화
게시자의 자체 명령입니다. PlugMCP 엔드포인트가 아닙니다.
Host a copy with our keys and logs.
npx -y @bitfloo/[email protected]Claude Code에는 로컬 명령용 설치 링크가 없습니다. 아래 명령을 복사해 터미널에서 실행합니다.
claude mcp add bitfloo-mailoo -- npx -y @bitfloo/mailoo@0.3.5터미널에서 실행합니다.
{ "mcpServers": { "bitfloo-mailoo": { "command": "npx", "args": [ "-y", "@bitfloo/[email protected]" ] } }}claude_desktop_config.json
원격 URL인가요, 내 컴퓨터에서 실행하는 명령인가요? 두 설치 방식의 차이
PlugMCP에서 실행
A new server you create. It is not this listing's official endpoint. Use the publisher install when you want their URL and their credentials.
실행Enables AI assistants and autonomous agents to read, search, send, manage, schedule, and analyze emails, calendars, Reminders, and ManageSieve filter scripts across multiple accounts. Exposes up to 57 tools (with full, core, and minimal toolset profiles), up to 7 prompts, and 6 resources over the MCP 2025/2026 protocol with outputSchema / structuredContent, 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, read-only side effects, and reconnect backoff is documented in docs/configuration.md and docs/tools.md.
Policy and how to report a vulnerability: SECURITY.md.
Mailoo is engineered with defense-in-depth sandboxing so AI agents can safely interact with untrusted mail and external servers:
execFile only) — Native OS integrations (macOS osascript for EventKit/Reminders/notifications, Linux notify-send, Windows powershell, and crontab installation) invoke child_process.execFile with strict argument arrays (shell: false), eliminating command injection vectors.net.BlockList) — Outbound alert webhooks validate URLs against an IPv4/IPv6 net.BlockList covering loopback, RFC 1918 private ranges, link-local/cloud metadata (169.254.169.254, 100.100.100.200), CGNAT, NAT64, 6to4, and reserved prefixes both at configuration time and at socket connection time (createWebhookConnectLookup), preventing DNS-rebinding attacks (src/safety/validation.ts).savePath) — Attachment and .eml exports via savePath are strictly confined to the working directory, walk every path segment with lstat, refuse hidden dotfiles and OS persistence directories (Library/LaunchAgents, .ssh, .gnupg), and open targets with O_CREAT | O_EXCL | O_NOFOLLOW under a 50 MiB file size cap (5 MiB inline base64 cap).<<<UNTRUSTED_EXTERNAL_CONTENT>>>) — Untrusted email subjects, sender headers, message bodies, previews, and authentication results are wrapped in <<<UNTRUSTED_EXTERNAL_CONTENT>>> … <<<END_UNTRUSTED_EXTERNAL_CONTENT>>> delimiters (stripping any forged markers inside the payload) so LLMs treat external mail as data, not instructions.0600) — config.toml is written and verified with mode 0600 inside a 0700 config directory ($XDG_CONFIG_HOME/mailoo/config.toml). Passwords and message bodies are redacted from the JSONL write audit log (src/safety/audit.ts).tls enforces implicit TLS with certificate verification (verify_ssl = true by default); starttls fails closed if the server does not advertise STARTTLS. Turning both off is accepted only for a loopback host. ManageSieve refuses AUTHENTICATE PLAIN over unencrypted sockets without STARTTLS.MCP_EMAIL_READ_ONLY, MCP_EMAIL_TOOLSET, dryRun) —
MCP_EMAIL_READ_ONLY=true disables all write tools, background watchers, hooks, and schedulers at startup, exposing only the 31 read-only tools.MCP_EMAIL_TOOLSET=full|core|minimal scopes the registered tool surface to match the agent's capability tier and context budget.dryRun: true on high-risk tools (send_email, reply_email, forward_email, send_draft, delete_email, bulk_action, delete_mailbox, sieve_put_script, sieve_delete_script) validates all parameters and account resolution and returns a [DRY RUN] preview without modifying server state.rate_limit (default 10 sends/minute) enforces an independent token bucket per account (src/safety/rate-limiter.ts). Buckets live in memory, so each server process and each mailoo scheduler check run counts on its own.Mailoo is designed to work across both frontier models (Claude, GPT, Gemini) and local/small 3B–8B parameter models (llama.cpp GBNF grammars, Ollama, vLLM):
MCP_EMAIL_TOOLSET / settings.toolset):
full (default) — All 57 tools (31 in read_only mode), including Calendar, Reminders, ManageSieve, Watcher, Scheduler, Templates, Contacts, and Analytics.core — 19 tools (10 in read_only mode) covering core email workflows (accounts, mailboxes, emails, threads, send, drafts, manage, bulk, attachments, health).minimal — 14 tools (8 in read_only mode) tailored for 3B–4B models with tight context budgets (accounts, mailboxes, emails, send, manage, health).account & Smart Account Resolution — When only a single account is configured or default_account (MCP_EMAIL_DEFAULT_ACCOUNT) is set, the account parameter is completely optional across tools. Account lookup also matches case-insensitively by profile name or email address (e.g., passing "[email protected]" resolves the matching account), and returns actionable error messages listing valid accounts (name (email) pairs) when ambiguous.emailId, id, or email_id as either string or integer (42 or "42"). Batch tools (get_emails, bulk_action) accept string or numeric ID arrays (["42", "43"] or [42, 43]). list_emails and search_emails accept both hasAttachment and has_attachment. All Zod schemas avoid regex lookaheads so llama.cpp GBNF grammar compilation succeeds without errors.get_email and get_thread default to format="text" and enforce a default maxLength of 20000 characters (appending a clear truncation notice when exceeded) so large HTML newsletters never overflow small context windows.outputSchema & structuredContent — Tools declare structured outputSchema contracts and return machine-readable structuredContent alongside human-readable text blocks.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:
~/.config/mailoo/config.tomlRequires Node.js ≥ 24.
npx -y @bitfloo/mailoo account add
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 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 account add
Building this repository needs pnpm 12 (the packageManager version in package.json):
git clone https://github.com/Bitfloo/mailoo.git
cd mailoo
pnpm install && pnpm build
node dist/main.js account add
The running image needs Docker, not Node on the host. Create the config first with npx -y @bitfloo/mailoo account add (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). The 0.3 tag follows the newest 0.3.x release. Production setups should pin the full version from the release (it matches the npm version) or the image digest.
docker pull ghcr.io/bitfloo/mailoo:0.3
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 account add, or a hand-written TOML) and mounted into the container.
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).
# Add an email account interactively (recommended)
npx -y @bitfloo/mailoo account add
# Or use the deprecated alias (same wizard)
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.
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). OAuth2 accounts log in with an access token refreshed from the configured refresh token.
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 = "[email protected]", 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:0.3 (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:0.3
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:0.3"
]
}
}
}
{
"mcpServers": {
"mailoo": {
"command": "npx",
"args": ["-y", "@bitfloo/mailoo", "stdio"],
"env": {
"MCP_EMAIL_ADDRESS": "[email protected]",
"MCP_EMAIL_PASSWORD": "your-app-password",
"MCP_EMAIL_IMAP_HOST": "imap.example.com",
"MCP_EMAIL_SMTP_HOST": "smtp.example.com"
}
}
}
}
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 Deprecated 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
notify test Send a test desktop notification
notify status Check platform notification support
--version, -v Print the package version
help Show help
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.
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
toolset = "full" # "full" | "core" | "minimal"
default_account = "personal" # optional when only one account is configured
save_to_sent = true # see docs/configuration.md — Gmail already files Sent
[[accounts]]
name = "personal"
email = "[email protected]"
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
An IMAP or SMTP block with tls = false and starttls = false, in the file or from MCP_EMAIL_*, loads only for localhost, an address in 127.0.0.0/8 written in full (such as 127.0.0.1), or ::1; any other host is refused at config load.
Note: OAuth2 support is experimental. Token refresh and provider-specific flows may require additional testing in your environment.
Token refresh and code exchange give up after 15 seconds, so a provider that stops answering fails the connect with OAuth2 token refresh timed out after 15s instead of hanging it. Callers that need a fresh token at the same time share one refresh request. The IDLE watcher logs in with the same access tokens.
[[accounts]]
name = "work"
email = "[email protected]"
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
For single-account setups (overrides config file):
Without the address, both hosts, and a password or a provider, the environment describes no account: Mailoo loads the config file instead, or fails with No configuration found. when there is none.
Sent copies, IMAP4rev2, Sieve host/port, and read_only env vars:
docs/configuration.md.
The scheduler enables future email delivery with a layered architecture:
stdio servers, only the one that runs the watcher and hooks checks. A check still running when the next one is due is skipped, and failed sends are logged to the connected MCP client at warningnpx -y @bitfloo/mailoo scheduler check for manual or cron-based processing. It sends with the same account settings as the server, including OAuth2 and save_to_sent, and closes its IMAP/SMTP connections before it exitsnpx -y @bitfloo/mailoo scheduler install sets up launchd (macOS) or crontab (Linux) to run every minute, independently of the MCP serverImportant — 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. A failing send is attempted up to 3 times before the email is marked
failed.
# 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). Every attempt for one entry carries the same Message-ID, <schedule id@account domain>, so a receiving server or client can drop the second copy. Once SMTP has accepted a message, a failure to update the queue file is reported, and the entry is not sent again as long as either the sent record or the move into sent/ succeeded. If both failed, the next check sends it again unless it has used all its attempts, then it is marked failed. Each entry tracks its attempts (at most 3) and the last error; list_scheduled returns both, and scheduler list shows the error of a failed entry. An entry the rate limit holds back stays pending for the next check and does not use an attempt.
The IMAP IDLE watcher monitors configured mailboxes in real-time using persistent IDLE connections (separate from tool connections). Each folder stays in IDLE between fetches, IDLE resumes about a second after each fetch, and idle_timeout sets how often IDLE is restarted. With several stdio servers on one machine (one per MCP client window), only one of them runs the watcher, hooks and scheduler; see configuration. When new emails arrive:
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 = "[email protected]|[email protected]" }
actions = { flag = true, labels = ["VIP"] }
Batches run one at a time. At most 500 new emails wait for the next batch; more are skipped with a warning in the log and stay in the mailbox unchanged.
Static rules use glob-style patterns (*@example.com) with | as OR separator (*@example.com|*@example.test). All conditions within a match are AND'd. A to pattern matches when any one recipient matches. An empty pattern counts as no condition, and a rule with no condition matches nothing. First matching rule wins.
Available actions: labels (string array), flag (boolean), mark_read (boolean), alert (boolean — forces desktop notification).
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.
The MCP log entry at the listed level names the account, folder, UID, labels
and rule. In alert entries, sender and subject appear only at debug: in a
separate entry, or for low in the single entry.
[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:
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):
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": "[email protected]" },
"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 = "[email protected]" }
actions = { flag = true, alert = true, labels = ["VIP"] }
Features:
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).
Only new mail in source_folders (default INBOX) that no static rule handled is classified. For each such message Mailoo sends one request to api.typesafe.ai (or TYPESAFE_BASE_URL). The request carries (src/services/mail-arrival/state.ts, src/services/mail-arrival/questions.ts):
Not sent: To, Cc, and Bcc addresses, Message-ID, other raw headers, attachment contents, and the body while include_body is false.
Mailoo remembers the last 5000 messages it classified and does not send them again. A message that reaches two of your accounts is classified once in each. A message whose request, or whose header read, failed is not remembered, so the next notice of it tries again.
auto_move and auto_flag are separate poles and default false. Filing destinations come from folders[].path (validated against IMAP LIST), not a live listing of every mailbox.
[settings.system_one]
enabled = false
include_body = false
auto_move = false
auto_flag = false
[[settings.system_one.folders]]
path = "Receipts"
description = "Invoices, receipts, and payment confirmations."
on_new_email = "notify" or "triage" both feed System One when it is on. none stays off.
Outbound calls, child processes, files, and environment variables below are what src/ does. Hook triage that uses MCP sampling stays inside the connected client; Mailoo does not dial a separate model host for that path.
mailoo http listens. It does not add an outbound destination. Provider presets in src/cli/providers.ts fill the IMAP and SMTP hosts the wizard saves.
Paths follow the XDG defaults in src/config/xdg.ts unless XDG_CONFIG_HOME, XDG_DATA_HOME, or XDG_STATE_HOME is set.
Templates under $XDG_CONFIG_HOME/mailoo/templates/ are read, not written by the server.
Single-account setup reads MCP_EMAIL_* (src/config/loader.ts). HTTP listens reads MCP_EMAIL_HTTP_HOST, MCP_EMAIL_HTTP_TOKEN, and MCP_EMAIL_HTTP_ALLOWED_HOSTS (src/safety/http-transport.ts). The same names are the Smithery config keys and the packages[].environmentVariables list in server.json.
Note: On servers that store labels as IMAP keywords, a keyword must be an IMAP atom (RFC 9051): no spaces, control or non-ASCII characters, and none of
( ) { % * " \ ]. Any other label is refused with an error before anything is sent, soReceipts (2024)fails (an older release accepted it). Seeadd_label/remove_labelfor removing an existing non-atom keyword.
Parameter-level notes for the tools above: docs/tools.md.
A prompt is listed only when the toolset registers the tools it calls: summarize_thread needs core or full, and summarize_meetings needs full. Where a send, draft, or bulk tool is missing (minimal, read_only), the prompt leaves that step out.
src/
├── main.ts — Entry point and subcommand routing
├── server.ts — MCP server factory
├── logging.ts — MCP protocol logging bridge
├── cli/ — Interactive CLI commands
│ ├── account-commands.ts — Account CRUD (list, add, edit, delete)
│ ├── setup.ts — Legacy setup alias → account add
│ ├── test.ts — Connection tester
│ ├── config-commands.ts — Config management (show, edit, path, init)
│ ├── install-commands.ts — MCP client registration (install, status, remove)
│ ├── providers.ts — Provider auto-detection (IMAP/SMTP presets)
│ └── scheduler.ts — Scheduler CLI
├── config/ — Configuration layer
│ ├── xdg.ts — XDG Base Directory paths
│ ├── schema.ts — Zod validation schemas
│ └── loader.ts — Config loader (TOML + env vars)
├── connections/
│ ├── auth.ts — IMAP/SMTP credentials (password or OAuth2)
│ ├── backoff.ts — Reconnect delays with jitter after a failed connect
│ ├── manager.ts — Lazy persistent IMAP/SMTP with OAuth2 (experimental)
│ └── probe.ts — One-shot IMAP/SMTP login checks (setup wizard, mailoo test)
├── services/ — Business logic
│ ├── imap.service.ts — IMAP operations
│ ├── label-strategy.ts — Provider-aware label strategy (ProtonMail/Gmail/IMAP keywords)
│ ├── smtp.service.ts — SMTP operations + optional \\Sent APPEND
│ ├── sieve.service.ts — ManageSieve (RFC 5804)
│ ├── template.service.ts — Email template engine
│ ├── oauth.service.ts — OAuth2 token management (experimental)
│ ├── mail-services.ts — IMAP/SMTP services from the config, for the servers and the scheduler CLI
│ ├── calendar.service.ts — ICS/iCalendar parsing
│ ├── scheduler.service.ts — Email scheduling queue
│ ├── watcher.service.ts — IMAP IDLE real-time watcher with auto-reconnect
│ ├── hooks.service.ts — AI triage via MCP sampling + static rules + auto-labeling/flagging
│ ├── notifier.service.ts — Multi-channel notification dispatcher (desktop/sound/webhook)
│ ├── presets.ts — Built-in hook presets (inbox-zero, gtd, priority-focus, etc.)
│ └── event-bus.ts — Typed EventEmitter for internal email events
├── tools/ — MCP tool definitions (57)
├── prompts/ — MCP prompt definitions (7)
├── resources/ — MCP resource definitions (6)
├── safety/ — Audit trail, rate limiter, stdio lifecycle, shutdown, writer lease
│ └── http-transport.ts — Streamable HTTP listen policy
├── utils/ — RFC 2047 compose, MIME body, auth headers
└── types/ — Shared TypeScript types
PRs accepted against develop (GitHub default). develop is the release
line; releases are tagged v* from it. Please conform to the
standard-readme specification
when editing this README. See CONTRIBUTING.md.
# Development workflow
pnpm install
pnpm typecheck # type check
pnpm check # lint and format
pnpm ci:local # lint, typecheck, unit; GreenMail if Docker is up
pnpm test # unit tests (Vitest; no mail server)
pnpm test:integration # GreenMail IMAP/SMTP (needs Docker)
pnpm test:all # unit plus GreenMail
pnpm build # build
pnpm start # run
pnpm test:integration and pnpm test:all need Docker. pnpm ci:local skips GreenMail when Docker is down. What GitHub runs on a pull request is listed in CONTRIBUTING.md. mailoo test / npx -y @bitfloo/mailoo test is a live-account connection probe, not Vitest.
This is a public LGPL-3.0-or-later fork of email-mcp by codefuturist. It is not an official codefuturist project. Original copyright remains with the original authors. Mailoo branding, Bitfloo trademarks, and new code are Copyright (c) 2026 Bitfloo.
Licensed under LGPL-3.0-or-later. The GNU GPL-3 text required by LGPL-3 is in COPYING. Attribution is recorded in NOTICE.
Email MCP server for AI agents: IMAP/SMTP, Gmail, Outlook, calendar, ManageSieve, AI triage, OAuth2.
{ "mcpServers": { "bitfloo-mailoo": { "command": "npx", "args": [ "-y", "@bitfloo/[email protected]" ] } }}도구
아직 도구 목록이 없습니다. 원격 서버는 첫 상태 확인 후에 도구 목록이 생깁니다.
FAQ
이 페이지에서 Cursor, Claude Desktop, Claude Code 또는 VS Code용 stdio 설정을 복사합니다. PlugMCP 프록시가 아니라 게시자의 설치 방식을 사용합니다.
이 레코드에는 필수 환경 변수가 등록되어 있지 않습니다.
@bitfloo/mailoo은(는) stdio를 통해 로컬에서 실행됩니다.
마지막 확인: 2026-11-14. Email MCP server for AI agents: IMAP/SMTP, Gmail, Outlook, calendar, ManageSieve, AI triage, OAuth2.