Skip to main content
Glama
lu-wo

Apple Contacts MCP

by lu-wo

Apple Contacts MCP

Local-first MCP server for safely searching, editing, and maintaining Apple Contacts notes on macOS.

The server uses Contacts.app automation through AppleScript today. That keeps install simple and uses macOS privacy prompts instead of cloud credentials. Writes are dry-run by default and require explicit confirmation.

Tools

  • contacts_status: check Contacts.app access and return aggregate counts.

  • search_contacts: search local contacts by name, organization, job title, email, or phone.

  • create_contact: create a contact. Dry-run by default.

  • update_contact: update scalar fields, notes, or add email/phone values. Dry-run by default.

  • append_contact_note: append a dated interaction log entry to a contact note. Dry-run by default.

  • delete_contact: delete a contact. Dry-run by default and requires a confirmation phrase.

  • test_roundtrip: create, edit, verify, and delete one dummy contact.

Related MCP server: contacts-mcp

Requirements

  • macOS with Contacts.app

  • Node.js 18 or newer

  • Contacts/Automation permissions when macOS prompts

Quick Start

git clone <repo-url>
cd apple-contacts-mcp
npm test
npm run smoke

npm run smoke verifies the MCP handshake and tool list without touching Contacts.

To run a live dummy create/edit/note/delete roundtrip:

npm run smoke:live

macOS may prompt for Contacts or Automation permissions. The live smoke test creates one dummy contact, edits it, appends a note, verifies the change, and deletes the dummy.

Install For Your Agent

This is a stdio MCP server. Any MCP-capable agent needs the same command:

node /absolute/path/to/apple-contacts-mcp/bin/apple-contacts-mcp.cjs

Use an absolute path. Relative paths are easy to break when an agent launches MCP servers from another working directory.

Install In Codex

After cloning:

codex mcp add apple-contacts -- node /absolute/path/to/apple-contacts-mcp/bin/apple-contacts-mcp.cjs

Then restart Codex or start a new Codex thread so the MCP tools are loaded.

To confirm the server is registered:

codex mcp list

Ask Codex:

Use apple-contacts to run contacts_status.

Install In Claude Desktop

Open the Claude Desktop config file on macOS:

open "$HOME/Library/Application Support/Claude/claude_desktop_config.json"

Add this under the top-level mcpServers object, then restart Claude Desktop:

{
  "mcpServers": {
    "apple-contacts": {
      "command": "node",
      "args": ["/absolute/path/to/apple-contacts-mcp/bin/apple-contacts-mcp.cjs"]
    }
  }
}

If the file already has other MCP servers, add only the apple-contacts entry inside the existing mcpServers object.

Ask Claude:

Use the Apple Contacts MCP server to run contacts_status. Do not show any contact values.

Install In Other Agents

Add a stdio MCP server with:

{
  "mcpServers": {
    "apple-contacts": {
      "command": "node",
      "args": ["/absolute/path/to/apple-contacts-mcp/bin/apple-contacts-mcp.cjs"]
    }
  }
}

If your agent has an MCP CLI, use its equivalent of:

<agent> mcp add apple-contacts -- node /absolute/path/to/apple-contacts-mcp/bin/apple-contacts-mcp.cjs

Good first prompt for any agent:

Install this repository as a local MCP server named apple-contacts. Use the absolute path to bin/apple-contacts-mcp.cjs, then restart or reload your MCP tools and run contacts_status. Treat contact data as personal data and keep writes dry-run unless I explicitly approve them.

Permissions

This server automates Contacts.app locally. The first live call may trigger macOS permission prompts for Contacts and/or Automation. Approve those prompts for the terminal or app that is launching the MCP server.

If a call fails because Contacts.app is not running, open Contacts and retry:

open -a Contacts

Write Safety

Create, update, and delete operations are dry-run by default. An actual write must pass both:

{
  "dryRun": false,
  "confirm": true
}

Delete also requires:

{
  "confirmPhrase": "delete contact"
}

This gives agents a natural two-step flow: propose the change first, then apply only after user approval.

Contact Notes

Use append_contact_note for CRM-style interaction logs instead of overwriting the full note field.

Input:

