• Customermates logo
    CustomermatesDocumentation
  • Introduction
Getting Started
  • Quickstart
  • Core Concepts
Connect your AI
  • Custom connector
  • CLI & editors
  • Rate limits
Integrations
  • MCP
  • Webhooks
  • OpenAPI 3.1.0
  • N8N
Self-Hosting
  • Get Started
  • Architecture & Security
App guide
  • Dashboard
  • Inbox
  • Records
  • Profile
  • Company
  • API Keys
  • Filter Syntax
  • Go back
  1. Introduction
  2. MCP

Model Context Protocol (MCP)

Customermates exposes a native MCP endpoint at /api/v1/mcp so Claude, ChatGPT, Cursor, and other agent clients can read and write your CRM directly.

Customermates exposes one MCP endpoint at https://customermates.com/api/v1/mcp. A connected client discovers all 45 CRM tools automatically. There are two ways to connect:

  • Custom connector (OAuth): for Claude (web, desktop, mobile) and ChatGPT. Paste the URL, sign in, approve. No key to manage. Start on Connect with a custom connector.
  • API key: for CLI and editor clients (Claude Code, Codex, Cursor, Gemini CLI) and raw HTTP. Send the 64-character key in the x-api-key header or a config file.

For end-to-end setup on one page, jump to your client: Claude Desktop, ChatGPT, Claude Code, Codex, Cursor, or Gemini. This page is the protocol reference.

When to use MCP

  • You want your AI to read and write the CRM without copying IDs around.
  • You want the AI to discover capabilities rather than hand-writing API calls.
  • You want one endpoint that works across Claude, ChatGPT, Cursor, Codex, and other clients.

Use OpenAPI instead when an engineer or integration service already knows which endpoint it needs. OpenAPI is the canonical HTTP reference. MCP is the agent-native interface built on top.

The endpoint

POST https://customermates.com/api/v1/mcp
Content-Type: application/json
Accept: application/json, text/event-stream
x-api-key: <your-64-character-key>

The endpoint speaks the Model Context Protocol (streamable HTTP variant). tools/list returns every tool with its JSON Schema. tools/call invokes a tool by name.

Because it is the streamable HTTP variant, every request must send Accept: application/json, text/event-stream. Without it the endpoint returns 406 Not Acceptable. All supported MCP clients set this automatically; only raw HTTP callers (curl, scripts) need to add it explicitly.

The x-api-key header is the API-key method. The key is 64 characters, base62 (a-z, A-Z, 0-9), and inherits the permissions of the user who created it. There is no per-key scoping. Custom-connector clients (Claude, ChatGPT) authenticate over OAuth instead and send a bearer token they obtain and refresh for you. See Connect with a custom connector.

Connect a client

ClientMethodGuide
Claude web & mobileCustom connector (OAuth)Connect with a custom connector
Claude DesktopConnector (OAuth) or config keyConnect Claude Desktop
ChatGPTConnector (OAuth) or key headerConnect ChatGPT
Claude CodeAPI keyConnect Claude Code
CodexAPI keyConnect Codex
CursorAPI keyConnect Cursor
Gemini CLIAPI keyConnect Gemini
Any MCP clientKey headerUse the endpoint and header above

The server briefs the model automatically the moment a client connects. Clients that support MCP prompts can also run the built-in get-started prompt for a personalized start.

Server instructions, prompts, and toolsets

You do not need to teach the model how to use the CRM. The server sends instructions when a client connects, so the model follows the workflow automatically: read the schema first, find ids before writing, change relations only through manage_record_links, and confirm before deleting or sending. In clients that support MCP prompts (Claude Code, Cursor), a built-in get-started prompt is available too; it interviews you and summarizes your workspace to personalize the start.

The full 45-tool surface is the default. Append ?toolsets= to the endpoint URL to narrow it, for example /api/v1/mcp?toolsets=records,messaging. Keys and details are in Narrowing with ?toolsets=.

How the tool surface is shaped

The MCP surface is built so that models with weaker planning can use it reliably:

  • Verb-first imperative names: create_contacts, update_deals, delete_records. No batch prefix. The verb matches intent.
  • Merged periphery: custom columns, widgets, and webhooks each live behind one tool (manage_custom_columns, manage_widgets, manage_webhooks) with an action switch, so the model picks an action instead of choosing among many near-identical tools.
  • Inline enum hints: every enum field lists its valid values inline in the description, so the model does not have to resolve external types.
  • Filter examples inline: every filters parameter has a concrete JSON example in its description.
  • Relationship safety: relations change only through manage_record_links (add or remove); passing null on a relationship array is rejected with a remediation hint.
  • Immutable column type: manage_custom_columns keeps type and entityType fixed on update (taken from the existing column); changing a type means delete and recreate.
  • Destructive flags: every destructive tool or action has destructiveHint: true and an IRREVERSIBLE description prefix.

CLI use

If you prefer a local client over a GUI, tools like mcporter can connect to the same endpoint. Store the API key once in the client config and call tools from the shell.

