local-apple-mcp

local-apple-mcp

Enables Claude or any MCP client to read Apple Mail, Calendar, Photos, and create Apple Notes locally on macOS, without any data leaving the machine.

Category
访问服务器

README

local-apple-mcp

A local, offline MCP server that lets Claude — or any MCP client — work with your Apple apps on macOS: read across multiple Mail accounts, check your Calendar, find and view Photos, and drop finished notes into Apple Notes.

Nothing leaves your Mac. No cloud service, no API keys, no accounts to sign up for, no third-party dependencies. Every tool runs through Apple's own frameworks (EventKit, PhotoKit) and AppleScript on the machine you run it on.

Built for people who juggle multiple email accounts and want an assistant that can actually read their native Apple Mail / Calendar / Photos to help plan a day — without handing that data to a web API.

Why local?

Most "connect your email/calendar to AI" tools route your data through a hosted service. This one doesn't. The server is a single Node file plus two small Swift helpers, all running under your own macOS user account and permissions. You can read every line of it in a few minutes.

  • Read-only by default. Four of the five tools only read. The one write tool (create_note) is create-only — it makes a new note and can't edit, append to, or delete anything.
  • No secrets. There's nothing to configure but your own account names and dates, which live in a gitignored config.json.
  • Auditable. ~750 lines of Node, zero npm dependencies, two readable Swift files.

Tools

Tool Access What it does
read_mail read-only Unread + flagged messages across one or more Apple Mail accounts (sender, subject, date, preview).
read_calendar read-only Upcoming events via EventKit, with recurring events correctly expanded. Also surfaces configured birthdays/anniversaries/holidays within 14 days.
search_photos read-only Search the Photos library by metadata only (album, favorites, date, filename, GPS). No image bytes. Cheap first pass.
view_photos read-only Export a shortlist of specific photos as downscaled JPEGs (to a temp folder) and return them as viewable images.
create_note create-only Make a new Apple Note (plain text or light Markdown). Never edits or deletes existing notes.

Requirements

  • macOS 14 (Sonoma) or later — the Calendar helper uses the modern EventKit full-access API.
  • Node.js 18+ — node --version to check. No packages to install.
  • Xcode Command Line Tools — provides the swiftc compiler used by build.sh. Install with xcode-select --install.
  • An MCP client, e.g. Claude Desktop or Claude Code.

Install

git clone https://github.com/armyrunner9916/local-apple-mcp.git
cd local-apple-mcp

# 1. Build the two Swift helpers (compiles calendar_helper + photos_helper)
./build.sh

# 2. Create your config from the template
cp config.example.json config.json
# then edit config.json (see "Configuration" below)

There is no npm install — the server has no dependencies.

Configuration

All of your personal settings live in config.json (which is gitignored, so it never gets committed). Copy config.example.json and edit:

{
  "mail": {
    "accounts": ["you@gmail.com", "you@work.com"]
  },
  "calendar": {
    "excludedCalendars": ["Holidays in United States", "Siri Suggestions", "Birthdays"]
  },
  "notes": {
    "defaultFolder": "Claude Notes",
    "scriptsFolder": "Claude Scripts"
  },
  "specialDates": {
    "birthdays": [{ "name": "Alex Doe", "month": 3, "day": 14 }],
    "anniversaries": [{ "name": "Wedding Anniversary", "month": 6, "day": 8, "year": 2020 }],
    "holidays": [
      { "name": "Mother's Day", "month": 5, "dynamic": "second_sunday" },
      { "name": "New Year's Day", "month": 1, "day": 1 }
    ]
  }
}

Field notes:

  • mail.accounts — must match exactly what Apple Mail shows in Settings → Accounts (e.g. "Google", or the address). If a name is wrong, that account is skipped with an error. Leave the array empty and read_mail will just tell you to configure it.
  • calendar.excludedCalendars — calendar titles to hide (holiday/suggestion noise). Anything not listed is included.
  • notes.defaultFolder — where create_note puts notes when no folder is passed. Created automatically if it doesn't exist.
  • specialDates.holidays — each holiday is either a fixed date (month + day) or computed via dynamic, which supports: "second_sunday", "third_sunday", "first_sunday_after_labor_day".