{
  "contactId": "CONTACT-ID-FROM-search_contacts",
  "date": "2026-06-04",
  "summary": "Met at an AI founder dinner. They are interested in local-first agent tooling.",
  "openThreads": [
    "Send the GitHub repo",
    "Follow up about a demo next week"
  ],
  "dryRun": true
}

The appended note entry uses:

- 2026-06-04 - Met at an AI founder dinner. They are interested in local-first agent tooling.
  Open threads: Send the GitHub repo; Follow up about a demo next week

An actual append requires:

{
  "dryRun": false,
  "confirm": true
}

Privacy

This server runs locally on your Mac. It does not call a cloud API or upload contacts on its own. Your agent will still see whatever contact data you ask the MCP server to return, so use field filters and redaction when possible.

Contacts may sync through iCloud, Google, Exchange, or another configured account. A local write can propagate to those services.

Current Backend

The first backend is AppleScript automation of Contacts.app. A future backend may use a signed Swift helper around Apple's Contacts.framework for more structured access.

Direct SQLite writes to ~/Library/Application Support/AddressBook are intentionally not supported.

License

MIT

Available Tools

6 tools
contacts_statusContacts StatusA

Check Apple Contacts access and return aggregate counts without exposing contact values.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses a key behavioral trait: 'without exposing contact values', ensuring privacy. However, it does not explicitly state whether the tool is read-only or mention any side effects, rate limits, or authentication requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence of 12 words, front-loading the action and result. No unnecessary words, every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no parameters, no output schema) and the context of sibling tools, the description adequately conveys its purpose and a key constraint. It could be more complete by specifying the types of aggregate counts, but it is sufficient for a zero-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% because there are no parameters. Baseline is 3. The description adds no parameter information since none exist, but that is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verb ('check') and resource ('Apple Contacts access') and explains the output ('aggregate counts'). It clearly distinguishes from sibling tools (create, delete, update, search) by focusing on access verification and summary statistics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for checking access and getting aggregate counts, but it does not explicitly state when to use it over alternatives or provide conditions like 'use this before creating contacts'. No exclusions or prerequisites are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_contactCreate ContactA

Create an Apple Contact. Dry-run by default; actual writes require dryRun=false and confirm=true.

ParametersJSON Schema
NameRequiredDescriptionDefault
firstNameNo
lastNameNo
organizationNo
jobTitleNo
departmentNo
nicknameNo
emailsNo
phonesNo
dryRunNo
confirmNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the destructive behavior (actual writes require flags) and the dry-run default. However, it does not cover other behavioral aspects such as idempotency, duplicate handling, or error responses.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long with no redundant information. Every word serves a purpose, making it highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 10 parameters, no output schema, and no annotations, the description is too minimal. It explains the dry-run mode but does not describe return values, validation rules, error handling, or any side effects, leaving significant gaps for an agent to correctly invoke the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, meaning the JSON schema provides no descriptions for any of the 10 parameters. The description only adds context for two parameters (dryRun and confirm), leaving the other eight parameters unexplained. This is insufficient for a tool with many parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Create' and the resource 'Apple Contact', making the purpose unambiguous. It distinguishes the tool from siblings like update_contact and delete_contact by focusing on creation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the default behavior (dry-run) and the explicit conditions for actual writes (dryRun=false and confirm=true). This provides clear guidance on when to use the tool and how to trigger real changes, though it does not explicitly mention when not to use it or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_contactDelete ContactA

Delete an Apple Contact by contactId. Dry-run by default and requires confirmPhrase='delete contact'.

ParametersJSON Schema
NameRequiredDescriptionDefault
contactIdYes
dryRunNo
confirmNo
confirmPhraseNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It reveals the dry-run default and confirmation requirement, but does not mention deletion irreversibility, side effects, or required permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. Each sentence adds value: operation and key parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Adequate for a simple delete tool, but lacks return value description, error conditions, and details about dry-run behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%. The description only explains contactId (by name) and confirmPhrase (requires), leaving dryRun and confirm undocumented. It partially compensates but is insufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool deletes an Apple Contact by contactId, using a specific verb and resource, which distinguishes it from sibling tools like create_contact or update_contact.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that dry-run is default and a confirmation phrase is required, providing clear usage context. However, it does not explicitly state when to use this tool over alternatives or mention any prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_contactsSearch ContactsB

