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.

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 16 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? I can send a setup link to your email.

Learn more

License

Apache-2.0 — see LICENSE.

Available Tools

16 tools
audit_spf_includesA
Read-onlyIdempotent
Inspect

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?

Beyond the annotations (readOnly, idempotent, openWorld), the description discloses critical behavioral constraints: unverified domains are always reported as unverified, never as available, and registry_confirmed: false means DNS-only inference with limitations. It also states that no SPF fix record exists, preventing misuse, which is substantial disclosure beyond 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 front-loaded with the purpose sentence and then provides essential details in a structured list. It is longer than the calibration's ideal but every sentence carries information; minor repetition of 'never as available' could be tightened, but overall the density 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?

Given there is no output schema, the description compensates by fully enumerating the return elements (resolved tree, lookup attribution, IPv4 count, all five finding types) and explaining edge cases like registry_confirmed and unverified domains. It also covers the alternative tool, making it contextually complete.

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 documents the domain parameter with 100% coverage, including normalization and allowed forms. The description adds only contextual references to 'the audited domain's OWN record' but no new format or syntax rules, so the baseline of 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 opens with a specific action and resource: 'Audit a domain's SPF supply chain' and explicitly differentiates from sibling count_spf_lookups by mentioning it as the alternative for 10-lookup questions. It also enumerates the main outputs (resolved tree, findings, IPv4 count), which further clarifies 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 names count_spf_lookups as the alternative when only the 10-lookup limit matters, which provides a clear when-to-use/not-use boundary. The cautions about not treating findings as instructions and relaying to the domain owner are additional usage guardrails.

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

build_dmarc_upgradeAInspect

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.8/5.0
Behavior5/5

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

Annotations are sparse (readOnlyHint=false, idempotentHint=false, destructiveHint=false), so the description carries the burden. It goes into depth: alignment signals are derived server-side and cannot be asserted by the caller; null record semantics; np=reject behavior; and the human-approval requirement. This exceeds what annotations alone could 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 long and contains a very long parenthetical enumerating null-record cases, which tests readability. However, every piece of content earns its place: null handling, policy limits, np behavior, and human approval are all essential. It is dense but not wasteful.

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 no output schema and minimal annotations, this description covers everything an agent needs: what the tool returns, when it returns null, how to handle null, what tags appear in the record, and the required human approval step. There is no meaningful gap.

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 documents the single `domain` parameter thoroughly, including punycode normalization, so the description doesn't need to repeat it. However, the description adds useful context about what the caller can influence (essentially only the domain) and what is server-side derived. Since schema coverage is 100%, the baseline is 3, and the added context earns a 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 opens with a specific verb and resource: 'Return a validated DMARC enforcement-upgrade record for a domain.' It clearly differentiates from siblings like generate_dmarc_record and validate_dmarc_record by describing what this tool does differently. The scope is unambiguous.

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 states when to use this tool versus alternatives: a scan can justify p=quarantine at most, while p=reject requires monitoring evidence. It also explains that a null record is an answer, not a fault, and instructs the caller to relay rationale and never compose a record. This is strong, actionable usage guidance.

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

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.9/5.0
Behavior5/5

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

