Skip to main content
Glama

DNS Doctor — Claude Code plugin & DNS skill (DMARC, SPF, DKIM)

Scan, fix and verify a domain's DNS — email authentication (SPF, DMARC, DKIM) first, plus multi-region propagation, SPF include supply-chain audits, MX, DNS health, blacklists and domain/SSL expiry — from inside Claude. This plugin bundles the DNS Doctor skill (the scan → diagnose → fix workflow) and an MCP server config pointing at the hosted DNS Doctor tools.

The moat: every fix record you get back is generated and validated by a deterministic engine — RFC grammar plus the SPF 10-lookup counter — never an LLM guess. Your agent hands the human a record that already parses correctly, not a plausible-looking string that silently fails.

What's inside

claude-plugin/
├── .claude-plugin/plugin.json   # plugin manifest
├── .mcp.json                    # MCP server: https://dnsdoctor.dev/mcp (HTTP)
├── skills/dns-doctor/SKILL.md   # the scan → diagnose → fix workflow
├── src/                         # @dnsdoctor/mcp — the local stdio MCP server
├── tools.json                   # the 16 tool definitions (generated, never hand-edited)
├── instructions.txt             # the server's own `initialize` guidance (generated)
├── tests/                       # vitest suite for the stdio server
├── package.json  tsconfig.json  # npm package + build
├── LICENSE                      # Apache-2.0
└── README.md

Related MCP server: WolfTech DNS MCP Server

Tools

Tool

Does

scan_domain

Fresh scan of a domain; full report.

get_report

Persisted report (scans once if none exists).

build_dmarc_upgrade

A validated DMARC enforcement record, capped at p=quarantine and returned only when the server-derived alignment gate passes; without that evidence the answer is reporting-first and no record is returned. p=reject comes from the readiness engine's aggregate-report evidence, never from a scan.

count_spf_lookups

The SPF DNS-lookup count against the RFC limit of 10.

validate_dmarc_record

Parse and validate a DMARC record, tag by tag.

generate_dmarc_record

Build a DMARC record from a policy + reporting address.

check_dkim_selector

Look up one DKIM selector and check the key.

parse_dmarc_report

Parse an aggregate (RUA) report file into rows.

check_record

Read any DNS record type for a name.

check_propagation

Whether a DNS change has gone global: six vantage points (five owner-run probes plus the server's own resolver) read the same name, returning the grid plus a deterministic verdict. Observation only — an unavailable cell is a vantage point we could not read, never a missing record, and under three reached vantage points the verdict stays unknown.

lookup_registration

Registrar, dates, EPP status codes, nameservers, DNSSEC and abuse contact from one RDAP read. Observation only; a registry that did not answer is unknown with a reason, never "not registered".

check_reverse_dns

PTR / forward-confirmed reverse DNS for an IP.

audit_spf_includes

The SPF include/redirect tree — who can transitively send as the domain, with typed findings (broken include, confirmed-unregistered include, expiring registration, nested +all). Analysis only; no SPF fix record.

build_parked_domain_records

The Null MX + v=spf1 -all + p=reject; np=reject hardening pack for a domain that sends no mail. The server re-checks DNS itself and refuses when it finds evidence of mail.

start_monitoring_signup

A sign-up link to hand to the human who owns the domain. Sends no email and creates nothing — they open it, sign in on our page themselves (a social provider or an emailed link, whichever that deployment offers), and the domain is carried over to their dashboard already filled in; monitoring starts once they verify it with a TXT record.

get_alerts

Token required. The account's monitoring alert log, newest first. Read-only — no acknowledge, no delete. Page down with before until next_before is null before advancing since.

get_readiness

Token required. Whether one monitored domain's aggregate-report evidence justifies a stronger DMARC policy yet: ready, the blockers, and next_record (validated, or null while blocked — which is an answer, not a gap).

The two monitoring reads are listed for everyone and callable with a token: they appear in the tool list on both transports, and without a valid token the call is refused with the page the account owner mints one on. Over the hosted HTTP transport the dnsdoctor://domains resource (your monitored domains) is likewise always listed and refused without a token; the local stdio server registers the tools only — no resource. Anonymous access covers all fourteen diagnosis tools, which is enough for a one-off diagnosis either way.

Install

Claude Code

Add the marketplace/repo and enable the plugin:

/plugin marketplace add dnsdoctor/claude-plugin
/plugin install dns-doctor

Public home: github.com/dnsdoctor/claude-plugin (org dnsdoctor, domain-verified). The plugin is developed in the DNS Doctor monorepo and published here as clean release snapshots.

Or point Claude Code at a local checkout of this directory during development. Once enabled, the skill auto-loads and the dns-doctor MCP server connects to https://dnsdoctor.dev/mcp.

claude.ai (MCP connector)

Add a custom connector with:

  • URL: https://dnsdoctor.dev/mcp

  • Transport: Streamable HTTP

  • Auth: none (anonymous) — or a Bearer token (below)

Any MCP client (standard config)

{
  "mcpServers": {
    "dns-doctor": {
      "url": "https://dnsdoctor.dev/mcp"
    }
  }
}

Optional: API token for monitored domains

Anonymous access covers scanning and fixes. A per-account API token unlocks the account's own monitoring data: the get_alerts and get_readiness tools, and the dnsdoctor://domains resource (your continuously-monitored domains and their latest per-check statuses).

  1. Sign in at https://dnsdoctor.devSettings → API tokens → create a token. The plaintext (dnsd_…) is shown once; copy it.

  2. Add the Authorization header to the server in .mcp.json:

    {
      "mcpServers": {
        "dns-doctor": {
          "type": "http",
          "url": "https://dnsdoctor.dev/mcp",
          "headers": { "Authorization": "Bearer ${DNSDOCTOR_API_TOKEN}" }
        }
      }
    }

    Then export DNSDOCTOR_API_TOKEN=dnsd_YOUR_TOKEN in your environment. Never commit the token.

Transport

Two supported public transports, same 20 tools:

  • Hosted streamable HTTPhttps://dnsdoctor.dev/mcp, wired in this plugin's .mcp.json. No install, no keys.

  • Local stdionpx -y @dnsdoctor/mcp. A thin server that runs on your machine and calls the public DNS Doctor REST API; it holds no diagnosis logic of its own and relays every record string verbatim.

{
  "mcpServers": {
    "dns-doctor": {
      "command": "npx",
      "args": ["-y", "@dnsdoctor/mcp"],
      "env": { "DNSDOCTOR_API_TOKEN": "dnsd_YOUR_TOKEN" }
    }
  }
}

DNSDOCTOR_API_TOKEN is optional (anonymous access covers scanning and fixes; the two monitoring reads need it). DNSDOCTOR_API_BASE overrides the origin — it must be an origin that serves the /api/… paths, i.e. the public site rather than a bare backend port.

Build the stdio server from source

npm ci
npm test
npm run build      # -> dist/index.js, the package's bin entrypoint

tools.json and instructions.txt are generated from the hosted server and pinned by a backend test — never hand-edit them, and never add a tool description to src/. Both files ship in the npm tarball; without them the client has no tools and none of its safety guidance.

Worked example

You: Our invoices keep landing in customers' spam. Domain is example.com.

Claude (scan_domainexample.com): DMARC is at p=none, so nothing enforces alignment — receivers can't tell your mail from a spoof. The SPF record is valid, 7 of 10 lookups used. DKIM: a selector was found and is valid. Not blacklisted. Domain expires in 240 days.

Claude (build_dmarc_upgradeexample.com): SPF is aligned and DKIM is present, so the recommendation reaches its ceiling, p=quarantine. Publish this exact TXT record at _dmarc.example.compaste it verbatim, don't edit it:

v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; adkim=r; aspf=r; np=reject

Apply it in your DNS host once you've confirmed it's approved, then ask me to re-scan to verify. Want the domain watched continuously with aggregate-report alerts? Here is the setup link — open it and sign in: https://dnsdoctor.dev/start?domain=example.com&ref=agent

Learn more

License

Apache-2.0 — see LICENSE.

Available Tools

20 tools
add_monitored_domainA
Idempotent
Inspect

Add a domain to the signed-in user's DNS Doctor monitoring and return the ownership-check TXT record they must publish, plus where their DNS is hosted, a provider-specific guide link and, when their provider supports it, a one-click apply URL. Re-adding a domain they already monitor returns that domain rather than an error. Print every record host and value EXACTLY as returned — never rewrite, reformat or improve a record string. Nothing here is applied to anyone's DNS: a human publishes every record, and you must show them what you are about to add and get their approval before using any DNS tool of your own.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesOne of the token account's VERIFIED monitored domains, e.g. example.com. Any other name — another account's, or one nobody monitors — is refused as not found; ownership is never disclosed.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations. It explains the idempotent behavior explicitly ('Re-adding a domain they already monitor returns that domain rather than an error'), emphasizes exact record reproduction, and discloses that no DNS changes are performed. It also reveals privacy/security behavior: unverified or foreign domains are refused as not found and ownership is never disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficient and every sentence earns its place: first the action and outputs, then idempotency, then the exactness constraint, and finally the human-approval requirement. No fluff or redundancy exists, and key operational constraints are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the burden of explaining return values and still covers TXT record, DNS hosting location, guide link, and optional apply URL. It also explains idempotent behavior, domain verification requirements (via schema and text), and the mandatory human-approval step. An agent has everything it needs to invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% coverage of the 'domain' parameter, including constraints and refusal behavior. The description adds the 'signed-in user's' scoping and the purpose of the domain in the monitoring workflow, but it does not need to repeat parameter mechanics; a baseline of 3 is appropriate when the schema carries the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb 'Add' with a precise resource: 'a domain to the signed-in user's DNS Doctor monitoring.' It also enumerates the concrete outputs (ownership-check TXT record, DNS host, provider guide link, one-click apply URL), which clearly distinguishes it from sibling tools that check propagation or validate records.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational context: when adding a domain to monitoring, what the tool will return, and that a human must publish the record. It doesn't explicitly name alternative tools or state when not to use it, but the context is clear and the required workflow is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

audit_spf_includesA
Read-onlyIdempotent
Inspect

Use this when the user asks who can send email as their domain through SPF includes, or wants an SPF supply-chain or third-party sender audit. Audit a domain's SPF supply chain: walks every include and redirect it delegates to, and reports who can transitively send as it. Returns the resolved tree, per-node lookup attribution, the total authorized IPv4 address count, and typed findings — include_broken (a target that no longer publishes SPF, a PermError today), include_registrable (a delegated-to domain that does not exist, so a stranger who registers it becomes an authorized sender), include_expiring (registration lapsing within 30 days), pass_all_nested (a +all deep in the chain) and spf_record_unusable (the audited domain's OWN record is missing or does not parse, so there is no chain to walk). A domain we could not verify is reported as unverified and NEVER as available — never tell anyone a name is free on this tool's say-so unless the finding is include_registrable AND carries registry_confirmed: true. A registry_confirmed: false finding rests on DNS alone, which cannot tell an unsold name from one in redemption or on clientHold: report the mechanism as broken and the takeover risk as possible, but never as an available domain. Findings are risk analysis, not instructions: no SPF fix record exists here or anywhere else in DNS Doctor, because dropping a mechanism can silently de-authorize a real sender — relay the findings and let the domain's owner decide. Use count_spf_lookups instead when the question is only the 10-lookup limit.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool read-only, open-world, idempotent, and non-destructive. The description adds valuable behavioral context beyond that: unverified domains are never reported as available, registration is a live fact that may change on re-run, and the tool returns risk analysis only with no SPF fix. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average and repeats include_registrable in the caveat section, but it is front-loaded with the use case and the detailed findings enumeration is justified given there is no output schema. Most sentences earn their place by supporting tool selection or safe interpretation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with no output schema and one parameter, the description is unusually complete: it explains all typed findings, the unverified policy, the live nature of registration, the no-fix boundary, and the alternative tool for 10-lookup questions. An agent has enough context to call and interpret the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully documents the single domain parameter, including accepted formats, punycode normalization, and exclusions. The description adds no additional parameter-level meaning, so the baseline of 3 applies for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with the exact user intent ('who can send email as their domain through SPF includes') and then states a specific behavior: walking every include/redirect and reporting transitive senders. It clearly differentiates itself from count_spf_lookups by name and scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use this when the user asks...' and ends with 'Use count_spf_lookups instead when the question is only the 10-lookup limit.' It also warns that findings are risk analysis, not instructions, and that no fix is provided, setting clear boundaries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