OpenAPI alongside MCP

Both live at the same base URL. MCP is /api/v1/mcp; the OpenAPI spec is at /api/v1/openapi. The OpenAPI operations map 1:1 to REST endpoints; MCP tools wrap those and add safety guardrails the raw API does not have.

Tool catalog

Customermates exposes 45 MCP tools, all enabled by default. They cover records, workspace, messaging, social posts, documentation and deep research, custom columns, widgets, webhooks, and admin. Every destructive tool is flagged and starts its description with IRREVERSIBLE. Relations change only through manage_record_links; the update tools never touch them.

Two flags per tool:

  • Read: no mutation.
  • Destructive: deletes data or cannot be undone. For merged tools the flag applies to their delete-capable actions.

Full JSON Schema for every tool is available live at POST /api/v1/mcp with method: "tools/list".

Records

Seventeen tools work against the five record types (contact, organization, deal, service, task). Records carry custom columns defined per workspace, so get_record_schema is the anchor: it returns the custom-column ids and option values that writes need. Fields such as a deal or task status are configurable singleSelect custom columns, not fixed native fields; get_record_schema returns whatever columns the workspace actually has.

ToolReadDestructivePurpose
get_record_schema✓Schema and custom-column metadata, never record data. One entity type, or all five when entity is omitted. Call before any create or update.
list_records✓Search, filter, sort, paginate one entity type. Always returns the total. Deals include totalValue and totalQuantity, services include amount.
search_records✓Free-text search across one or more entity types in one call.
get_records✓Full record data by id, up to 100, mixed entity types allowed; contacts also by email, phone, or provider:handle. Always returns fields; add markdown notes per item with include=withNotes.
create_contactsCreate up to 100 contacts, custom-column values and relation ids inline.
create_organizationsCreate up to 100 organizations, custom-column values and contact/user/deal/task ids inline.
create_dealsCreate up to 100 deals, services as an inline array.
create_servicesCreate up to 100 services, custom-column values and user/deal/task ids inline.
create_tasksCreate up to 100 tasks, custom-column values and relation ids inline.
update_contactsPartial update by contact key (id, email, phone, or provider:value); org/deal/user/task relations untouched, but a provided identifiers array REPLACES the contact's messaging channels (unlisted ones are unlinked).
update_organizationsPartial update by id. Never touches relations.
update_dealsPartial update by id, including singleSelect custom-column values and services (an inline {serviceId, quantity} array that REPLACES the deal's full service set); org/user/contact/task relations untouched (use manage_record_links).
update_servicesPartial update by id.
update_tasksPartial update by id, including singleSelect custom-column values. Never touches relations.
update_record_notesReplace or append markdown notes on 1 to 100 records, selected by mode.
manage_record_linksAdd or remove ids on one relation (action add or remove). The only way to change relations.
delete_records✓IRREVERSIBLE hard-delete of 1 to 100 records by id (contacts also by email, phone, or provider:value).

All create and update tools take custom-column values via customFieldValues; call get_record_schema first for the column ids.

Workspace

ToolReadDestructivePurpose
get_workspace_context✓Your user, the company profile, all roles including permissions, and your connected messaging accounts (your own plus any shared with the workspace) in one call. The natural first call of a session.
list_users✓Team members with id, name, email, roleId, and status.

Messaging

The messaging surface is live today and available from the Pro tier.

ToolReadDestructivePurpose
get_messaging_threads✓Two modes: without threadId lists inbox threads with filters and sorting (threads with no message yet are hidden unless they hold a draft); with threadId returns one thread plus a page of its messages (default 25, newest first, drafts included).
get_activities✓Activity timeline (messages, audit-log changes, LinkedIn account activities, and calendar events) for the workspace or one record.
get_calendars✓Three modes: list: "calendars" (default) lists the calendars of accessible connected accounts; list: "events" lists calendar events ordered by start time, filterable by calendarId or a startsAt date range; with eventId it returns one event's detail including organizer and attendees. Ids match the entityId of calendar webhook events.
send_chat_messageDelivers immediately. With threadId replies in an existing chat; with connectedAccountId plus attendeeIdentifiers starts a new one (optional chatName names a group). New LinkedIn chats default to Classic; set linkedinProduct to sales_navigator or recruiter to send an InMail (needs inmailSubject), or inmail:true to InMail someone outside your network on Classic.
send_emailDelivers immediately. Send or reply from a connected email account; can send a saved draft via draftMessageId.
save_message_draftPrepare a reply for review: the draft shows up in the inbox compose box and the user sends it. Drafts are thread-bound, one per thread, saving again updates it.
discard_message_draft✓Delete a draft by its draft message id.
update_messaging_threadSet the thread state: unread, open, closed, or spam.
connect_messaging_accountGenerate a link the user opens in a browser to connect a channel (WhatsApp, LinkedIn, email, Instagram, Telegram). You return the link; the user finishes auth there. Expires in 30 minutes.

Social posts

ToolReadDestructivePurpose
get_social_posts✓Posts on LinkedIn or Instagram, read through a connected account. Lists any user's posts via authorIdentifier (a public identifier or provider member id, e.g. from a contact's linkedin channel; defaults to me, the account owner), or fetches a single post by postId.
get_social_post_engagement✓Engagement on a post: kind=comments (default) lists comments, kind=reactions lists who reacted; with commentId it returns the reactions on that comment.
get_social_profile✓A LinkedIn or Instagram profile of a person or company by identifier (the /in/<slug> or /company/<slug> part of the profile url, a provider id, or me); returns name, headline, location, counts and network distance where available, plus a type telling person and organization apart.
manage_social_relationsConnection requests: list invitations (received by default, or your own sent/outgoing via direction), invite (sends a real request), accept, or cancel by invitationId.
linkedin_search_sales_leads✓Finds people via LinkedIn Sales Navigator: either from a pasted search URL or as a structured search with filters (keywords, location, industry, company, job title, seniority and more). Lead rows include the current positions (company, role and company id, usable with get_social_profile). Requires a Sales Navigator subscription.
linkedin_search_sales_companies✓Finds companies via LinkedIn Sales Navigator: either from a pasted company search URL or as a structured search with filters (keywords, location, industry, headcount, annual revenue and more). Requires a Sales Navigator subscription.
linkedin_get_sales_search_parameters✓Resolves the ids behind LinkedIn Sales Navigator search inputs by type (locations, industries, job titles, functions, companies, schools, groups and more) plus your lead/account lists and saved/recent searches; keyword is optional, so a bare type enumerates the whole family.
linkedin_manage_sales_listsLinkedIn Sales Navigator lead and account lists: list them, browse the members of one, or save a lead or company to an existing list. New lists are created in Sales Navigator itself.

