Skip to main content
Glama
OrtaMarco

domain-security-mcp-server

by OrtaMarco

domain-security-mcp-server

An MCP server that lets an AI agent audit the email and domain security of any domain — SPF, DKIM, DMARC, MTA-STS, TLS-RPT, BIMI, DNSSEC, DNS, TLS/SSL and WHOIS — in plain language. No API keys required.

ci npm MCP TypeScript License: MIT

Built on the v2 MCP SDK: the server speaks the 2026-07-28 protocol revision and keeps accepting 2025-era clients (Claude Desktop, Claude Code, Cursor) from the same factory — the era is negotiated per connection, so there is nothing to configure on either side.

Ask Claude "Is acme.com protected against email spoofing?" and it runs a full authentication audit and hands you a graded report with prioritised fixes — instead of you pasting a domain into five different web tools.

> Is ortamarco.me protected against email spoofing?

  email_auth_audit(domain="ortamarco.me")

  Grade: A (95/100) · MX: present
  ✅ SPF ends in '-all' (hard fail). 3/10 DNS lookups.
  ✅ DMARC policy is enforced ('p=reject').
  ✅ DKIM key found for selector: google.
  Top recommendation: add a TLS-RPT record for delivery-failure reports.

Why this exists

The email-security ecosystem is full of single-purpose web checkers (SPF here, DMARC there, WHOIS somewhere else) and the few MCP equivalents are locked behind paid API tokens. This server brings the whole deliverability & domain-security toolkit to any MCP client, key-free, with one headline workflow tool that does the synthesis for you.

It is the agent-facing companion to the network tools at ortamarco.me and shares the same battle-tested core (public-resolver DNS, host validation, timeouts).

Related MCP server: Dechonet MCP

Tools

Tool

What it does

email_auth_audit

One-call SPF + DKIM + DMARC + MX audit → 0–100 score, A–F grade, prioritised fixes

spf_check

Parse SPF; recursively count DNS lookups vs the RFC 7208 limit of 10; flag +all/?all

dmarc_check

Parse DMARC policy (p, sp, rua, pct, aspf/adkim) with warnings

dkim_check

Probe <selector>._domainkey keys (supply selectors or use common ones)

mta_sts_check

Validate the _mta-sts TXT and the .well-known/mta-sts.txt policy + mode

tls_rpt_check

Check the _smtp._tls TLS-RPT record

bimi_check

Check the default._bimi BIMI record

dnssec_check

DS/DNSKEY presence + DNSSEC AD validation flag (via DoH)

dns_lookup

All record types (A/AAAA/CNAME/MX/NS/TXT/SOA) via public resolvers

ssl_certificate

TLS cert issuer, validity window, days-to-expiry, SANs, fingerprint

whois_lookup

Registrar, dates, name servers, status (raw port-43 WHOIS, IANA-resolved)

reverse_dns

PTR records for an IP

ip_geolocation

Offline IP geolocation (DB-IP Lite) + reverse DNS

mx_lookup

Mail servers (MX) with priority and resolved IPs

caa_check

Which CAs may issue TLS certificates (CAA records)

blacklist_check

IP/domain against open-access email DNSBLs

dns_propagation

Compare a record across 5 public resolvers worldwide

http_security_headers

Grade a site's HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy and COOP

analyze_email_headers

Parse raw headers → SPF/DKIM/DMARC verdicts + Received hop chain with delays

Every tool is read-only, declares an outputSchema and returns structuredContent (validated by the SDK) alongside human-readable Markdown (default) or JSON (response_format="json"), plus actionable error messages.

Install

Requires Node.js 20.18+. Nothing to clone — every MCP client can run it with npx.

Use it with Claude Code

claude mcp add domain-security -- npx -y domain-security-mcp-server

Use it with Claude Desktop or Cursor

Add to claude_desktop_config.json (or ~/.cursor/mcp.json) — see examples/:

{
  "mcpServers": {
    "domain-security": {
      "command": "npx",
      "args": ["-y", "domain-security-mcp-server"]
    }
  }
}

On Windows use "command": "cmd" with "args": ["/c", "npx", "-y", "domain-security-mcp-server"]. Restart the client, then ask: "Audit the email security of stripe.com."

Self-host (HTTP transport)

The same server speaks stateless Streamable HTTP for remote or multi-client use. One endpoint serves both protocol eras and there is no session state, so no Mcp-Session-Id header is issued or expected.

TRANSPORT=http npx -y domain-security-mcp-server
# POST JSON-RPC to http://127.0.0.1:3000/mcp   ·   health at /healthz

It is safe by default: it binds to 127.0.0.1 and only accepts localhost Host and Origin headers, which blocks DNS-rebinding attacks from a web page. To expose it — for example behind Coolify or Traefik — opt in explicitly:

Variable

Default

Purpose

TRANSPORT

stdio

http to serve Streamable HTTP

PORT

3000

Listening port

HOST

127.0.0.1

Bind address; 0.0.0.0 to accept remote connections

ALLOWED_HOSTS

Comma-separated hostnames the Host header may carry (e.g. mcp.example.com)

ALLOWED_ORIGINS

Comma-separated origins allowed to call from a browser

MCP_AUTH_TOKEN

If set, every request needs Authorization: Bearer <token>

Binding to a non-loopback address without ALLOWED_HOSTS or MCP_AUTH_TOKEN works, but the server says so on stderr. With Docker (the image sets HOST=0.0.0.0):

docker build -t domain-security-mcp .
docker run -p 3000:3000 -e ALLOWED_HOSTS=mcp.example.com -e MCP_AUTH_TOKEN=change-me domain-security-mcp

Security

The tools reach out to hosts that the caller names, so every outbound connection is screened against server-side request forgery:

  • Private, loopback, link-local (cloud metadata), shared, multicast and reserved addresses are refused in every spelling, including IPv4 embedded in IPv6 ([::ffff:169.254.169.254]).

  • The check happens at connect time, on the address the socket is actually about to use, so DNS rebinding and names only an internal resolver knows are refused too. Redirects are followed by hand and every hop is re-checked.

  • Response bodies, redirects, WHOIS referrals and every network call are capped and time-limited.

Found a problem? Please open a private security advisory.

Develop

npm run dev      # tsx watch (stdio)
npm run inspect  # open the MCP Inspector against the built server
npm run build     # type-check + emit dist/
npm run typecheck # type-check only
npm test          # offline unit tests: SSRF guard, SPF/DMARC/DKIM scoring,
                  # header parsing, HTTP transport defaults
npm run smoke     # call all 19 tools on BOTH protocol eras and validate
                  # structuredContent against each tool's outputSchema

evals/ holds a 10-question LLM evaluation set (stable, verifiable) and instructions for running it — see evals/README.md.