If config.json is missing, the server still runs on sensible defaults (Mail simply reports that no accounts are configured).

Granting macOS permissions (the important part)

macOS gates access to Mail, Calendar, and Photos behind its privacy system (TCC). The process that launches the MCP server — your MCP client (Claude Desktop, Claude Code, or the terminal you run it from) — is what needs permission. This is where most setup problems happen, so do this carefully.

The first time each tool runs, macOS should prompt. If it doesn't, or you denied it, grant access manually in System Settings → Privacy & Security:

  1. Full Disk Access — add and enable your MCP client (or terminal app). This is the most reliable way to let it read the Mail store. (System Settings → Privacy & Security → Full Disk Access.)
  2. Calendars → Full Access — enable your MCP client. Required for read_calendar.
  3. Photos — enable your MCP client. See the note below on why this asks for "Full Access."
  4. Automation — the first create_note (and Mail read) may pop an Automation prompt to control Mail / Notes. Allow it. (System Settings → Privacy & Security → Automation.)

After changing any of these, fully quit and reopen your MCP client so it picks up the new grant.

Why Photos asks for "Full Access" even though this is read-only

Apple's PhotoKit exposes only two permission levels: "Add Photos Only" and "Full Access" (read/write). There is no read-only tier. To read photo metadata or export a thumbnail at all, an app is required to request Full Access — there simply is no narrower permission to ask for.

This server never writes to your Photos library. search_photos reads metadata; view_photos exports downscaled copies to a temp folder on disk. No asset is ever created, edited, or deleted (the code calls zero PhotoKit mutating APIs — see the READ-ONLY GUARANTEE comment in photos_helper.swift). The permission label is Apple's; the behavior is read-only.

Wiring it into your MCP client

Claude Desktop

Edit your claude_desktop_config.json:

  • macOS path: ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "local-apple": {
      "command": "node",
      "args": ["/absolute/path/to/local-apple-mcp/server.js"]
    }
  }
}

Use the absolute path to server.js. Restart Claude Desktop, and the tools appear.

Claude Code

claude mcp add local-apple -- node /absolute/path/to/local-apple-mcp/server.js

Security model

  • Transport is stdio. The server speaks JSON-RPC over stdin/stdout to the client that launched it. It opens no network sockets and makes no outbound connections.
  • Read-only, except one create-only write. read_mail, read_calendar, search_photos, and view_photos cannot change anything. create_note can only add a new note.
  • Runs as you. It has exactly the access your macOS user + the granted TCC permissions allow — nothing more.
  • Your data stays in config.json, which is gitignored.

Limitations

  • macOS only. It depends on Apple frameworks and AppleScript.
  • Mail reading uses AppleScript, which requires the Mail app and can be slow on very large inboxes (tune days_back). Account names must match exactly.
  • Photo scene/keyword search is filename-only. PhotoKit doesn't expose Apple's on-device scene labels via a public query, so keyword matches filenames. For real subject matching, let the model look at a shortlist via view_photos.
  • create_note can't dedupe. Because it can't read existing notes, every call makes a new note — it never detects duplicates.
  • First-run permission prompts can be finicky; see the permissions section.

Project layout

local-apple-mcp/
├── server.js               # the MCP server (Node, no dependencies)
├── config.example.json     # copy to config.json and fill in
├── calendar_helper.swift   # EventKit helper (build with ./build.sh)
├── photos_helper.swift     # PhotoKit helper (build with ./build.sh)
├── build.sh                # compiles both Swift helpers
├── package.json
├── .gitignore
├── LICENSE                 # MIT
└── README.md

More from Armyrunner Studios

Built by Armyrunner Studios. Stop by to see the other apps I've shipped.

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选