Documentation and deep research

ToolReadDestructivePurpose
search_docs✓Full-text search over the docs; defaults to the product guides (source=docs); pass source=api or all to include the REST API reference. Returns slug, source, title, url, snippet.
get_docs_page✓One documentation page as markdown with its canonical URL. Lists valid slugs on a miss.
search✓Required by ChatGPT deep research connectors; federates CRM records and docs. Interactive agents should prefer search_records or search_docs.
fetch✓Deep-research companion to search: fetches one result by its id.

Custom columns

ToolReadDestructivePurpose
manage_custom_columns✓One tool with an action switch: list, upsert (create or update), delete. Covers all ten column types; type and entityType are immutable on update. Delete is IRREVERSIBLE and removes every stored value.

Widgets

ToolReadDestructivePurpose
manage_widgets✓One tool with an action switch: list, get, create, update, delete. The get action returns the computed data points alongside the configuration, so aggregate totals come straight from a widget.

Webhooks

ToolReadDestructivePurpose
manage_webhooks✓One tool with an action switch: list, get, create, update, delete, plus the delivery log (action list_deliveries, scoped to one webhook's current url when you pass its id) and re-delivery (action resend_delivery).

Admin and team

ToolReadDestructivePurpose
update_workspace_settingstarget profile updates your own name, country, and avatar; target company updates the workspace currency (admin only).
manage_teamInvite members by email (action invite, up to 20, sends real invitation emails) or change a member's role and status (action update_member).

Narrowing with ?toolsets=

All 45 tools are on by default. To expose only part of the surface, append ?toolsets= with comma-separated group keys to the endpoint URL:

https://customermates.com/api/v1/mcp?toolsets=records,messaging

Keys: records, workspace, messaging, social, docs, custom-columns, widgets, webhooks, admin. No parameter means everything; unknown keys are ignored. search and fetch are always on so deep-research connectors keep working on any narrowed surface.

Safety rules baked in

  • Confirm before destructive actions. The server instructions tell the model to confirm with the user before delete_records and before any send tool.
  • Relations change only via manage_record_links. The update tools never touch relations, and null on a relationship array is rejected server-side with a remediation hint.
  • Draft, then send. send_email and send_chat_message deliver immediately. When asked to prepare a message, the agent uses save_message_draft and the user sends from the inbox. Drafts are thread-bound; a brand-new outbound message cannot be drafted.
  • Destructive flags everywhere. Every destructive tool or action has destructiveHint: true and an IRREVERSIBLE description prefix.
  • Every enum field lists its valid values inline in the description, and every filters field includes a concrete JSON example.

Next

  • Custom connector: end-to-end setup on one page.
  • Filter syntax: every operator, with examples.
  • Webhooks: the other half of the agentic loop.
When to use MCP
The endpoint
Connect a client
Server instructions, prompts, and toolsets
How the tool surface is shaped
CLI use
OpenAPI alongside MCP
Tool catalog
Records
Workspace
Messaging
Social posts
Documentation and deep research
Custom columns
Widgets
Webhooks
Admin and team
Narrowing with ?toolsets=
Safety rules baked in
Next