Despite readOnlyHint=true, the description adds critical runtime behavior: the server independently re-checks DNS (existence, MX, SPF, DKIM selectors), returns null with rationale if mail is found, reports lookup failures as failures, and never auto-publishes ('Publishing is the human's decision'). 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.

Conciseness5/5

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

Every sentence earns its place: purpose, domain exclusion, human-confirmation protocol, server re-check behavior, and publishing handoff. It is a dense but structured single paragraph, front-loaded with the main action.

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 fully by explaining return shape (three records, or null with rationale, or failure), ordering constraint, and the human approval step. Combined with a complete parameter schema, an agent can invoke this tool correctly and interpret results.

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 100% of parameters; the description adds nuance for confirm_no_mail beyond the schema by framing it as a human-only decision that 'unlocks the question, not the answer' and instructing to ask before setting. It doesn't discuss rua_email or domain, but the schema already fully documents those, so the baseline for high coverage is met with a slight bonus for the confirm_no_mail guidance.

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 verb and resource: 'Build the three-record hardening pack' for a NON-SENDING domain, naming the exact records (Null MX, hard-fail SPF, p=reject DMARC). It clearly scopes to parked/redirect/brand-defensive domains, distinguishing it from sibling tools like generate_dmarc_record or build_dmarc_upgrade.

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?

Explicit when-to-use and when-not-to-use: 'For parked, redirect and brand-defensive domains only — NEVER for a domain that sends any mail.' It also instructs the agent to ask the human owner before setting confirm_no_mail, and to relay rationale rather than retry, providing concrete decision rules.

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

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.7/5.0
Behavior5/5

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

Beyond the readOnlyHint and idempotentHint annotations, the description specifies the return values (verdict, explanation, key record), explicitly states that no fix record is returned, and explains why, providing full behavioral transparency.

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?

Four sentences, front-loaded with purpose, no unnecessary words. Every sentence adds value.

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 simple input schema (2 params) and no output schema, the description fully covers what the tool does, what it returns, and why it doesn't return a fix record, making it contextually complete.

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 baseline is 3, but the description adds context: it explains that the selector is the exact one from the sending platform and provides examples, enhancing agent understanding 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 clearly states the tool checks a specific DKIM selector, distinguishes from a full scan's common-selector sweep, and contrasts with sibling tools like scan_domain that do broader scanning.

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 explains when to use this tool (when the exact selector is known, which a full scan might miss) and notes that the selector is not guessable, but does not explicitly mention alternatives or when not to use it.

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

Check whether a DNS change has propagated GLOBALLY: six vantage points (five owner-run probes on separate 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?

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, and the description adds substantial behavioral detail: a grid plus verdict, 'unavailable' meaning no answer rather than a negative result, downgrade to 'unknown' below three vantage points, and the instruction to report reach ratios. It also reinforces observation-only behavior consistently with annotations. No contradiction.

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 a single dense paragraph but front-loads the primary purpose in the first clause. Every sentence adds operational value, covering vantage points, exact-name handling, record types, expected_value semantics, and verdict downgrade rules. It is somewhat run-on, but no wasted words are present.

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 return semantics, and it does so thoroughly: grid, deterministic verdict, 'unavailable' meaning, unknown downgrade, and the vantage_reached/vantage_total reporting guidance. Combined with rich annotations and complete parameter descriptions, an agent has enough to select, invoke, and interpret the result 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%, and the description mostly restates what the schema already says: exact name preservation, TXT for SPF/DMARC, and expected_value's match/mismatch behavior. It adds minor operational color but no genuinely new parameter meaning, so the 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?

The description opens with a specific verb and resource: 'Check whether a DNS change has propagated GLOBALLY,' then details six vantage points and a deterministic verdict. This clearly distinguishes it from the sibling check_record, which implies a single-vantage check. The global scope is unambiguous and not a tautology.

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 says 'Call it after the human publishes a record' and explains why: the caller has only one network vantage point while the tool has six. It also advises reporting vantage_reached/total instead of claiming convergence on partial coverage. However, it does not name alternative tools or give explicit when-not-to-call conditions beyond the implied 'before publishing.'

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

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.5/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true, idempotentHint=true, and openWorldHint=true. The description adds valuable context: it reads from authoritative and caching resolvers, reports agreement/disagreement, and explains output interpretations (empty values mean genuine absence; max_wait_seconds is remaining TTL). This enhances transparency 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 description is a single dense paragraph that covers purpose, parameter details, and output interpretation. It is relatively concise but could be more structured (e.g., bullet points or separate sections) to improve scanability. No wasted sentences.

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 there is no output schema, the description adequately explains return values: '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, combined with parameter details and annotations, makes the tool self-contained.

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?

Schema coverage is 100% (all three parameters documented), but the description significantly enriches meaning. For 'kind', it explains the derived query logic for spf/dmarc; for 'host', it clarifies which record types it applies to; for 'domain', it specifies formatting and Unicode handling. This goes well beyond schema basics.

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: '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.' This specific verb-resource pair distinguishes it from sibling tools like check_dkim_selector or validate_dmarc_record, which cover different DNS checks.

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 explains what the tool does and provides usage context (e.g., for checking DNS propagation after a change). It includes a caveat: 'This samples two resolvers, so never describe it as worldwide or as propagation coverage.' However, it does not explicitly state when not to use it or name alternative tools, leaving some ambiguity for the agent.

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

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.3/5.0
Behavior4/5

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

Discloses additional behavioral traits beyond annotations: describes the two-step resolution process, possible verdicts, and warns against misinterpreting bare PTRs. 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.

Conciseness5/5

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

Three concise sentences with front-loaded purpose, clear verdict explanation, and practical guidance. No superfluous text.

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 rich annotations, the description covers all necessary context: input constraints, process, output meaning, and proper usage. Complete and self-contained.

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 in the schema already explains the public address requirement well. The description repeats this but does not add new semantic information 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?

Description clearly states the tool checks forward-confirmed reverse DNS for one sending IP, explaining the process and distinguishing it from siblings like check_dkim_selector or check_record which focus on other aspects.

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?

Provides clear when-to-use context: pass a public IP, never report bare PTR, fix by IP owner. However, it does not explicitly mention alternatives or when not to use this tool.

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

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.6/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, destructiveHint=false. The description adds concrete behavioral details: what return fields are provided (record_valid, findings, has_pass_all, etc.), the lookup counting logic, and the explicit statement that no SPF fix record is returned. This goes well beyond 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 concise but thorough, front-loading the purpose and return values. Every sentence adds useful information without redundancy. It could be slightly more structured, but it is efficient and clear.

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 complexity of SPF validation and the fact that there is no output schema, the description thoroughly covers all aspects: what the tool does, the two usage modes, the specific return fields, and important constraints (diagnose-only, no fix). It is complete for an agent to correctly invoke the tool.

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 both parameters. The description adds meaningful context: domain resolves the published record and counts recursively through nested includes, while record parses a pasted record counting only its own terms. This adds value beyond the schema 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?

The description starts with 'Validate an SPF record and count what it costs,' clearly stating the verb and resource. It lists specific return fields and explicitly distinguishes this tool from siblings by noting 'This is the SPF validator — there is no separate one.' This makes it highly specific and differentiated.

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 provides explicit guidance: 'Pass EXACTLY ONE of domain or record,' explaining when to use each. It also clarifies that this tool is 'diagnose-only' and why it does not return a fix record. While it doesn't list specific alternative tools, the usage context is clear enough.

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

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.9/5.0
Behavior5/5

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

Annotations indicate readOnlyHint and idempotentHint, and the description adds valuable behavioral context: the generated record always includes np=reject regardless of p=, it is re-validated before return, and human approval is required. These details go well beyond the annotations by explaining internal validation logic and output guarantees.

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 compact (four sentences) and front-loaded with the primary purpose. Every sentence delivers critical information: what it does, key parameters, the np=reject behavior, re-validation, and human approval requirement. No wasted words.

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 generation tool with no output schema, the description fully covers what the output looks like (a DMARC record), important constraints (np=reject), validation behavior (re-validated), and usage steps (present verbatim, human approval). It gives an agent everything needed to invoke the tool 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 baseline is 3. The description adds parameter-related clarity by noting that the `policy` parameter does not influence np=reject ('independently of the p= you choose'), which is not obvious from the schema. However, most parameter semantics are already well documented in the schema 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?

The description clearly states the tool's function: 'Build a DMARC record from scratch for a domain that has none, using a validating engine.' It distinguishes itself from siblings by emphasizing 'from scratch' and 'never compose one yourself,' differentiating from validate_dmarc_record and build_dmarc_upgrade.

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 states when to use: 'for a domain that has none,' and when not to: 'never compose one yourself.' It also provides a clear constraint: 'Present it verbatim; a human must approve before publishing.' This gives strong contextual guidance on when and how to use the tool.

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

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

A5/5.0
Behavior5/5

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

Annotations already mark readOnlyHint=true and destructiveHint=false, but the description adds depth: it explains the deliberate read-only design ('acknowledging an alert is the human's own triage'), details the delivery_class semantics ('dashboard_only' rows excluded from digest mail), and the inclusive-since behavior that causes row repetition. This is valuable contextual information 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 dense but every sentence earns its place: purpose, paging rule, inclusive-since semantics, read-only rationale, and row field enumeration. It is front-loaded with the core action and progressively provides necessary detail without fluff or redundancy.

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 there is no output schema, the description compensates by naming all returned row fields (id, domain, type, check, summary, etc.) and explaining the delivery_class meaning. It covers authentication (API token), paging, filters, and behavioral constraints, making it complete for an agent to use the tool correctly.

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?

Although the schema already describes each parameter (100% coverage), the description adds critical operational meaning: `since` is an INCLUSIVE floor (so de-duplicate on id), `before` is an opaque cursor that must be relayed verbatim, and invalid `type`/`domain` values are rejected rather than silently ignored. This clarifies usage subtleties that raw schema descriptions omit.

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 'Read the monitoring alert log for the domains the caller's account monitors, newest first', which clearly states the action (read), resource (monitoring alert log), and scope (caller's domains, newest first). This distinguishes it from sibling tools focused on DNS/DMARC operations, making the purpose unmistakable.

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 provides explicit procedural guidance: 'PAGE DOWN BEFORE ADVANCING `since`' and warns that ignoring it drops rows. It also states when not to use mutation-like operations ('there is no ack and no delete here') and clarifies the read-only intent. This goes beyond simple context to give definitive usage rules.

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

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.9/5.0
Behavior5/5

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

Beyond the readOnlyHint and idempotentHint annotations, the description adds critical behavioral context: the null next_record is a valid answer, the agent must relay blockers and never compose a stronger record, and any returned record must be presented verbatim for human approval. It also mentions API token requirements and return semantics.

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 front-loaded with a clear purpose, then delivers return semantics, safety guardrails, and usage guidance. Every sentence carries essential information—none are filler—and the structure logically progresses from what it does to how to handle its outputs.

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 explains the return values (readiness, blockers, window, next_record) and the null semantics, which is crucial for correct agent behavior. It also covers the human-approval requirement and the tool's role in the enforcement workflow, making it complete for a tool of this complexity.

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 input schema already covers the domain parameter well (verified, monitored, ownership not disclosed). The description adds meaning by emphasizing that the domain is specifically the one whose RUA report window the verdict is computed from, and that it must be a single domain from the caller's account, reinforcing the scope.

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 verb+resource statement: 'Read the DMARC enforcement-readiness verdict for ONE domain the caller's account monitors.' It clearly defines the tool's scope and distinguishes it from sibling tools like scan_domain by framing it as the evidence-based readiness check.

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 states when to use the tool: 'Use this before proposing enforcement.' It also contrasts with scan_domain, noting that a scan shows current policy but only this evidence window can determine if tightening would reject real mail, providing effective guidance on alternatives.

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

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.8/5.0
Behavior4/5

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

Annotations indicate readOnlyHint=false, idempotentHint=true. The description explains that scanning occurs only once if no report exists, and lists the report contents including scanned_at for staleness judgment. This adds valuable context beyond annotations without contradiction.

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 tightly written with no wasted words, front-loading the core purpose and usage guidance. Two sentences cover purpose, behavior, and alternatives efficiently.

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 domain check tool with one parameter and no output schema, the description comprehensively covers what the report contains (seven checks), when to use the alternative, and how to judge staleness. It is fully adequate for agent decision-making.

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?

Schema has full coverage for the single domain parameter. The description adds extra meaning: 'Bare registrable names and subdomains both work; scheme, path or port do not belong here. Unicode names are accepted and normalized to punycode.' This significantly enhances understanding.

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 report for a domain, scanning only if none exists, and distinguishes it from scan_domain which re-reads state. The verb 'Return' and resource 'stored report' are specific.

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 states 'the right default for a first look' and advises to 'Prefer scan_domain when you specifically need state re-read right now — for example after a DNS change.' This provides clear when-to-use and when-not-to-use guidance.

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

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.7/5.0
Behavior5/5

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

The description discloses key traits beyond annotations: the tool is stateless ('nothing is stored, parsed and discarded'), idempotent, and read-only (matching annotations). It also specifies input size limits (2 MiB decoded) and format support, which annotations do not cover, adding significant behavioral context.

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 three sentences, each earning its place: purpose, required input format, and stateless nature. It is front-loaded with the core action and efficiently conveys all necessary details without redundancy.

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?

The description adequately covers input, constraints, and effect. It hints at output ('readable per-source aggregates') but does not detail the exact structure. Given no output schema, a brief mention of the output format would improve completeness, but the core information is sufficient for correct invocation.

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 description adds meaningful context beyond the input schema. For 'content_base64', it clarifies to encode file bytes, not paste raw XML. For 'filename', it notes the filename is only for logging and does not affect parsing. This helps the agent avoid common mistakes.

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 parses a single DMARC aggregate (RUA) report into per-source aggregates, specifying what information is extracted (sender, volume, SPF/DKIM alignment). This is distinct from sibling tools which handle building, checking, or generating DNS records, so the purpose is unambiguous.

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 provides explicit instructions on how to invoke the tool: pass base64-encoded file bytes, optionally with a filename. It states the file can be XML, .gz, or .zip up to 2 MiB. While it does not contrast with siblings, the context of parsing vs. fetching (get_report) or checking DNS records is clear enough for an agent to decide.

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

scan_domainAInspect

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.7/5.0
Behavior5/5

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

The annotations only declare non-read-only, non-idempotent, non-destructive behavior. The description adds critical behavioral detail beyond that: cache-first explanations, a ~minute dedup window, reuse of stored reports, and the scanned_at caveat. This gives the agent an accurate mental model of what actually happens on repeat calls.

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 front-loaded with the core action and output, then layers the cache caveat and usage routing in later sentences. Every sentence earns its place: output shape, behavioral nuance, and tool selection are each covered without redundancy.

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 present, the description compensates by specifying the checks, status values, observed record, and fix_record structure. It also covers the non-obvious caching behavior that could otherwise lead an agent to misreport state. For a single-parameter tool, this is complete.

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 covers the single parameter at 100% with rich details about accepted formats, subdomains, and punycode normalization. The tool description itself does not add much parameter-level meaning beyond naming the domain as the scan target, 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?

The description opens with a specific verb and resource ('Force a fresh scan of a domain') and enumerates the seven deterministic checks and the per-check output fields. It clearly distinguishes itself from the sibling get_report by contrasting fresh scans with cached answers.

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 states when to use this tool ('when you need current state') and when to prefer an alternative ('use get_report when a recent cached answer will do'). It also warns about the dedup window and advises checking scanned_at after DNS edits, giving actionable selection and timing guidance.

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

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.7/5.0
Behavior5/5

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

Beyond the readOnly and idempotent annotations, the description explains that nothing is created, no email is sent, the signup_url opens an external page, the domain is transferred only after owner sign-in, and monitoring starts only after TXT ownership proof. This is rich behavioral disclosure with no contradiction.

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?

Front-loaded purpose, followed by necessary workflow details and a concrete output instruction. Every sentence earns its place; no filler.

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?

Without an output schema, the description still names both return values (signup_url and message), explains the asynchronous side effects, and instructs exact formatting. An agent has everything needed to invoke and present the result 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 schema already documents domain format. The description adds meaning by explaining what happens to the domain value: it is carried over to the owner's dashboard and pre-filled after sign-in, which is useful behavioral context beyond validation.

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: 'Return a sign-up link to give to the HUMAN who owns a domain,' which clearly distinguishes it from the sibling DNS/email monitoring tools. The purpose is immediately evident from the first sentence.

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 clear context: this is for handing off monitoring to the domain owner themselves, and explicitly says 'never sign in on their behalf.' It does not name sibling alternatives explicitly, but the intended use case is unmistakable.

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

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.8/5.0
Behavior5/5

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

Annotations already indicate readOnlyHint and idempotentHint, and the description adds meaningful behavioral context: it performs no DNS lookup, accepts only a pasted record string, reports parsed tags and findings, and explains the alignment-evidence limitation. The upgrade_record policy explanation also clarifies an important boundary. 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 front-loaded with the core purpose and remaining sentences add useful routing and policy context. The upgrade_record/p=reject explanation is somewhat lengthy for a validation tool, but it earns its place by preventing misuse.

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 a single parameter, no output schema, and annotations covering safety, the description provides enough detail: what it validates, what it returns at a high level, what it does not do, and how it relates to upgrade paths. The agent can call it correctly without additional context.

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 provides strong coverage (100%) with an example and the 'record value only' clarification. The description reinforces this by saying 'pass the record string itself' and explicitly excluding DNS lookup, adding slight value 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 opens with a specific verb and resource: 'Validate a pasted DMARC record', then lists concrete outputs (parsed tags, level'd findings, validity). It clearly distinguishes itself from DNS-lookup and record-generation siblings by explicitly stating 'No DNS lookup' and by contrasting with upgrade_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?

It explicitly states when to use the tool ('pass the record string itself') and when not to use a scan-based alternative, explaining why upgrade_record is capped at p=quarantine and that p=reject requires aggregate-report evidence. This gives the agent actionable selection criteria.

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. Dates show when Glama detected each change.

  1. 1 tool updatev1.6.0
    • Addedcheck_propagation
  2. 2 tool updatesv1.3.1
    • Addedget_alerts
    • Addedget_readiness
  3. 2 tool updatesv1.3.0
    • Addedaudit_spf_includes
    • Addedbuild_parked_domain_records
  4. 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."
  5. 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.6/5.0
Disambiguation5/5

Each tool targets a specific, distinct operation: scanning, checking specific records, validating, generating records, etc. There is no overlap; for example, scan_domain and get_report are clearly differentiated by freshness, and check_dkim_selector is separate from the general scan.

Naming Consistency5/5

All tools use a consistent verb_noun pattern with snake_case: build_dmarc_upgrade, check_dkim_selector, scan_domain, etc. The naming is predictable and clear.

Tool Count5/5

11 tools is well-scoped for a DNS diagnosis and monitoring server. It covers scanning, specific checks, validation, report parsing, and monitoring setup without being excessive or too sparse.

Completeness4/5

The server covers the major aspects of email authentication (SPF, DKIM, DMARC) and general DNS checks, plus reverse DNS and monitoring signup. Minor gaps like DNSSEC details or bulk operations are absent but not critical for the core purpose.

Maintenance

ActivityMaintained
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
    99
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dnsdoctor/claude-plugin'

If you have feedback or need assistance with the MCP directory API, please join our Discord server