# Backlink MCP Docs — Install, 13 Tools, REST

> Developer docs for the Backlink MCP server: Claude and Cursor install, all 13 tools, REST examples, auth, and rate limits.

- Canonical page: https://backlinkmcp.com/docs
- MCP endpoint: `POST https://backlinkmcp.com/api/mcp` (JSON-RPC 2.0, streamable HTTP, no install, 13 tools)
- REST: `GET https://backlinkmcp.com/api/v1/authority?domain=example.com`, `/api/v1/backlinks?domain=example.com` ([docs](https://backlinkmcp.com/docs.md))
- Pricing: Free = 10 lookups/day per IP, 25 backlink rows, no signup. Pro = $19/mo, unlimited daily lookups, 100 rows, `ai_visibility_report` (operator-issued; self-serve checkout is not live)
- Data limits: the index is domain-level (referring domains with authority + outbound counts). No per-link URLs, anchor text or rel/dofollow. `domain_rating` is not Moz DA and not a Google factor
- Site index for agents: https://backlinkmcp.com/llms.txt

---

Everything to wire up BacklinkMCP over MCP or REST: install snippets, tool schemas, real response shapes, auth, rate limits, and error handling. Not sure which transport? [MCP vs REST](https://backlinkmcp.com/articles/mcp-vs-rest-api) explains when an agent should use which. New to the product? Start at the [MCP server overview](https://backlinkmcp.com/mcp-server-for-seo) — or read why LLMs [can't check backlinks without a tool](https://backlinkmcp.com/articles/can-llms-check-backlinks).

## MCP install

BacklinkMCP is a remote MCP server (JSON-RPC 2.0 over streamable HTTP) at `https://backlinkmcp.com/api/mcp`. No install, no local process — add the URL to your client's config.

### Claude Desktop

Edit `claude_desktop_config.json` and restart the app.

```
{
  "mcpServers": {
    "backlinkmcp": {
      "url": "https://backlinkmcp.com/api/mcp"
    }
  }
}
```

### Claude Code

From a project directory:

```
claude mcp add --transport http backlinkmcp https://backlinkmcp.com/api/mcp
```

### Cursor

Add to `.cursor/mcp.json` (project) or the global MCP settings:

```
{
  "mcpServers": {
    "backlinkmcp": {
      "url": "https://backlinkmcp.com/api/mcp"
    }
  }
}
```

For a Pro key, prefer the `Authorization: Bearer` header (Auth). A `?key=` query param still works for MCP clients that can only store a URL, and it gets logged, so do not paste a live key into a shared config.

## Recipes

The point of backlinks-over-MCP isn't a prettier dashboard — it's that an agent can chain the graph and the live web in one turn, then act on the result. Paste any of these into Claude (Desktop or Code) once the server is connected. Each is a workflow that would take several manual steps and a CSV export in a traditional tool.

### Competitor backlink teardown → live outreach shortlist

Finds domains that link your competitors but *not* you (the gap you can close), then verifies which still publish outbound links *today* — so you pitch warm targets you don't already have, not stale ones.

```
Using backlinkmcp, run find_link_prospects with my domain mysite.com and
competitors stripe.com and squareup.com to get domains that link a competitor
but not me. Then run verify_link_live on the top prospects to confirm they
still publish outbound links today. Give me a table sorted by authority, and
for each, one line on why it might link to a payments product — as a backlink
outreach shortlist.
```

### Vet a guest-post target before you pitch

Authority alone can be inflated by junk. This asks the agent to sanity-check the score against who actually links the site.

```
Before I pitch a guest post to smashingmagazine.com, use backlinkmcp to
get its domain_authority_score and its top linkers. Tell me whether the
authority looks earned (wiki/edu/news/real editorial links) or inflated by
low-quality or infrastructure links, and give me a go / no-go.
```

### Did my backlinks survive? (link reclamation)

Feed the agent the domains that used to link you; it checks each live and flags the drop-offs to chase.

```
Use backlinkmcp verify_link_live to check whether these domains still link
to my site example.com right now: theverge.com, techcrunch.com, wired.com.
List which ones are confirmed live and which dropped the link, so I can send
reclamation emails to the ones that dropped it.
```

verify_link_live only fetches homepages, so a "not_found" means the link isn't on the front page today — it may still live on an inner page. Treat drop-offs as leads to check, not confirmed removals.

### Audit your inbound links for spam

Scans your own linkers for spammy patterns — abused TLDs, spam keywords, link-farm outbound counts — and hands you a review list, not a trigger-happy disavow file.

```
Use backlinkmcp flag_toxic_links on my domain example.com. Group the flagged
domains by severity, and for the high-severity ones tell me which single signal
drove each flag. Remind me that Google says most sites should not disavow, and
help me decide which (if any) are worth a manual review.
```

flag_toxic_links is a heuristic on domain-level signals (TLD, name patterns, authority, outbound counts) — candidates to *review*, never a confirmed toxic link. Google's own guidance is that most sites should not use the disavow tool at all; only disavow with a manual action or clear negative-SEO.

### Find who links your whole niche

Intersects several competitors' backlink profiles to surface the publications, directories, and roundups that link the whole category — the ones you almost certainly need too.

```
Use backlinkmcp common_linkers on notion.so, airtable.com, and coda.io to
find the domains that link more than one of them. Prioritize the ones that link
all three — those are the must-have targets for a productivity tool — and give
me a shortlist with a one-line pitch angle for each.
```

## MCP tools

Thirteen tools — three read from the cached graph engine, one fetches the live web, three run link-building analysis (competitor gap, toxic-link audit, and multi-domain overlap), two cover AI visibility (a free robots/AI-crawler audit and a Pro multi-LLM panel), and four run page-level technical SEO (on-page audit, structured data, Core Web Vitals, IndexNow). `tools/list` returns their full JSON Schema; here's the practical summary.

### domain_authority_score

Editorial-authority score for a domain, weighted toward wiki/edu/gov/news referrers.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Root domain, e.g. `stripe.com` |

Example `structuredContent` in the tool result:

```
{
  "domain": "stripe.com",
  "found": true,
  "domain_rating": 80.9,
  "referring_domains": 702082,
  "links_out": 41
}
```

### top_linkers_for_domain

Top 25 domains linking to a given domain, ranked by the linking domain's own authority.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Root domain, e.g. `stripe.com` |

### backlinks_for_domain

Full backlink payload: total inlink count plus the ranked linking domains — up to 100 rows on Pro, 25 on the free tier.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Root domain, e.g. `stripe.com` |

Example `structuredContent` (Pro key — the free tier returns `row_cap` 25):

```
{
  "domain": "stripe.com",
  "found": true,
  "total_inlinks": 702082,
  "row_cap": 100,
  "ranked_returned": 100,
  "results": [
    { "source": "en.wikipedia.org", "authority": 48213, "links_out": 3 },
    { "source": "github.com", "authority": 39187, "links_out": 12 }
  ]
}
```

Per-linker `authority` here is the same relative link-authority score used by `find_link_prospects` (a raw integer, higher = stronger) — distinct from the 0–100 `domain_rating` returned by `domain_authority_score`.

### verify_link_live

Live verification: fetches each linking domain's homepage right now and confirms an actual `href` to the target exists. Only homepages are fetched, so `not_found` means "no link on the homepage today", not "the link is gone".

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Root domain whose backlinks to verify, e.g. `stripe.com` |
| linkers | string[] | no | Specific linking domains to check (max 15); defaults to top linkers from the graph |
| limit | integer | no | How many top linkers to check when `linkers` is omitted (default 8, max 15) |

Example `structuredContent`:

```
{
  "domain": "stripe.com",
  "checked": 8,
  "confirmed": 5,
  "results": [
    { "linker": "github.com", "status": "confirmed",
      "evidence": ["https://stripe.com/"], "checked_url": "https://github.com/" },
    { "linker": "en.wikipedia.org", "status": "not_found",
      "checked_url": "https://en.wikipedia.org/" }
  ],
  "note": "homepage-only check; not_found &ne; link removed"
}
```

### find_link_prospects

Competitor backlink-gap analysis: pass your domain and 1–3 competitors, get the domains that link a competitor but not you — ranked by the linking domain's authority. A warm link-building outreach shortlist. Domain-level only (the index has no per-link URLs or anchor text), so each row is a *domain to pitch*, not a confirmed link. CDN/analytics/marketing-widget/social noise is filtered out. Free mines 1 competitor and returns up to 25 prospects; Pro mines up to 3 and returns up to 100.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Your root domain — the site you want more backlinks for, e.g. `yoursite.com` |
| competitors | string[] | yes | Competitor root domains to mine (1–3); the free tier uses only the first |

Example `structuredContent` (Pro, two competitors). `authority` is BacklinkMCP's relative link-authority score (higher = stronger linker), not a 0–100 rating; prospects linking multiple competitors are the warmest:

```
{
  "your_domain": "ugmonk.com",
  "your_linker_count": 50,
  "competitors": [
    { "domain": "studioneat.com", "ok": true, "total_inlinks": 445, "linkers_seen": 50 },
    { "domain": "baronfig.com", "ok": true, "total_inlinks": 358, "linkers_seen": 50 }
  ],
  "total_prospects_before_cap": 88,
  "filtered_junk_count": 2,
  "row_cap": 100,
  "prospects": [
    { "source": "kk.org", "authority": 4565, "links_out": 3291,
      "linked_competitors": ["studioneat.com", "baronfig.com"] },
    { "source": "uncrate.com", "authority": 1931, "links_out": 1628,
      "linked_competitors": ["studioneat.com"] }
  ]
}
```

### flag_toxic_links

Toxic / low-quality backlink audit — the inverse of `find_link_prospects`. Scans a domain's own linkers and flags spammy *disavow candidates*: abused TLDs (`.tk`/`.xyz`/`.loan`…), spam keywords in the domain, hyphen/keyword stuffing, and link-farm-level outbound counts. Domain-level heuristic only (no per-link URL or anchor), so each row is a *domain to review*, not a confirmed toxic link. Note: Google says most sites should **not** disavow — use this to audit, not to auto-disavow. Free returns up to 25 flags, Pro up to 100.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | The domain whose inbound links you want to audit, e.g. `yoursite.com` |

Example `structuredContent`. `toxicity_score` is a 0–100 heuristic (higher = more signals); severity is `high` at 70+:

```
{
  "domain": "yoursite.com",
  "total_linkers_evaluated": 100,
  "total_flagged": 6,
  "high_severity": 2,
  "medium_severity": 4,
  "row_cap": 100,
  "flagged": [
    { "source": "cheap-viagra-pills.tk", "authority": 3, "links_out": 40,
      "toxicity_score": 110, "severity": "high",
      "reasons": ["high-abuse TLD (.tk)", "spam keyword in domain (\"viagra\")", "low authority (3) vs this profile"] },
    { "source": "linkdirectory.info", "authority": 6, "links_out": 9000,
      "toxicity_score": 50, "severity": "medium",
      "reasons": ["links out to 9000 domains — far above this profile's median (link farm/directory pattern)"] }
  ],
  "disclaimer": "Heuristic flags to review — Google says most sites should not disavow."
}
```

### common_linkers

Multi-domain backlink overlap. Pass 2–4 domains, get the domains that link to *more than one* of them — ranked by overlap (how many of the set they link) then authority. Answers "who links my whole niche?" — the must-have publications, directories, and roundups your competitors all share. Domain-level only (no per-link URL or anchor). Free compares 2 domains, Pro up to 4; returns up to 25 rows free / 100 Pro.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domains | string[] | yes | Root domains to intersect (2–4), e.g. `["a.com","b.com","c.com"]`; the free tier uses only the first 2 |

Example `structuredContent` (Pro, three domains). `overlap_count` is how many of the set the linker links; domains linking *all* of them are the highest-priority targets:

```
{
  "targets": [
    { "domain": "studioneat.com", "ok": true, "linkers_seen": 50 },
    { "domain": "baronfig.com", "ok": true, "linkers_seen": 50 },
    { "domain": "ugmonk.com", "ok": true, "linkers_seen": 50 }
  ],
  "targets_resolved": 3,
  "total_overlap_before_cap": 12,
  "row_cap": 100,
  "common_linkers": [
    { "source": "kk.org", "authority": 4565, "links_out": 3291,
      "overlap_count": 3, "linked_targets": ["studioneat.com", "baronfig.com", "ugmonk.com"] },
    { "source": "uncrate.com", "authority": 1931, "links_out": 1628,
      "overlap_count": 2, "linked_targets": ["studioneat.com", "baronfig.com"] }
  ]
}
```

### ai_visibility_report Pro

AI Visibility / GEO audit. Asks a panel of AI models a buyer-intent question ("what's the best *<category>*?") and reports whether your brand gets recommended, who the models prefer instead (share-of-voice across the panel), *why* the leader wins — diagnosed against BacklinkMCP's own authority/link data — and which domains to earn links from to catch up. Two modes via the `mode` param: `parametric` (default — the models' baked-in brand memory, cheap) or `retrieval` (live web-search models = what the AI answers right now, SEO/citation-driven; costs more). **Pro plan only** (runs a live multi-model panel): 6 models × 3 prompts × up to 4 competitors per report, metered by a daily per-key credit budget.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Your root domain — the brand you're measuring, e.g. `yoursite.com` |
| competitors | string[] | no | Competitor root domains to track share-of-voice against and diagnose the winner |
| prompts | string[] | no | Buyer-intent queries, e.g. `["best project management tool for a startup"]` |
| category | string | no | Shortcut used only if `prompts` is omitted — turned into "What is the best <category>?" |
| mode | string | no | `parametric` (default) or `retrieval` (live web search; costs more credits) |

Example `structuredContent` (Pro):

```
{
  "your_brand": "Airtable",
  "your_visibility": { "top_pick_rate": 0, "mention_rate": 0, "rank": null },
  "share_of_voice": [
    { "brand": "Trello", "top_pick_rate": 0.8, "mention_rate": 1.0 }
  ],
  "leader": { "brand": "Trello", "domain": "trello.com", "top_pick_rate": 0.8 },
  "diagnosis": {
    "your_referring_domains": 40884,
    "leader_referring_domains": 56608,
    "referring_domain_multiple": 1.4,
    "link_targets_to_close_gap": ["yelp.com", "dribbble.com", "booking.com"]
  }
}
```

### ai_crawler_audit

Reads a site's robots.txt and reports which AI crawlers it allows or blocks — sorted by *consequence*. Blocking a **visibility** crawler (OAI-SearchBot, PerplexityBot, ChatGPT-User, Claude-User…) removes the site from live AI answers; blocking a **training** crawler (GPTBot, CCBot, Google-Extended…) only opts out of model training. Those need opposite decisions, so they never share one "blocked" list. Checks 25 known AI crawlers, whether `/llms.txt` exists, and general robots hygiene (Sitemap directives, whole-site `Disallow: /`). Free — no LLM calls.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| domain | string | yes | Root domain to audit, e.g. `yoursite.com` |

Verdicts read the site's *declared* robots.txt policy, not observed crawler behavior, and per-path wildcard semantics are not evaluated — "partial" means some paths are restricted, not a per-path ruling.

### site_audit

Fetches one page and audits its core on-page SEO signals: title and meta-description length, canonical tag, heading structure, image alt-text coverage, viewport tag, robots meta, and word count. Returns a list of concrete issues plus the raw measurements.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| url | string | yes | Full page URL, e.g. `https://example.com/page` |

```
{
  "url": "https://theboard.world/",
  "ok": true,
  "status": 200,
  "titleLength": 61,
  "descriptionLength": 150,
  "canonical": "https://theboard.world/",
  "h1Count": 1,
  "imageCount": 19,
  "imagesMissingAlt": 0,
  "wordCount": 705,
  "issues": ["Title too long (61 chars, recommend <=60)"]
}
```

Single page, raw HTML, no JavaScript rendering — tags injected by client-side JS are invisible to it, and this is not a site crawl.

### schema_validate

Extracts every JSON-LD block from a page, checks that each parses, and flags missing recommended fields for common schema.org types (Article, NewsArticle, Product, Organization, WebSite, BreadcrumbList, FAQPage, LocalBusiness).

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| url | string | yes | Full page URL to check for structured data |

JSON-LD only — Microdata and RDFa are not read. Missing-field flags are recommended-field checks, not Google's full rich-result eligibility test.

### core_web_vitals

Core Web Vitals (LCP, INP, CLS) and a performance score via Google PageSpeed Insights — both a lab Lighthouse run and real-user CrUX field data when the page has enough Chrome traffic to have any.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| url | string | yes | Full page URL to test |
| strategy | string | no | `mobile` (default) or `desktop` |

This relays Google's API. Lab numbers come from a single Lighthouse run and vary between runs; field numbers are null when the page lacks CrUX data. Google's keyless quota is shared across callers and can return HTTP 429 — that's a quota response, not a problem with your page.

### indexnow_submit

Submits one or more URLs to IndexNow for near-instant pickup by Bing and Yandex. You supply an IndexNow key *you* control and have already hosted at `https://<your-domain>/<key>.txt` — this tool does not create or host that key for you. All URLs in one call must be on the same host.

| Param | Type | Required | Description |
| --- | --- | --- | --- |
| urls | string \| string[] | yes | One URL or an array of URLs, all on the same host |
| key | string | yes | Your IndexNow key, already hosted at `https://<host>/<key>.txt` |

HTTP 200/202 means IndexNow *accepted the batch for key verification* — not that anything was crawled or indexed. If the key file isn't reachable at `keyLocation`, verification fails afterwards and nothing is picked up.

## REST endpoints

Same engine, plain HTTP GET. Good for scripts, backends, or anything that isn't an MCP client.

### GET /api/v1/authority?domain=X

```
curl "https://backlinkmcp.com/api/v1/authority?domain=stripe.com"
```

```
{
  "ok": true,
  "authority": {
    "domain": "stripe.com",
    "found": true,
    "domain_rating": 80.9,
    "referring_domains": 702082,
    "links_out": 41
  }
}
```

### GET /api/v1/backlinks?domain=X

```
curl "https://backlinkmcp.com/api/v1/backlinks?domain=stripe.com"
```

```
{
  "ok": true,
  "backlinks": {
    "domain": "stripe.com",
    "found": true,
    "total_inlinks": 702082,
    "ranked_returned": 100,
    "results": [
      { "source": "en.wikipedia.org", "authority": 48213, "links_out": 3 },
      { "source": "github.com", "authority": 39187, "links_out": 12 }
    ]
  }
}
```

### GET /api/health

Always HTTP 200. Read the JSON: `ok`/`engine` is the cheap origin `/health` probe; `listing` is a separate backlinks-path signal (`up`/`down`/`unknown`). Do not treat engine-up as listing-up.

```
curl "https://backlinkmcp.com/api/health"
```

### POST /api/mcp

JSON-RPC 2.0 endpoint — this is what MCP clients call under the hood. You can hit it directly too:

```
curl -X POST "https://backlinkmcp.com/api/mcp" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"domain_authority_score","arguments":{"domain":"stripe.com"}}}'
```

## Auth

The free tier needs no key at all — it's rate-limited by IP. Pro keys unlock the unlimited tier (key use is covered by the [terms](https://backlinkmcp.com/terms) and [privacy policy](https://backlinkmcp.com/privacy)). **Preferred:** pass the key in the `Authorization` header so it never lands in URLs, server logs, or browser history:

```
curl "https://backlinkmcp.com/api/v1/authority?domain=stripe.com" \
  -H "Authorization: Bearer YOUR_KEY"
```

A `?key=` query parameter also works as a fallback (handy for MCP clients that only take a URL), but avoid it where you can — query strings get logged:

```
curl "https://backlinkmcp.com/api/v1/authority?domain=stripe.com&key=YOUR_KEY"
```

The `Authorization` header wins if both are sent. Get a key on the [Pro plan](https://backlinkmcp.com/pricing).

## Rate limits

Free tier: **10 lookups/day**, tracked per calendar day (UTC). Anonymous callers are counted by IP; a free API key is counted by key. Every REST call and every MCP `tools/call` counts against the same daily bucket. **Pro keys are unlimited** — that's the plan's core perk, alongside the full 100-row linker lists.

When the limit is hit, REST returns HTTP 429 with `limited: true`; MCP returns a normal tool result (not an error) with an upgrade message in the text content, so agents don't treat it as a crash.

## Error shapes

Two distinct "not a success" shapes to check for, on both REST and MCP:

### Rate limit reached

```
{
  "ok": false,
  "limited": true,
  "error": "Free daily limit reached (10/day). Upgrade: https://backlinkmcp.com#pricing"
}
```

### Engine busy / upstream unavailable

```
{
  "ok": false,
  "busy": true,
  "error": "Engine temporarily unavailable, try again shortly."
}
```

Always check `ok` first. If `ok` is false, check `limited` to distinguish "you're out of free lookups" (retry tomorrow or upgrade) from `busy` (retry with backoff — transient).

## Related tools & guides

[Free MCP for SEO](https://backlinkmcp.com/mcp-server-for-seo)
[MCP vs REST](https://backlinkmcp.com/articles/mcp-vs-rest-api)
[AI-search playbook](https://backlinkmcp.com/articles/how-to-rank-in-ai-search)
[Can ChatGPT check backlinks?](https://backlinkmcp.com/articles/can-llms-check-backlinks)
[Free backlink checker API](https://backlinkmcp.com/free-backlink-checker)
[Domain authority API](https://backlinkmcp.com/domain-authority-api)
