npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jdot6/apple-mail-mcp

v0.1.0

Published

The only way to give Claude (or any LLM) access to Apple Mail and iCloud — local AppleScript bridge for macOS

Readme

apple-mail-mcp

The only way to give Claude (or any LLM) access to Apple Mail and iCloud.

Gmail and Outlook have APIs. iCloud doesn't. If you're a Mac user whose email lives in Apple Mail — iCloud, iCloud+, or any account synced through it — there's no web API an LLM can call. This server bridges that gap using AppleScript on your local machine.

It gives Claude full control over Apple Mail: read, search, compose, reply, move, flag, and delete messages using natural language, against your real inbox, with no cloud intermediary.

Built on AppleScript via osascript, with an optional MailKit extension for real-time new-mail events.


Tools

| Tool | Description | |------|-------------| | list_folders | List all accounts and their mailboxes | | list_emails | Paginate messages in a mailbox (newest-first) | | get_email | Read a message's full headers and body | | search_emails | Filter by sender, subject, date range across mailboxes | | compose_email | Create a draft or send a new message immediately | | reply_email | Reply to a message, open as draft or send immediately | | move_email | Move a message to any mailbox | | archive_email | Move to Archive (iCloud) or All Mail (Gmail) | | move_to_junk | Move to Junk (iCloud) or Spam (Gmail) | | flag_email | Set or clear the flag on a message | | mark_read | Mark a message as read or unread | | delete_email | Move to Deleted Messages (iCloud) or Trash (Gmail) | | get_pending_events | Drain real-time new-mail events from the MailKit bridge |


Requirements

  • macOS (tested on Sonoma / Sequoia)
  • Apple Mail open and configured with at least one account
  • Node.js 18+

Installation

npx (recommended)

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "apple-mail": {
      "command": "npx",
      "args": ["-y", "@jdot6/apple-mail-mcp"]
    }
  }
}

Restart Claude Desktop, then ask: "What folders do I have in my mail?"

Bootstrap script

Clones the repo, builds it, and patches the Claude config automatically:

curl -fsSL https://raw.githubusercontent.com/jayvee6/apple-mail-mcp/master/install.sh | bash

Manual

git clone https://github.com/jayvee6/apple-mail-mcp.git
cd apple-mail-mcp
npm install && npm run build

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "apple-mail": {
      "command": "/opt/homebrew/bin/node",
      "args": ["/path/to/apple-mail-mcp/dist/index.js"]
    }
  }
}

Use which node to get the full path to your Node binary. Restart Claude Desktop.

Automation Permission

The first time you use a mail tool, macOS will ask whether to allow node to control Mail. Click Allow. If you accidentally deny it, go to System Settings → Privacy & Security → Automation and re-enable it for your terminal or Node.js runtime.


How It Works

Claude ──stdio──▶ MCP server (Node.js)
                      │
                      ├── runScript("list_messages", [...args])
                      │        │
                      │        └── osascript scripts/applescript/list_messages.applescript
                      │                 │
                      │                 └── Apple Mail (AppleScript dictionary)
                      │
                      └── HTTP bridge  ◀── MailKit extension (optional)
                          localhost:27182

Message references are composite keys that uniquely identify a message without a fragile integer index:

{account}::{mailbox}::{RFC 2822 Message-ID}

e.g.  iCloud::INBOX::<[email protected]>

Every list/search result includes a message_ref. Tools that operate on individual messages (get_email, reply_email, move_email, etc.) take this ref as input. The account and mailbox components scope the AppleScript lookup to the right mailbox; the RFC 2822 ID is the stable identifier. Mail's whose predicate makes the per-message lookup O(1).


MailKit Bridge (optional)

The MailKitBridge/ directory contains an Xcode project for a Mail extension that fires a local HTTP POST to localhost:27182/event when new messages arrive. This populates get_pending_events in real time rather than requiring a manual poll.

The MCP server starts the HTTP listener on startup regardless — it's a no-op if the extension isn't installed.

To build and install the extension: open MailKitBridge/MailKitBridge.xcodeproj in Xcode, build the MailKitBridgeApp scheme, run the app once to register the extension, then enable it in Mail → Settings → Extensions.


Development

npm run dev          # run with tsx (no build step)
npm run build        # compile TypeScript → dist/
npm run typecheck    # type-check without emitting

AppleScript files live in scripts/applescript/ and are invoked directly via osascript — no compilation needed. You can test them standalone:

osascript scripts/applescript/list_folders.applescript
osascript scripts/applescript/list_messages.applescript "iCloud" "INBOX" "1" "5"

Security Notes

  • The HTTP bridge binds to 127.0.0.1 only — not reachable from outside the machine.
  • Script names are validated against path.basename() before use to prevent path traversal.
  • Arguments are passed to osascript via execFile (not a shell), so there is no shell-injection surface.
  • AppleScript calls time out after 30 seconds to prevent hangs if Mail is frozen or showing a permission prompt.

License

MIT