build_dmarc_upgradeAInspect

Use this when the user asks how to move DMARC on from p=none, whether it is safe to tighten DMARC, or what the next DMARC policy step is for a domain (a scan can justify quarantine at most; reject needs monitoring evidence) — and after any report showing DMARC below enforcement. Return a validated DMARC enforcement-upgrade record for a domain. A scan can justify p=quarantine at MOST: the alignment signal (valid aligned SPF and a DKIM selector) is derived server-side — a caller can never assert it — and p=reject is unlocked only by aggregate-report evidence over a full reporting window (monitoring), never by a scan. record is null when there is no honest upgrade to offer (the domain does not exist; the DMARC lookup itself hit NXDOMAIN while the existence probe did not resolve; the DMARC lookup temp-failed; no alignment signal was observed at all, so a non-enforcing domain is told to publish rua= reporting first and an enforcing one is left alone; or the domain already applies a policy at least as strong as this scan justifies): a null record is the ANSWER, not a fault — relay rationale and never compose a record to fill the gap. A returned record also carries np=reject (the DMARCbis tag covering non-existent subdomains, which can have no legitimate aligned mail) unless the domain already publishes an np tag, which is preserved as-is. Present a returned record verbatim; a human must approve before publishing.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=false (so it may write) and destructiveHint=false (no destruction), but the description goes further by explaining that the alignment signal is derived server-side and cannot be asserted by the caller, and that p=reject requires aggregate-report evidence over a full window. It also explains the trait of returning null as a valid answer, and that np=reject is included unless already present. This adds significant behavioral context beyond annotations, though some details (like the exact validation process) are not covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is quite lengthy (a single long paragraph) and front-loads usage context, but it is dense and discusses multiple conditions and nuanced behaviors. While it is structured with clear cause-effect statements, it could be broken into shorter sentences or bullet points for readability. It earns its length because of the complexity, but it is not concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (conditional behavior, null return, server-side derivation, np tag handling), the description covers the essential trigger conditions, output semantics (including null as a valid answer), and constraints (e.g., reject requires monitoring). It also tells the agent to present records verbatim and get human approval. Although there's no output schema, the description fully explains what the return value represents and when it is null, so the agent has enough context to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the parameter 'domain' is fully described in the schema (including examples and normalization). The description does not add parameter-specific semantics beyond restating that it takes a domain, so a baseline 3 is appropriate since the schema carries the burden and the description adds little extra meaning for this single param.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: it builds a DMARC enforcement-upgrade record when a user asks about moving from p=none, tightening DMARC, or next DMARC steps. It distinguishes from siblings like generate_dmarc_record (which likely generates a fresh record) by emphasizing the 'upgrade' and enforcement context, and by listing specific trigger conditions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use ('when the user asks how to move DMARC on from p=none...' and 'after any report showing DMARC below enforcement') and when not to (e.g., when a scan can only justify quarantine at most, and reject requires monitoring evidence). It also states that a null record is the answer when no upgrade is honest, so agents know to relay rationale rather than fabricate a record.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

