Skip to content
Inspect My DNS

MCP server

Ask your assistant about a domain and let it read the report itself. The same engine as the website and the JSON API, served as Model Context Protocol tools. No key and no sign-up.

The endpoint

https://inspectmydns.com/mcp

Streamable HTTP, stateless, JSON responses. Every tool returns exactly the JSON its API endpoint does — the same errors, the same rate limits — and the server tells the client how to read it.

Claude Code

claude mcp add --transport http inspectmydns https://inspectmydns.com/mcp

Add --scope user to have it in every project rather than just the current one. With an API key, pass it as a header:

claude mcp add --transport http inspectmydns https://inspectmydns.com/mcp \
  --header "Authorization: Bearer imd_…"

Run /mcp inside Claude Code to check it connected. Claude Code calls from your own machine, so it spends your own budget — not one shared with anybody else.

Claude (web and desktop)

  • Open Settings → Connectors and choose Add custom connector.
  • Paste https://inspectmydns.com/mcp and leave the OAuth fields empty.
  • In a chat, enable it from the + menu under Connectors.

On Team and Enterprise plans an owner adds it once under Admin settings → Connectors, and members connect to it from their own settings.

ChatGPT

  • Go to chatgpt.com/plugins, select +, then Add custom MCP server.
  • Give it a name, enter https://inspectmydns.com/mcp under Connection, and choose OAuth. Leave the client ID and secret empty; ChatGPT registers itself.
  • Accept the warning and create it; ChatGPT lists the five tools it found.
  • When ChatGPT asks you to connect, sign in with your email and approve. The screen names chatgpt.com as where access is sent.

Linked, ChatGPT runs on your account’s limit — your best key’s tier, or the free one — instead of the budget every other ChatGPT user shares. You can still choose No authentication; ChatGPT then offers to link when the shared budget runs out. Disconnect it any time from /keys. Workspace plans may need an admin to allow custom MCP servers first.

Cursor, VS Code and others

Cursor reads ~/.cursor/mcp.json (or .cursor/mcp.json in a project), and most other editor clients take the same shape:

{
  "mcpServers": {
    "inspectmydns": {
      "url": "https://inspectmydns.com/mcp"
    }
  }
}

VS Code reads .vscode/mcp.json, which names the transport:

{
  "servers": {
    "inspectmydns": {
      "type": "http",
      "url": "https://inspectmydns.com/mcp"
    }
  }
}

Any client that speaks Streamable HTTP works. To use a key, add an Authorization: Bearer imd_… header in whatever way the client accepts headers.

Tools

ToolArgumentsWhat it does
inspect_domaindomain, refresh?Full DNS, mail-authentication, TLS and registration report for one domain, from querying each of its nameservers directly. Served from a scan finished in the last 5 minutes when there is one, otherwise scans (typically 5-15 seconds) and returns the finished report. Same JSON as GET /api/v1/domain/{name}.
domain_historydomainThe stored scans in which the domain's significant records changed, newest first, each with one-line summaries of what moved. Reads stored data only and never scans. Same JSON as GET /api/v1/domain/{name}/history.
get_scanshare_idOne immutable historical report by its share id — the last path segment of a shareUrl such as https://inspectmydns.com/s/kWpmpKnwcPY3. Never scans. Same JSON as GET /api/v1/scan/{shareId}.
searchqueryResolve a query to the domain report it names, for clients that search before they fetch. Pass a domain name or a URL; returns at most one result, whose id is the domain to pass to fetch. Does not scan. Prefer inspect_domain when it is available.
fetchidThe full report for a domain id returned by search, as a document. Served from a scan finished in the last 5 minutes when there is one, otherwise scans first. Prefer inspect_domain when it is available.

inspect_domain is the one to use. search and fetch exist because ChatGPT’s deep research only calls tools with those names; search never scans. Only inspect_domain and fetch can start a scan, and only for a domain with no report from the last 5 minutes, or when refresh is set.

Things to ask

  • “Is example.com set up correctly for email?”
  • “Why would mail from example.com land in spam?”
  • “What changed in example.com’s DNS recently?”
  • “I just added a DMARC record to example.com — check it again.” (The one case where refresh is the right call.)

Limits

The same counters as the API. Cached reports cost nothing; a fresh scan counts against these:

CounterLimit
Fresh checks across all domains30 an hour anonymous, or your key’s tier
Fresh checks of one domain3 per 15 minutes
Reads (domain_history, get_scan)60 a minute, or more with a key

Hosted clients — Claude on the web, ChatGPT — call from their vendor’s servers, not from you, so everybody using this server through the same client shares one anonymous budget. When it runs out, the tool answers rate_limited with the most recent stored report attached under stale, and a well-behaved assistant uses that rather than retrying. Linking an account over OAuth, or Claude Code with a key, is the way to an allowance of your own.

What the assistant is told

Sent to the client when it connects, so the model knows how to read a report before it asks for one. The full version, for pasting into a prompt, is on the API page.

Inspect My DNS produces one diagnostic report per domain: delegation and
nameserver agreement, DNSSEC, mail authentication (SPF, DKIM, DMARC, MTA-STS),
mail and web hosts, TLS, registration and expiry, and provider attribution.

Call inspect_domain once per domain the user asked about; it answers almost
every question. It reuses a scan from the last 5 minutes and otherwise scans
and returns when the scan is done — never poll or retry it. Pass refresh only
when the user is changing DNS and wants to watch the change land: a scan sends
live queries to infrastructure belonging to somebody who did not ask to be
probed. Do not enumerate subdomains or scan every name you come across.

Reading a report: score is 0-100, or null when the domain was never
meaningfully present in DNS (scoreStatus says why; never report it as 0).
severity "unknown" means we could not measure a check, usually our own blocked
port; it is not a finding against the domain. reputation.partial true or
safeBrowsing.checked false mean "not measured", not "clean". Quote each check's
summary, and link shareUrl so the person can open the same report.

Errors carry an error code: domain_blocked means the owner opted out (do not
work around it); rate_limited carries the most recent stored report in stale,
so use that instead of retrying; scan_failed is our failure, not the domain's.

Troubleshooting

You seeMeaning
This page, after opening the endpoint in a browserExpected. The endpoint only answers MCP clients, which POST to it.
405 on GETAlso expected: the server is stateless and offers no event stream.
415The request was not sent as application/json. Every MCP client does this; a hand-written request might not.
403 cross_origin_mcp_refusedA browser page on another site tried to call it. Use the JSON API, which allows that.
domain_blockedThe domain’s owner asked not to be scanned.
severity "unknown" in a reportWe could not measure that check. It is not a fault of the domain.

Privacy

The server sees the tool calls — a domain name, a share id — and nothing of the conversation around them. Calls are handled exactly like API requests: the caller’s address is hashed for rate limiting and never stored. The privacy policy covers both.