Skip to main content
ClaudeWave
fairquery avatar
fairquery

website-contact-company-enricher

View on GitHub

Domain to public business contacts: role emails (MX/disposable-validated), phones, socials, company name, address. Respects robots.txt. Apify Actor + stdio MCP server.

MCP ServersOfficial Registry0 stars0 forks● TypeScriptMITUpdated today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/18/2026
Install in Claude Code / Claude Desktop
Method: Manual
Claude Code CLI
git clone https://github.com/fairquery/website-contact-company-enricher
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "website-contact-company-enricher": {
      "command": "node",
      "args": ["/path/to/website-contact-company-enricher/dist/index.js"],
      "env": {
        "APIFY_TOKEN": "<apify_token>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Clone https://github.com/fairquery/website-contact-company-enricher and follow its README for install instructions.
Detected environment variables
APIFY_TOKEN
Use cases

MCP Servers overview

# Website Contact & Company Enricher

**Turns company domains into one row each (public business emails, phones, social profiles, company name and address) for $3 per 1,000 domains.** You pay $0.003 per domain that returns a result row, and unreachable, blocked or invalid domains are free. Example: enriching 500 domains costs at most 500 × $0.003 = **$1.50**, plus Apify's $0.00005 Actor-start fee.

**Fairquery** Apify Actor that turns a list of **domains** into one clean row per company: **business emails** (validated for MX, disposable domains and typos), **phone numbers** (E.164), **social profiles**, **company name**, **description** and **postal address**, taken from the homepage and its contact / about / imprint pages. Plain HTTP, no browser, **robots.txt respected**, one request at a time per site.

## When to use this Actor (LLM / tool selection)

Use it when an agent or sales-ops workflow needs to:

- Add a contact email, phone and LinkedIn company page to a list of company websites (CRM enrichment, lead lists, vendor onboarding)
- Find the generic inbox (`info@`, `sales@`, `support@`, `press@`) of a company and check that its domain actually receives mail
- Get the legal company name and address from structured data or the imprint page (EU sites)
- Collect a company's official social accounts

Do **not** use it to find personal emails of individuals or to scrape people's profiles. By default it returns **role / generic mailboxes only** (`emailScope: "role"`); personal LinkedIn profiles (`/in/…`) are never returned.

## How it works

1. Normalises each input (`https://www.Acme.com/contact`, `jane@acme.com`, `acme.com` → `acme.com`) and removes duplicates.
2. Reads `robots.txt` (RFC 9309: missing = allowed, 5xx = disallowed) and honours `Disallow` rules and `Crawl-delay` for user agent `FairqueryBot`.
3. Fetches the homepage, then the best-scoring same-site pages (contact, Kontakt, contacto, about, imprint/Impressum, legal notice, team…) up to `maxPagesPerDomain`, waiting `requestDelayMs` between requests to the same site.
4. Extracts: JSON-LD `Organization`/`LocalBusiness` (name, legalName, telephone, email, address, sameAs), `mailto:` and `tel:` links, Cloudflare-protected emails, `name [at] domain [dot] com` obfuscation, `og:site_name`, `<address>` blocks, social links.
5. Validates emails with the same code as [Fairquery Email Validator](https://apify.com/fairquery/email-validator-mx-disposable): syntax, DNS-over-HTTPS MX/null-MX, disposable list, free-provider and typo checks (no SMTP probing).

## Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `domains` | `string[]` | (required) | Domains, URLs or emails |
| `maxPagesPerDomain` | int | `5` | 1–15, homepage included |
| `emailScope` | `role` \| `business` \| `all` | `role` | `business` adds named addresses on the company's own domain |
| `validateEmails` | bool | `true` | MX / disposable / typo |
| `checkSpfDmarc` | bool | `false` | SPF/DMARC for the company mail domain |
| `defaultPhoneCountry` | string | – | e.g. `US`; also parse national-format numbers in page text |
| `domainConcurrency` | int | `5` | Sites in parallel |
| `requestDelayMs` | int | `1000` | Delay between requests to one site |
| `requestTimeoutSecs` | int | `15` | Per request |
| `domainTimeoutSecs` | int | `40` | Hard limit per domain (all pages + DNS). At the limit you get the data collected so far (`partial: true`), or an uncharged `DOMAIN_TIMEOUT` error row if the homepage never loaded |
| `maxDomains` | int | `1000` | Safety cap |

```json
{ "domains": ["apify.com", "stripe.com", "https://basecamp.com/"], "maxPagesPerDomain": 4 }
```

## Output

```json
{
  "schema_version": "1.0.0", "type": "domain", "input": "apify.com", "domain": "apify.com", "final_url": "https://apify.com/",
  "company_name": "Apify Technologies s.r.o.",
  "description": "Cloud platform for web scraping, browser automation, AI agents, and data for AI…",
  "emails": [
    { "email": "hello@apify.com", "source_url": "https://apify.com/contact", "is_role_account": true, "on_company_domain": true,
      "is_free_provider": false, "is_disposable": false, "verdict": "valid", "reasons": ["ROLE_ACCOUNT"], "has_mx": true, "mail_provider": "Google Workspace / Gmail" }
  ],
  "primary_email": "hello@apify.com",
  "phones": [{ "e164": "+18889262289", "raw": "+1 888 926 2289", "source_url": "https://stripe.com/contact/sales", "source": "tel" }],
  "social_links": { "linkedin": ["https://linkedin.com/company/apify"], "twitter": ["https://x.com/apify"], "github": ["https://github.com/apify"] },
  "address": "Na Příkopě 959/27, 11000, Prague, CZ",
  "mail_domain": { "has_mx": true, "null_mx": false, "mail_provider": "Google Workspace / Gmail", "has_spf": null, "has_dmarc": null, "dmarc_policy": null },
  "pages_crawled": ["https://apify.com/", "https://apify.com/contact"], "pages_blocked_by_robots": 0, "robots_txt": "ok", "email_scope": "role"
}
```

Error rows (`type: "error"`, never charged): `INPUT_EMPTY`, `INVALID_DOMAIN`, `MAX_DOMAINS_EXCEEDED`, `SITE_UNREACHABLE`, `BLOCKED_BY_ROBOTS`, `ENRICH_FAILED`, `DOMAIN_TIMEOUT`, `RUN_TIMEOUT_NEAR`.

**`RUN_SUMMARY`** (key-value store): pages fetched, pages blocked by robots.txt, emails found vs. excluded by scope, DNS requests, charged events.

## Pricing

| Event | Price | When |
| --- | --- | --- |
| `domain-enriched` | $0.003 | Each domain that returns a result row |
| `apify-actor-start` | $0.00005 | Once per run, per GB of memory (Apify default event) |

Error rows (`SITE_UNREACHABLE`, `BLOCKED_BY_ROBOTS`, `INVALID_DOMAIN`, `ENRICH_FAILED`, …) are **never charged**. A domain is charged once, however many pages are crawled (up to `maxPagesPerDomain`).

**Worked example:** 1,000 domains from a Google Maps export, of which 120 are unreachable or blocked: 880 × $0.003 = **$2.64**, plus $0.00005.

To cap spend, set a maximum cost per run in the run options; the Actor stops cleanly at the limit. `maxDomains` caps how many domains one run processes. Prices are from the Store pricing tab (October 2026).

## Memory / runtime

Default **256 MB**, no browser, no proxy. With the default politeness settings a domain takes about 3–8 s (homepage + 4 pages, 1 s apart), and 5 domains run in parallel, so 100 domains finish in roughly 1–3 minutes. Sites that block datacenter IPs or need JavaScript to render contact details will return fewer fields. Memory is capped at 512 MB (more does not help: the Actor is network-bound). Each domain has a hard 40 s time limit (`domainTimeoutSecs`), so one slow or tarpitting site can't hang the run, and every finished domain is saved and charged immediately. The default run timeout is 15 minutes (about 500–1,000 domains); shortly before the timeout the Actor stops starting new domains and adds an uncharged `RUN_TIMEOUT_NEAR` row listing how many were skipped, so split very large lists or raise the timeout.

## MCP / Apify tools

Call from agents via [Apify MCP](https://mcp.apify.com) with Actor `fairquery/website-contact-company-enricher`:

```json
{ "actor": "fairquery/website-contact-company-enricher", "input": { "domains": ["acme.com"] } }
```

## Local stdio MCP server

The [`mcp/`](./mcp) folder is a stdio MCP server (TypeScript, `@modelcontextprotocol/sdk`) with two tools, both with annotations and output schemas:

| Tool | What it does | Cost |
| --- | --- | --- |
| `enrich_domains` | Runs this Actor and returns the rows | Needs `APIFY_TOKEN`, billed per domain |
| `normalize_domains` | Cleans URLs/emails into unique domains, lists invalid ones | Free, local, no token |

```bash
cd mcp && npm install && npm run build
node scripts/smoke-test.mjs                          # initialize + tools/list + free tool, no token
APIFY_TOKEN=... node scripts/smoke-test.mjs --call   # real call
```

```json
{ "mcpServers": { "fairquery-contact-enricher": { "command": "node", "args": ["/path/to/website-contact-company-enricher/mcp/dist/index.js"], "env": { "APIFY_TOKEN": "<your Apify token>" } } } }
```

Docker: the root `Dockerfile` builds the MCP server image (`docker build -t fairquery-contact-enricher-mcp .`); it is also the Dockerfile for Glama. The Actor image is `.actor/Dockerfile`. `glama.json` lists `fairquery` as maintainer.

## Works well after

- [Google Maps Scraper](https://apify.com/compass/crawler-google-places): pass the `website` column into `domains` to add a generic inbox, phone, LinkedIn page and legal name to each business.
- [Google Search Results Scraper](https://apify.com/apify/google-search-scraper) or any company list: domains, URLs and email addresses are all accepted and normalised.
- Next steps: re-check the emails with the [Email Validator](https://apify.com/fairquery/email-validator-mx-disposable) just before sending, and screen company names with the [Sanctions & Watchlist Screener](https://apify.com/fairquery/sanctions-watchlist-screener) when you onboard suppliers or customers.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| Run is rejected because `domains` is required | The input had no domains. The three sample domains in the Console form are prefill only and are not sent with API calls. |
| `BLOCKED_BY_ROBOTS` or few pages crawled | The site's robots.txt disallows `FairqueryBot` for those paths, and the Actor honours it. These rows are free. |
| `SITE_UNREACHABLE` / no emails on a JavaScript-heavy site | The site blocks datacenter IPs or renders contact details with JavaScript. The Actor uses plain HTTP with no proxy or browser, so such sites return fewer fields. |
| Named people's emails missing | By default `emailScope` is `role` (info@, sales@ …). Use `business` to include named addresses on the company's own domain, but only if you have a lawful basis to process them. |
| Run slower than expected | Politeness settings: `requestDelayMs` (default 1,000 ms between requests to one site) and `domainConcurrency` (default 5). Raise concurrency rather than lowering the delay. |
ai-agentsapifyapify-actorb2bcompany-contactscompany-datacompany-enrichmentcontact-enrichmentcontact-extractioncontact-findercrawlerdomain-enrichmentemail-finderlead-generationmcpmcp-servermodel-context-protocolrobots-txttypescriptweb-scraping

What people ask about website-contact-company-enricher

What is fairquery/website-contact-company-enricher?

+

fairquery/website-contact-company-enricher is mcp servers for the Claude AI ecosystem. Domain to public business contacts: role emails (MX/disposable-validated), phones, socials, company name, address. Respects robots.txt. Apify Actor + stdio MCP server. It has 0 GitHub stars and its last recorded update is dated 2026-10-18.

How do I install website-contact-company-enricher?

+

You can install website-contact-company-enricher by cloning the repository (https://github.com/fairquery/website-contact-company-enricher) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is fairquery/website-contact-company-enricher safe to use?

+

Our security agent has analyzed fairquery/website-contact-company-enricher and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains fairquery/website-contact-company-enricher?

+

fairquery/website-contact-company-enricher is maintained by fairquery. The last recorded GitHub activity is dated 2026-10-18, with 0 open issues.

Are there alternatives to website-contact-company-enricher?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy website-contact-company-enricher to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: fairquery/website-contact-company-enricher
[![Featured on ClaudeWave](https://claudewave.com/api/badge/fairquery-website-contact-company-enricher)](https://claudewave.com/repo/fairquery-website-contact-company-enricher)
<a href="https://claudewave.com/repo/fairquery-website-contact-company-enricher"><img src="https://claudewave.com/api/badge/fairquery-website-contact-company-enricher" alt="Featured on ClaudeWave: fairquery/website-contact-company-enricher" width="320" height="64" /></a>