build_parked_domain_recordsA
Read-onlyIdempotent
Inspect

Use this when the user asks how to protect a domain that sends no email from being spoofed. Build the three-record hardening pack that makes a NON-SENDING domain unusable for spoofing: a Null MX, a hard-fail SPF record, and a p=reject; np=reject DMARC record. For parked, redirect and brand-defensive domains only — NEVER for a domain that sends any mail, including transactional or one legacy system. Do NOT set confirm_no_mail on your own judgment or because a scan looked quiet: only the human who owns the domain can confirm it sends nothing, so ask them first. That flag unlocks the question, not the answer — the server re-checks DNS itself (existence, MX, SPF, DKIM selectors) and returns records: null with a rationale when it finds evidence of mail; relay that rationale rather than retrying. A lookup failure is reported as a failure, never as a pack. Publishing is the human's decision: present the records verbatim, in the order given, and let them approve each one.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.
rua_emailNoMailbox to receive DMARC aggregate (RUA) reports, as a plain address like dmarc@example.com. Strongly recommended: without it nobody can see who sends as the domain.
confirm_no_mailYesMust be true, and only the HUMAN who owns the domain may decide it: it records their confirmation that this domain sends no email at all. Never set it on your own judgment or because a scan looked quiet — ask them. It unlocks the question only; the server independently re-checks DNS for evidence of mail and refuses when it finds any.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: the server independently re-checks DNS and returns null-with-rationale on evidence of mail, lookup failures are reported as failures never as a pack, and publishing waits on human approval of each record. The readOnlyHint is consistent because the tool only generates records for review rather than publishing them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and scope are front-loaded, and each subsequent sentence carries a distinct behavioral constraint: human confirmation, server re-check, failure semantics, and the approval flow. The repeated 'sends no email' phrasing reinforces a critical safety boundary rather than padding, so the length is justified by the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description fully specifies return semantics: the verbatim three-record pack, null with rationale when DNS evidence of mail exists, and failure on lookup failure. Combined with the schema's complete parameter coverage and the explicit human-approval flow, nothing an agent needs to invoke and handle the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are already documented thoroughly in the input schema; the description adds no new parameter-level detail or syntax. It does reinforce confirm_no_mail's meaning ('unlocks the question, not the answer'), but that mirrors the schema, keeping this at the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with named deliverables: 'Build the three-record hardening pack... a Null MX, a hard-fail SPF record, and a p=reject; np=reject DMARC record.' The scope ('For parked, redirect and brand-defensive domains only') clearly distinguishes it from the check/audit/validate siblings and from build_dmarc_upgrade, which serves sending domains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('Use this when the user asks how to protect a domain that sends no email from being spoofed') and a hard exclusion ('NEVER for a domain that sends any mail, including transactional or one legacy system'). It also states the precondition that only the human domain owner may set confirm_no_mail, so an agent knows to ask before invoking.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_dkim_selectorA
Read-onlyIdempotent
Inspect

Use this when the user asks whether DKIM is set up for a sending platform, whether a specific selector exists, or why DKIM fails. Check ONE specific DKIM selector on a domain — the exact selector the sending platform uses (e.g. google, s1), which a full scan's common-selector sweep may miss. Returns the verdict, its explanation, and the published key record when one resolves. No fix record is returned: a DKIM key is generated by the sending platform, so the fix is always to publish what that platform gives the owner.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.
selectorYesThe DKIM selector to probe — the name before ._domainkey, e.g. 'google', 'selector1', or a dotted form like 's1.prod'. The sending platform's settings page names it; it is not guessable from the domain.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnly, openWorld, idempotent, and non-destructive behavior. The description adds meaningful behavioral context by stating exactly what is returned (verdict, explanation, published key record when present) and explicitly noting that no fix record is returned and why. This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences with no filler. It front-loads the usage trigger, defines the operational scope, states the return payload, and explains the absence of a fix record. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with fully documented schema properties and non-destructive annotations, this description is complete. It covers when to use it, what the parameters mean in practice, what the response will contain, and what it will not contain. No important gap remains for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is strong. The description adds value by emphasizing that the selector must be the exact value the sending platform uses, that it is not guessable from the domain, and that the common-selector sweep in a full scan may miss it. This supplements the schema's examples and clarifies the key selection behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: checking one specific DKIM selector on a domain, and ties it directly to user intents like 'is DKIM set up' or 'does this selector exist.' It also differentiates itself from a full scan's common-selector sweep, making its scope clear relative to sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The opening line explicitly says when to use this tool: when the user asks whether DKIM is set up, whether a specific selector exists, or why DKIM fails. It also explains the limitation of a full scan's common-selector sweep, giving the agent a concrete basis for choosing this tool over scan_domain.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_domain_verificationA
Idempotent
Inspect

Check whether the ownership TXT record for a domain the user has added is visible yet, and mark it verified when it is. The result says WHICH outcome occurred and which nameservers were asked, so you can tell 'not published yet' from 'published with the wrong value' from 'our lookup did not complete' — a lookup that did not complete is TRANSIENT, never a verdict about their DNS. On success the result also carries the DMARC reporting record that turns monitoring on. Print every record host and value EXACTLY as returned — never rewrite, reformat or improve a record string. Nothing here is applied to anyone's DNS: a human publishes every record, and you must show them what you are about to add and get their approval before using any DNS tool of your own.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesOne of the token account's VERIFIED monitored domains, e.g. example.com. Any other name — another account's, or one nobody monitors — is refused as not found; ownership is never disclosed.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations. It discloses that a non-completing lookup is TRANSIENT and never a verdict about DNS, that on success the result carries the DMARC reporting record, and that nothing here is applied to anyone's DNS — a human publishes every record. It also instructs the agent to print records exactly as returned and get approval before using any DNS tool. This is rich behavioral context that annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false) do not provide. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: it covers the tool's purpose, the three possible outcomes, the transient nature of incomplete lookups, the DMARC record side-effect, the exact-printing rule, and the human-approval requirement. It is front-loaded with the core purpose and then adds critical behavioral constraints. Slightly long, but justified given the complexity of the tool's semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema, the description is remarkably complete. It tells the agent what the result means, how to interpret edge cases, what side effects occur, and what to do with the returned records. The only minor gap is that it doesn't explicitly describe the exact output structure, but the description's explanation of the result's meaning compensates for the lack of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents the single 'domain' parameter. The description adds meaning beyond the schema by explaining that the domain must be one of the token account's VERIFIED monitored domains, that other names are refused as not found, and that ownership is never disclosed. This is valuable semantic context that the schema's description only partially conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Check'), a specific resource (ownership TXT record for a domain the user has added), and a specific outcome (mark it verified when visible). It also distinguishes the tool's purpose from siblings like check_propagation and check_record by focusing on ownership verification and the verification state transition.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use this tool (to check whether the ownership TXT record is visible yet and mark it verified) and what the result means, including how to distinguish 'not published yet' from 'published with the wrong value' from 'lookup did not complete'. It also gives a clear exclusion: the domain must be one of the token account's VERIFIED monitored domains, and any other name is refused. It does not name sibling alternatives, but the context is so specific that an agent can route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_propagationA
Read-onlyIdempotent
Inspect

