Scoring tools
Two read-only tools let an assistant evaluate the citation value of a domain or a prospective placement:
score_publisher_value— the AI Placement Value Score (AIPVS) for one or more publisher domains.score_placement_quality— the AI Placement Quality Score (PQS) for a prospective placement, optionally combined with a publisher's AIPVS.
Both are read-only: scoring never creates a publisher record, edits anything, or queues enrichment. When a domain hasn't been enriched yet, the score comes back as an estimate flagged with needsEnrichment: true.
A third set of tools scores real coverage in bulk — see Bulk placement scoring for an organization below. Those ones write.
score_publisher_value (AIPVS)
Scores one or more publisher domains 0–100 — how valuable a citation from that domain is for AI visibility. AIPVS combines three layers: organic authority, AI citation accessibility, and AI training influence.
| Parameter | Type | Notes |
|---|---|---|
domains | string[] | 1–10 publisher domains to score. |
propertyId | string (optional) | Score in this property's brand context — adds category relevance and brand uplift. From list_properties. |
Each result includes the publisher's score, tier, AI impact multiplier, per-layer detail, and needsEnrichment. Passing a propertyId scores each publisher for that brand (category fit and brand-specific uplift); omitting it scores in general.
Any publisher flagged needsEnrichment: true has an estimated score until it's enriched. Treat those as directional.
For the full methodology, see AI Placement Value Score.
score_placement_quality (PQS)
Scores a prospective placement 0–100 — how much citation value a placement would earn, given its type, position, editorial control, and link attribute. Pass a publisherDomain (and optionally propertyId) to also compute that publisher's AIPVS and the combined total placement value (AIPVS × PQS ÷ 100).
| Parameter | Type | Notes |
|---|---|---|
placementType | enum | Where/how the brand appears on the page (see below). |
editorialControl | enum | How much control the brand has over the content. |
linkAttribute | enum | The link's rel attribute. |
assumedPosition | number (optional) | Position on the page, 0 = top … 1 = bottom (default 0.15). |
publisherDomain | string (optional) | Also compute this publisher's AIPVS and the total placement value. |
propertyId | string (optional) | Brand context for the AIPVS layer. From list_properties. |
Accepted values
placementType | editorialControl | linkAttribute |
|---|---|---|
dedicated_article | full_authorship | dofollow |
roundup_top | collaborative | nofollow |
roundup_top_third | quoted | sponsored |
roundup_middle_third | mentioned | ugc |
roundup_bottom_third | unpredictable | no_link |
passing_mention | ||
sidebar_widget_biobox | ||
quote_only |
The result returns the pqs (with per-sub-score detail and the effective weights) and, when a publisherDomain is given, the publisher's aipvs and the combined totalPlacementValue. Without a publisherDomain, aipvs and totalPlacementValue are null.
For the full methodology, see AI Placement Quality Score.
Bulk placement scoring for an organization
score_placement_quality scores a placement you are considering. To score coverage you have already earned — a list of real URLs — use score_placement_urls. It fetches each page, finds the brand mention, and returns a real PQS with placement type, link attribute, sentiment, and author.
This is the only organization-scoped surface on the connector. Every other account tool starts from a propertyId; these start from an organizationId (from list_my_organizations), because the brands you score against don't have to be properties on your account at all.
These three tools are the connector's other write surface. score_placement_urls creates a coverage group, brand records, and placements in your organization, and triggers page fetches. It is free today; a monthly cap can be configured per deployment, and a call that would exceed it is refused. Nothing is ever published.
score_placement_urls
| Parameter | Type | Notes |
|---|---|---|
organizationId | string | From list_my_organizations. You must be a member of it. |
rows | { url, brand }[] | 1–200 pairs. The same URL may appear twice against two different brands — that's two placements, not a duplicate. |
name | string (optional) | A name for the coverage group, shown in the app. Defaults to a timestamped "MCP import". |
brandOverrides | record (optional) | Per-brand { companyName?, aliases? }, keyed by the same brand string used in rows. Only applied to brands this call creates. |
How a brand is resolved
The brand on each row is not a property id — it's whatever identifies the brand:
| You pass | Read as | What happens |
|---|---|---|
A bare domain — acme.com | A BRAND | Matched against the organization's existing properties (clients, prospects, and brands scored earlier). A match is reused; no record is created. |
A URL with a path — https://acme.com/products/widget | A PRODUCT, anchored on that page | Matched on that seed URL within the organization, then reused or created the same way. |
| Anything without a domain-shaped host | — | Reported in invalidRows with a reason. The rest of the batch still imports. |
A brand with no match becomes a hidden scoring-only brand record: a property row carrying the company name and the aliases the scorer needs to spot mentions, flagged so it never appears in the Clients grid, the Prospects list, or list_properties. It costs nothing and runs no reports. If you later add that domain as a real property, the hidden record is promoted rather than duplicated, and the placements you've already scored stay attached.
Aliases are derived automatically from the company name and domain. Pass brandOverrides when the user knows better — for instance when the site's title isn't the name the press uses.
The mention matcher is a case-insensitive substring search, so keep any alias you supply long and distinctive. A short one false-positives inside ordinary words ("Ford" inside "afford").
The poll loop
score_placement_urls returns immediately with a groupId, added, duplicates, invalid, invalidRows, and brands: { created, reused } so you can tell the user exactly which brand records were created. Scoring itself runs in the background — expect roughly 30 seconds per placement, five in parallel.
Poll get_coverage_group(groupId) every ~5 seconds until done is true:
| Parameter | Type | Notes |
|---|---|---|
groupId | string | From score_placement_urls or list_coverage_groups. |
includeAipvs | boolean (optional) | Add each publisher's AIPVS, scored in that item's own brand context (default true, up to 100 distinct brand/publisher pairs). |
limit | number (optional) | Max items returned, newest first (default 200, max 500). counts.items is always the group's full size. |
The result carries counts (items, pending, running, completed, failed) and a done flag — done is true once nothing is pending or running, and it answers for the whole group, not just the page of items returned. An item whose placement hasn't been created yet counts as pending. Each item returns its url, domain, title, the brand it was scored against, its placement (status, failureCode, pqsScore, pqsTier, pqsTierLabel, placement type, link attribute, sentiment, author), and its aipvs.
AIPVS is network-bound, so pass includeAipvs: false while a batch is still running and read it once the placements have completed.
A placement that finishes with a failureCode of no_brand_mention usually means the brand's aliases are wrong for how that outlet writes the name — fix the aliases in the app and re-score.
get_coverage_group also reads a property's coverage group, where every item is scored against that property's own brand. Use list_coverage_groups(organizationId) to find groups you scored earlier; it returns the organization's cross-brand batches by default, and takes scope: "property" | "all" or a propertyId for per-client coverage groups.
When to use which
- "Is this outlet worth pitching?" →
score_publisher_valueon the domain(s), ideally with yourpropertyIdfor brand context. - "How good would this specific placement be?" →
score_placement_qualitywith the placement's shape, pluspublisherDomainto fold in the outlet's value and get a single total. - "Score this list of coverage we earned." →
score_placement_urls, then pollget_coverage_group. This is the one that reads the real page.
Related
- AI Placement Value Score methodology
- AI Placement Quality Score methodology
- Placement scoring dashboard — the same bulk scoring in the app, with the import wizard and CSV/PDF export
- Coverage API — the REST equivalent of
score_placement_urls, for automation platforms - Publisher Lookup dashboard · Placements dashboard
- Prompts — the
evaluate_publishersprompt drivesscore_publisher_value