Search Apple Contacts by name, organization, job title, email, or phone.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
limitNo
includeEmailsNo
includePhonesNo
revealValuesNo

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must fully disclose behavior. It does not mention that results can be limited via the limit parameter, that emails and phones are included only if requested, or the meaning of revealValues. The tool's read-only nature is implied but not stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence, but it omits critical parameter details. It is front-loaded with the primary action but sacrifices completeness for brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With five parameters, no schema descriptions, and no output schema, the description is too brief to fully inform an agent. It fails to explain key parameters or expected output, making it incomplete for effective tool usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, yet the description only explains the query parameter implicitly by listing searchable fields. The other four parameters (limit, includeEmails, includePhones, revealValues) are completely unexplained, leaving the agent to guess their purpose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb 'Search' and resource 'Apple Contacts', and lists searchable fields (name, organization, job title, email, phone). It effectively distinguishes from sibling tools like create_contact or delete_contact.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (to search contacts) but does not provide explicit guidance on when not to use it or alternatives. Given the sibling tools are clearly different actions, the usage context is clear but lacks exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

test_roundtripTest Contacts RoundtripA

Create, edit, verify, and delete one dummy contact. Requires confirm=true.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description is the sole source for behavioral disclosure. It states the tool performs a sequence of actions (create, edit, verify, delete) on a dummy contact, suggesting it is a test operation with no lasting side effects. However, it lacks details on error behavior, verification specifics, and what happens if confirm is false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise with two sentences and no wasted words. While a bulleted list of actions might improve readability, the current structure effectively communicates the tool's purpose and requirement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool is a simple test utility with one parameter and no output schema, the description provides the essential information: the composite action and the confirm requirement. However, it does not explain what 'verify' entails, the expected outcome, or how to interpret results, leaving some gaps for the agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, confirm, has no description in the schema (0% coverage). The description adds crucial meaning by stating 'Requires confirm=true,' indicating that the tool only performs actions when confirm is true. This clarifies the parameter's role beyond the schema's boolean type and default value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool creates, edits, verifies, and deletes one dummy contact, which explains the roundtrip testing purpose. However, it does not explicitly distinguish itself from sibling tools like create_contact or delete_contact, which are individual operations for production use.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description includes a usage condition: 'Requires confirm=true.' This tells when the tool will actually execute. However, it does not provide guidance on when to use this composite test tool versus individual sibling tools, nor does it explain the effect of confirm=false.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_contactUpdate ContactA

Update an Apple Contact by contactId. Dry-run by default; actual writes require dryRun=false and confirm=true.

ParametersJSON Schema
NameRequiredDescriptionDefault
contactIdYes
changesYes
dryRunNo
confirmNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses dry-run behavior and confirmation requirement, but no mention of side effects, error handling, or permissions. With no annotations, more detail expected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences, front-loaded with purpose. No redundant words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Missing details on 'changes' object structure, return value, error states. For a mutation tool with nested parameter, this is insufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only adds meaning to dryRun and confirm parameters. The 'changes' object parameter lacks any structural description. Schema coverage is 0%, so description should compensate more.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states verb 'Update' and resource 'Apple Contact by contactId'. Distinguishes from siblings like create_contact and delete_contact.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly notes dry-run default and requirement of dryRun=false and confirm=true for actual writes. Provides clear context for safe usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedcontacts_status
    • First observedcreate_contact
    • First observeddelete_contact
    • First observedsearch_contacts
    • First observedtest_roundtrip
    • First observedupdate_contact

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct operation: status check, create, delete, search, roundtrip test, and update. No overlap in functionality.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern (e.g., create_contact, search_contacts), with only 'contacts_status' varying slightly but still adhering to the pattern.

Tool Count5/5

Six tools is an appropriate and focused set for managing Apple Contacts, covering core operations without unnecessary bloat.

Completeness5/5

The tool surface covers CRUD operations (create, search/read, update, delete) plus a status check and a roundtrip test for validation. No obvious gaps for the domain.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Local MCP server that exposes Apple Contacts data, enabling phone, email, and name lookups via a helper app.
    5
    5 npm
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Local MCP server for macOS native apps: Mail, Calendar, Reminders, Notes, Messages, and Contacts. Enables reading and organizing your Mac life through a single stdio process using AppleScript/JXA.
    40
    9 npm
    MIT