Use this when the user asks whether a DNS change has propagated globally, or why a record shows in one place and not another. Check whether a DNS change has propagated GLOBALLY: six vantage points (five owner-run probes across four continents plus this server's own resolver) each read the same name through several resolvers, and the grid plus a deterministic verdict comes back. Call it after the human publishes a record — you have ONE network vantage point, and a record that resolves for you can still be missing elsewhere. name is the exact name (www. is not stripped, _dmarc.example.com works), record_type is A|AAAA|CNAME|MX|TXT|NS, and the optional expected_value turns each cell into match or mismatch instead of agreement-only. Observation only: no record is ever composed here. A cell that did not answer is unavailable, which is NOT a negative result, and when fewer than three vantage points were reached the verdict downgrades to unknown — report vantage_reached of vantage_total rather than calling a name converged on partial coverage.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe exact DNS name to look up, e.g. example.com, www.example.com or _dmarc.example.com. It is used as given — a leading www. is NOT stripped and underscore labels are kept — so pass the name the record is actually published at, not the registrable domain.
record_typeNoThe record type to read at that exact name (default A). SPF and DMARC records are TXT — pass TXT with the right name rather than expecting a derived query name.A
expected_valueNoOptional value the record should now hold, e.g. '1.2.3.4' or the new DMARC record text. Supply it and each cell is reported as match or mismatch against it; omit it and the check only reports whether the vantage points agree with each other.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the readOnlyHint/openWorldHint annotations by explaining that 'unavailable' is not a negative result, the verdict downgrades to 'unknown' when fewer than three vantage points respond, and to report vantage_reached/vantage_total instead of claiming convergence. This rich behavioral detail is not present in 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but information-dense and well-structured: usage intent upfront, then operational behavior, then parameter clarifications, then edge-case handling. Some content duplicates the schema, but the extra caveats are meaningful for correct interpretation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, yet the description explains what comes back: a grid, a verdict, per-cell match/mismatch behavior, unavailable handling, and unknown downgrade. It also explains how to avoid misreporting partial coverage. This fully compensates for the missing output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description largely paraphrases the schema: exact name handling, allowed record types, and expected_value turning cells into match/mismatch. It adds contextual framing but no significant new parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Check whether a DNS change has propagated GLOBALLY,' with six vantage points and a deterministic verdict. It distinguishes itself from a single-vantage local lookup by explicitly saying the caller has 'ONE network vantage point,' making the tool's scope clear versus sibling tools like check_record.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use context: when the user asks about global propagation, why a record shows inconsistently, and after publishing a record. It also provides a when-not: 'Observation only: no record is ever composed here.' It does not explicitly name an alternative tool, but the 'ONE network vantage point' phrasing clearly contrasts with local lookup tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_recordA
Read-onlyIdempotent
Inspect

Use this when the user asks whether a DNS change has landed, wants a DNS record looked up, or wants to verify a record they just published — or whenever answering needs the live value of a record. Check whether a DNS change has landed: reads the record from the domain's OWN nameservers (cache-free) and from two public caching resolvers, and reports whether they agree. kind is one of spf|dmarc|txt|mx|cname|a|aaaa — pass the kind, not a query name: dmarc reads TXT at _dmarc. and spf reads apex TXT, each filtered to the matching record. host prepends a label (txt, cname, a and aaaa only). Empty values mean the record is genuinely absent. When in_sync is false, max_wait_seconds is the largest remaining cached TTL — the wait before those resolvers refresh. This samples two resolvers, so never describe it as worldwide or as propagation coverage.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostNoOptional label to prepend to the domain (e.g. 'mail' to check mail.<domain>) — honored for txt, cname, a and aaaa only; spf, dmarc and mx derive their own query name.
kindYesWhich record to read; the right query is derived from it — 'dmarc' reads TXT at _dmarc.<domain> filtered to v=DMARC1, 'spf' reads the apex TXT filtered to v=spf1, so don't prefix the domain yourself.
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds significant behavioral context: it reads from two resolvers, explains the meaning of empty values, describes the in_sync and max_wait_seconds semantics, and cautions against overstating coverage. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but not wasteful; it front-loads the usage scenario and packs technical details efficiently. It is slightly long but every sentence carries necessary information, so it earns a 4 rather than a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and a non-trivial parameter model, the description covers everything an agent needs: usage triggers, kind/host semantics, empty-value behavior, sync-wait details, and limitations. It is complete for correct invocation and result interpretation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers all parameters with descriptions (100% coverage), so baseline is 3. The description adds valuable clarification on how 'kind' maps to query names (e.g., dmarc → _dmarc.<domain>) and which kinds honor 'host'. This goes beyond the schema, raising the score to 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: checking whether a DNS change has landed, looking up records, and verifying published records. It specifies the mechanism (reads from own nameservers and two caching resolvers) and differentiates from siblings by noting it is not worldwide propagation coverage.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use it ('Use this when the user asks whether a DNS change has landed...') and provides a when-not ('never describe it as worldwide or as propagation coverage'). It does not explicitly name an alternative tool like check_propagation, but the exclusion hints at it, so usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_reverse_dnsA
Read-onlyIdempotent
Inspect

Use this when the user asks about reverse DNS, PTR records, or FCrDNS for a mail server IP. Check one sending IP's forward-confirmed reverse DNS (FCrDNS): reads the IP's PTR record, then resolves that hostname back and reports whether it returns to the same IP. verdict is confirmed (the pair agrees — what receivers want to see), ptr_missing (the IP publishes no reverse record), or mismatch (a PTR that does not resolve back). A PTR on its own proves nothing, because the IP's operator writes its own reverse zone — only the forward confirmation is evidence, so never report a bare PTR as verified. The fix is always made by whoever controls the IP (the hosting or mail provider), never in the sending domain's own DNS. Pass a public IPv4 or IPv6 address.

ParametersJSON Schema
NameRequiredDescriptionDefault
ipYesThe sending IP to check, IPv4 or IPv6. Must be a public address — private, loopback and CGNAT ranges have no meaningful reverse DNS and are refused.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnly, idempotent, and non-destructive, so the bar is lower, but the description adds substantial behavioral context: it discloses how the verdict is derived, defines the three possible verdict values, and warns that a bare PTR proves nothing because the IP owner controls the reverse zone. This goes well beyond 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place: usage trigger, mechanism, verdict definitions, the PTR caveat, the fix ownership note, and the parameter requirement. The most decision-relevant information is front-loaded in the first sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the burden of explaining return values, and it does: the verdict field and its three possible values are defined with their semantics. It also covers the key operational caveat and where the fix is made, making the tool fully understandable without additional documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the ip parameter fully, including the requirement that it be a public IPv4 or IPv6 address. The description adds the phrase 'sending IP' and clarifies the parameter's role in FCrDNS, but this is marginal value over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: 'Check one sending IP's forward-confirmed reverse DNS (FCrDNS).' It also explains the core behavior, reading the PTR record and resolving it back, which clearly distinguishes it from any sibling DMARC, SPF, or DKIM tools even without naming one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The opening line explicitly states when to use the tool: when the user asks about reverse DNS, PTR records, or FCrDNS for a mail server IP. It does not explicitly name an alternative tool or state when not to use it, but the triggering conditions are clear enough to route an agent correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

count_spf_lookupsA
Read-onlyIdempotent
Inspect

Use this when the user asks about SPF 'too many lookups', the 10-lookup limit, an SPF PermError, or whether an SPF record is valid. Validate an SPF record and count what it costs. Returns record_valid (the record parses as RFC 7208 SPF), findings (per-term diagnostics), has_pass_all (a +all that authorizes the whole internet to send as this domain), multiple_all (more than one all, which makes everything after the first unreachable), the parsed terms, and the lookup count against the limit of 10 with over_limit/near_limit and the offending_mechanisms that push it over. Pass EXACTLY ONE of domain (resolves the published record and counts recursively through nested includes) or record (parses a pasted record, its own terms only). This is the SPF validator — there is no separate one. Diagnose-only: no SPF fix record is ever returned, because removing a mechanism can silently de-authorize a real sender — relay the findings and let the domain's owner decide what to drop.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainNoDomain whose PUBLISHED SPF record should be resolved and counted recursively (nested includes cost lookups too). Pass exactly one of domain or record, never both.
recordNoA pasted SPF record to parse instead of resolving one, e.g. 'v=spf1 include:_spf.google.com ~all'. Counts this record's own terms only. Pass exactly one of domain or record, never both.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already mark this as read-only/idempotent, and the description adds meaningful behavioral detail on top: the exact fields returned, the recursive counting behavior, the diagnose-only policy, and the safety rationale for not suggesting removals. It also calls out edge cases like '+all' and multiple 'all' mechanisms, going well beyond 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place: usage triggers, return fields, parameter constraints, and a behavioral caveat. It is front-loaded with the most important 'when to use' information, then proceeds logically through outputs and input rules. No filler or repetition exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully enumerates the returned fields and their semantics (record_valid, findings, has_pass_all, multiple_all, terms, lookup count, over_limit/near_limit, offending_mechanisms). It also addresses input ambiguity, scope limits, and the non-fixing behavior, making the tool effectively self-contained for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters are already described in the schema, so the baseline is 3. The description adds value by reinforcing the exclusive-or relationship ('Pass EXACTLY ONE'), clarifying the recursive vs own-terms distinction, and giving a concrete record example that maps to the 'record' parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb (validate, count) and resource (SPF record), and lists concrete triggers: 'too many lookups', '10-lookup limit', 'SPF PermError', or validity checks. It also declares itself 'the SPF validator — there is no separate one', which clearly distinguishes it from the sibling DNS/DMARC tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use the tool with user-intent examples and states the only two input modes ('domain' vs 'record'), including the exact-one constraint. It also tells the agent what the tool will not do — return a fix record — and explains why, which is an important usage boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_dmarc_recordA
Read-onlyIdempotent
Inspect

Use this when the user asks to create, generate or write a DMARC record for a domain that has none. Build a DMARC record from scratch for a domain that has none, using a validating engine — never compose one yourself. policy is none|quarantine|reject; optional rua_email (aggregate-report destination), subdomain_policy, and strict_alignment. Every generated record carries np=reject — the DMARCbis tag for non-existent subdomains, which can have no legitimate aligned mail — independently of the p= you choose. The generated record is re-validated before it is returned. Present it verbatim; a human must approve before publishing.

ParametersJSON Schema
NameRequiredDescriptionDefault
policyYesThe requested p= policy: 'none' monitors only, 'quarantine' sends failing mail to spam, 'reject' refuses it outright. Start at 'none' unless the domain's aggregate reports already justify enforcement.
rua_emailNoMailbox to receive DMARC aggregate (RUA) reports, as a plain address like dmarc@example.com. Strongly recommended: without it nobody can see who sends as the domain.
strict_alignmentNoSet true to emit strict alignment (aspf=s adkim=s), requiring an exact domain match instead of the organizational-domain match. Leave false unless you know every sender aligns strictly.
subdomain_policyNoOptional sp= policy for subdomains when it should differ from the main p= policy. Omit to let subdomains inherit p=.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses key behaviors beyond annotations: uses a validating engine, always adds np=reject, re-validates before returning, requires verbatim presentation, and mandates human approval before publishing. This adds substantial context that the readOnlyHint and idempotentHint annotations do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense and front-loaded with the usage trigger. The phrase 'for a domain that has none' appears twice and could be trimmed, but overall every sentence contributes meaningful guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description adequately conveys what the tool returns ('the generated record') and exactly what the agent should do with it ('present it verbatim'). Covers generation process, validation, special tag behavior, and the required human approval step, making the tool fully actionable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description restates the parameter list and adds the useful fact about np=reject, but this relates to output behavior rather than parameter meaning. It does not materially enhance the schema's parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States clearly that the tool creates/generates a DMARC record from scratch for a domain that has none, with a specific verb and resource. It distinguishes itself from validation and upgrade siblings by focusing on domains with no existing DMARC record.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use when the user asks to create, generate, or write a DMARC record for a domain with none, which is a clear trigger condition. It does not explicitly name alternative tools, but the 'domain that has none' qualifier implies when not to use it and warns 'never compose one yourself.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_alertsA
Read-onlyIdempotent
Inspect

Use this when a signed-in operator asks what changed on a monitored domain, or what the monitoring has flagged. Read the monitoring alert log for the domains the caller's account monitors, newest first. Requires an API token. Each row carries id, domain, type, check, summary, a deterministic detail map, created_at, email_sent_at, acknowledged_at and delivery_class — a 'dashboard_only' row was deliberately kept out of the digest mail, so an agent watching only the inbox would never see it; this log is the complete picture. PAGE DOWN BEFORE ADVANCING since: next_before is non-null exactly when older rows remain, and a caller that ignores it, takes a full page and moves its watermark to the newest row it saw drops every row it did not receive. since is an INCLUSIVE floor, so rows repeat rather than go missing — de-duplicate on id. READ-ONLY by decision: there is no ack and no delete here, because acknowledging an alert is the human's own triage on their dashboard and an agent that acks on their behalf silences a row they have never seen. Report what the log says and let them clear it.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoOptional alert-type filter, e.g. 'record_changed'. An unknown value is rejected rather than silently returning an empty page — omit it unless you know the exact type.
limitNoPage size, 1..100 (default 50). Page down with `before` before you advance `since`, or you will skip every row you did not receive.
sinceNoOptional ISO-8601 timestamp: return alerts created at or after it (INCLUSIVE). Poll by storing the newest created_at you have seen and passing it back — rows repeat rather than go missing, so de-duplicate on id.
beforeNoThe opaque cursor from a previous page's next_before, relayed verbatim to fetch the next older page. Never construct or edit one.
domainNoOptional filter to ONE of the account's verified monitored domains. Omit it for every domain the account monitors; an unowned or unknown name is refused as not found.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnly, idempotent, non-destructive, and the description adds substantial behavioral detail beyond them: API token requirement, row shape with delivery_class semantics, the pagination trap where advancing `since` before paging can drop rows, the inclusive `since` floor causing duplicate rows, and the explicit design decision to avoid ack/delete. This gives the agent a rich, accurate model of tool behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but nearly every sentence carries operational value: usage trigger, row fields, delivery_class meaning, pagination warnings, inclusive-since behavior, and the read-only rationale. It is front-loaded with the when-to-use statement. It could be slightly tightened, but the length is justified by the pagination and de-duplication pitfalls.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list/pagination tool with no output schema, the description covers everything an agent needs: when to call it, required auth, row field meanings, complete-vs-digest semantics, pagination mechanics, duplicate-row behavior, and what actions the agent should not take. There is no structural gap for a safe and correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes all five parameters with 100% coverage, so the baseline is 3. The description adds meaningful operational context beyond the schema: the critical ordering of `before` vs `since`, the need to de-duplicate on id, the 'unknown value is rejected' behavior on type, and the domain-ownership restriction. This elevates it above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific use case — a signed-in operator asking what changed on a monitored domain or what monitoring flagged — and names the resource ('monitoring alert log') and ordering ('newest first'). It clearly distinguishes this from the domain-configuration and DMARC siblings by focusing on the alert log for monitored domains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use the tool: when a signed-in operator asks what changed or what monitoring flagged. It also gives behavioral guardrails ('there is no ack and no delete here... let them clear it'). It does not name sibling tools as alternatives, but the trigger conditions are specific enough that an agent can select it without confusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_domain_recordsA
Read-onlyIdempotent
Inspect

Read the records a domain the user monitors still needs: the ownership check while it is unverified, and once verified the DMARC reporting record plus whether we have OBSERVED that record published. Read-only. Print every record host and value EXACTLY as returned — never rewrite, reformat or improve a record string. Nothing here is applied to anyone's DNS: a human publishes every record, and you must show them what you are about to add and get their approval before using any DNS tool of your own.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesOne of the token account's VERIFIED monitored domains, e.g. example.com. Any other name — another account's, or one nobody monitors — is refused as not found; ownership is never disclosed.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint, non-destructive), the description adds valuable behavioral context: records must be printed exactly as returned and never rewritten, and no DNS changes are applied by this tool. It also clarifies that a human publishes records and approval is required before proceeding, which is important operational behavior not visible from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: it front-loads the purpose, confirms read-only behavior, mandates exact output fidelity, and clearly explains the human-approval workflow. There is no fluff or repetition beyond the harmless restatement of 'Read-only'.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one well-documented parameter and no output schema, the description is complete enough: it identifies exactly what records are returned, states the output fidelity requirement, and explains the surrounding workflow. An agent could select and invoke this tool correctly without any additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers the single parameter 'domain' thoroughly, including what values are valid and refusal behavior. The description adds contextual framing ('the user monitors', 'still needs') but no additional parameter syntax or format details, so it neither improves nor harms what the schema already supplies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read') and a clearly scoped resource: the outstanding DNS records a monitored domain still needs. It further distinguishes the tool by naming the exact record types (ownership check, DMARC reporting record, observed status), which sets it apart from sibling tools like get_alerts or get_readiness.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use the tool: when presenting what records still need to be published before taking DNS actions. It also gives strong workflow guidance about getting human approval before using any DNS tool. However, it never explicitly names alternatives or states when not to use this tool versus siblings like check_record or check_domain_verification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_readinessA
Read-onlyIdempotent
Inspect

