# Connect AI agents (MCP)

> Connect Claude, ChatGPT, Cursor, and other AI agents to ReverseContact using the Model Context Protocol.

## What is MCP

The [Model Context Protocol](https://modelcontextprotocol.io) (MCP) is an open standard that lets AI assistants call external tools directly. Once connected, your AI agent can enrich profiles, search people and companies, and more, all through natural conversation.

ReverseContact exposes **16 tools** via MCP. Same data, same credits, same rate limits as the REST API.

## Prerequisites

- A ReverseContact account
- An MCP-compatible client (claude.ai, Cowork, Claude Desktop, Claude Code, ChatGPT, Codex, Cursor, etc.)

Two ways to authenticate:

- **Sign in with your account (OAuth)**: clients with OAuth support (claude.ai, Cowork, Claude Desktop, Claude Code, mobile, ChatGPT) connect with no API key. The first connection opens your browser, you approve the access, and a dedicated API key named `MCP - {app}` is created in your workspace automatically.
- **API key**: every other client authenticates with an active API key (`rc_*`) in the `Authorization` header. Create one from [API Keys](https://app.reversecontact.com/api-keys).

## Server details

| Property | Value |
|----------|-------|
| URL | `https://api.reversecontact.com/mcp` |
| Transport | Streamable HTTP (POST only) |
| Authentication | OAuth 2.1 (sign in) or `Authorization: Bearer rc_your_api_key` |
| Protocol | JSON-RPC 2.0 |

## Setup by client

For clients using an API key, replace `rc_your_api_key` with your actual key in the examples below.

### Claude.ai, Claude Desktop, Cowork and mobile

ReverseContact is published in the Claude connector directory, so there is nothing to paste and no API key involved:

1. Open [our page in the Claude connector directory](https://claude.ai/directory/reverse-contact).
2. Click **Connect**: your browser opens the ReverseContact consent page. Sign in if needed, pick the workspace shown, and approve.

The connector is then available in claude.ai chats, Claude Desktop, Cowork, Claude Code on the web and the mobile apps. To revoke it later, delete its `MCP - {app}` key from [API Keys](https://app.reversecontact.com/api-keys).

Prefer to add it by hand, or your organization restricts the directory? Open **Settings** > **Connectors** > **Add custom connector**, paste `https://api.reversecontact.com/mcp` as the URL, confirm, then click **Connect** and approve the same consent page.

### Claude Code

Claude Code supports HTTP MCP servers natively. The fastest path is one command in your terminal, no API key needed:

**Terminal**

```bash [bash]
claude mcp add --transport http reversecontact https://api.reversecontact.com/mcp
```

Then start a Claude Code session and run `/mcp`: select `reversecontact` and authenticate. Your browser opens the consent page, you approve, and the tools come online.

For headless or CI environments where the browser flow is not an option, pass an API key explicitly instead:

**Terminal**

```bash [bash]
claude mcp add --transport http reversecontact \
  https://api.reversecontact.com/mcp \
  --header "Authorization: Bearer rc_your_api_key"
```

Alternatively, add a `.mcp.json` file at the root of your project to share the server with your team:

**.mcp.json**

```json [JSON]
{
  "mcpServers": {
    "reversecontact": {
      "type": "http",
      "url": "https://api.reversecontact.com/mcp",
      "headers": {
        "Authorization": "Bearer rc_your_api_key"
      }
    }
  }
}
```

### ChatGPT

ReverseContact is published in the ChatGPT plugin directory, so there is nothing to paste and no API key involved:

1. Open [our page in the ChatGPT plugin directory](https://chatgpt.com/plugins/plugin_asdk_app_6a709e3aa59c81919cf58da3451d6bc2).
2. Click **Add**: your browser opens the ReverseContact consent page. Sign in if needed, pick the workspace shown, and approve.

The connector is then available in ChatGPT. Enable it from the composer (plus menu) in any chat. To revoke it later, delete its `MCP - {app}` key from [API Keys](https://app.reversecontact.com/api-keys).

Prefer to add it by hand, or your organization restricts the directory? Enable Developer mode under **Settings** > **Connectors** > **Advanced settings** (paid ChatGPT plan: Plus, Pro, Business, Enterprise or Edu), then **Create** a connector: name it `ReverseContact`, paste `https://api.reversecontact.com/mcp` as the URL, keep Authentication on **OAuth**, and approve the same consent page.

### Codex

The Codex CLI reads the bearer token from an environment variable, so the key never lands in a config file:

**Terminal**

```bash [bash]
export RC_API_KEY="rc_your_api_key"
codex mcp add reversecontact \
  --url https://api.reversecontact.com/mcp \
  --bearer-token-env-var RC_API_KEY
```

Add the `export` line to your shell profile so the variable is set whenever Codex launches. This writes the server to `~/.codex/config.toml`:

**config.toml**

```toml [TOML]
[mcp_servers.reversecontact]
url = "https://api.reversecontact.com/mcp"
bearer_token_env_var = "RC_API_KEY"
```

### Cursor

Create a `.cursor/mcp.json` file at the root of your project. Cursor connects over HTTP natively, keyed on `url` (no `type` field):

**.cursor/mcp.json**

```json [JSON]
{
  "mcpServers": {
    "reversecontact": {
      "url": "https://api.reversecontact.com/mcp",
      "headers": {
        "Authorization": "Bearer rc_your_api_key"
      }
    }
  }
}
```

### Gemini CLI

Gemini CLI supports remote Streamable HTTP MCP servers. Add ReverseContact to `~/.gemini/settings.json` for your user account, or `.gemini/settings.json` for one project:

**settings.json**

```json [JSON]
{
  "mcpServers": {
    "reversecontact": {
      "httpUrl": "https://api.reversecontact.com/mcp",
      "headers": {
        "Authorization": "Bearer rc_your_api_key"
      }
    }
  }
}
```

Run `gemini mcp list` to check the connection. The Gemini app's custom connector surface is separate and does not support this setup yet.

### Other clients (mcp-remote)

Most clients that support HTTP MCP servers accept the same URL and `Authorization: Bearer rc_your_api_key` header through their own config format. If your MCP client only supports stdio transport, use `mcp-remote` as a bridge:

**mcp-remote**

```bash [bash]
npx mcp-remote https://api.reversecontact.com/mcp \
  --header "Authorization: Bearer rc_your_api_key"
```

This works with any client that supports stdio-based MCP servers.

## Available tools

### Enrichment

| Tool | What it does | Credits | Response |
|------|-------------|---------|----------|
| `enrich_person` | Get a person's LinkedIn profile from cache, or resolve by email/name | 1 (cached) / 2 (resolve if found) | Instant |
| `enrich_person_live` | Force a fresh social profile scrape for a person profile from a URL or `prs_…` id | 2 (live) | Async |
| `enrich_company` | Get a company's LinkedIn profile from cache from its LinkedIn URL (description, size, HQ, industry) | 1 (cached) | Instant |
| `enrich_company_live` | Force a fresh social profile scrape for a company profile from a URL or `com_…` id | 2 (live) | Async |

### Search

| Tool | What it does | Credits | Response |
|------|-------------|---------|----------|
| `search_persons` | Search people by name, title, company, industry, location, skills, languages, keywords or recent job change | 1 / profile delivered | Instant |
| `search_persons_lookalike` | Find people who look like one seed profile, from its LinkedIn profile URL | 1 / profile delivered | Instant |
| `count_persons` | Count the people matching the `search_persons` filters, without returning any profile | 0 | Instant |
| `search_companies` | Search companies by name, domain, industry, size, location | 1 / page | Instant |
| `list_person_search_filters` | List the filters accepted by `search_persons` and `count_persons`, with their allowed values | 0 | Instant |
| `list_company_search_filters` | List the filters accepted by `search_companies`, with their allowed values | 0 | Instant |

`count_persons` accepts exactly the filters of `search_persons`, without `cursor` or `perPage`, and returns the total across all pages: the same number as [People search count](https://docs.reversecontact.com/endpoints/search-people-count).

`search_persons_lookalike` reads its criteria from the seed profile: its current function and sub-function with their tenure, its seniority and its location. It takes only `url`, `perPage` (1 to 100, default 25) and `cursor`, never returns the seed, and returns full profiles shaped like `search_persons`, with the same cursor pagination. A search filter is refused with `LOOKALIKE_FILTERS_NOT_SUPPORTED`, and a page with no profile or a seed that is not in the search index yet costs 0 credits. It serves the same results as [People lookalike](https://docs.reversecontact.com/endpoints/search-people-lookalike).

The filter catalogs return every filter with its type, description and example. An allowed-value list longer than 50 entries (industries, sub-functions, country codes) is returned as its size in `allowedValuesCount`; name the field in the `fields` parameter to get its complete list. They serve the same catalogs as [People search available fields](https://docs.reversecontact.com/endpoints/search-people-available-fields) and [Company search available fields](https://docs.reversecontact.com/endpoints/search-companies-available-fields).

### Contact

| Tool | What it does | Credits | Response |
|------|-------------|---------|----------|
| `find_email` | Find a person's professional email addresses from a LinkedIn profile URL, or from a name and company domain | 3 (refunded if no email found) | Async |
| `find_phone` | Find a person's phone numbers from a LinkedIn profile URL, or from a name and company domain | 20 (refunded if no phone number found) | Async |

Both tools take a LinkedIn profile `url`, or a name (`fullName`, or `firstName` and `lastName`) with `companyDomain`. The credits are debited when the job is created and refunded when nothing is found. They return a `taskId` (with `webhookId` and `pollUrl`), and the result is retrieved with `check_task`, as described in [Async workflow](#async-workflow). A workspace without phone finding access gets `CONTACT_PHONE_FINDER_DISABLED` from `find_phone` and is not charged. They run the same lookups as [Find Email](https://docs.reversecontact.com/endpoints/contact-email) and [Find Phone](https://docs.reversecontact.com/endpoints/contact-phone).

### Utility (free)

| Tool | What it does | Credits | Response |
|------|-------------|---------|----------|
| `check_person` | Check whether a person profile is cached and how fresh it is, from a LinkedIn URL or `prs_…` id | 0 | Instant |
| `check_company` | Check whether a company profile is cached and how fresh it is, from a LinkedIn URL or `com_…` id | 0 | Instant |
| `check_usage` | Check your credit balance and rate limit status | 0 | Instant |
| `check_task` | Poll the status of an async operation | 0 | Instant |

Company lookup by domain is not available as an MCP tool. To go from a domain to a company profile, search with `search_companies` and its `companyDomain` filter, then pass the LinkedIn URL it returns to `enrich_company`.

## Example prompts

Once the MCP server is connected, ask your AI agent in natural language. These examples map to the tools above and use the same credits as the REST API.

1. **Enrich a person from an email**
   > Enrich the LinkedIn profile for `alex@acme.com` and summarize current title, company, and recent experience.

2. **Find and enrich a company from a domain**
   > Search for the company with domain `stripe.com`, then enrich its LinkedIn profile and return industry, employee range, headquarters, and a one-paragraph description.

3. **Search people with filters**
   > Find people who are Heads of Sales or VPs of Sales at SaaS companies in the United States. Return the first page of results with name, title, and company.

4. **Size an audience before paying for it**
   > How many sales directors work in France? Count them first, and return the first 25 profiles only if there are fewer than 5,000.

5. **Search companies with filters**
   > Search for fintech companies with 50 to 200 employees headquartered in France. List name, domain, and size.

6. **Check usage before a batch**
   > Check my ReverseContact credit balance and rate limit status before I run a larger enrichment batch.

7. **Async live enrichment workflow**
   > Live-enrich the LinkedIn profile `https://www.linkedin.com/in/example` with `enrich_person_live` and, if the tool returns a task id, poll until the result is ready, then summarize the profile.

8. **Find people like a profile**
   > Find 25 people who look like `https://www.linkedin.com/in/example` and list their name, title, company and location.

9. **Find a professional email**
   > Find the professional email address of Jane Doe at `acme.com`, wait for the result, then give me the address.

Tip: for live enrichments and contact lookups the agent receives a `taskId` from `enrich_person_live`, `enrich_company_live`, `find_email` or `find_phone` and should call `check_task` until status is `succeeded` or `errored`. You usually do not need to manage that loop yourself.

## Async workflow

The live tools (`enrich_person_live`, `enrich_company_live`) and the contact tools (`find_email`, `find_phone`) run asynchronously. They return a `taskId` instead of data:

**Async response**

```json [JSON]
{
  "taskId": "abc123",
  "status": "processing",
  "message": "Scraping LinkedIn profile. Poll with check_task in ~10 seconds."
}
```

Use `check_task` with the `taskId` to poll for results. Tasks typically complete in 10–60 seconds.

**Status flow:** `in_progress` → `succeeded` or `errored`

When succeeded, `check_task` returns the full data payload. Your AI agent handles this polling automatically. Just ask for what you need.

## Credits and rate limits

MCP tools consume the same credits and respect the same rate limits as the REST API. That means:

- MCP calls use the same endpoint pricing as REST.
- MCP calls count toward the same gateway RPM limits as REST API calls. `count_persons` is free but still counts, like its REST endpoint; `check_usage`, `check_task` and the two filter catalogs do not.
- Agent LLM turns are different: they consume credits but do not affect gateway RPM until the Agent triggers a real tool call.

Use `check_usage` to inspect your current balance before expensive operations, and `count_persons` to size a people search for free before `search_persons` bills each profile delivered.

See [Rate limits & credits](https://docs.reversecontact.com/guides/rate-limits-credits) for details on quotas and throttling.

## Troubleshooting

| Error | Cause | Fix |
|-------|-------|-----|
| `Authentication required` (code -32001) | Missing or invalid credentials | OAuth clients: re-authenticate from the client (the access expires if its key is deleted). API key clients: check the key is active and the `Bearer` prefix is present |
| `SSE streaming not supported` (code -32601) | Client sent a GET request | Your client must use POST. Use `mcp-remote` if it defaults to SSE |
| `RATE_LIMIT_EXCEEDED` | Too many requests per minute | Wait for the rate limit window to reset. Check limits with `check_usage` |
| `INSUFFICIENT_CREDITS` | Not enough credits for the operation | Top up credits from the dashboard |
| `TRIAL_RESTRICTED` | Trial plans cannot use live/async endpoints | Upgrade to a paid plan |
| `LOOKALIKE_FILTERS_NOT_SUPPORTED` | `search_persons_lookalike` received a search filter (0 credits) | Send only `url`, `perPage` and `cursor`, or use `search_persons` to combine filters |
| `CONTACT_PHONE_FINDER_DISABLED` | Phone finding is not enabled for the workspace (0 credits) | Use `find_email`, or ask us to enable phone finding |
| Connection timeout | Client cannot reach the server | Verify the URL is `https://api.reversecontact.com/mcp` and your network allows HTTPS |
