mcpField
A
Apple Contacts

Apple Contacts

Local
cupertino.mgcrea.ioProductivity5Updated today

About Apple Contacts

An MCP server for Apple Contacts on macOS. It resolves phone numbers and email addresses to names using the local address book, and also supports contact search and retrieval; writes are off by default.

Key features

  1. 01Resolve batches of numbers and emails to names
  2. 02Search, list, and retrieve contacts
  3. 03Create and update contacts when enabled
  4. 04Report ambiguous matches instead of guessing

Use cases

  1. 01Resolve a phone number or email to a contact
  2. 02Search and inspect address book entries
  3. 03Create or update contacts with writes enabled

MCP support

The MCP server exposes handle resolution, contact search, listing, and retrieval tools. Contact write tools are registered only when APPLE_CONTACTS_ALLOW_WRITES=1.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"mgcrea-mcp-apple-contacts": {
"command": "npx",
"args": [
"-y",
"@mgcrea/mcp-apple-contacts"
],
"env": {
"APPLE_CONTACTS_ALLOW_WRITES": "<APPLE_CONTACTS_ALLOW_WRITES>"
}
}
}
}
Run commandnpx -y @mgcrea/mcp-apple-contacts
Environment variables to set
APPLE_CONTACTS_ALLOW_WRITESRegister the mutating tools. Off by default, and the gate decides whether the write tools exist at all rather than merely refusing — an agent with writes off cannot see them.

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npm@mgcrea/mcp-apple-contacts1.31.0

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

@mgcrea/mcp-apple-contacts

Model Context Protocol server for the macOS Apple Contacts address book.

Unofficial. Not affiliated with Apple. It reads the address book already on your Mac.

Why it exists: resolving handles

apple_contacts_resolve_handles turns phone numbers and email addresses into names, in batches of up to 500. Everything else here is in service of that.

This is the surface where the file-lane rule is about capability, not speed. Contacts' scripting dictionary answers in ~65 ms — comfortably fast, and still useless for this: resolving a phone number means a suffix-keyed index over every stored number, and no quantity of Apple Events round trips produces one. So reads go through read-only SQLite, and there is no Apple Events read lane.

The lookup builds in 3 ms over 947 phone keys and 295 email keys, then is kept for the life of the process.

Permissions — this one is different

PermissionNeeded forNotes
Contacts (its own)readsprompts — answer the dialog, and that's it
Automation → Contactswrites onlyreads are unaffected

Contacts fails differently from every other surface in this family: it sits behind its own TCC service rather than behind Full Disk Access, and unlike Full Disk Access that permission prompts. So the fix is usually "answer the dialog", not "go to System Settings" — and nothing here asks you to hand over whole-disk access for an address book.

Tools

Read: diagnostics, resolve_handles, search_contacts, list_contacts, get_contact.

Write, registered only when APPLE_CONTACTS_ALLOW_WRITES=1 — with the flag off they are invisible to the model, not merely refused: create_contact, update_contact.

resolveHandles() is also exported from the package root, for callers already inside Node that would rather not go through MCP to reach it.

Configuration

VariableDefault
APPLE_CONTACTS_ALLOW_WRITESoffRegister the mutating tools.
APPLE_CONTACTS_PHONE_SUFFIX_DIGITS9Suffix key length; 6–15.
APPLE_CONTACTS_INDEX_MODEautoauto | ro | immutable | off.
APPLE_CONTACTS_STOREautoExplicit store path.
APPLE_CONTACTS_OSASCRIPT_TIMEOUT_MS30000Sized for the first-run permission prompt.

Notes that will bite you

  • The store is plural. locate.ts returns a list and every query fans out — on a real machine, stores=2/2, contacts=421, matching Apple Events exactly. A server reading only the first store silently loses an account.
  • Nine-digit suffix keys, and the length travels inside the lookup object so the index and the query cannot diverge. A self-join over a real address book at 7, 9 and 10 digits settles it: 7 and 9 collide identically (10 of 947 keys, 1.1%), and 10 drops a key while losing the national-to-E.164 join.
  • Ambiguity is a status, never a guess — resolved / unknown / ambiguous / shortcode. unknown is documented in the tool description as expected, not as an error.
  • Z_ENT filters to ABCDContact. Without it, a list tool returns your groups as people.
  • A write can succeed and still not persist. Contacts holds changes in an unsaved buffer, so a mutation can read back correctly inside the same script and never reach the store. Every write script saves and then re-reads.

Licence

MIT.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.