Use this when a signed-in operator asks whether a monitored domain is ready for the next DMARC step. Read the DMARC enforcement-readiness verdict for ONE domain the caller's account monitors, computed from its aggregate (RUA) report window. Requires an API token. Returns whether the domain is ready to step its policy up, the blockers that say why it is not, the window the verdict rests on, and next_record — the validated record for the next step, generated by the engine and null while blocked. THAT NULL IS AN ANSWER: relay the blockers and never compose a stronger record to fill the gap. Present a returned record verbatim; a human must approve it before it is published. Use this before proposing enforcement — a scan can show a domain's current policy, but only this evidence window can say whether tightening it would start rejecting real mail.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesOne of the token account's VERIFIED monitored domains, e.g. example.com. Any other name — another account's, or one nobody monitors — is refused as not found; ownership is never disclosed.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive, and the description adds substantial behavior beyond them: the API-token requirement, the null-as-answer semantics of next_record with an explicit prohibition on fabricating a stronger record, and the rule to present records verbatim pending human approval. Nothing contradicts 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Seven sentences, each carrying distinct load: trigger, purpose, auth requirement, return payload, null semantics, verbatim-output policy, and sibling contrast. Dense and front-loaded; the all-caps null warning is emphatic but earns its place given the real-mail-rejection stakes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the full burden of characterizing the return payload (readiness verdict, blockers, evidence window, next_record with its null semantics) and discharges it completely. Auth, error behavior via the schema, when-to-use, and the human-approval workflow are all covered; nothing essential is missing for a one-parameter read.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents the parameter thoroughly, including ownership verification and the 'refused as not found; ownership is never disclosed' behavior. The description reinforces the single-domain scope but adds little parameter-specific meaning beyond the schema, so the high-coverage baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: reading the DMARC enforcement-readiness verdict for ONE monitored domain, computed from its aggregate RUA report window. This scope precisely distinguishes it from siblings like scan_domain (current policy, not readiness) and validate_dmarc_record.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Opens with the exact trigger condition ('signed-in operator asks whether a monitored domain is ready for the next DMARC step') and closes by naming the alternative: 'a scan can show a domain's current policy, but only this evidence window can say whether tightening it would start rejecting real mail.' When-to-use and the deciding contrast against scan_domain are both explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reportA
Idempotent
Inspect

