JXA Mail MCP

JXA Mail MCP

A high-performance MCP server for Apple Mail that uses optimized JavaScript for Automation (JXA) to search and manage emails. It enables users to list accounts, fetch mailboxes, and retrieve today's, unread, or flagged messages with significantly improved speed through batch property fetching.

Category
Visit Server

README

JXA Mail MCP

A fast MCP (Model Context Protocol) server for Apple Mail, using optimized JXA (JavaScript for Automation) scripts with batch property fetching for 87x faster performance.

Features

  • list_accounts - List all configured email accounts
  • list_mailboxes - List mailboxes for an account
  • get_emails - Fetch emails from any mailbox with pagination
  • get_todays_emails - Fetch all emails received today
  • get_unread_emails - Fetch unread emails
  • get_flagged_emails - Fetch flagged emails
  • search_emails - Search emails by subject or sender
  • fuzzy_search_emails - Typo-tolerant search using trigram + Levenshtein matching

Installation

With pipx (recommended)

pipx install jxa-mail-mcp

From source

Requires Python 3.13+ and uv:

git clone https://github.com/imdinu/jxa-mail-mcp
cd jxa-mail-mcp
uv sync

Usage

Add to Claude Code

After installing with pipx:

{
  "mcpServers": {
    "mail": {
      "command": "jxa-mail-mcp"
    }
  }
}

Or from source:

{
  "mcpServers": {
    "mail": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/jxa-mail-mcp", "jxa-mail-mcp"]
    }
  }
}

Run directly

jxa-mail-mcp

Configuration

Set default account and mailbox via environment variables:

export JXA_MAIL_DEFAULT_ACCOUNT="Work"
export JXA_MAIL_DEFAULT_MAILBOX="Inbox"

Or in Claude Code config:

{
  "mcpServers": {
    "mail": {
      "command": "jxa-mail-mcp",
      "env": {
        "JXA_MAIL_DEFAULT_ACCOUNT": "Work"
      }
    }
  }
}

Test in Python

from jxa_mail_mcp.server import get_todays_emails, search_emails, fuzzy_search_emails

emails = get_todays_emails(account="iCloud", mailbox="Inbox")
results = search_emails("meeting", account="Work", limit=10)

# Fuzzy search - tolerates typos
results = fuzzy_search_emails("meetting nottes", limit=10)  # finds "meeting notes"

Architecture

src/jxa_mail_mcp/
├── __init__.py         # Exports mcp instance and main()
├── server.py           # FastMCP server and MCP tools
├── config.py           # Environment variable configuration
├── builders.py         # QueryBuilder for constructing JXA scripts
├── executor.py         # JXA script execution utilities
└── jxa/
    ├── __init__.py     # Exports MAIL_CORE_JS
    └── mail_core.js    # Shared JXA utilities library

Design Principles

  1. Separation of concerns: Python handles logic/types, JavaScript handles Mail.app interaction
  2. Builder pattern: QueryBuilder constructs optimized JXA scripts programmatically
  3. Shared JS library: mail_core.js provides reusable utilities injected into all scripts
  4. Type safety: Python type hints ensure correct usage

Performance

The Problem

Naive AppleScript/JXA iteration is extremely slow:

// SLOW: ~54 seconds for a few hundred messages
for (let msg of inbox.messages()) {
    results.push({
        from: msg.sender(),      // IPC call to Mail.app
        subject: msg.subject(),  // IPC call to Mail.app
    });
}

Each property access triggers a separate Apple Event IPC round-trip.

The Solution: Batch Property Fetching

JXA supports fetching a property from all elements at once:

// FAST: ~0.6 seconds (87x faster)
const msgs = inbox.messages;
const senders = msgs.sender();   // Single IPC call returns array
const subjects = msgs.subject(); // Single IPC call returns array

for (let i = 0; i < senders.length; i++) {
    results.push({ from: senders[i], subject: subjects[i] });
}

Benchmark Results

Method Time Speedup
AppleScript (per-message) 54.1s 1x
JXA (per-message) 53.9s 1x
JXA (batch fetching) 0.62s 87x

Fuzzy Search Performance

Fuzzy search uses trigrams for fast candidate selection and Levenshtein distance for accurate ranking. Tested on a mailbox with ~6,000 emails:

Search Type Time Overhead
Regular search ~360ms -
Fuzzy search ~480ms +33%

The trigram pre-filtering keeps fuzzy search fast by avoiding expensive Levenshtein calculations on non-matching words.

Example: Searching for "reserch studies" (typo) correctly finds "research studies" with 0.94 similarity score.

Development

uv sync
uv run ruff check src/
uv run ruff format src/

# Test
uv run python -c "
from jxa_mail_mcp.server import list_accounts, get_todays_emails
print('Accounts:', len(list_accounts()))
print('Today:', len(get_todays_emails()))
"

License

GPL-3.0-or-later

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured