AstraVerify Domain Trust Check
Server Details
Email security and AI discoverability scores for any domain, with the exact record or tag to fix.
- Status
- Healthy
- Uptime
- 99.6% over 43 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
TDQS
Scored across 5 tools
Each tool targets a distinct action+output: two independent scores (check_discoverability, check_email_security), a raw per-crawler response (fetch_as_crawler), an aggregate report (get_report), and a post-fix recheck (verify_fix). The descriptions explicitly route the agent — get_report first, then single-subject tools, and fetch_as_crawler only when check_discoverability flags a crawl issue. The potential overlap between check_discoverability's crawl-access score and fetch_as_crawler is called out and resolved in-text ('scores across all six at once' vs 'the one raw response').
All five tools follow a strict snake_case verb_noun pattern (check_*, fetch_*, get_*, verify_*). The verbs are semantically appropriate and no convention mixing occurs. A predictable, readable scheme throughout.
Five tools is a tight, well-scoped set for a domain trust checker: two subject scorers, one drill-down fetch, one aggregator, and one verification step. Each tool has a non-redundant role in the workflow and none feels like filler.
The surface covers both scoring domains (email security and discoverability), aggregation with shareable output, history comparison, and post-fix re-verification — a full lifecycle for the stated purpose. Minor gaps remain, such as batch/multi-domain comparison or scheduled monitoring beyond include_history, but core workflows have no dead ends.
Available Tools
5 toolscheck_discoverabilityCheck discoverability (search and AI crawler readiness)ARead-onlyIdempotentInspect
Check whether search engines and AI assistants can crawl, read and quote this site. Use when the person asks about SEO basics, robots.txt, sitemaps, llms.txt, or whether Google, ChatGPT, Claude or Perplexity can see their site. Input: a bare domain like example.com. Returns a Discoverability score 0-100 broken into crawl access (25: robots.txt, plus what the edge actually serves to Googlebot, Bingbot, OAI-SearchBot, PerplexityBot, ClaudeBot and GPTBot), site plumbing (20: HTTPS, one canonical host, sitemap, real 404s), page metadata (20), structured data (20) and answer-engine readiness (15: llms.txt, a definitional opening, question-form headings). Every finding carries the exact file, tag or record to publish. It makes roughly 15 fetches over a few seconds - robots.txt, the sitemap, the root page, up to four pages listed in the sitemap, llms.txt, the preview image, one deliberately missing URL to see how 404s are handled, and the root page once as each of the six crawlers. It identifies itself as AstraVerifyBot, except on those six checks, where the point is to send the crawler's own user-agent. It fetches nothing off that domain and crawls no further. Cached 15 minutes. It changes nothing on the site. This is a separate scan from check_email_security and does not include it. It scores crawl access across all six crawlers at once; for the exact response a single named crawler receives - status, redirect chain, headers, the text it would index - use fetch_as_crawler.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The domain to check, as the person gave it (no scheme, no path). Reserved names such as example.com are refused. | |
| refresh | No | Force a fresh scan instead of the cached result (rate limited) |
Output Schema
| Name | Required | Description |
|---|---|---|
| cdn | No | |
| raw | No | What the components add up to, before the cap |
| grade | Yes | A+ to F, or null alongside a null score |
| score | Yes | Out of 100, exactly as astraverify.com shows it. Null when not_applicable or inconclusive is set. |
| capped | No | |
| domain | Yes | |
| reason | No | Why score is null, when it is |
| verdict | No | One sentence on what engines can do with the site |
| held_back | No | Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score |
| components | No | |
| open_fixes | No | Findings above info level |
| report_url | No | The report page for this domain on astraverify.com |
| request_id | No | req_... for this call. Quote it when reporting a problem with the result. |
| website_at | No | When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request. |
| not_checked | No | Parts skipped in this scan |
| inconclusive | No | The site could not be fetched, so the scan could not be completed. A failure to measure, not a finding about the site. |
| canonical_host | No | |
| not_applicable | No | The domain publishes no web address, so there is no website to assess. Not a low score: score and grade are null and there are no recommendations. verdict names the domain to scan instead. |
| recommendations | No | |
| cache_age_seconds | No | Age of the result; 0 means it was scanned just now |
| verified_component | No | Set by verify_fix: the component re-checked |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, non-destructive, open-world), and the description goes well beyond them: ~15 fetches over a few seconds, the exact resources fetched, self-identification as AstraVerifyBot except on the six crawler-impersonation checks, no off-domain fetches, no further crawling, 15-minute cache, and no site mutation. This is unusually rich disclosure of runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, and the operational detail (fetch plan, user-agent behavior, caching, sibling routing) is all decision-relevant rather than padding. The parenthetical scoring breakdown is dense and slightly long, but each clause maps to a distinct behavior an agent benefits from knowing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only scan with a full annotation set and an output schema, the description covers the remaining gaps an agent needs: trigger conditions, scope boundaries, side-effect profile, runtime cost, caching, and the sibling routing rule for single-crawler queries. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters and the baseline is 3. The description adds format guidance beyond the schema ('Input: a bare domain like example.com') and the 'Cached 15 minutes' statement explains why the refresh flag exists. It stops short of naming the parameters explicitly, so it is not a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Check whether search engines and AI assistants can crawl, read and quote this site') and scopes it with the scoring breakdown (crawl access, plumbing, metadata, structured data, answer-engine readiness). It explicitly distinguishes itself from check_email_security ('a separate scan... does not include it') and fetch_as_crawler, so an agent can route correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggers ('Use when the person asks about SEO basics, robots.txt, sitemaps, llms.txt, or whether Google, ChatGPT, Claude or Perplexity can see their site') and names the alternative with the condition that selects it ('for the exact response a single named crawler receives... use fetch_as_crawler'). When-to-use, when-not-to-use, and the sibling boundary are all spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_email_securityCheck email security (MX, SPF, DKIM, DMARC)ARead-onlyIdempotentInspect
Check whether anyone can send email as this domain, and whether its own mail reaches the inbox. Use when the person asks about email security, spoofing or phishing risk, SPF, DKIM or DMARC setup, or why their mail goes to spam. Input: a bare domain like example.com - no scheme, no path. Given a URL or an email address, extract the domain and say what you extracted. Subdomains score in their own right: mail from the apex is not evidence about mail.example.com. Returns an Email Security score 0-100 broken into MX (25), SPF (25), DKIM (20) and DMARC (30), the status of each published record, the mail provider identified from MX, and the exact DNS record to publish for every finding. DNS-only, so it answers in about a second; cached 15 minutes, and refresh is for when DNS has just changed. One caveat to pass on rather than hide: DKIM selectors cannot be enumerated from DNS. They are found by probing the selectors known for the mail provider plus a list of a few hundred common names. A provider that issues random selectors - Amazon SES and Postmark among them - can only be confirmed from a live email, so report DKIM as not found by probing, never as proof the domain does not sign.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The domain to check, as the person gave it (no scheme, no path). Reserved names such as example.com are refused. | |
| refresh | No | Force a fresh scan instead of the cached result (rate limited) |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | What the components add up to, before the cap |
| grade | Yes | A+ to F |
| score | Yes | Out of 100, exactly as astraverify.com shows it |
| capped | No | |
| domain | Yes | |
| null_mx | No | The domain declares that it sends and receives no mail |
| records | No | DNS records found, keyed mx, spf, dkim, dmarc |
| provider | No | Mail provider detected from MX; null when not recognised |
| held_back | No | Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score |
| components | No | |
| open_fixes | No | Findings above info level |
| report_url | No | The report page for this domain on astraverify.com |
| request_id | No | req_... for this call. Quote it when reporting a problem with the result. |
| recommendations | No | |
| cache_age_seconds | No | Age of the result; 0 means it was scanned just now |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered and the bar is lower. The description nonetheless adds real behavioral context the annotations cannot: DNS-only, roughly one-second latency, a 15-minute cache, and the important DKIM selector enumeration caveat that a random-selector provider like SES or Postmark can never be proven unsigned by probing. That disclosure is well beyond the structured fields, so it sits above a 3 in substance, but it discloses no auth needs or rate-limit specifics beyond a passing mention.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then usage triggers, then input handling, then output shape, then the DKIM caveat, so a skimming agent still gets the essentials first. Every sentence carries information; the length is warranted by the caching and DKIM-probing caveats rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, yet the description sensibly previews the 0-100 score weighting and per-record status anyway. Combined with latency, caching, input extraction rules and the honesty caveat about DKIM false negatives for random-selector providers, an agent has everything needed to call this correctly and interpret the result without overclaiming.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and the schema already documents both parameters. The description adds meaning beyond it: the domain must be bare with no scheme or path, it must be extracted from a URL or address with the extraction reported back, subdomains are scored in their own right rather than inheriting the apex, and refresh is tied to a specific condition. That is substantive param-level guidance rather than restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with unusual precision: checking whether anyone can send mail as the domain, and whether its own mail reaches the inbox. This is clearly distinct from siblings like check_discoverability, fetch_as_crawler, get_report and verify_fix, and an agent can route to it without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names explicit trigger conditions (email security, spoofing/phishing risk, SPF/DKIM/DMARC setup, mail going to spam) and gives input-handling rules for the non-bare forms (URL or email address must be reduced to a domain). It also states when to use refresh versus the cache ('refresh is for when DNS has just changed'), which is a genuine when/when-not distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_as_crawlerFetch the root page as a named crawlerARead-onlyIdempotentInspect
Show exactly what one named crawler receives from the domain's root page. Use when the person asks "what does Google see?" or "can ChatGPT read my site?", and whenever check_discoverability reports a crawl-access problem. check_discoverability scores crawl access across all six crawlers; this returns the one raw response behind that score, which is what explains such a result rather than restating it. robots.txt can read perfectly while a CDN or firewall returns 403 to one crawler and 200 to another, and only a real fetch shows that. Inputs: domain (bare, like example.com) and agent, exactly one of googlebot, bingbot, oai-searchbot, perplexitybot, claudebot, gptbot. Call it once per crawler to compare them. Returns the HTTP status, the full redirect chain, response headers, content type, the text that crawler would index, and flags for an outright block or a bot-challenge page - which is how cloaking becomes visible. One live fetch of the root page, nothing else, and it changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| agent | Yes | ||
| domain | Yes | The domain to check, as the person gave it (no scheme, no path). Reserved names such as example.com are refused. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ms | No | |
| agent | Yes | |
| chain | No | Redirect hops |
| error | No | |
| label | No | The crawler as its operator names it |
| title | No | |
| domain | Yes | |
| status | No | HTTP status the crawler received |
| blocked | No | The response refused the crawler (403, 429 or similar) |
| extract | No | The text this crawler would index; null when the fetch failed |
| headers | No | |
| challenge | No | A bot-challenge page rather than the site |
| final_url | No | |
| request_id | No | req_... for this call. Quote it when reporting a problem with the result. |
| content_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/openWorld, but the description adds genuine behavioral context: it is a single live root-page fetch, it discloses what is returned (status, redirect chain, headers, indexed text, block/bot-challenge flags), and explains that robots.txt can read fine while a CDN returns 403. That rationale is value beyond structured fields, though the 'changes nothing' clause is largely redundant with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and usage triggers before the explanatory rationale and return details. Every sentence earns its place, though the passage is on the long side and the closing 'nothing else, and it changes nothing' partly restates the annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-param live-fetch tool with an output schema, the description covers purpose, alternatives, inputs, scope limitations (root page only), and the diagnostic context for interpreting a block or challenge. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (agent enum has no schema description). The description compensates by specifying domain format ('bare, like example.com') and enumerating all six valid agent values, which adds real meaning beyond the bare enum list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Show exactly what one named crawler receives from the domain's root page') and explicitly distinguishes itself from the sibling check_discoverability. An agent can tell what this does and how it differs from the scoring tool without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggers ('what does Google see?', 'can ChatGPT read my site?', whenever check_discoverability reports a crawl-access problem) and names the alternative with the condition that selects it. It also instructs 'Call it once per crawler to compare them,' covering multi-call usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_reportDomain Trust report (both scores)AIdempotentInspect
Both AstraVerify scores for a domain, plus a shareable report link. Reach for this first on any broad question - "is my domain set up right?", "check my domain", "what should I fix first?" - and use the single-subject tools only once the person has narrowed it to email or to the website. Input: a bare domain like example.com. Returns the Email Security score, the Discoverability score, every open fix ranked critical then important then informational, and report_url. Work down that order. Some findings are marked as needing no action - a weak key the provider generates and the owner cannot replace, for instance - so do not present those as work. Unlike the other tools here, this one creates something: report_url is a snapshot of these findings saved to a new unlisted page at astraverify.com/r/..., and that page is what the person can send to whoever administers the domain. It opens later without rescanning, after the scan itself has aged out. Running the tool again on an unchanged scan returns the same page rather than a second one. Nothing is written anywhere the person owns. Set include_history to answer "has this improved?" or "did my fix land?": it adds the first and latest reading of each score, the move between them, and only the dates the score actually changed. A domain we have not watched before says so rather than reporting a flat line.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The domain to check, as the person gave it (no scheme, no path). Reserved names such as example.com are refused. | |
| refresh | No | Force a fresh scan instead of the cached result (rate limited) | |
| include_history | No | Also return how these scores have moved over time, and when |
Output Schema
| Name | Required | Description |
|---|---|---|
| domain | Yes | |
| history | No | Present only when include_history was set. |
| live_url | No | The live page, which rescans when the result is stale |
| report_url | No | Saved snapshot (/r/<id>) that opens without a rescan; safe to share |
| request_id | No | req_... for this call. Quote it when reporting a problem with the result. |
| website_at | No | When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request. |
| email_security | Yes | |
| discoverability | No | |
| recommendations | No | Both scans, ranked by severity |
| discoverability_error | No | |
| email_cache_age_seconds | No | |
| discoverability_cache_age_seconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false; the description goes well beyond them by explaining *why* it is not read-only (it creates an unlisted report_url snapshot), that the page persists after the scan ages out, that re-running on an unchanged scan returns the same page, and that nothing is written anywhere the person owns. It also flags findings that require no action and the include_history behavior on first-time domains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but it is front-loaded with purpose and routing before the return-value and behavioral detail, and nearly every sentence carries non-obvious information. Minor redundancy: enumerating the returned scores and ranked fixes overlaps with the output schema and with the schema's own coverage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a create-side effect, an output schema, and full parameter coverage, the description fills the remaining gaps: report persistence, idempotency, the critical/important/informational ranking order, and the 'no action needed' caveat. Nothing an agent needs to call or interpret it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning for include_history — it names the exact question it answers ('has this improved?', 'did my fix land?') and specifies it returns first/latest readings, the delta, and only dates the score changed. Caching/idempotency context also informs refresh, though refresh itself is not elaborated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — returns both AstraVerify scores for a domain plus a shareable report link — and explicitly distinguishes itself from the single-subject siblings (check_email_security, check_discoverability). An agent can tell exactly what this tool returns and when it is the right one without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing: 'Reach for this first on any broad question' and 'use the single-subject tools only once the person has narrowed it to email or to the website.' Both the when and the when-not are stated, with the alternative named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_fixRe-check one discoverability area after a fixARead-onlyIdempotentInspect
Re-check a single discoverability component after the person has fixed it. Use only once check_discoverability has reported that component failing and the person says the fix is done - never speculatively. Without a previous scan to compare against it returns NOT_READY. Inputs: domain (bare, like example.com) and component, one of crawl, plumbing, metadata, structured, answer - the identifier from the earlier scan's findings. Returns that component re-measured and the updated Discoverability score, so you can tell the person plainly whether the change worked. Always a live re-fetch, never served from cache, which is exactly why it beats a second check_discoverability straight after an edit. It draws on the discoverability fresh-scan budget for that domain (30 an hour, counted across all callers), so use a full check_discoverability instead when several areas changed. It only re-reads public pages; it changes nothing on the site.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The domain to check, as the person gave it (no scheme, no path). Reserved names such as example.com are refused. | |
| component | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| cdn | No | |
| raw | No | What the components add up to, before the cap |
| grade | Yes | A+ to F, or null alongside a null score |
| score | Yes | Out of 100, exactly as astraverify.com shows it. Null when not_applicable or inconclusive is set. |
| capped | No | |
| domain | Yes | |
| reason | No | Why score is null, when it is |
| verdict | No | One sentence on what engines can do with the site |
| held_back | No | Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score |
| components | No | |
| open_fixes | No | Findings above info level |
| report_url | No | The report page for this domain on astraverify.com |
| request_id | No | req_... for this call. Quote it when reporting a problem with the result. |
| website_at | No | When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request. |
| not_checked | No | Parts skipped in this scan |
| inconclusive | No | The site could not be fetched, so the scan could not be completed. A failure to measure, not a finding about the site. |
| canonical_host | No | |
| not_applicable | No | The domain publishes no web address, so there is no website to assess. Not a low score: score and grade are null and there are no recommendations. verdict names the domain to scan instead. |
| recommendations | No | |
| cache_age_seconds | No | Age of the result; 0 means it was scanned just now |
| verified_component | No | Set by verify_fix: the component re-checked |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/open-world/non-destructive, but the description adds behavior the annotations cannot: a NOT_READY result when there is no prior scan, a live re-fetch that is never cache-served, a shared budget of 30 scans/hour counted across all callers, and the reassurance that it only re-reads public pages and changes nothing. That is substantive operational context beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and precondition are front-loaded, and nearly every sentence carries distinct information (precondition, inputs, return, freshness rationale, budget, side effects). It runs long and the budget/cache sentences could be tightened, but there is little pure filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read tool with an output schema, the description covers everything an agent needs: precondition, input format, failure mode (NOT_READY), freshness guarantee, quota impact, and side-effect safety. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (only domain is documented in the schema), so the description compensates by explaining that domain is bare ('like example.com') and that component is 'the identifier from the earlier scan's findings' drawn from the enumerated list. It also conveys the cross-call dependency between component and the prior scan's findings, which the schema enum alone cannot express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('re-check a single discoverability component') and scopes it to a post-fix re-verification, which cleanly separates it from the sibling check_discoverability that does the full scan. An agent can pick this apart from its siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit precondition ('use only once check_discoverability has reported that component failing and the person says the fix is done - never speculatively') and names the alternative for the other case ('use a full check_discoverability instead when several areas changed'). Both when-to-use and when-not-to-use are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
get_report2 fields changed- added
Input schema / properties / include_historyAdded value: +{ + "description": "Also return how these scores have moved over time, and when", + "type": "boolean" +} - added
Output schema / properties / historyAdded value: +{ + "description": "Present only when include_history was set.", + "properties": { + "discoverability": { + "properties": { + "change": { + "description": "Points between the first and latest reading. Null when there is only one.", + "type": [ + "integer", + "null" + ] + }, + "first": { + "properties": { + "at": { + "type": "string" + }, + "change": { + "description": "Points moved since the previous reading", + "type": [ + "integer", + "null" + ] + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + } + }, + "type": "object" + }, + "latest": { + "properties": { + "at": { + "type": "string" + }, + "change": { + "description": "Points moved since the previous reading", + "type": [ + "integer", + "null" + ] + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + } + }, + "type": "object" + }, + "readings": { + "type": "integer" + }, + "transitions": { + "description": "Only the readings where the score moved", + "items": { + "properties": { + "at": { + "type": "string" + }, + "change": { + "description": "Points moved since the previous reading", + "type": [ + "integer", + "null" + ] + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "verdict": { + "description": "One sentence, safe to quote. Says plainly when there is no history yet.", + "type": "string" + } + }, + "type": "object" + }, + "email_security": { + "properties": { + "change": { + "description": "Points between the first and latest reading. Null when there is only one.", + "type": [ + "integer", + "null" + ] + }, + "first": { + "properties": { + "at": { + "type": "string" + }, + "change": { + "description": "Points moved since the previous reading", + "type": [ + "integer", + "null" + ] + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + } + }, + "type": "object" + }, + "latest": { + "properties": { + "at": { + "type": "string" + }, + "change": { + "description": "Points moved since the previous reading", + "type": [ + "integer", + "null" + ] + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + } + }, + "type": "object" + }, + "readings": { + "type": "integer" + }, + "transitions": { + "description": "Only the readings where the score moved", + "items": { + "properties": { + "at": { + "type": "string" + }, + "change": { + "description": "Points moved since the previous reading", + "type": [ + "integer", + "null" + ] + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "verdict": { + "description": "One sentence, safe to quote. Says plainly when there is no history yet.", + "type": "string" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +}
3 tool updates
- Changed
check_discoverability2 fields changed- added
Output schema / properties / website_at / properties / componentsAdded value: +{ + "description": "Component headlines only; scan this domain for the checks behind them", + "items": { + "properties": { + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / website_at / properties / report_urlAdded value: +{ + "type": "string" +}
- Changed
get_report4 fields changed- added
Output schema / properties / discoverability / properties / website_at / properties / componentsAdded value: +{ + "description": "Component headlines only; scan this domain for the checks behind them", + "items": { + "properties": { + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / discoverability / properties / website_at / properties / report_urlAdded value: +{ + "type": "string" +} - added
Output schema / properties / website_at / properties / componentsAdded value: +{ + "description": "Component headlines only; scan this domain for the checks behind them", + "items": { + "properties": { + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / website_at / properties / report_urlAdded value: +{ + "type": "string" +}
- Changed
verify_fix2 fields changed- added
Output schema / properties / website_at / properties / componentsAdded value: +{ + "description": "Component headlines only; scan this domain for the checks behind them", + "items": { + "properties": { + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / website_at / properties / report_urlAdded value: +{ + "type": "string" +}
3 tool updates
- Changed
check_discoverability1 field changed- added
Output schema / properties / website_atAdded value: +{ + "description": "When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request.", + "properties": { + "cache_age_seconds": { + "type": "integer" + }, + "domain": { + "type": "string" + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + }, + "verdict": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +}
- Changed
get_report2 fields changed- added
Output schema / properties / discoverability / properties / website_atAdded value: +{ + "description": "When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request.", + "properties": { + "cache_age_seconds": { + "type": "integer" + }, + "domain": { + "type": "string" + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + }, + "verdict": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / website_atAdded value: +{ + "description": "When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request.", + "properties": { + "cache_age_seconds": { + "type": "integer" + }, + "domain": { + "type": "string" + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + }, + "verdict": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +}
- Changed
verify_fix1 field changed- added
Output schema / properties / website_atAdded value: +{ + "description": "When the domain asked about serves no website but its registrable domain does, that domain's discoverability result. The score belongs to `domain` here, not to the domain in the request.", + "properties": { + "cache_age_seconds": { + "type": "integer" + }, + "domain": { + "type": "string" + }, + "grade": { + "type": "string" + }, + "open_fixes": { + "type": "integer" + }, + "score": { + "type": "integer" + }, + "verdict": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +}
5 tool updates
- Changed
check_discoverability1 field changed- added
Output schema / properties / request_idAdded value: +{ + "description": "req_... for this call. Quote it when reporting a problem with the result.", + "type": "string" +}
- Changed
check_email_security1 field changed- added
Output schema / properties / request_idAdded value: +{ + "description": "req_... for this call. Quote it when reporting a problem with the result.", + "type": "string" +}
- Changed
fetch_as_crawler1 field changed- added
Output schema / properties / request_idAdded value: +{ + "description": "req_... for this call. Quote it when reporting a problem with the result.", + "type": "string" +}
- Changed
get_report2 fields changed- added
Output schema / properties / discoverability / properties / request_idAdded value: +{ + "description": "req_... for this call. Quote it when reporting a problem with the result.", + "type": "string" +} - added
Output schema / properties / request_idAdded value: +{ + "description": "req_... for this call. Quote it when reporting a problem with the result.", + "type": "string" +}
- Changed
verify_fix1 field changed- added
Output schema / properties / request_idAdded value: +{ + "description": "req_... for this call. Quote it when reporting a problem with the result.", + "type": "string" +}
1 tool update
- Changed
check_email_security2 fields changed- changed
Output schema / properties / provider / descriptionPrevious value: -"Mail provider detected from MX"New value: +"Mail provider detected from MX; null when not recognised" - changed
Output schema / properties / provider / typePrevious value: -"string"New value: +[ + "string", + "null" +]
4 tool updates
- Changed
check_discoverability2 fields changed- added
Output schema / properties / held_backAdded value: +{ + "description": "Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score", + "type": "integer" +} - changed
Output schema / properties / raw / descriptionPrevious value: -"Before the cap rules that hold the headline back while a fix is open"New value: +"What the components add up to, before the cap"
- Changed
check_email_security2 fields changed- added
Output schema / properties / held_backAdded value: +{ + "description": "Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score", + "type": "integer" +} - changed
Output schema / properties / raw / descriptionPrevious value: -"Before the cap rules that hold the headline back while a fix is open"New value: +"What the components add up to, before the cap"
- Changed
get_report4 fields changed- added
Output schema / properties / discoverability / properties / held_backAdded value: +{ + "description": "Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score", + "type": "integer" +} - changed
Output schema / properties / discoverability / properties / raw / descriptionPrevious value: -"Before the cap rules that hold the headline back while a fix is open"New value: +"What the components add up to, before the cap" - added
Output schema / properties / email_security / properties / held_backAdded value: +{ + "description": "Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score", + "type": "integer" +} - changed
Output schema / properties / email_security / properties / raw / descriptionPrevious value: -"Before the cap rules that hold the headline back while a fix is open"New value: +"What the components add up to, before the cap"
- Changed
verify_fix2 fields changed- added
Output schema / properties / held_backAdded value: +{ + "description": "Points the cap holds back while a fix is open (89 cap) or a critical one is (69). Not taken from any component: sum(components.points) - held_back = score", + "type": "integer" +} - changed
Output schema / properties / raw / descriptionPrevious value: -"Before the cap rules that hold the headline back while a fix is open"New value: +"What the components add up to, before the cap"
5 tool updates
- Changed
check_discoverability11 fields changed- changed
Output schema / properties / canonical_host / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / cdn / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / descriptionPrevious value: -"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)"New value: +"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where). Null when there is nothing to publish, for example \"turn on DKIM in your provider\"." - changed
Output schema / properties / recommendations / items / properties / fix / properties / kind / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / label / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / note / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / value / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / where / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / typePrevious value: -"object"New value: +[ + "object", + "null" +]
- Changed
check_email_security9 fields changed- changed
Output schema / properties / recommendations / items / properties / fix / descriptionPrevious value: -"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)"New value: +"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where). Null when there is nothing to publish, for example \"turn on DKIM in your provider\"." - changed
Output schema / properties / recommendations / items / properties / fix / properties / kind / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / label / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / note / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / value / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / where / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / typePrevious value: -"object"New value: +[ + "object", + "null" +]
- Changed
fetch_as_crawler5 fields changed- changed
Output schema / properties / content_type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / extract / descriptionPrevious value: -"The text this crawler would index"New value: +"The text this crawler would index; null when the fetch failed" - changed
Output schema / properties / extract / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / final_url / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / title / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
get_report39 fields changed- added
Output schema / properties / discoverability / properties / canonical_hostAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / discoverability / properties / cdnAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / discoverability / properties / grade / descriptionPrevious value: -"A+ to F"New value: +"A+ to F, or null alongside a null score" - changed
Output schema / properties / discoverability / properties / grade / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / discoverability / properties / inconclusiveAdded value: +{ + "description": "The site could not be fetched, so the scan could not be completed. A failure to measure, not a finding about the site.", + "type": "boolean" +} - added
Output schema / properties / discoverability / properties / not_applicableAdded value: +{ + "description": "The domain publishes no web address, so there is no website to assess. Not a low score: score and grade are null and there are no recommendations. verdict names the domain to scan instead.", + "type": "boolean" +} - added
Output schema / properties / discoverability / properties / not_checkedAdded value: +{ + "description": "Parts skipped in this scan", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / discoverability / properties / reasonAdded value: +{ + "description": "Why score is null, when it is", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / descriptionPrevious value: -"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)"New value: +"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where). Null when there is nothing to publish, for example \"turn on DKIM in your provider\"." - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / kind / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / label / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / note / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / value / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / properties / where / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / discoverability / properties / recommendations / items / properties / fix / typePrevious value: -"object"New value: +[ + "object", + "null" +] - changed
Output schema / properties / discoverability / properties / score / descriptionPrevious value: -"Out of 100, exactly as astraverify.com shows it"New value: +"Out of 100, exactly as astraverify.com shows it. Null when not_applicable or inconclusive is set." - changed
Output schema / properties / discoverability / properties / score / typePrevious value: -"integer"New value: +[ + "integer", + "null" +] - added
Output schema / properties / discoverability / properties / verdict / descriptionAdded value: +"One sentence on what engines can do with the site" - added
Output schema / properties / discoverability / properties / verified_componentAdded value: +{ + "description": "Set by verify_fix: the component re-checked", + "type": "string" +} - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / descriptionPrevious value: -"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)"New value: +"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where). Null when there is nothing to publish, for example \"turn on DKIM in your provider\"." - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / kind / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / label / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / note / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / value / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / properties / where / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / email_security / properties / recommendations / items / properties / fix / typePrevious value: -"object"New value: +[ + "object", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / descriptionPrevious value: -"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)"New value: +"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where). Null when there is nothing to publish, for example \"turn on DKIM in your provider\"." - changed
Output schema / properties / recommendations / items / properties / fix / properties / kind / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / label / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / note / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / value / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / where / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / typePrevious value: -"object"New value: +[ + "object", + "null" +]
- Changed
verify_fix11 fields changed- changed
Output schema / properties / canonical_host / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / cdn / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / descriptionPrevious value: -"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)"New value: +"The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where). Null when there is nothing to publish, for example \"turn on DKIM in your provider\"." - changed
Output schema / properties / recommendations / items / properties / fix / properties / kind / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / label / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / note / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / value / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / properties / where / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / recommendations / items / properties / fix / typePrevious value: -"object"New value: +[ + "object", + "null" +]
2 tool updates
- Changed
check_discoverability7 fields changed- changed
Output schema / properties / grade / descriptionPrevious value: -"A+ to F"New value: +"A+ to F, or null alongside a null score" - changed
Output schema / properties / grade / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / inconclusiveAdded value: +{ + "description": "The site could not be fetched, so the scan could not be completed. A failure to measure, not a finding about the site.", + "type": "boolean" +} - added
Output schema / properties / not_applicableAdded value: +{ + "description": "The domain publishes no web address, so there is no website to assess. Not a low score: score and grade are null and there are no recommendations. verdict names the domain to scan instead.", + "type": "boolean" +} - added
Output schema / properties / reasonAdded value: +{ + "description": "Why score is null, when it is", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / score / descriptionPrevious value: -"Out of 100, exactly as astraverify.com shows it"New value: +"Out of 100, exactly as astraverify.com shows it. Null when not_applicable or inconclusive is set." - changed
Output schema / properties / score / typePrevious value: -"integer"New value: +[ + "integer", + "null" +]
- Changed
verify_fix7 fields changed- changed
Output schema / properties / grade / descriptionPrevious value: -"A+ to F"New value: +"A+ to F, or null alongside a null score" - changed
Output schema / properties / grade / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / inconclusiveAdded value: +{ + "description": "The site could not be fetched, so the scan could not be completed. A failure to measure, not a finding about the site.", + "type": "boolean" +} - added
Output schema / properties / not_applicableAdded value: +{ + "description": "The domain publishes no web address, so there is no website to assess. Not a low score: score and grade are null and there are no recommendations. verdict names the domain to scan instead.", + "type": "boolean" +} - added
Output schema / properties / reasonAdded value: +{ + "description": "Why score is null, when it is", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / score / descriptionPrevious value: -"Out of 100, exactly as astraverify.com shows it"New value: +"Out of 100, exactly as astraverify.com shows it. Null when not_applicable or inconclusive is set." - changed
Output schema / properties / score / typePrevious value: -"integer"New value: +[ + "integer", + "null" +]
5 tool updates
- Changed
check_discoverability1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "cache_age_seconds": { + "description": "Age of the result; 0 means it was scanned just now", + "type": "integer" + }, + "canonical_host": { + "type": "string" + }, + "capped": { + "type": "boolean" + }, + "cdn": { + "type": "string" + }, + "components": { + "items": { + "description": "One scored area of the domain", + "properties": { + "enabled": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "key", + "name", + "points", + "max" + ], + "type": "object" + }, + "type": "array" + }, + "domain": { + "type": "string" + }, + "grade": { + "description": "A+ to F", + "type": "string" + }, + "not_checked": { + "description": "Parts skipped in this scan", + "items": { + "type": "string" + }, + "type": "array" + }, + "open_fixes": { + "description": "Findings above info level", + "type": "integer" + }, + "raw": { + "description": "Before the cap rules that hold the headline back while a fix is open", + "type": "integer" + }, + "recommendations": { + "items": { + "properties": { + "component": { + "type": "string" + }, + "fix": { + "description": "The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)", + "properties": { + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + }, + "where": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "scan": { + "enum": [ + "email", + "discoverability" + ], + "type": "string" + }, + "severity": { + "enum": [ + "critical", + "important", + "info" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "id", + "severity", + "title" + ], + "type": "object" + }, + "type": "array" + }, + "report_url": { + "description": "The report page for this domain on astraverify.com", + "type": "string" + }, + "score": { + "description": "Out of 100, exactly as astraverify.com shows it", + "type": "integer" + }, + "verdict": { + "description": "One sentence on what engines can do with the site", + "type": "string" + }, + "verified_component": { + "description": "Set by verify_fix: the component re-checked", + "type": "string" + } + }, + "required": [ + "domain", + "score", + "grade" + ], + "type": "object" +}
- Changed
check_email_security1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "cache_age_seconds": { + "description": "Age of the result; 0 means it was scanned just now", + "type": "integer" + }, + "capped": { + "type": "boolean" + }, + "components": { + "items": { + "description": "One scored area of the domain", + "properties": { + "enabled": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "key", + "name", + "points", + "max" + ], + "type": "object" + }, + "type": "array" + }, + "domain": { + "type": "string" + }, + "grade": { + "description": "A+ to F", + "type": "string" + }, + "null_mx": { + "description": "The domain declares that it sends and receives no mail", + "type": "boolean" + }, + "open_fixes": { + "description": "Findings above info level", + "type": "integer" + }, + "provider": { + "description": "Mail provider detected from MX", + "type": "string" + }, + "raw": { + "description": "Before the cap rules that hold the headline back while a fix is open", + "type": "integer" + }, + "recommendations": { + "items": { + "properties": { + "component": { + "type": "string" + }, + "fix": { + "description": "The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)", + "properties": { + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + }, + "where": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "scan": { + "enum": [ + "email", + "discoverability" + ], + "type": "string" + }, + "severity": { + "enum": [ + "critical", + "important", + "info" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "id", + "severity", + "title" + ], + "type": "object" + }, + "type": "array" + }, + "records": { + "additionalProperties": { + "items": { + "type": "object" + }, + "type": "array" + }, + "description": "DNS records found, keyed mx, spf, dkim, dmarc", + "type": "object" + }, + "report_url": { + "description": "The report page for this domain on astraverify.com", + "type": "string" + }, + "score": { + "description": "Out of 100, exactly as astraverify.com shows it", + "type": "integer" + } + }, + "required": [ + "domain", + "score", + "grade" + ], + "type": "object" +}
- Changed
fetch_as_crawler1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "agent": { + "type": "string" + }, + "blocked": { + "description": "The response refused the crawler (403, 429 or similar)", + "type": "boolean" + }, + "chain": { + "description": "Redirect hops", + "items": { + "properties": { + "status": { + "type": "integer" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "challenge": { + "description": "A bot-challenge page rather than the site", + "type": "boolean" + }, + "content_type": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "error": { + "type": [ + "string", + "null" + ] + }, + "extract": { + "description": "The text this crawler would index", + "type": "string" + }, + "final_url": { + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "label": { + "description": "The crawler as its operator names it", + "type": "string" + }, + "ms": { + "type": "integer" + }, + "status": { + "description": "HTTP status the crawler received", + "type": [ + "integer", + "null" + ] + }, + "title": { + "type": "string" + } + }, + "required": [ + "domain", + "agent" + ], + "type": "object" +}
- Changed
get_report1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "discoverability": { + "properties": { + "cache_age_seconds": { + "description": "Age of the result; 0 means it was scanned just now", + "type": "integer" + }, + "capped": { + "type": "boolean" + }, + "components": { + "items": { + "description": "One scored area of the domain", + "properties": { + "enabled": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "key", + "name", + "points", + "max" + ], + "type": "object" + }, + "type": "array" + }, + "domain": { + "type": "string" + }, + "grade": { + "description": "A+ to F", + "type": "string" + }, + "open_fixes": { + "description": "Findings above info level", + "type": "integer" + }, + "raw": { + "description": "Before the cap rules that hold the headline back while a fix is open", + "type": "integer" + }, + "recommendations": { + "items": { + "properties": { + "component": { + "type": "string" + }, + "fix": { + "description": "The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)", + "properties": { + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + }, + "where": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "scan": { + "enum": [ + "email", + "discoverability" + ], + "type": "string" + }, + "severity": { + "enum": [ + "critical", + "important", + "info" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "id", + "severity", + "title" + ], + "type": "object" + }, + "type": "array" + }, + "report_url": { + "description": "The report page for this domain on astraverify.com", + "type": "string" + }, + "score": { + "description": "Out of 100, exactly as astraverify.com shows it", + "type": "integer" + }, + "verdict": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "discoverability_cache_age_seconds": { + "type": [ + "integer", + "null" + ] + }, + "discoverability_error": { + "type": [ + "string", + "null" + ] + }, + "domain": { + "type": "string" + }, + "email_cache_age_seconds": { + "type": "integer" + }, + "email_security": { + "properties": { + "cache_age_seconds": { + "description": "Age of the result; 0 means it was scanned just now", + "type": "integer" + }, + "capped": { + "type": "boolean" + }, + "components": { + "items": { + "description": "One scored area of the domain", + "properties": { + "enabled": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "key", + "name", + "points", + "max" + ], + "type": "object" + }, + "type": "array" + }, + "domain": { + "type": "string" + }, + "grade": { + "description": "A+ to F", + "type": "string" + }, + "open_fixes": { + "description": "Findings above info level", + "type": "integer" + }, + "raw": { + "description": "Before the cap rules that hold the headline back while a fix is open", + "type": "integer" + }, + "recommendations": { + "items": { + "properties": { + "component": { + "type": "string" + }, + "fix": { + "description": "The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)", + "properties": { + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + }, + "where": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "scan": { + "enum": [ + "email", + "discoverability" + ], + "type": "string" + }, + "severity": { + "enum": [ + "critical", + "important", + "info" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "id", + "severity", + "title" + ], + "type": "object" + }, + "type": "array" + }, + "report_url": { + "description": "The report page for this domain on astraverify.com", + "type": "string" + }, + "score": { + "description": "Out of 100, exactly as astraverify.com shows it", + "type": "integer" + } + }, + "type": "object" + }, + "live_url": { + "description": "The live page, which rescans when the result is stale", + "type": "string" + }, + "recommendations": { + "description": "Both scans, ranked by severity", + "items": { + "properties": { + "component": { + "type": "string" + }, + "fix": { + "description": "The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)", + "properties": { + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + }, + "where": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "scan": { + "enum": [ + "email", + "discoverability" + ], + "type": "string" + }, + "severity": { + "enum": [ + "critical", + "important", + "info" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "id", + "severity", + "title" + ], + "type": "object" + }, + "type": "array" + }, + "report_url": { + "description": "Saved snapshot (/r/<id>) that opens without a rescan; safe to share", + "type": "string" + } + }, + "required": [ + "domain", + "email_security" + ], + "type": "object" +}
- Changed
verify_fix1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "cache_age_seconds": { + "description": "Age of the result; 0 means it was scanned just now", + "type": "integer" + }, + "canonical_host": { + "type": "string" + }, + "capped": { + "type": "boolean" + }, + "cdn": { + "type": "string" + }, + "components": { + "items": { + "description": "One scored area of the domain", + "properties": { + "enabled": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "max": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "points": { + "type": "integer" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "key", + "name", + "points", + "max" + ], + "type": "object" + }, + "type": "array" + }, + "domain": { + "type": "string" + }, + "grade": { + "description": "A+ to F", + "type": "string" + }, + "not_checked": { + "description": "Parts skipped in this scan", + "items": { + "type": "string" + }, + "type": "array" + }, + "open_fixes": { + "description": "Findings above info level", + "type": "integer" + }, + "raw": { + "description": "Before the cap rules that hold the headline back while a fix is open", + "type": "integer" + }, + "recommendations": { + "items": { + "properties": { + "component": { + "type": "string" + }, + "fix": { + "description": "The exact change to publish: a DNS record (name, type, value) or a file or tag (kind, label, value, where)", + "properties": { + "kind": { + "type": "string" + }, + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "note": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + }, + "where": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "scan": { + "enum": [ + "email", + "discoverability" + ], + "type": "string" + }, + "severity": { + "enum": [ + "critical", + "important", + "info" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "id", + "severity", + "title" + ], + "type": "object" + }, + "type": "array" + }, + "report_url": { + "description": "The report page for this domain on astraverify.com", + "type": "string" + }, + "score": { + "description": "Out of 100, exactly as astraverify.com shows it", + "type": "integer" + }, + "verdict": { + "description": "One sentence on what engines can do with the site", + "type": "string" + }, + "verified_component": { + "description": "Set by verify_fix: the component re-checked", + "type": "string" + } + }, + "required": [ + "domain", + "score", + "grade" + ], + "type": "object" +}
5 tool updates
- First observed
check_discoverability - First observed
check_email_security - First observed
fetch_as_crawler - First observed
get_report - First observed
verify_fix
Publisher details
- Operator
- AstraVerify · Publisher source
- Operator website
- https://astraverify.com · Publisher source
- Vendor relationship
- First-party · Publisher source
- Documentation
- https://astraverify.com/connect
- Trust center
- Not available
- Restrictions
- Not applicable
Related MCP Connectors
Check a domain's email authentication: SPF, DKIM, DMARC, BIMI, MX, MTA-STS, TLS-RPT. Score + fixes.
Email posture for any domain: can it receive mail, can it be spoofed? MX, SPF and DMARC.
Domain checks: SPF, DKIM, DMARC, BIMI, MTA-STS, SSL/TLS and HTTP security headers.
Assess any domain's email security across SPF, DMARC, DKIM, MTA-STS, DNSSEC, DANE, and TLS-RPT.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to check a domain's email authentication and health across SPF, DKIM, DMARC, BIMI, MX, MTA-STS, and TLS-RPT, returning a score and recommended fixes.MIT
- AlicenseAqualityAmaintenanceEnables AI agents to audit email and domain security (SPF, DKIM, DMARC, etc.) for any domain without requiring API keys.1901MIT
- AlicenseAqualityBmaintenanceProvides comprehensive email deliverability and domain registration analysis, evaluating SPF, DKIM, DMARC, DNS records, and expiry to identify issues and suggest fixes.51MIT
- AlicenseAqualityAmaintenanceEnables auditing any domain's email deliverability and DNS health, including SPF, DKIM, DMARC, MX, mail provider, DNS blacklist status, catch-all, domain age, and a deliverability score.169 npm1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.