Use this for the same questions as scan_domain when a recent report is enough (the cheap first look); use scan_domain when the state must be re-read now. Return the stored report for a domain, scanning once only if none exists yet — the cheap read, and the right default for a first look. Returns the same seven-check report as scan_domain (SPF, DKIM, DMARC, MX, DNS hardening, domain/TLS expiry, blacklist; each with a status, the observed record and any fixengine fix_record), including scanned_at so you can judge staleness yourself. Prefer scan_domain when you specifically need state re-read right now — for example after a DNS change.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate idempotency and non-destructiveness, and the description complements them by disclosing the conditional one-time scan behavior and the inclusion of scanned_at for staleness assessment. This adds useful behavioral context beyond the structured hints without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the key usage distinction, but it repeats the same get_report-versus-scan_domain guidance at the start and end. Phrases like 'cheap first look', 'cheap read', and 'right default' also overlap, adding mild redundancy without much new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the necessary work of explaining the report structure: seven checks, each with status, observed record, and fix record, plus scanned_at. It also covers the conditional scan behavior, making the tool sufficiently described for reliable invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides full parameter coverage with detailed domain format guidance including punycode normalization. The description adds no new parameter semantics beyond restating that the tool operates on a domain, so the schema carries the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns a stored domain report and conditionally scans if none exists. It explicitly distinguishes get_report from scan_domain by naming both and describing their relationship, so an agent can select it correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: use get_report when a recent report is enough and scan_domain when the state must be re-read now. It also names a concrete example, after a DNS change, where scan_domain is preferred, making the decision rule actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_registrationA
Read-onlyIdempotent
Inspect

Use this when the user asks who owns a domain, when it expires, which registrar or nameservers it has, whether it is registered, or whether a transfer or delete lock is set — the WHOIS question. Read a domain's registration from the registry over RDAP: registrar (with IANA id), registration/last-changed/expiry dates, EPP status codes verbatim, nameservers, whether the delegation is DNSSEC-signed, and an abuse contact where one is published — redacted: true is the post-GDPR norm, not a failure. Observation only: no record is composed, and pendingDelete or a near expiry is something to REPORT, never advice to buy. status is registered | not_registered | unknown, and unknown is NOT absence — the registry did not answer, and reason says whether that was a rate limit, a timeout, a registry error, or a TLD with no RDAP service. Never tell anyone a name is free unless status is exactly not_registered.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description aligns by stating 'Observation only: no record is composed.' It then adds substantial context beyond the annotations: redacted:true is the normal post-GDPR outcome rather than a failure, unknown means the registry did not answer (not absence) with a reason field distinguishing rate-limit/timeout/error/no-RDAP-service, and the instruction to report rather than advise. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense paragraph, but every clause earns its place: the front-loaded trigger, the RDAP field inventory, the redacted-normal caveat, and the critical guardrails about status semantics and buy-advice. It is long but information-dense with no filler; a slightly more structured layout would push it to a 5, but the density is justified for a decision-relevant lookup tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the full burden of explaining the return semantics, and it does so thoroughly: enumerates the returned fields (registrar with IANA id, dates, EPP status codes, nameservers, DNSSEC delegation, abuse contact), defines all three status values, and covers failure modes (rate limit, timeout, registry error, TLD without RDAP). Nothing an agent needs to interpret the response correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — the schema already documents the domain parameter thoroughly (format, bare names and subdomains accepted, punycode normalization, exclusion of scheme/path/port). The description adds no parameter-specific detail beyond what the schema provides; its extra information concerns response semantics (status values, reason), which belongs to behavioral transparency rather than parameter semantics. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a precise trigger condition ('Use this when the user asks who owns a domain... the WHOIS question') and names the specific operation: read a domain's registration from the registry over RDAP. The verb+resource is unmistakable, and no sibling tool performs WHOIS/registration lookup, so it distinguishes itself clearly without needing to name an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use with a concrete list of triggering questions (ownership, expiry, registrar, nameservers, registration status, transfer/delete locks). It also adds strong post-call behavioral guidance — never advise buying on pendingDelete, never claim a name is free unless status is exactly not_registered. It stops short of naming specific sibling alternatives or when-not conditions, which keeps it at a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