How it works

src/
├── index.ts        # transport selection (stdio | http), v2 SDK entry points
├── server.ts       # factory: registers every tool on one McpServer
├── core/           # pure logic, no MCP coupling — reusable & testable
│   ├── validate.ts # input validation and the address classifier
│   ├── netguard.ts # connect-time SSRF guard, redirect-safe fetch, capped bodies
│   ├── dns.ts      # public-resolver DNS + DoH client
│   ├── net.ts      # MX, CAA, DNSBL and propagation checks
│   ├── tls.ts      # certificate inspection and trust
│   ├── whois.ts    # port-43 WHOIS with IANA/registrar referral
│   ├── http.ts     # security-header grading
│   ├── geoip.ts    # offline IP geolocation on DB-IP Lite (each file read on first use)
│   ├── email-headers.ts  # raw header parsing and hop timing
│   └── email-auth.ts  # SPF/DKIM/DMARC/MTA-STS/TLS-RPT/BIMI/DNSSEC + scoring
└── tools/          # thin MCP wrappers (Zod schemas, descriptions, formatting)

The core/ layer is deliberately free of any MCP types, so the exact same logic powers both this server and the web tools on ortamarco.me.

Credits

IP Geolocation by DB-IP. ip_geolocation uses the free DB-IP "IP to City Lite" database, licensed under CC BY 4.0 and installed as the @ip-location-db/dbip-city-mmdb package; the credit also appears in the tool's description and Markdown output. The database has no time zone, so time_zone is estimated from the coordinates with @photostructure/tz-lookup (CC0).

License

MIT © Marco Orta

Available Tools

19 tools
analyze_email_headersEmail Header AnalyzerA
Read-onlyIdempotent

Parse raw email headers and report the SPF/DKIM/DMARC verdicts (from Authentication-Results), key fields (From, Subject, Date, Message-ID, Return-Path) and the Received hop chain with per-hop delays and total transit time.

Args:

  • headers (string): the raw email headers.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { auth{spf,dkim,dmarc}, fields{}, hops[{index,from,by,date,delaySec}], totalSec }.

Example: paste the headers from "Show original" in Gmail to trace a message's path and authentication.

ParametersJSON Schema
NameRequiredDescriptionDefault
headersYesThe raw email headers to analyze (RFC 5322).
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
authYes
hopsYes
fieldsYes
totalSecYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already establish read-only/idempotent/non-destructive behavior. The description adds value by clarifying that verdicts come from Authentication-Results headers rather than live DNS checks, and by detailing per-hop delays and total transit time. It does not mention edge cases like missing Authentication-Results headers, but this is a minor gap given the annotation coverage.

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 well organized with a front-loaded summary, Args, Returns, and an Example. It is compact and readable, though the Args and Returns sections partially duplicate the input and output schemas rather than adding entirely new information.

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 two-parameter surface, full schema coverage, rich output schema, and annotations, the description is complete. It provides a concrete example, the output shape, and enough behavioral context for an agent to invoke this tool correctly without needing 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%, and the description's Args section mostly restates the schema: headers is a string, response_format is markdown/json with a default. It adds no meaning beyond what the input schema already provides, so the baseline score 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 uses a specific verb-resource pairing ('Parse raw email headers and report...') and names concrete outputs: SPF/DKIM/DMARC verdicts, key fields, and Received hop chain. This clearly distinguishes it from siblings like spf_check and dkim_check by its raw-header input and transport-path analysis.

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 a concrete scenario: 'paste the headers from "Show original" in Gmail to trace a message's path and authentication.' This makes the intended usage clear, though it does not explicitly contrast the tool with siblings or state when a different tool should be chosen.

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

bimi_checkBIMI CheckA
Read-onlyIdempotent

Check a domain's BIMI record (default._bimi. TXT), which points to the brand logo (and optional VMC) displayed next to authenticated mail. BIMI requires an enforced DMARC policy to take effect.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { found, record, findings[] }.

