Skip to main content
Glama
toshi38
by toshi38

mac-mail-mcp

A local MCP server that lets an AI agent read your email in Apple Mail (Mail.app) on macOS, prepare drafts and, after you confirm, send messages. It drives Mail.app through AppleScript, so it works with any account Mail is signed into: iCloud, Gmail, Exchange or Microsoft 365, IMAP and so on. No API keys, OAuth apps or app registrations are needed.

It ships with OpenCode agents, but the server works with any MCP client.

Tools

Tool

What it does

list

Lists the newest messages in the configured mailbox (id, received, from, subject, read)

read

Reads one message by id. Bodies are capped at 20,000 characters

draft

Opens a draft in Mail for you to review and send. Never sends

send

Shows the full message in a Mail dialog and sends only if you click Send (Cancel is the default button). Bodies are capped at 2,000 characters so the whole message fits in the dialog

MCP clients usually prefix tool names with the server name, so a server configured as mail gives mail_list, mail_read, mail_draft and mail_send.

Related MCP server: apple-mail-mcp

Requirements

  • macOS with Mail.app, and at least one account added in Mail (System Settings > Internet Accounts, or Mail > Add Account) that has finished syncing

  • Bun 1.3 or later

  • An MCP client, such as OpenCode

Setup

1. Install

git clone https://github.com/toshi38/mac-mail-mcp.git ~/code/mac-mail-mcp
cd ~/code/mac-mail-mcp
bun install

2. Choose the account

Find your account names as Mail knows them:

osascript -e 'tell application "Mail" to get name of every account'

The first time you run this, macOS asks whether your terminal may control Mail. Allow it.

To see an account's mailboxes, replace <account> with one of the names:

osascript -e 'tell application "Mail" to get name of every mailbox of account "<account>"'

Then create ~/.config/mac-mail-mcp/config.json:

{ "account": "<account>", "mailbox": "Inbox" }

Key

Default

Meaning

account

""

Account to read from and send as. Empty means the unified inbox across every account, sending from Mail's default account

mailbox

"Inbox"

Mailbox within the account. Matched case-insensitively, so Inbox also finds INBOX

To keep the config somewhere else, set MAC_MAIL_CONFIG to its path. Changes apply on the next tool call, with no restart needed.

3. Connect your MCP client

OpenCode

Run the installer. It copies the mail and mail-send agents into ~/.config/opencode/agents/ and prints the server entry with your paths filled in:

./scripts/install.sh

Add the printed entry to ~/.config/opencode/opencode.json. It looks like this:

"mcp": {
  "mail": {
    "type": "local",
    "command": ["/Users/<you>/.bun/bin/bun", "/Users/<you>/code/mac-mail-mcp/src/main.ts"],
    "codemode": false
  }
}
  • "codemode": false offers the tools to the model directly. Without it, OpenCode only exposes them through its Code Mode execute tool, which the bundled agents deny.

  • Use the absolute path to bun. OpenCode's background service may not have ~/.bun/bin on its PATH.

Then restart OpenCode (opencode service restart) and choose who can use the tools (next section).

Other MCP clients

The server speaks MCP over stdio. Point your client at bun /path/to/mac-mail-mcp/src/main.ts. For example, in Claude Code:

claude mcp add mail -- bun /path/to/mac-mail-mcp/src/main.ts

4. Allow OpenCode to control Mail

The first time an agent uses one of the tools, macOS asks whether OpenCode (or your MCP client) may control Mail. Allow it. If you dismissed the prompt, turn it on under System Settings > Privacy & Security > Automation.

Who can use the tools

Email is untrusted input: anyone can send you a message containing instructions aimed at your agent. How much that matters depends on what else the agent reading your mail can do. In OpenCode, pick one of these setups in opencode.json.

Every agent (simplest). Your normal agents can use the mail tools, and OpenCode asks before each call. Allowing the read tools skips that prompt for reading. Blocking open with mailto: links stops an agent working around a failed tool by opening whatever app handles email links on your Mac, which may be a different account:

"permission": {
  "mail_list": "allow",
  "mail_read": "allow",
  "bash": { "open *mailto:*": "deny" }
}

The trade-off: an agent that also has shell, file and web access is reading mail written by strangers.

Dedicated agents only (safest). Hide the tools from every agent except the bundled ones:

"permission": {
  "mail_*": "deny",
  "bash": { "osascript *": "deny", "open *mailto:*": "deny" }
}

Then press Tab in OpenCode to switch to one of these:

Agent

Tools

mail

mail_list, mail_read, mail_draft. Cannot send

mail-send

The same, plus mail_send

Both agents deny every other tool, so they have no shell, file editing, web access, subagents or Code Mode. The shell rules stop your other agents scripting Mail (or Outlook) directly or opening mailto: links.

Whichever setup you choose, nothing is sent until you click Send in Mail's confirmation dialog. The server also tells agents, in its MCP instructions, tool descriptions and every error, to report failures instead of working around them.

Checks

Run these after setup:

  1. Ask for a summary of your inbox. You should get real messages.

  2. Ask the agent to send yourself an email, then press Cancel in the Mail dialog. Nothing should be sent.

  3. Send yourself an email asking the assistant to forward your inbox somewhere, then ask for a summary. The agent should report the request and do nothing about it.

  4. With the dedicated agents, ask mail to run ls and to fetch a URL. Both should be refused.

Troubleshooting

Symptom

Fix

"Not authorised to control Mail"

Allow the client under System Settings > Privacy & Security > Automation

"Mail could not find the account, mailbox or message"

Check account and mailbox against the osascript commands in step 2

The agent says it has no mail tools

In OpenCode, check that the server shows as Connected, that codemode is false, and that your permissions do not deny mail_* for that agent. Restart OpenCode after config changes

Listing takes several seconds

Normal on large mailboxes: Mail answers AppleScript slowly. Ask for fewer messages

A message is sent from the wrong address

Set account. With an empty account, Mail uses its default account

Development

bun test
bun run typecheck

The tests cover the client with a fake runner, the MCP server over an in-memory transport and, on macOS, compile every AppleScript with osacompile without launching Mail.

Values reach AppleScript as arguments and are never spliced into script source, so message text cannot run as AppleScript. Scripts are passed to osascript on stdin, so arguments starting with - are not read as options.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    This MCP server allows AI assistants to read, send, search, and manage emails in Apple Mail on macOS. It uses AppleScript to interact with the Mail app locally.
    52
    2,506 npm
    97
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to fetch emails from local Apple Mail accounts and mailboxes, and parse Google Scholar alert emails to extract paper titles and links.
    MIT