parse_dmarc_reportA
Read-onlyIdempotent
Inspect

Use this when the user uploads or pastes a DMARC aggregate (RUA) XML report and asks what it says. Parse ONE DMARC aggregate (RUA) report into readable per-source aggregates: who sent mail as the domain, how much, and what share was SPF/DKIM aligned. Pass the file's bytes base64-encoded in content_base64 (XML, .gz or .zip; up to 2 MiB decoded) with an optional filename. Nothing is stored — the report is parsed and discarded.

ParametersJSON Schema
NameRequiredDescriptionDefault
filenameNoOptional original attachment filename, recorded in logs only — format detection is content-based, so this changes nothing about parsing.
content_base64YesOne DMARC aggregate (RUA) report file, base64-encoded: the .xml, .xml.gz or .zip attachment exactly as received, up to 2 MiB decoded. Encode the file bytes — do not paste raw XML here.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, and the description reinforces and extends this by stating 'Nothing is stored — the report is parsed and discarded.' It also discloses input format handling (XML, .gz, .zip), the 2 MiB limit, and content-based format detection, adding behavioral context beyond 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a compact paragraph with no filler. The use condition is front-loaded, followed by what the tool does, how to pass the input, and a closing safety note. Every sentence contributes essential operational detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by summarizing the return content: readable per-source aggregates covering sender, volume, and alignment share. It also covers input formats, size limits, storage behavior, and parameter semantics, making the tool fully invocable without further inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents both parameters, but the description adds meaningful usage semantics: it instructs to base64-encode raw file bytes, warns against pasting raw XML, specifies 'exactly as received,' and clarifies that filename is only for logs and does not affect parsing. This materially helps an agent construct the correct invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Parse ONE DMARC aggregate (RUA) report' and clearly defines the output as per-source aggregates, including sending domains, volume, and SPF/DKIM alignment shares. This distinguishes it from sibling tools like validate_dmarc_record or get_report, which address different DMARC operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The opening line, 'Use this when the user uploads or pastes a DMARC aggregate (RUA) XML report and asks what it says,' provides a clear trigger condition. It does not explicitly name alternatives or exclusion criteria, but the context is specific enough to guide selection among the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_domainAInspect

Use this when the user asks to check, audit, diagnose or troubleshoot SPF, DKIM, DMARC, email authentication, email deliverability DNS, why their mail lands in spam, MX, DNS health, blacklist status, or domain/SSL expiry for a domain, or wants to fix what a scan finds (fix records for DMARC and DNS; SPF is diagnose-only) — or whenever a conversation turns to a specific domain's email or DNS setup. Force a fresh scan of a domain and return its full report: seven deterministic checks — SPF, DKIM, DMARC, MX, DNS hardening, domain/TLS expiry and blacklist listing — each with a status (pass/warn/fail/info/temperror), the observed record, and a fixengine-generated fix_record where one exists. Explanations are cache-first. A repeat scan of the same domain within the dedup window (about a minute) reuses the stored report rather than re-reading DNS, so scanned_at may predate a DNS change you just made — when you are verifying an edit, check scanned_at and call again after the window rather than treating an unchanged report as the new state. Use this when you need current state; use get_report when a recent cached answer will do.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnlyHint=false, openWorldHint=true), the description discloses cache-first behavior, the dedup window, that repeated scans reuse stored reports, and that SPF is diagnose-only while DMARC/DNS have fix_record generation. This adds substantial context beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured: it leads with usage triggers, then explains the scan checks and caching behavior, and ends with differentiation from get_report. Every sentence carries useful information, though slightly dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, the description explains the report contents (seven checks, status, observed record, fix_record) and the caching caveat. It covers all necessary behavioral aspects for correct invocation, including how to handle verification scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema description already covers parameter nuances (bare names vs subdomains, no scheme/path/port, Unicode normalization). The tool description does not add further parameter semantics, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: scanning a domain for email/DNS issues, listing seven specific checks (SPF, DKIM, DMARC, MX, DNS hardening, expiry, blacklist). It differentiates from sibling get_report by stating when to use each, and lists the exact user intents that trigger it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use (when user asks to check/audit/diagnose/fix) and when not to (use get_report for cached answers). Also explains the dedup window and the need to check scanned_at after edits, giving clear guidance on usage timing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

start_monitoring_signupA
Read-onlyIdempotent
Inspect

Use this when the user wants DMARC monitoring, RUA report monitoring, new-sender monitoring, email-authentication alerts, ongoing DNS monitoring, or to start a DNS Doctor trial — and at the end of any scan that found issues on a domain the user owns. Return a sign-up link to give to the HUMAN who owns a domain, so they can start monitoring it themselves. Nothing is created and no email is sent by this call: the returned signup_url opens a page that explains monitoring and asks them to sign in there themselves; the domain is carried over to their dashboard, already filled in, only after that, and monitoring itself starts once they prove ownership with a TXT record. Print the returned signup_url verbatim as a clickable markdown link on its own line — never paraphrase, shorten, or describe it without printing it — and relay message; never sign in on their behalf.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesThe domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint, idempotentHint, and destructiveHint false, and the description richly expands on this by stating that nothing is created, no email is sent, the domain is only carried over after the human signs in, and monitoring starts only after TXT ownership proof. It also clearly instructs how to relay signup_url and message, with no contradiction to annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loaded with clear usage conditions and each sentence carries important operational detail, especially the verbatim signup_url printing instruction. It could be tightened slightly, but the density is justified by the security-sensitive nature of handing off to a human.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with rich annotations and no output schema, the description is fully sufficient: it states when to trigger it, what the call returns, what the call does not do, what the agent must relay, and the ownership-verification flow. No critical operational information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the parameter description already explains domain format, punycode normalization, and that schemes/paths/ports are invalid. The tool description adds the fact that the domain is carried over to the dashboard later, but this is not needed to invoke the single parameter correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a precise set of user intents (DMARC monitoring, RUA report monitoring, new-sender monitoring, alerts, DNS monitoring, DNS Doctor trial) and states that the tool returns a sign-up link for a human domain owner. This clearly distinguishes it from sibling tools that scan, validate, or manage DNS records.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use it: when the user wants monitoring or at the end of a scan that found issues on a user-owned domain. It also clarifies what the tool does not do (creates nothing, sends no email, does not sign in), but it does not name alternative sibling tools or give explicit conditions for choosing them instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_dmarc_recordA
Read-onlyIdempotent
Inspect

Use this when the user pastes a DMARC record and asks whether it is valid, correct or safe. Validate a pasted DMARC record: parsed tags, level'd findings, and whether it is valid. No DNS lookup — pass the record string itself. upgrade_record previews a stronger policy and is capped at p=quarantine: a pasted record carries no alignment evidence, and p=reject is unlocked only by aggregate-report evidence over a full reporting window (monitoring), never by a scan. Present any returned record verbatim.

