# Google Contacts MCP (npm · mcp-google-contacts)

MCP server for the Google People API: search, create, update and delete contacts and groups.

- Trust score: 79/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-20

## Components

- npm · `mcp-google-contacts`: 79/100 (this document), [markdown](https://verifymcp.io/servers/a1-x-tech-mcp-google-contacts/mcp-google-contacts.md), [page](https://verifymcp.io/servers/a1-x-tech-mcp-google-contacts/mcp-google-contacts)

## Channel facts

- Registry: `npm`
- Package: `mcp-google-contacts`
- Version: `0.2.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-20.

- **Supply Chain Security**: 98/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 31 of 97 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 70/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 5400 tokens (~216/item across 25 items; 25 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 70/100
  - Stability observed for 21 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 26 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Google Contacts MCP server?

Google Contacts MCP runs locally as an npm package, launched with npx -y mcp-google-contacts. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add a1-x-tech-mcp-google-contacts -- npx -y mcp-google-contacts
```

### Cursor

```json
{
  "mcpServers": {
    "a1-x-tech-mcp-google-contacts": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-google-contacts"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "a1-x-tech-mcp-google-contacts": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-google-contacts"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add a1-x-tech-mcp-google-contacts -- npx -y mcp-google-contacts
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "a1-x-tech-mcp-google-contacts": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "mcp-google-contacts"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add a1-x-tech-mcp-google-contacts --command npx --arg -y --arg mcp-google-contacts
```

### Hermes

```yaml
mcp_servers:
  a1-x-tech-mcp-google-contacts:
    command: "npx"
    args: ["-y", "mcp-google-contacts"]
```

### Netclaw

```json
{
  "McpServers": {
    "a1-x-tech-mcp-google-contacts": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "mcp-google-contacts"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add a1-x-tech-mcp-google-contacts -t stdio -c npx -a -y mcp-google-contacts
```

### Other

```json
{
  "mcpServers": {
    "a1-x-tech-mcp-google-contacts": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-google-contacts"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-20 (score 79, +1)

- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.67 → unverified
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] Schema quality: 252 → 216
- [functional] First check of Schema quality: unverified
- [functional] Package version: 0.1.0 → 0.2.0

### 2026-09-18 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 60 to 63. That category is still filling its 30-day observation window: 18 days of observed history at the previous scan, 19 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-16 (score 77, +1)

No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-14 (score 76, +1)

No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-12 (score 75, +1)

No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-10 (score 74, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-07 (score 73, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-06 (score 72, +3)

- [functional improvement] Stability: unverified → 0.23

## MCP tools (25)

### `auth_status` (~81 tokens)

Google connection status

Shows whether this server is connected to Google: token presence and source (env variables or a stored in-chat login), expiry, the Google account email, granted vs missing OAuth scopes, where the credentials file lives and where the OAuth client comes from. Makes no network calls and never returns the token itself. Call it first when other tools report the server is not connected.

### `setup_instructions` (~109 tokens)

Setup instructions

Step-by-step checklist for connecting this server to Google: creating a Google Cloud project and a Desktop-app OAuth client, publishing the consent screen (mandatory — Testing-mode refresh tokens die after 7 days), downloading the client JSON and handing its PATH to set_client. Works without any credentials; the checklist shortens to 'enable the API + log in' when an OAuth client is already configured (one client serves the whole mcp-google-* line). Never asks the user to paste secrets into the chat.

### `set_client` (~111 tokens)

Save the OAuth client

Saves the OAuth client credentials from the JSON file downloaded from Google Cloud Console ('Download JSON' on a Desktop-app client). Pass the file PATH — the secret must never be pasted into the chat. The client is stored once in the shared ~/.config/mcp-google-auth/client.json (owner-only) and reused by every mcp-google-* server; tokens stay per-server. After this, call start_login.

Input parameters:

- `path` (string, required): Absolute path to the client_secret_*.json file downloaded from Google Cloud Console.

### `start_login` (~114 tokens)

Start the Google login

First step of connecting from the chat, without editing config files or restarting the client. Returns authorizeUrl — show it to the user as a clickable link and ask them to open it in the browser ON THIS MACHINE, pick the Google account and approve access. A one-shot listener on 127.0.0.1 catches Google's redirect; the code is exchanged locally and never passes through the chat. Does not open the browser itself. The attempt lives 10 minutes; when the browser shows the success page, call finish_login.

### `finish_login` (~116 tokens)

Finish the Google login

Second step: confirms the browser consent finished, saves the tokens to an owner-only file and verifies the login with a read-only identity call, returning the account email and the granted scopes. After success every tool works immediately — no client restart. If the user granted only part of the requested permissions, the login is still saved and missingScopes lists what will not work. Logging in under a different Google account replaces the previous login (its refresh token is revoked best-effort) and the response carries previousAccountEmail so the change never goes unnoticed.

### `logout` (~62 tokens)

Disconnect from Google

Revokes the stored token at Google (oauth2.googleapis.com/revoke) and deletes the local credentials file. Tokens supplied via env variables are NOT touched — remove them from the MCP client config manually; envTokenStillSet in the response says whether any are still in effect.

### `list_contacts` (~332 tokens)

List contacts

Lists the account's saved contacts (People API people/me/connections): connections[] of Person objects with resourceName, etag and the requested person_fields (default names, emailAddresses, phoneNumbers, organizations, memberships — an absent field may be unmasked, not empty), plus nextPageToken, totalItems and (when requested) nextSyncToken. page_size up to 1000 (default 100); paginate with page_token. For incremental polling set request_sync_token=true on a full listing, store nextSyncToken, and pass it as sync_token next time to get only changed/deleted people (deleted ones carry metadata.deleted=true); an expired token (~7 days) fails with HTTP 410 EXPIRED_SYNC_TOKEN — re-list without sync_token. Covers only the user's own saved contacts — not the Workspace directory and not auto-saved addresses (see list_other_contacts).

Input parameters:

- `page_size` (integer): Contacts per page (1..1000, default 100).
- `page_token` (string): nextPageToken from the previous page.
- `person_fields` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `request_sync_token` (boolean): Ask for a nextSyncToken on the last page (for later incremental syncs).
- `sort_order` (string): Sort order (default LAST_MODIFIED_ASCENDING). Ignored when sync_token is set.
- `sync_token` (string): Sync token from a previous listing — returns only people changed since then.

### `search_contacts` (~227 tokens)

Search contacts

Searches the account's saved contacts by prefix match on names, nicknames, emails, phones and organizations (People API people:searchContacts). Returns results[] of { person } with the requested read_mask fields. Max 30 results, no pagination — this is a quick lookup, not an export; use list_contacts to enumerate everything. The search index lags writes by seconds to minutes: a contact created or updated moments ago may be missing here even though list_contacts and get_contact already see it (the documented cache-warmup request is sent automatically before the session's first search, but the lag is server-side). Searches only the user's own saved contacts.

Input parameters:

- `page_size` (integer): Max results (1..30, API cap; default 10).
- `query` (string, required): The search text, e.g. a name prefix ("Ann"), email or phone fragment.
- `read_mask` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.

### `get_contact` (~179 tokens)

Get a contact

Fetches one contact by resource name ("people/c...", or "people/me" for the signed-in user's own profile) with an explicit field mask. Returns a Person with resourceName, etag and the requested person_fields (default names, emailAddresses, phoneNumbers, organizations, memberships). The etag in the result is what update_contact needs to change this contact safely; memberships list the contact's groups as contactGroups/<id> resource names.

Input parameters:

- `person_fields` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `resource_name` (string, required): The contact's full resource name, e.g. "people/c1234567890" — exactly as returned by list_contacts, search_contacts or create_contact.

### `batch_get_contacts` (~163 tokens)

Get many contacts at once

Fetches up to 200 contacts in one call (People API people:batchGet) — far cheaper against the tight per-user quota than a get_contact loop. Returns responses[], one per requested resource name IN THE SAME ORDER, each { requestedResourceName, status, person }; a missing contact gets a NOT_FOUND status in its own entry instead of failing the whole call, so check per-entry status. person_fields works exactly like in get_contact.

Input parameters:

- `person_fields` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `resource_names` (array, required): The contacts to fetch (1..200 people/<id> resource names).

### `create_contact` (~436 tokens)

Create a contact

Creates a new contact in the account's Google Contacts and returns the created Person (resourceName, etag and the person_fields mask — use the resourceName for every later call). Provide any subset of the normalized fields: name parts, nickname, emails[], phones[], addresses[], organization, birthday, notes, urls[]; at least one is required. The API has NO duplicate detection — creating the same contact twice yields two contacts, so after an ambiguous failure (timeout/5xx; never auto-retried) check via search/list before re-sending. A just-created contact appears in list_contacts/get_contact immediately but reaches the search_contacts index with a delay. Contact photos need raw_request (updateContactPhoto).

Input parameters:

- `addresses` (array): Postal addresses. On update this list replaces ALL existing addresses; [] clears them.
- `birthday` (string): Birthday: "YYYY-MM-DD", or "MM-DD" for a year-less birthday. On update "" clears it.
- `emails` (array): Email addresses. On update this list replaces ALL existing emails; [] clears them.
- `family_name` (string): Last name.
- `given_name` (string): First name.
- `middle_name` (string): Middle name.
- `nickname` (string): Nickname. On update "" clears it.
- `notes` (string): Free-text notes (the "Notes" field in Google Contacts). On update "" clears it.
- `organization` (object): Employer info. On update it replaces the existing organizations; {} clears them.
- `person_fields` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `phones` (array): Phone numbers. On update this list replaces ALL existing phones; [] clears them.
- `prefix` (string): Honorific prefix, e.g. "Dr.".
- `suffix` (string): Honorific suffix, e.g. "Jr.".
- `urls` (array): Websites. On update this list replaces ALL existing urls; [] clears them.

### `update_contact` (~513 tokens)

Update a contact

Updates an existing contact and returns the updated Person. Only the provided fields are touched (updatePersonFields is computed automatically), but each provided field group is REPLACED AS A WHOLE: passing emails replaces all emails ([] clears them), passing any name part rewrites the whole name, and scalar fields clear on an empty value ("" for nickname/notes/birthday, {} for organization) — fetch current values with get_contact first and send complete groups, or data is silently dropped. Updates are etag-guarded: pass the etag from get_contact to fail cleanly (HTTP 400) if someone edited the contact meanwhile, or omit it and the current etag is fetched automatically (one extra read; last-write-wins). At least one contact field is required.

Input parameters:

- `addresses` (array): Postal addresses. On update this list replaces ALL existing addresses; [] clears them.
- `birthday` (string): Birthday: "YYYY-MM-DD", or "MM-DD" for a year-less birthday. On update "" clears it.
- `emails` (array): Email addresses. On update this list replaces ALL existing emails; [] clears them.
- `etag` (string): The contact's etag from get_contact — omit to auto-fetch the current one.
- `family_name` (string): Last name.
- `given_name` (string): First name.
- `middle_name` (string): Middle name.
- `nickname` (string): Nickname. On update "" clears it.
- `notes` (string): Free-text notes (the "Notes" field in Google Contacts). On update "" clears it.
- `organization` (object): Employer info. On update it replaces the existing organizations; {} clears them.
- `person_fields` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `phones` (array): Phone numbers. On update this list replaces ALL existing phones; [] clears them.
- `prefix` (string): Honorific prefix, e.g. "Dr.".
- `resource_name` (string, required): The contact's full resource name, e.g. "people/c1234567890" — exactly as returned by list_contacts, search_contacts or create_contact.
- `suffix` (string): Honorific suffix, e.g. "Jr.".
- `urls` (array): Websites. On update this list replaces ALL existing urls; [] clears them.

### `delete_contact` (~147 tokens)

Delete a contact

Permanently deletes one contact from the account's Google Contacts. There is no undo through this API (the Google Contacts UI keeps its own 30-day trash, but nothing here reads or restores it) — verify the resource_name with get_contact before deleting. Returns an empty result on success. After an ambiguous failure (timeout/5xx; never auto-retried) check with get_contact before re-sending: the delete may already have happened, and a second attempt then fails with 404.

Input parameters:

- `resource_name` (string, required): The contact's full resource name, e.g. "people/c1234567890" — exactly as returned by list_contacts, search_contacts or create_contact.

### `list_contact_groups` (~220 tokens)

List contact groups

Lists the account's contact groups (labels): contactGroups[] with resourceName (contactGroups/<id>), name, groupType and memberCount, plus nextPageToken and totalItems. Two kinds come back: USER_CONTACT_GROUP (labels the user created — the only kind that can be renamed or deleted) and SYSTEM_CONTACT_GROUP (built-ins like contactGroups/myContacts and contactGroups/starred — fixed). group_fields defaults to metadata, groupType, memberCount, name; add memberCount explicitly if you narrow it and still want sizes. page_size up to 1000; sync_token works like in list_contacts (410 = expired, re-list in full).

Input parameters:

- `group_fields` (array): Group fields to return (default metadata, groupType, memberCount, name).
- `page_size` (integer): Groups per page (1..1000, default 30).
- `page_token` (string): nextPageToken from the previous page.
- `sync_token` (string): Sync token from a previous listing — only changes since then.

### `get_contact_group` (~169 tokens)

Get a contact group

Fetches one contact group by resource name: name, groupType, memberCount and etag — plus, when max_members > 0, memberResourceNames[] with up to that many member contacts as people/<id> resource names (the only way the API returns a group's members; feed them to batch_get_contacts for details). The etag is what update_contact_group uses to rename safely.

Input parameters:

- `group_fields` (array): Group fields to return (default metadata, groupType, memberCount, name).
- `max_members` (integer): How many member resource names to include (0 or omitted = none, just the group).
- `resource_name` (string, required): The group's full resource name, e.g. "contactGroups/12abc34d567" — from list_contact_groups.

### `create_contact_group` (~87 tokens)

Create a contact group

Creates a new user contact group (label) and returns it (resourceName contactGroups/<id>, name, etag). Group names must be unique — creating a duplicate name fails with 409 CONFLICT rather than making a second group. Put contacts into the new group with modify_group_members.

Input parameters:

- `name` (string, required): The group's display name (must be unique among the user's groups).

### `update_contact_group` (~162 tokens)

Rename a contact group

Renames a user contact group (the only mutable group attribute). Etag-guarded like contact updates: pass etag from get_contact_group to fail cleanly on a concurrent edit, or omit it and the current etag is fetched automatically (one extra read). System groups (contactGroups/myContacts, starred, ...) cannot be renamed; the new name must stay unique (409 CONFLICT otherwise). Returns the updated group.

Input parameters:

- `etag` (string): The group's etag from get_contact_group — omit to auto-fetch the current one.
- `name` (string, required): The new display name.
- `resource_name` (string, required): The group's full resource name, e.g. "contactGroups/12abc34d567" — from list_contact_groups.

### `delete_contact_group` (~149 tokens)

Delete a contact group

Permanently deletes a user contact group (label). By default the member contacts SURVIVE — they only lose the label; delete_contacts=true also PERMANENTLY DELETES every contact in the group, so use it only when that is explicitly wanted (check the roster first via get_contact_group with max_members). System groups cannot be deleted. Returns an empty result on success; there is no undo through this API.

Input parameters:

- `delete_contacts` (boolean): Also permanently delete every member contact (default false — contacts just lose the label).
- `resource_name` (string, required): The group's full resource name, e.g. "contactGroups/12abc34d567" — from list_contact_groups.

### `modify_group_members` (~194 tokens)

Add or remove group members

Adds and/or removes contacts in a contact group (label) in one call — at least one of add/remove is required, together up to ~1000 names. Contacts are addressed by their people/<id> resource names. The HTTP 200 response is NOT a full success receipt — read it: notFoundResourceNames lists contacts that do not exist (their changes were skipped) and canNotRemoveLastContactGroupResourceNames lists contacts that could not leave their last group. Removing a contact from a group never deletes the contact, and re-running the same call converges. Contacts cannot be removed from contactGroups/myContacts this way.

Input parameters:

- `add` (array): Contacts to add to the group.
- `remove` (array): Contacts to remove from the group.
- `resource_name` (string, required): The group's full resource name, e.g. "contactGroups/12abc34d567" — from list_contact_groups.

### `batch_create_contacts` (~221 tokens)

Create many contacts at once

Creates up to 200 contacts in one call (People API people:batchCreateContacts). Each entry takes the same normalized fields as create_contact (name parts, emails[], phones[], addresses[], organization, birthday, notes, urls[]) and needs at least one. Returns createdPeople[] with each new resourceName. The call is atomic — a validation error anywhere creates nothing — but after an AMBIGUOUS failure (timeout/5xx; never auto-retried) the batch may still have committed: check via list_contacts before re-sending, or every contact gets created twice (the API has no duplicate detection). Send mutate batches sequentially, never in parallel — that is also how the per-user write quota stretches furthest.

Input parameters:

- `contacts` (array, required): The contacts to create (1..200), each with the create_contact field set.
- `read_mask` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.

### `batch_update_contacts` (~233 tokens)

Update many contacts at once

Updates up to 200 contacts in one call (People API people:batchUpdateContacts). Each entry names a contact (resource_name, optional etag — missing etags are auto-fetched in ONE extra batchGet read) plus the same normalized fields as update_contact. CAUTION — the API applies ONE shared update mask to the whole batch, computed here as the union of every entry's provided field groups: a group that one entry provides and another omits is CLEARED on the omitting entry. Safest is to give every entry the same set of fields; each provided group replaces its stored group as a whole, exactly like update_contact. Atomic per request; a stale etag fails the whole batch with 400 — re-read and retry deliberately, never blindly.

Input parameters:

- `read_mask` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `updates` (array, required): The updates (1..200) — give every entry the same set of contact fields (shared mask).

### `batch_delete_contacts` (~140 tokens)

Delete many contacts at once

Permanently deletes up to 500 contacts in one call (People API people:batchDeleteContacts). There is no undo through this API — list the exact resource names first (batch_get_contacts shows what each one is) and treat the call as final. Returns an empty result on success; atomic per request. After an ambiguous failure (timeout/5xx; never auto-retried) check which contacts still exist via batch_get_contacts instead of re-sending — the deletes may have committed, and a second call then reports NOT_FOUND.

Input parameters:

- `resource_names` (array, required): The contacts to delete permanently (1..500 people/<id> resource names).

### `list_other_contacts` (~305 tokens)

List or search Other contacts

Lists 'Other contacts' — addresses Google auto-saved from the user's email interactions; they are NOT in the saved contact list and never appear in list_contacts/search_contacts. Give query to search them instead of listing (prefix match, max 30 results, no pagination — the warmup request is sent automatically before the session's first search); without query it lists with page_token pagination (page_size up to 1000) and optional sync tokens (request_sync_token/sync_token; expired ones fail with 410 — re-list in full). Only names, emailAddresses, phoneNumbers, photos and metadata exist here. Other contacts are read-only: to edit one, first make it a real contact with copy_other_contact. Requires the contacts.other.readonly OAuth scope — a 403 means the refresh token was minted without it.

Input parameters:

- `page_size` (integer): Page size when listing (1..1000, default 100); max matches when searching (1..30).
- `page_token` (string): nextPageToken from the previous page (listing only).
- `query` (string): Search text; when set, page_token and sync tokens are invalid.
- `read_mask` (array): Fields to return (default names, emailAddresses, phoneNumbers) — Other contacts have no more.
- `request_sync_token` (boolean): Ask for a nextSyncToken (listing only).
- `sync_token` (string): Return only changes since this token (listing only).

### `copy_other_contact` (~197 tokens)

Copy an Other contact into My Contacts

Copies an 'Other contact' (from list_other_contacts) into the user's saved contacts — the only write that exists for Other contacts. copy_mask picks which fields carry over (names, emailAddresses, phoneNumbers; default all three). Returns the NEW saved person — use its resourceName ('people/c...') for further edits; the original otherContacts entry remains. Copying the same entry twice creates duplicate saved contacts. Requires BOTH the contacts and contacts.other.readonly OAuth scopes.

Input parameters:

- `copy_mask` (array): Fields to copy into the new saved contact (default all three).
- `read_mask` (array): Person fields to return (default names, emailAddresses, phoneNumbers, organizations, memberships). Only masked fields come back — an absent field may be unmasked, not empty.
- `resource_name` (string, required): The Other-contact's full resource name, e.g. "otherContacts/c123" — from list_other_contacts.

### `raw_request` (~232 tokens)

Raw Google People API call

Escape hatch to call any Google People API v1 path directly, for requests the typed tools don't cover — e.g. contact photos (PATCH "v1/people/<id>:updateContactPhoto" with {"photoBytes":"<base64>"} or DELETE "v1/people/<id>:deleteContactPhoto"), "Other contacts" (GET "v1/otherContacts?readMask=..." — needs the contacts.other.readonly scope on the token), or extra query parameters like sources. The path may carry a query string; repeated parameters are written inline ("v1/people:batchGet?resourceNames=people/a&resourceNames=people/b&personFields=names"). The Bearer token is added automatically; the method defaults to GET. Writes are never retried after ambiguous failures.

Input parameters:

- `body` (object): JSON request body (POST/PUT/PATCH only).
- `method` (string): HTTP method. Defaults to GET.
- `path` (string, required): API path relative to https://people.googleapis.com, e.g. "v1/people/c123?personFields=names".

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/a1-x-tech-mcp-google-contacts/mcp-google-contacts#diagnostics

## Score history

- 2026-09-20: 79
- 2026-09-19: 78
- 2026-09-18: 78
- 2026-09-17: 77
- 2026-09-16: 77
- 2026-09-15: 76
- 2026-09-14: 76
- 2026-09-13: 75
- 2026-09-12: 75
- 2026-09-11: 74
- 2026-09-10: 74
- 2026-09-09: 73
- 2026-09-08: 73
- 2026-09-07: 73
- 2026-09-06: 72
- 2026-09-05: 69
- 2026-09-04: 69
- 2026-09-03: 69
- 2026-09-02: 69
- 2026-09-01: 69
- 2026-08-31: 69
- 2026-08-30: 54

## Common questions

### What is the Google Contacts MCP server?

Google Contacts MCP is listed in the public MCP registry as io.github.A1-x-Tech/mcp-google-contacts. MCP server for the Google People API: search, create, update and delete contacts and groups. This page covers its npm package (mcp-google-contacts).

### Is the Google Contacts MCP server safe to use?

Google Contacts MCP scores 79 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Google Contacts MCP server expose?

Google Contacts MCP exposes 25 tools: auth_status, setup_instructions, set_client, start_login, finish_login, and 20 more. Their descriptions and schemas cost roughly 4,899 tokens of context every time the server is loaded.

### Is the Google Contacts MCP server still maintained?

Google Contacts MCP is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Google Contacts MCP server under?

Google Contacts MCP declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/mcp-google-contacts
- Socket report: https://socket.dev/npm/package/mcp-google-contacts
- Repository: https://github.com/A1-x-Tech/mcp-google-contacts
- Changelog RSS feed: https://verifymcp.io/servers/a1-x-tech-mcp-google-contacts/mcp-google-contacts.xml
- Changelog JSON feed: https://verifymcp.io/servers/a1-x-tech-mcp-google-contacts/mcp-google-contacts.json
- HTML version of this page: https://verifymcp.io/servers/a1-x-tech-mcp-google-contacts/mcp-google-contacts