Example: "Does cnn.com have BIMI set up?" -> bimi_check(domain="cnn.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
domainYes
recordNo
findingsYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior. The description adds meaningful context about the lookup target, the DMARC prerequisite, and the returned structure. No contradiction exists between the description and 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 compact, front-loaded, and well organized with Args, Returns, and Example sections. Every line carries useful information, and there is no filler or repetition beyond what serves clarity.

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 simple read-only DNS record check with full schema documentation and an output schema, the description is complete. It includes the exact lookup name, the prerequisite, the return shape, and a real-world example. Nothing essential is missing 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 parameters are already documented well. The description still adds value with a concrete usage example and the default response_format behavior. This goes beyond the baseline without introducing ambiguity.

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 identifies the exact resource being checked (the default._bimi.<domain> TXT record) and the action (check), plus what the record is used for. This makes it clearly distinguishable from sibling tools like spf_check, dmarc_check, and dkim_check. The example reinforces the purpose with a concrete domain.

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 states the key prerequisite: BIMI requires an enforced DMARC policy to take effect. This gives the agent useful context about when this check is relevant. It does not explicitly name alternative tools, but the record-specific definition makes the intended use obvious.

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

blacklist_checkDNSBL Blacklist CheckA
Read-onlyIdempotent

Check whether an IPv4 address (or a domain's A records) appears on email DNS blocklists (DNSBLs). Only open-access lists are queried (SpamCop, UCEPROTECT-1, DroneBL, s5h); Spamhaus and Barracuda refuse public-resolver queries and are excluded.

Args:

  • query (string): an IPv4 address or a domain.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { ips[], listedCount, checked, results[{ip, hits[{list, listed, reason, error}]}], note }. A list that did not answer carries an error and is not counted as clean.

Example: "Is 203.0.113.5 blacklisted?" -> blacklist_check(query="203.0.113.5").

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesAn IPv4 address or a domain to check against DNSBLs.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
ipsYes
noteYes
queryYes
checkedYes
resultsYes
listedCountYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description need not repeat safety. It adds valuable behavioral context: only open-access lists are queried, non-answering lists carry an error and are not counted as clean, and the return structure is described. This goes beyond annotations and gives the agent a clear expectation of edge cases.

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 organized into a clear opening statement, Args, Returns, and an Example. It is thorough but not redundant; every sentence adds information. The only slight redundancy is the return structure being partially explained in both the description and the schema, but it is not excessive.

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 two parameters and a structured output, the description is complete: it defines the purpose, scope of lists, input types, output format, and return payload, including error handling for unresponsive lists. The example clarifies invocation. Nothing an agent needs to call it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100% with descriptions for both query and response_format. The description reinforces this by clarifying query accepts IPv4 or domain, and response_format has a default and two enum values. It also adds an example usage that demonstrates parameter invocation, exceeding the baseline set by 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 action ('Check whether...') on a specific resource ('IPv4 address or a domain's A records') against DNSBLs, and distinguishes it by naming the exact lists included and excluded. This clearly differentiates it from sibling tools like spf_check or dmarc_check, which target other email authentication mechanisms.

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 makes the intended use clear: checking DNSBL status. It also provides an explicit exclusion of Spamhaus and Barracuda due to public-resolver refusal, giving the agent context on limitations. However, it does not explicitly name alternative sibling tools for other email checks, though the purpose is distinct enough that this is a minor gap.

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

caa_checkCAA Record CheckA
Read-onlyIdempotent

Check a domain's CAA (Certification Authority Authorization) records — which CAs are allowed to issue TLS certificates for it. Absence means any CA may issue.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { found, issue[], issuewild[], iodef[] }.

Example: "Which CAs can issue certs for google.com?" -> caa_check(domain="google.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to query, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
iodefYes
issueYes
domainYes
issuewildYes

TDQS

A4.1/5.0
Behavior3/5

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

Annotations already convey that the tool is read-only, idempotent, and non-destructive. The description adds useful domain context about CAA absence and lists return fields, but it does not disclose operational behavior such as live DNS query mechanics, caching, or resolver dependence. Given the annotation coverage, this is adequate but not exceptionally rich.

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 front-loads the core purpose, includes a one-line semantic clarification, then presents Args, Returns, and an Example in a compact, scannable structure. Every line earns its place and there is 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?

For a simple two-parameter, read-only DNS lookup with 100% schema coverage and an output schema, the description is complete. It states the operation, explains the meaning of absent results, specifies the return shape, and provides an example mapping to the correct argument.

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 documents both parameters fully, including the enum and default for response_format, so the baseline is 3. The description restates the arguments and gives a helpful example, but adds no new type, constraint, or semantic detail beyond what the schema already provides.

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 a domain's CAA ... records'. It also explains the real-world meaning ('which CAs are allowed to issue TLS certificates'), making the tool's purpose unambiguous and clearly distinct from sibling DNS/email 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 gives clear context for when to use the tool, including the important semantic that absence of CAA records means any CA may issue, and provides a natural-language example mapping a user query to the correct call. It does not explicitly name alternative tools or state when not to use it, but the intended use is strongly implied.

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

dkim_checkDKIM Record CheckA
Read-onlyIdempotent

Look up DKIM public keys at ._domainkey.. Because DKIM selectors are arbitrary and undiscoverable, you should pass the selector(s) your mail provider uses for a definitive answer; otherwise a curated list of common selectors is probed and a miss is inconclusive.

Args:

  • domain (string): the domain to check.

  • selectors (string[], optional): DKIM selectors to probe.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { any_found, probed_selectors, selectors[{selector, found, record, key_type}], findings[] }.

Examples:

  • "Does acme.com publish a DKIM key for selector 'google'?" -> dkim_check(domain="acme.com", selectors=["google"])

  • "Find any DKIM keys for acme.com" -> dkim_check(domain="acme.com")

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
selectorsNoDKIM selectors to check (e.g. ['google']). If omitted, common provider selectors are probed — absence is then inconclusive.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainYes
findingsYes
any_foundYes
selectorsYes
probed_selectorsYes

TDQS

A4.7/5.0
Behavior4/5

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

No contradictions with annotations (readOnly, openWorld, idempotent, non-destructive). The description adds essential behavioral context: the probing of a curated selector list, the inconclusive nature when selectors are omitted, and the return structure. However, since annotations already indicate it's read-only and non-destructive, the extra transparency credit is capped; still, the details on selector behavior are valuable.

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 well-structured: a lead sentence stating the action, a clear conditional on selectors, a concise Args section mirroring the schema, a Returns section, and two practical examples. Every sentence adds value, no redundancy, and key caveats 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?

Given the tool's moderate complexity, full schema coverage, annotations, and an output schema that documents the return structure, the description covers all essential aspects: what it does, how to use it, edge cases (inconclusive results), and example invocations. The agent has enough to call it correctly without missing information.

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 describes each parameter. The description reinforces the meaning of domain and selectors, and clarifies the response_format choices. Since schema does the heavy lifting, baseline is 3, but the description adds the critical insight that selectors are undiscoverable and omission is inconclusive, which is a meaningful semantic enhancement.

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 explicitly states it looks up DKIM public keys at a specific DNS naming pattern, distinguishes it from siblings by focusing on DKIM selectors, and includes concrete example queries. This is a clear, specific purpose that an agent can act on.

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 advises when to pass selectors (for a definitive answer) and warns that omitting them yields inconclusive results. It also provides two examples that illustrate the two usage modes. This gives clear, operational guidance beyond the schema.

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

dmarc_checkDMARC Record CheckA
Read-onlyIdempotent

Fetch and parse a domain's DMARC record (_dmarc.). Reports the policy (p=), subdomain policy (sp=), reporting addresses (rua/ruf), pct and alignment (aspf/adkim), and warns on monitor-only or partial deployments.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { found, record, policy, tags{}, findings[] }.

Example: "What is paypal.com's DMARC policy?" -> dmarc_check(domain="paypal.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
tagsYes
foundYes
domainYes
policyNo
recordNo
findingsYes

TDQS

A4/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnlyHint, idempotentHint, openWorldHint, non-destructive), so the bar is lower. The description adds real behavioral context beyond that: it warns on monitor-only or partial deployments and exposes a findings[] array, signaling that a present-but-permissive record is a meaningful result rather than an error. No rate-limit or auth notes, but for this tool the annotations plus warning behavior are sufficient.

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 compact and front-loads the core purpose in the first sentence, and the example earns its place. However, the Args bullets largely duplicate the schema descriptions, and the Returns line overlaps with the existing output schema — two sections that repeat structured data rather than adding 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?

For a low-complexity, read-only DNS tool with full schema coverage, rich annotations, and an output schema, the description is nearly complete: it states the query target, the parsed fields, the warning behaviors, the return shape, and a usage example. The only minor gap is that it never spells out what happens when no DMARC record exists, though the 'found' field implies it.

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 documents both parameters fully (coverage 100%), including the domain example and the response_format enum/default. The Args block in the description essentially restates the schema ('domain to check', 'output format') without adding deeper meaning such as expected inputs or edge-case rules, so it adds no real value beyond the structured fields.

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 ('Fetch and parse a domain's DMARC record (_dmarc.<domain>)') and enumerates the exact fields it extracts (p=, sp=, rua/ruf, pct, aspf/adkim). This clearly distinguishes it from siblings like spf_check, dkim_check, and the generic dns_lookup without needing to open any schema.

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 example ('What is paypal.com's DMARC policy?') gives a concrete trigger condition for the tool, and the warning behavior ('warns on monitor-only or partial deployments') hints at when the tool is useful during an audit. It does not explicitly mention exclusions or call out when a sibling like email_auth_audit or dns_lookup would be the better choice, so it stops one step short of a 5.

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

dns_lookupDNS LookupA
Read-onlyIdempotent

Resolve all common DNS record types (A, AAAA, CNAME, MX, NS, TXT, SOA) for a domain in one call, using public resolvers (Cloudflare/Google/Quad9).

Args:

  • domain (string): the domain to query, e.g. "example.com".

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: a map of record type -> list of records. Each record has { type, host, value, priority? }.

Examples:

  • "What are the MX records for stripe.com?" -> dns_lookup(domain="stripe.com")

  • Use ssl_certificate for TLS details, whois_lookup for registration data.

Errors: returns an error if the domain is malformed or has no resolvable records.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to query, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainYes
recordsYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already provide readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the bar is lower. The description adds that it uses public resolvers (Cloudflare/Google/Quad9), the return format (map of record type to list of records with fields), and error behavior, which are valuable disclosures 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 well-structured: starts with purpose, then Args, Returns, Examples, Errors. It is detailed but not bloated; every section adds value. The only minor issue is the mention of error handling which could be inferred, but it is useful.

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?

It covers all key aspects: what it does, parameters, return structure, examples, alternatives, and error behavior. With an output schema present, return format doesn't need to be exhaustive. Missing details like rate limits are irrelevant given readOnlyHint. The description is complete for correct 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?

Schema coverage is 100%, so the schema clearly documents both domain and response_format. The description adds context about the format values ('markdown' for human-readable, 'json' for full structured payload) but this mostly repeats schema. However, it does clarify that domain is for querying and includes an example, adding marginal value.

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 resolves all common DNS record types for a domain in one call. It lists specific record types and unique value proposition (all-in-one) that distinguishes it from siblings like mx_lookup or dnssec_check.

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 includes usage examples and explicitly mentions alternatives: 'Use ssl_certificate for TLS details, whois_lookup for registration data.' It does not explicitly state when not to use the tool, but the examples and alternatives provide clear context.

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

dns_propagationDNS Propagation CheckA
Read-onlyIdempotent

Compare a domain's DNS records across multiple public resolvers worldwide (Cloudflare, Google, Quad9, OpenDNS, AdGuard) to see whether a change has propagated.

Args:

  • domain (string): the domain to check.

  • type ('A'|'AAAA'|'CNAME'|'MX'|'NS'|'TXT'): record type (default 'A').

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { type, consistent, resolvers[{name, server, values[], error}] }.

Example: "Has the A record for example.com propagated?" -> dns_propagation(domain="example.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoRecord type (default 'A').A
domainYesDomain to check.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
typeYes
domainYes
resolversYes
consistentYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and non-destructive behaviorabb. The description adds valuable behavioral context beyond that: it queries multiple named public resolvers, aggregates responses, and returns a consistency verdict plus per-resolver values/errors. This is more than a bare mutation/read label.

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 well structured and front-loaded with the key action, followed by a compact Args list, a return shape, and a concrete example. No sentence is wasted, and the example is practical for an agent deciding how to invoke the 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?

For a read-only, idempotent lookup tool with one required parameter spelled out in the schema.not, the description is complete: it explains the global multi-resolver behavior, lists all parameters with defaults, and shows the response shape. An agent has everything needed 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 description coverage is 100%, and the schema already defines domain, type, and response_format with enums, defaults, and descriptions. The description repeats these details and adds a useful example mapping a natural-language question to arguments, but it does not add meaningful 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?

The description opens with a specific verb-resource pair: 'Compare a domain's DNS records across multiple public resolvers worldwide.' It lists concrete resolvers and names the goal ('to see whether a change has propagated'), which clearly differentiates it from siblings like dns_lookup or mx_lookup.

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 context for when to use the tool: whenever a change's propagation status across resolvers is in question. It does not explicitly name alternative tools or state when not to use it, so it stops short of a full 5, 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.

dnssec_checkDNSSEC CheckA
Read-onlyIdempotent

Check whether a domain is protected by DNSSEC. Queries DS and DNSKEY records over DNS-over-HTTPS and reads the resolver's Authenticated Data (AD) flag to confirm the chain of trust validates.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { enabled, validated, ds_records, dnskey_records, findings[] }.

Example: "Is cloudflare.com DNSSEC-signed?" -> dnssec_check(domain="cloudflare.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainYes
enabledYes
findingsYes
validatedYes
ds_recordsYes
dnskey_recordsYes

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already establish read-only, idempotent, non-destructive behavior; the description adds genuine behavioral detail on top by explaining that it queries DS/DNSKEY records over DNS-over-HTTPS and inspects the resolver's AD flag to validate chain of trust. It is transparent about mechanism, though it does not discuss failure modes such as network errors or non-existent domains.

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 well structured and front-loaded: purpose first, then args, return shape, and an example. It is a bit long relative to its simple two-parameter surface, and the Args block repeats information already in the input schema, but every part is coherent and useful rather than rambling.

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?

Given only two parameters, rich annotations, and a declared output schema, the description covers the necessary ground: what it does, how it works, what it returns, and how it should be called. Missing edge-case details like what happens for unsigned domains or resolver timeouts are minor in this 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?

Both parameters are already fully documented by the input schema (100% coverage), including domain length and response_format enum/default. The description restates the parameters in prose and adds an example, but does not materially extend the schema's semantic 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 clearly identifies what is checked — whether a domain is DNSSEC-protected — and distinguishes the tool from nearby DNS/mail siblings by naming the concrete mechanism (DS and DNSKEY records, AD flag via DNS-over-HTTPS). The example query reinforces the exact use case, leaving no ambiguity.

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

Usage Guidelines3/5

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

The description gives a clean implied usage context ('Check whether a domain is protected by DNSSEC') and a worked example, but it never says when *not* to use it or which sibling tools to prefer for alternative checks like SPF, DMARC, or plain DNS lookups. Usage guidance is therefore adequate but implicit rather than explicit.

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

email_auth_auditEmail Authentication AuditA
Read-onlyIdempotent

Headline tool. Audits a domain's email-authentication posture in one call — SPF, DKIM, DMARC and MX — then returns a 0–100 score, an A–F grade and a prioritised list of fixes. Use this first; reach for the per-record tools (spf_check, dmarc_check, dkim_check) only when you need the full detail of one mechanism.

Args:

  • domain (string): the domain to audit.

  • dkim_selectors (string[], optional): DKIM selectors to probe. If omitted, common provider selectors are tried (absence is then inconclusive).

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns (JSON): { "domain": string, "grade": "A".."F", "score": number, // 0-100 "has_mx": boolean, "mx_hosts": string[], "spf": { found, record, all_qualifier, lookup_count, exceeds_lookup_limit, findings[] }, "dmarc":{ found, policy, tags, findings[] }, "dkim": { any_found, selectors[], findings[] }, "top_recommendations": string[] }

Examples:

  • "Is example.com protected against email spoofing?" -> email_auth_audit(domain="example.com")

  • "Audit acme.com, our DKIM selector is 'k1'" -> email_auth_audit(domain="acme.com", dkim_selectors=["k1"])

Errors: returns an error only if the domain is malformed; missing records are reported as findings, not errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to audit, e.g. 'example.com'.
dkim_selectorsNoOptional DKIM selectors to check (e.g. ['google','selector1']). If omitted, a list of common provider selectors is probed.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
spfYes
dkimYes
dmarcYes
gradeYes
scoreYes
domainYes
has_mxYes
mx_hostsYes
top_recommendationsYes

TDQS

A5/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 valuable behavioral context beyond that: it explains the return format (score, grade, fixes), the error behavior (only malformed domain errors; missing records are findings), and the nuance that omitting dkim_selectors makes absence inconclusive. This is rich disclosure that helps an agent interpret results correctly. 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?

The description is long but every section earns its place: headline, args, returns, examples, errors. It is front-loaded with the primary purpose and use-first guidance. The structure is scannable and free of redundancy, making it efficient despite its length.

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?

The tool is complex (multiple mechanisms, optional selectors, format selection, return payload), and the description covers all aspects: parameter behaviors, return structure (full JSON shape), examples for common use cases, and error semantics. Given the schema and annotations, nothing an agent needs to invoke this tool correctly is missing.

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%, so the baseline is 3, but the description adds substantial meaning: it clarifies the optionality of dkim_selectors, the default behavior when omitted (common selectors probed, inconclusive absence), and the response_format semantics (markdown vs json). The examples further illustrate parameter usage. This goes well beyond what the schema alone 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 ('Audits') and resource ('a domain's email-authentication posture'), enumerating the mechanisms (SPF, DKIM, DMARC, MX) and the deliverable (score, grade, fixes). It explicitly differentiates from the sibling per-record tools by naming them and indicating when to use them instead, so an agent can immediately tell this is the aggregate/headline tool.

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 gives explicit guidance: 'Use this first' and 'reach for the per-record tools only when you need the full detail of one mechanism.' It also provides concrete examples mapping natural-language queries to tool invocations, leaving no ambiguity about when to select this tool over alternatives.

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

http_security_headersHTTP Security HeadersA
Read-onlyIdempotent

Fetch a URL and grade its HTTP security headers (HSTS, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, COOP). Returns a 0–100 score, an A–F grade, and per-header notes.

Args:

  • url (string): URL or host to check (scheme defaults to https://).

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { url, final_url, status, grade, score, checks[{header, present, value, note}], missing[] }.

Example: "Grade the security headers on https://news.ycombinator.com" -> http_security_headers(url="https://news.ycombinator.com"). Errors: returns an error if the URL is invalid or the host is unreachable.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL or host to check, e.g. 'https://example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYes
gradeYes
scoreYes
checksYes
statusYes
missingYes
final_urlYes

TDQS

A4.4/5.0
Behavior4/5

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

The annotations already declare the operation read-only, idempotent, non-destructive, and open-world, so the description carries a lighter burden here. Beyond those hints, the description adds genuinely useful behavior details: scheme defaults to https, the response includes final_url, and invalid or unreachable hosts produce errors. It does not discuss rate limits or network cost, but those are not essential for this kind of lookup tool.

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 its purpose, then organized into Args, Returns, Example, and Errors sections. There is no filler, and every sentence contributes operational information that an agent needs to call the tool correctly.

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?

Given that this is a read-only, single-input network check with a clear output schema, the description covers the important context: inputs, defaults, output shape, example usage, and error conditions. It does not mention rate limits or authentication, but nothing in the tool's design suggests those are needed for a successful call.

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 has full parameter descriptions, so the baseline is 3. The description adds value beyond the schema by clarifying that 'url' accepts a bare host and defaults to https, and by showing a full invocation example. This makes correct parameter selection more obvious than the schema alone.

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: 'Fetch a URL and grade its HTTP security headers,' and enumerates the exact headers covered (HSTS, CSP, X-Content-Type-Options, etc.). This clearly distinguishes it from the sibling DNS, email, and TLS tools even without explicitly naming 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?

The description gives clear context for when the tool is appropriate—checking HTTP security headers on a URL—and includes a concrete example of how an agent should invoke it. It does not explicitly list sibling alternatives or say when not to use it, so it stops short of the highest tier of usage guidance.

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

ip_geolocationIP GeolocationA
Read-onlyIdempotent

Geolocate an IP address (country, region, city, coordinates, time zone) using the offline DB-IP Lite database, plus its reverse-DNS hostname. No external API.

Args:

  • ip (string): IPv4 or IPv6 address.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { ip, country_iso, country_name, region, city, latitude, longitude, time_zone, hostname }.

Example: "Where is 151.101.1.69 located?" -> ip_geolocation(ip="151.101.1.69"). Note: geolocation is approximate (city-level at best) and offline data may lag reality. The time zone is estimated from the coordinates. Data: IP Geolocation by DB-IP (https://db-ip.com), licensed CC BY 4.0 — credit it when showing these results.

ParametersJSON Schema
NameRequiredDescriptionDefault
ipYesIPv4 or IPv6 address, e.g. '1.1.1.1'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
ipYes
cityNo
regionNo
hostnameNo
latitudeNo
longitudeNo
time_zoneNo
country_isoNo
country_nameNo

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, covering the safety profile. The description adds valuable behavioral context beyond that: geolocation is approximate, data may lag reality, time zone is estimated from coordinates, and licensing attribution is required. This goes beyond the annotations and enriches the agent's understanding.

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 well-structured and front-loaded with the main purpose, followed by clearly labeled sections (Args, Returns, Example, Note, Data). Every sentence earns its place: the approximation note is critical, and the licensing instruction is essential for compliance. It is appropriately sized without verbosity.

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 simple two-parameter tool with an output schema, the description is complete. It includes the return structure (ip, country_iso, etc.), a concrete example, limitations (approximate, data lag), and licensing. An agent has all necessary information to invoke the tool correctly and interpret the results.

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% for both parameters (ip and response_format), including types, defaults, and examples. The description's Args section merely restates these parameters without adding new semantic meaning. Per the baseline rule for full schema coverage, a score of 3 is appropriate; the description does not compensate with extra parameter insights.

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 ('Geolocate'), a resource (IP address), and enumerates the output fields (country, region, city, coordinates, time zone) plus the reverse-DNS hostname. It also distinguishes the tool by noting it uses an offline DB-IP Lite database with no external API, which separates it from the sibling DNS/email tools. This is a clear, unambiguous purpose.

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 makes the tool's usage obvious through its stated purpose and notes 'No external API' implying it is fast and offline. However, it does not explicitly name alternative tools or provide conditions for when to use this tool over siblings. Since the function is so specific, an agent would naturally select it for IP geolocation, but explicit guidance on alternatives is missing.

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

mta_sts_checkMTA-STS CheckA
Read-onlyIdempotent

Check a domain's MTA-STS deployment: the _mta-sts TXT record AND the policy file at https://mta-sts./.well-known/mta-sts.txt. Reports the enforcement mode (enforce/testing/none) and the listed MX hosts. MTA-STS forces TLS for inbound SMTP and blocks downgrade attacks.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { dns_record_found, policy_found, mode, policy{}, findings[] }.

Example: "Does gmail.com enforce MTA-STS?" -> mta_sts_check(domain="gmail.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
modeNo
domainYes
policyNo
findingsYes
policy_foundYes
dns_record_foundYes

TDQS

A3.9/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, so the safety profile is covered. The description adds behavioral context by explaining what MTA-STS does (forces TLS, blocks downgrade attacks) and what the check entails (TXT record + policy fetch). It does not contradict 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 well-structured: a concise opening sentence, an Args section, and a Returns line. It is front-loaded with the core purpose and includes a helpful example. Slightly wordy in the middle but overall efficient.

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 tool has an output schema and annotations cover safety. The description still provides a brief return shape ({ dns_record_found, policy_found, mode, policy{}, findings[] }) and an example invocation, which is sufficient for an agent to call it correctly. Minor gap: no mention of timeouts or DNS propagation, but not essential given the annotations.

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% – both domain and response_format have clear descriptions, including enum values and defaults. The description's Args section essentially repeats schema info without adding new semantics. Baseline of 3 applies since the schema carries the parameter documentation.

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 domain's MTA-STS deployment, specifying both the TXT record and policy file, and what it reports (enforcement mode, MX hosts). It is a specific verb+resource and distinct from siblings like spf_check or dmarc_check, which target different protocols.

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

Usage Guidelines3/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 an example, but it does not explicitly contrast it with alternatives like email_auth_audit or mention when NOT to use it. Usage context is implied (when you need MTA-STS status) but no exclusions or sibling differentiation are stated.

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

mx_lookupMX LookupA
Read-onlyIdempotent

Look up a domain's mail servers (MX records) with priority and the IPs they resolve to.

Args:

  • domain (string): the domain to query.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: array of { exchange, priority, ips[] }.

Example: "What are the mail servers for github.com?" -> mx_lookup(domain="github.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to query, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
domainYes
recordsYes

TDQS

A3.8/5.0
Behavior4/5

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

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds useful behavior beyond that: it converts MX lookups into a structured result of exchange, priority, and resolved ips[]. It does not mention external network dependency or failure modes, but for a simple read-only DNS lookup this is not a serious gap and there is no contradiction with the annotations.

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

Conciseness4/5

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

The description is compact and front-loaded with the purpose sentence, followed by concise Args, Returns, and Example sections. The Args list somewhat duplicates the schema, but the redundancy is minimal and the overall structure is easy for an agent to scan.

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 full schema coverage, an output schema, and read-only annotations, this description is complete: it explains the query target, the output format choices, the return shape, and provides a concrete example. Nothing essential to selecting or invoking 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%: both domain and response_format are documented in the schema. The description's Args section largely restates those schema definitions, and the example only reinforces the domain parameter without adding meaning beyond what the schema already provides.

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

Purpose4/5

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

The opening sentence states a specific verb and resource: 'Look up a domain's mail servers (MX records) with priority and the IPs they resolve to.' This clearly identifies what the tool does and distinguishes it from the other DNS/email sibling tools by naming the exact record type and outputs, though it does not explicitly contrast it with siblings.

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

Usage Guidelines3/5

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

The example 'What are the mail servers for github.com?' implies when the tool is appropriate, but the description gives no explicit when-to-use or when-not-to-use guidance, nor does it point to alternatives such as dns_lookup for general DNS record queries. The usage context is clear but left to inference.

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

reverse_dnsReverse DNS (PTR)A
Read-onlyIdempotent

Resolve the PTR (reverse DNS) records for an IP address — the hostname(s) the IP maps back to.

Args:

  • ip (string): IPv4 or IPv6 address.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { ip, hostnames: string[] }.

Example: "What hostname does 8.8.8.8 reverse to?" -> reverse_dns(ip="8.8.8.8"). Errors: returns an error if the IP is invalid or has no PTR record.

ParametersJSON Schema
NameRequiredDescriptionDefault
ipYesIPv4 or IPv6 address, e.g. '1.1.1.1'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
ipYes
hostnamesYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it returns an error for invalid IPs or missing PTR records, and it documents the return shape ({ ip, hostnames: string[] }). 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 compact and well-structured: a one-sentence purpose, a short Args list, a Returns line, an example, and an Errors line. Every sentence earns its place, and the most important information (what it does) is 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?

The tool is simple (2 params, 1 required, no nested objects) and has an output schema. The description covers purpose, parameters, return shape, example usage, and error behavior. Nothing an agent needs to call it correctly is missing.

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

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 both parameters. The description adds a brief mention of the ip parameter in the Args section and the default for response_format, but it does not add significant new meaning beyond the schema. 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 states a specific verb ('Resolve'), a specific resource ('PTR records for an IP address'), and clarifies the output ('hostname(s) the IP maps back to'). It distinguishes itself from sibling tools like dns_lookup and mx_lookup by focusing on reverse DNS. The example query further anchors the purpose.

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 a clear example of when to use it ('What hostname does 8.8.8.8 reverse to?') and implies it is for reverse lookups, which differentiates it from forward DNS tools. It does not explicitly name alternatives or state when not to use it, but the context signals and sibling list make the use case clear.

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

spf_checkSPF Record CheckA
Read-onlyIdempotent

Fetch and analyse a domain's SPF record. Detects: missing/multiple records, the trailing 'all' qualifier (+all/?all/~all/-all), and counts DNS-querying terms recursively against the RFC 7208 limit of 10.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { found, record, multiple_records, all_qualifier, lookup_count, exceeds_lookup_limit, findings[] }.

Example: "Does sendgrid.net's SPF exceed the 10-lookup limit?" -> spf_check(domain="sendgrid.net").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
domainYes
recordNo
findingsYes
lookup_countYes
all_qualifierNo
multiple_recordsYes
exceeds_lookup_limitYes

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare the tool read-only and idempotent, and the description adds meaningful behavioral detail beyond that: it recursively counts DNS-querying terms against the RFC 7208 limit, detects qualifier variants, and exposes a structured return payload. This gives the agent a clear model of what the tool computes.

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 and well-organized: a front-loaded summary, a small Args block, a Returns line, and a single illustrative example. Every section adds value and there is 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?

Given the tool's complexity, the description covers the analysis logic, the return shape, the parameters, and a usage example. With read-only/idempotent annotations and an output schema already present, nothing essential is missing for correct 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?

Schema description coverage is 100%, so the schema already documents both parameters and the response_format default. The description repeats these details and adds an example, but provides no substantive semantic information beyond what the schema already offers; 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 opens with a specific verb and resource: 'Fetch and analyse a domain's SPF record.' It then enumerates the concrete detections (missing/multiple records, trailing 'all' qualifier, RFC 7208 lookup limit), which clearly distinguishes it from sibling tools like dmarc_check and dkim_check.

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 context for when the tool is appropriate and includes a concrete example question ('Does sendgrid.net's SPF exceed the 10-lookup limit?'). It does not explicitly name alternatives or exclusion conditions, so it stops short of a 5.

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

ssl_certificateSSL/TLS Certificate InspectorA
Read-onlyIdempotent

Inspect the TLS certificate served by a host: issuer, subject, validity window, days-until-expiry, SANs, serial and SHA-256 fingerprint. Flags expired or soon-to-expire certificates.

Args:

  • domain (string): host to connect to.

  • port (number): TLS port (default 443).

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: certificate fields plus { days_until_expiry, expired, expires_soon, trusted, hostname_matches, authorization_error }. An untrusted certificate (self-signed, unknown root, wrong host) is still inspected and reported, never silently passed.

Example: "When does github.com's certificate expire?" -> ssl_certificate(domain="github.com"). Errors: returns an error if the host is unreachable or serves no certificate.

ParametersJSON Schema
NameRequiredDescriptionDefault
portNoTLS port (default 443).
domainYesDomain (or host) to inspect, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
hostYes
portYes
expiredYes
trustedYes
valid_toNo
valid_fromNo
expires_soonYes
serial_numberNo
hostname_matchesYes
days_until_expiryNo
subject_alt_namesYes
fingerprint_sha256No
issuer_common_nameNo
authorization_errorNo
issuer_organizationNo
subject_common_nameNo

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint. The description goes further by disclosing important behavior: untrusted certificates are still inspected and reported, never silently passed, and unreachable hosts or missing certificates produce errors. This meaningfully informs the agent 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 cleanly organized into Args, Returns, Example, and Errors sections with no filler. Every block earns its place, and the minor duplication of parameter wording does not harm readability.

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?

It covers parameters, return fields, a concrete example, error behavior, and the edge case of untrusted certificates. With an output schema present and annotations covering the safety profile, nothing needed to invoke this 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 domain, port, and response_format are already fully documented in the schema. The description's Args block mostly restates the schema rather than adding new semantic detail, 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 'Inspect the TLS certificate served by a host' – a specific verb plus a concrete resource and even lists the exact certificate fields. It is immediately recognizable as a certificate inspection tool and is distinct from the email, DNS, and HTTP-header 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 Guidelines4/5

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

It provides a clear, actionable example ('When does github.com's certificate expire?') that demonstrates the intended use case. It does not explicitly name alternatives or say when not to use this tool, so it stops short of full routing guidance.

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

tls_rpt_checkTLS-RPT CheckA
Read-onlyIdempotent

Check a domain's TLS-RPT record (_smtp._tls. TXT). TLS-RPT lets you receive reports about TLS delivery failures to your domain.

Args:

  • domain (string): the domain to check.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { found, record, findings[] }.

Example: "Does microsoft.com publish TLS-RPT?" -> tls_rpt_check(domain="microsoft.com").

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to check, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
domainYes
recordNo
findingsYes

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already cover readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds the return-shape note and a usage example, but does not add behavioral details such as DNS lookups, timeout behavior, or error conditions. The description is consistent with annotations and adds some practical value.

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 well-organized and front-loaded with purpose, followed by argument and return details. The Args/Return sections add some redundancy with the schema, but they are brief and the example is useful.

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?

For a low-complexity read-only lookup tool with full schema coverage and annotations, the description is largely complete. It could be slightly stronger with a note about when to use this versus the broader email_auth_audit, but nothing important is missing for directly calling the tool.

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 the schema: domain and response_format semantics are already detailed in the schema. The example invocation does add a tiny bit of practical guidance, but not enough to move 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 states a specific verb and resource: 'Check a domain's TLS-RPT record (_smtp._tls.<domain> TXT)'. It identifies the exact record type and purpose, making it easily distinguishable from sibling tools like dmarc_check, spf_check, and dkim_check.

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 context: TLS-RPT is for receiving reports about TLS delivery failures, so an agent can infer when this tool is relevant. It does not explicitly name alternatives or exclusions, but the context is clear enough for a single-purpose DNS check.

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

whois_lookupWHOIS LookupA
Read-onlyIdempotent

Look up domain registration data over the raw WHOIS protocol (port 43): registrar, creation/update/expiry dates, name servers and domain status. Resolves the correct WHOIS server via IANA and follows registrar referrals. No API key.

Args:

  • domain (string): the domain to look up.

  • response_format ('markdown' | 'json'): output format (default 'markdown'). JSON includes the raw WHOIS text.

Returns: { domain, registrar, created, updated, expires, name_servers[], status[], whois_server }.

Example: "Who is the registrar for openai.com and when does it expire?" -> whois_lookup(domain="openai.com"). Errors: returns an error if no WHOIS server answers (some ccTLDs restrict or rate-limit WHOIS).

ParametersJSON Schema
NameRequiredDescriptionDefault
domainYesDomain to look up, e.g. 'example.com'.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
rawYes
domainYes
statusYes
createdNo
expiresNo
updatedNo
registrarNo
name_serversYes
whois_serverNo
registrant_orgNo

TDQS

A4.1/5.0
Behavior4/5

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

Annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false) already cover the safety profile, lowering the bar. The description genuinely adds context beyond the annotations: IANA server resolution and registrar referral following, port 43 mechanics, no-auth requirement, and an honest error disclosure about ccTLD restrictions and rate limits. It stops short of 5 because it doesn't mention potential slowness of referral chases or timeouts.

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 opening sentence is strong and front-loaded, but the description runs roughly five paragraphs and the Args/Returns sections largely duplicate parameter and output descriptions already present in the input schema and output schema. The unique contributions (referral resolution, error caveat, example) are edited and placed well, but duplicated content prevents a higher score.

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 2-parameter, 1-required-parametered tool with full schema description coverage, rich annotations, an output schema, and an error disclaimer, the description covers everything an agent needs to invoke it correctly: protocol behavior, failure outcomes, output format selection, and a natural-language trigger example. Nothing material 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 both parameters are fully described in the input schema, so the baseline of 3 applies. The description adds only marginal value: it clarifies that JSON output embeds the raw WHOIS text, which is a slight semantic addition over the schema's 'full structured payload.'

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 action and resource — 'Look up domain registration data over the raw WHOIS protocol (port 43)' — and enumerates the exact output dimensions (registrar, dates, name servers, status). It differentiates itself from DNS/email-security siblings (dns_lookup, spf_check, ssl_certificate) by being explicitly about registration data over WHOIS, so an agent can distinguish it without opening sibling schemas.

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 example ('Who is the registrar for openai.com and when does it expire?' -> whois_lookup(domain="openai.com")) gives a clear concrete trigger, and the 'No API key' note plus the ccTLD restriction caveat set expectations. It lacks an explicit when-not-to-use or named alternative routes (e.g., 'use dns_lookup for records'), so it stops short of a 5.

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. 19 tool updatesv1.2.1
    • Changedanalyze_email_headers5 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / headers / maxLength
        Added value: +200000
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / fields / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedbimi_check4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedblacklist_check6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / query / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / results / items / properties / hits / items / properties / error
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • changedOutput schema / properties / results / items / properties / hits / items / required
        Previous value: -[
        -  "list",
        -  "zone",
        -  "listed",
        -  "reason"
        -]New value: +[
        +  "list",
        +  "zone",
        +  "listed",
        +  "reason",
        +  "error"
        +]
    • Changedcaa_check4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddkim_check6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • addedInput schema / properties / selectors / items / maxLength
        Added value: +63
      • addedInput schema / properties / selectors / maxItems
        Added value: +50
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddmarc_check5 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / tags / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changeddns_lookup6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / records / additionalProperties / items / properties / extra / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / records / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changeddns_propagation4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddnssec_check4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedemail_auth_audit17 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / dkim_selectors / items / maxLength
        Added value: +63
      • addedInput schema / properties / dkim_selectors / maxItems
        Added value: +50
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedOutput schema / properties / dkim / properties / findings / items / $ref
        Removed value: -"#/properties/spf/properties/findings/items"
      • addedOutput schema / properties / dkim / properties / findings / items / additionalProperties
        Added value: +false
      • addedOutput schema / properties / dkim / properties / findings / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "severity": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / dkim / properties / findings / items / required
        Added value: +[
        +  "severity",
        +  "message"
        +]
      • addedOutput schema / properties / dkim / properties / findings / items / type
        Added value: +"object"
      • removedOutput schema / properties / dmarc / properties / findings / items / $ref
        Removed value: -"#/properties/spf/properties/findings/items"
      • addedOutput schema / properties / dmarc / properties / findings / items / additionalProperties
        Added value: +false
      • addedOutput schema / properties / dmarc / properties / findings / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "severity": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / dmarc / properties / findings / items / required
        Added value: +[
        +  "severity",
        +  "message"
        +]
      • addedOutput schema / properties / dmarc / properties / findings / items / type
        Added value: +"object"
      • addedOutput schema / properties / dmarc / properties / tags / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedhttp_security_headers4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / url / maxLength
        Added value: +2048
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedip_geolocation4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / ip / maxLength
        Added value: +45
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedmta_sts_check5 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / policy / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedmx_lookup4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedreverse_dns4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / ip / maxLength
        Added value: +45
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedspf_check4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedssl_certificate8 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / authorization_error
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / hostname_matches
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / trusted
        Added value: +{
        +  "type": "boolean"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "host",
        -  "port",
        -  "subject_alt_names",
        -  "expired",
        -  "expires_soon"
        -]New value: +[
        +  "host",
        +  "port",
        +  "subject_alt_names",
        +  "expired",
        +  "expires_soon",
        +  "trusted",
        +  "hostname_matches"
        +]
    • Changedtls_rpt_check4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedwhois_lookup4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / maxLength
        Added value: +253
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  2. 19 tool updatesv1.0.0
    • First observedanalyze_email_headers
    • First observedbimi_check
    • First observedblacklist_check
    • First observedcaa_check
    • First observeddkim_check
    • First observeddmarc_check
    • First observeddns_lookup
    • First observeddns_propagation
    • First observeddnssec_check
    • First observedemail_auth_audit
    • First observedhttp_security_headers
    • First observedip_geolocation
    • First observedmta_sts_check
    • First observedmx_lookup
    • First observedreverse_dns
    • First observedspf_check
    • First observedssl_certificate
    • First observedtls_rpt_check
    • First observedwhois_lookup

TDQS

A4.1/5.0

Scored across 19 tools

Disambiguation4/5

Each tool targets a distinct security check (SPF, DMARC, DKIM, MTA-STS, TLS-RPT, BIMI, DNSSEC, CAA, etc.), and the aggregate email_auth_audit is explicitly positioned as the entry point versus the per-record detail tools. Minor overlap exists between dns_lookup and mx_lookup, but descriptions clarify their different purposes.

Naming Consistency4/5

Names are consistently snake_case and mostly follow a resource_check or resource_lookup pattern, which is predictable. A few deviations like email_auth_audit, reverse_dns, http_security_headers, and analyze_email_headers break the strict pattern but remain readable and recognizable.

Tool Count3/5

19 tools is on the heavy side and exceeds the comfortable 15-tool threshold, though the breadth is somewhat justified by covering email authentication, DNS, TLS, web headers, WHOIS, and blacklists. It is not excessive enough to feel chaotic, but it is borderline for an MCP server.

Completeness5/5

For a read-only domain security auditor, the surface is remarkably complete: email authentication, DNSSEC/CAA, TLS certificates, HTTP security headers, WHOIS, blacklists, and email header forensics are all covered. The aggregate audit plus per-record detail tools form a coherent workflow with no major dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables DNS and email security analysis through passive and active scanning capabilities. Provides comprehensive domain security checks including SPF, DMARC, DNSSEC validation, MX record analysis, and SMTP connectivity testing.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Domain security reconnaissance for AI agents — 13 tools (DNS+DNSSEC, SSL/TLS, HTTP security headers, SPF/DKIM/DMARC email auth, port scan, ASN, RDAP/WHOIS) plus a one-shot security_scan returning a 0–100 Health Score (A–F). Free, no API key.
    15
    70 npm
    1
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Provides email validation and domain configuration auditing tools for AI assistants, enabling single address checks, bulk list cleaning, SPF verification, and full mail setup grading (A-F) with actionable fixes.
    4
    36 npm
    MIT