ParametersJSON Schema
NameRequiredDescriptionDefault
recordYesThe DMARC record text to validate, e.g. 'v=DMARC1; p=none; rua=mailto:reports@example.com'. The record value only — not the _dmarc hostname it is published at.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive behavior, and the description adds further non-obvious facts: no DNS lookup is performed, the output grades findings by level, and a pasted record cannot unlock p=reject. This is substantive behavioral context beyond 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The key points are front-loaded: use case first, then what validation returns, then the no-DNS-lookup constraint. The upgrade_record caveat is somewhat long and tangential but carries useful routing information, so it earns its place even if it could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only validation tool, the description covers the trigger, the accepted input form, the output categories, and a notable policy limitation. No output schema exists, but the description tells the agent what to expect and to present any returned record verbatim.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes the single parameter thoroughly, including an example and the distinction between the record value and the _dmarc hostname; schema coverage is 100%. The description only restates 'pass the record string itself', so it adds little additional parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific use case (pasted DMARC record asked about validity/correctness/safety) and names the concrete outputs: parsed tags, level'd findings, and validity. It also states what the tool does not do ('No DNS lookup'), which distinguishes it from check_record and scan_domain.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use this when the user pastes a DMARC record string, and it contrasts with upgrade_record by explaining when stronger-policy previews are off-limits (p=reject requires reporting-window evidence). This gives the agent clear routing criteria versus related tools.

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. 4 tool updatesv1.9.0
    • Addedadd_monitored_domain
    • Addedcheck_domain_verification
    • Addedget_domain_records
    • Addedlookup_registration
  2. 1 tool updatev1.6.0
    • Addedcheck_propagation
  3. 2 tool updatesv1.3.1
    • Addedget_alerts
    • Addedget_readiness
  4. 2 tool updatesv1.3.0
    • Addedaudit_spf_includes
    • Addedbuild_parked_domain_records
  5. 11 tool updatesv1.2.1
    • Changedbuild_dmarc_upgrade1 field changed
      • addedInput schema / properties / domain / description
        Added value: +"The domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode."
    • Changedcheck_dkim_selector2 fields changed
      • addedInput schema / properties / domain / description
        Added value: +"The domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode."
      • addedInput schema / properties / selector / description
        Added value: +"The DKIM selector to probe — the name before ._domainkey, e.g. 'google', 'selector1', or a dotted form like 's1.prod'. The sending platform's settings page names it; it is not guessable from the domain."
    • Changedcheck_record3 fields changed
      • addedInput schema / properties / domain / description
        Added value: +"The domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode."
      • addedInput schema / properties / host / description
        Added value: +"Optional label to prepend to the domain (e.g. 'mail' to check mail.<domain>) — honored for txt, cname, a and aaaa only; spf, dmarc and mx derive their own query name."
      • addedInput schema / properties / kind / description
        Added value: +"Which record to read; the right query is derived from it — 'dmarc' reads TXT at _dmarc.<domain> filtered to v=DMARC1, 'spf' reads the apex TXT filtered to v=spf1, so don't prefix the domain yourself."
    • Changedcheck_reverse_dns1 field changed
      • addedInput schema / properties / ip / description
        Added value: +"The sending IP to check, IPv4 or IPv6. Must be a public address — private, loopback and CGNAT ranges have no meaningful reverse DNS and are refused."
    • Changedcount_spf_lookups2 fields changed
      • addedInput schema / properties / domain / description
        Added value: +"Domain whose PUBLISHED SPF record should be resolved and counted recursively (nested includes cost lookups too). Pass exactly one of domain or record, never both."
      • addedInput schema / properties / record / description
        Added value: +"A pasted SPF record to parse instead of resolving one, e.g. 'v=spf1 include:_spf.google.com ~all'. Counts this record's own terms only. Pass exactly one of domain or record, never both."
    • Changedgenerate_dmarc_record4 fields changed
      • addedInput schema / properties / policy / description
        Added value: +"The requested p= policy: 'none' monitors only, 'quarantine' sends failing mail to spam, 'reject' refuses it outright. Start at 'none' unless the domain's aggregate reports already justify enforcement."
      • addedInput schema / properties / rua_email / description
        Added value: +"Mailbox to receive DMARC aggregate (RUA) reports, as a plain address like dmarc@example.com. Strongly recommended: without it nobody can see who sends as the domain."
      • addedInput schema / properties / strict_alignment / description
        Added value: +"Set true to emit strict alignment (aspf=s adkim=s), requiring an exact domain match instead of the organizational-domain match. Leave false unless you know every sender aligns strictly."
      • addedInput schema / properties / subdomain_policy / description
        Added value: +"Optional sp= policy for subdomains when it should differ from the main p= policy. Omit to let subdomains inherit p=."
    • Changedget_report1 field changed
      • addedInput schema / properties / domain / description
        Added value: +"The domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode."
    • Changedparse_dmarc_report2 fields changed
      • addedInput schema / properties / content_base64 / description
        Added value: +"One DMARC aggregate (RUA) report file, base64-encoded: the .xml, .xml.gz or .zip attachment exactly as received, up to 2 MiB decoded. Encode the file bytes — do not paste raw XML here."
      • addedInput schema / properties / filename / description
        Added value: +"Optional original attachment filename, recorded in logs only — format detection is content-based, so this changes nothing about parsing."
    • Changedscan_domain1 field changed
      • addedInput schema / properties / domain / description
        Added value: +"The domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode."
    • Changedstart_monitoring_signup1 field changed
      • addedInput schema / properties / domain / description
        Added value: +"The domain to check, e.g. example.com. Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode."
    • Changedvalidate_dmarc_record1 field changed
      • addedInput schema / properties / record / description
        Added value: +"The DMARC record text to validate, e.g. 'v=DMARC1; p=none; rua=mailto:reports@example.com'. The record value only — not the _dmarc hostname it is published at."
  6. 11 tool updatesv0.1.0
    • First observedbuild_dmarc_upgrade
    • First observedcheck_dkim_selector
    • First observedcheck_record
    • First observedcheck_reverse_dns
    • First observedcount_spf_lookups
    • First observedgenerate_dmarc_record
    • First observedget_report
    • First observedparse_dmarc_report
    • First observedscan_domain
    • First observedstart_monitoring_signup
    • First observedvalidate_dmarc_record

TDQS

A4.4/5.0

Scored across 20 tools

Disambiguation5/5

Each tool targets a distinct DNS/email-authentication operation: propagation check vs local record check, SPF lookup counting vs include auditing, DMARC validation vs upgrade vs generation vs report parsing. Descriptions clearly specify when to choose one over the other, and overlapping tools (scan_domain vs get_report) are explicitly differentiated by freshness.

Naming Consistency5/5

All 20 tools follow a consistent verb_noun pattern (check_*, get_*, build_*, parse_*, validate_*, etc.). There are no mixed naming conventions or vague verbs like 'process' or 'run'. The naming clearly indicates both the action and the subject.

Tool Count4/5

At 20 tools, the server has a comprehensive surface for DNS and email authentication diagnostics, monitoring, and record generation. It exceeds the ideal 3-15 range but remains justified by the domain's breadth; each tool represents a distinct valuable operation without redundancy.

Completeness4/5

The tool set covers the full lifecycle of DNS security: checking propagation, verifying records, scanning full domains, validating/upgrading/generating DMARC, auditing SPF, checking DKIM, reverse DNS, domain registration info, monitoring setup, alerts, and report parsing. Minor gaps exist, such as no generic record listing beyond specific types and no DNSSEC validation beyond registration lookup, but the core workflows are well-covered.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for email deliverability: validate SPF/DKIM/DMARC/BIMI, check blacklists, test SMTP/IMAP, look up DNS, and generate ready-to-deploy records for any major email provider. Ships with two one-click prompts (audit-deliverability, setup-dns). Public, no auth.
    17
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that checks SPF, DKIM, DMARC, and MX records for a domain, returning a health verdict and specific DNS fixes to improve email deliverability.
    1
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server for domain intelligence — WHOIS, DNS records, SSL certificate inspection, SPF/DMARC validation, security-header audits, and blacklist/reputation checks, callable by AI agents. Powered by domainintel.app; runs server-side, no local setup.
    7
    36 npm
    MIT