Skip to main content
Glama
atfinke

contacts-mcp

by atfinke
README.md
# contacts-mcp

Local MCP server that exposes Apple Contacts data through a `Contacts.framework` helper app.

Built entirely by OpenAI GPT-5.4 via Codex.

## Install

```bash
git clone https://github.com/<your-account>/contacts-mcp.git
cd contacts-mcp
./bootstrap.sh
```

## Run

```bash
npm run start
```

## Permissions

Run `contacts_permissions` once with `prompt: true`.

The helper app is intended to be built with the project's normal code signing so macOS can attribute Contacts access to a stable app identity.

If the prompt does not appear from inside Codex, launch the helper app directly once:

```bash
open ContactsMCPHelperApp/build/Build/Products/Release/ContactsMCPHelperApp.app
```

When opened directly, the app will request Contacts access and show a status alert. After that initial grant, the MCP tools can read visible contacts normally.

Lookup behavior is intentionally narrow: `contacts_lookup_phone`, `contacts_lookup_email`, and `contacts_search_name` return zero or more ranked matches, `contacts_get_contact` fetches one unified contact by identifier, and the server does not expose any write path.

Phone lookup uses the framework predicate first, then falls back to canonical digit matching when needed. Email lookup uses the framework predicate first, then falls back to exact case-insensitive comparison.
Name search uses the framework name predicate first, then backfills ranked matches across full name, nickname, organization, and component fields when needed.

## MCP config

```json
{
  "mcpServers": {
    "contacts": {
      "command": "node",
      "args": ["/absolute/path/to/contacts-mcp/dist/index.js"],
      "env": {
        "CONTACTS_MCP_HELPER_APP_PATH": "/absolute/path/to/contacts-mcp/ContactsMCPHelperApp/build/Build/Products/Release/ContactsMCPHelperApp.app"
      }
    }
  }
}
```

## Verify

```bash
npm run verify
```

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a distinct query modality: permission check, lookup by phone, lookup by email, fetch by ID, and search by name. No two tools overlap in input type or purpose, so misselection is unlikely.

Naming Consistency4/5

All names use snake_case with a consistent `contacts_` prefix, and four of five follow a verb_noun pattern. `contacts_permissions` is a slight noun-form deviation but remains predictable.

Tool Count5/5

Five tools is well-scoped for a read-focused Contacts helper: permissions, three query modalities, and one ID fetch. Each tool has a clear role and none feels redundant.

Completeness4/5

The surface covers access check and all common read paths (ID, phone, email, name). It lacks any list-all/browse operation or mutation tools, but those may be outside the stated read-lookup scope; core retrieval is covered.

Maintenance

ActivityInactive
ResponsivenessNo issues