Skip to main content
Glama

drwho.me

drwhome MCP server

Free tools for domains, mail and the web, and a free MCP server that gives the same tools to AI agents. No account, no API key.

DNS and most email checks run in your browser (17 of the 32 tools), so the domain never reaches drwho.me. SPF, DMARC, DKIM, TLS-RPT and the blacklist check go from your browser straight to Cloudflare's public DNS. Site checks, WHOIS and the certificate log run on the server, which does not store what you check. So do MTA-STS and the other tools that must read another site's response or open a socket.

drwho.me is built by Hikmah Technologies, the team behind Domain Posture. Each tool here checks one thing. Domain Posture runs every check at once, grades them and tells you what to fix first.

Use the MCP server

Claude Code:

claude mcp add --transport http drwho https://drwho.me/mcp/mcp

Most other clients take this shape (check your client's docs):

{ "mcpServers": { "drwho": { "url": "https://drwho.me/mcp/mcp" } } }

Fair use: 60 tool calls per hour per address. Listing the tools is never limited. On the website, server-side checks are limited to 60 an hour per address (30 an hour shared by requests with no address), and IP lookup to 30 an hour.

To run it yourself over stdio:

docker build -t drwho-mcp .
docker run -i --rm drwho-mcp

Tools

Tool

What it does

dossier_summary

Nine DNS, email and TLS checks on a domain, one graded line each

dossier_dns, dossier_mx, dossier_dnssec

DNS records, mail servers, DNSSEC

dossier_spf, dossier_dmarc, dossier_dkim

Email authentication

dossier_mta_sts, dossier_tlsrpt

Inbound mail TLS policy and reporting

dossier_tls, dossier_headers, dossier_redirects, dossier_cors

TLS certificate, response headers, redirect chain, CORS preflight

dossier_web_surface, dossier_ai_crawlers, dossier_llms_txt, dossier_security_txt

robots.txt, sitemap, page metadata, AI-crawler policy, llms.txt, security.txt

dossier_whois, dossier_ct_log

Registration data, subdomains in certificate logs

dns_lookup, ip_lookup, user_agent_parse

One DNS record type, IP location and network, user agent parsing

base64_encode, base64_decode, jwt_decode, json_format, url_encode, url_decode, uuid_generate

Developer utilities, run locally

Every tool is read-only. A result for a domain also links to the full graded report on Domain Posture.

Related MCP server: mcp-server-devutils

How it is built

TypeScript on Node 22. Hono renders the pages on the server as plain HTML. There is no client framework: two small custom elements (<dw-check>, <dw-live>) run the tools in the page. The check logic is the MIT-licensed @hikmahtech/dossier-checks package, shared by the browser, the server and the MCP server.

src/content/tools.ts   the tool list; pages, sitemap and navigation read it
src/checks/            which checks run in the browser and which on the server
src/reports/           turns a check result into a report: a verdict and rows
src/lib/               pure logic for the developer tools (also used by MCP)
src/client/            browser scripts, one bundle per tool kind
src/views/             pages; tool views are found by file name
src/mcp/               the MCP tools, the HTTP endpoint, the manifests
src/server/            client address, rate limit, outbound network guard

docs/ADDING_A_TOOL.md explains how to add a tool.

Safety

The server fetches sites that visitors name, so it guards its own network. Before a check runs, the domain must resolve only to public addresses. On top of that, every outgoing connection is checked at the socket layer, whichever library opens it, so a redirect, a changed DNS answer or a WHOIS referral cannot reach a private address. See src/server/ssrf.ts.

The content security policy allows no inline or evaluated script.

Run it

pnpm install
pnpm dev          # http://localhost:3000
pnpm test
pnpm lint

Configuration is in .env.example. Everything is optional: without IPINFO_TOKEN the two IP tools say they are not configured, and without GA_MEASUREMENT_ID no analytics loads. MCP tool calls are counted in a separate GA4 property set by GA_MCP_MEASUREMENT_ID and GA_MCP_API_SECRET; without both, none are sent. Each event carries the client's name and version and a caller id: a keyed hash of the caller's address whose key changes every UTC day, so GA can count distinct callers per day but never sees an address or the domain checked. Set MCP_CALLER_SALT to a long random value to keep ids stable across restarts within a day.

glama.json and server.json are generated from the code with pnpm manifests. A test fails if they are out of date.

Deploy

Dockerfile.web is the website and the hosted MCP endpoint. Dockerfile is the stdio MCP server. .paas/app.yaml is the manifest for koyracloud.

Unknown paths redirect to the same path on domainposture.com. drwho.me used to be that product's address, and links and signed documents issued then must keep working.

Licence

MIT

Available Tools

21 tools
base64_decodeAInspect

Decode a Base64 or Base64url string back to its original UTF-8 plaintext. Use to inspect encoded payloads, credentials, or embedded data; accepts both standard (+/) and URL-safe (-_) alphabets, with or without trailing = padding. Pure local decode with no network calls; validates that the result is valid UTF-8. Returns the decoded string on success. On failure (invalid Base64 or non-UTF-8 bytes), returns an error message describing what went wrong.

Inputs: input (required).

base64_encodeAInspect

Encode a UTF-8 plaintext string to standard Base64 (RFC 4648 §4, +/= alphabet). Use when you need to embed binary-safe text in HTTP headers, data URIs, or JSON payloads; note this tool uses the standard alphabet — replace + with - and / with _ manually if URL-safe Base64 is required. Pure local encoding with no network calls. Returns the Base64-encoded string as plain text. Always succeeds for valid UTF-8 input.

Inputs: input (required).

dns_lookupAInspect

Resolve a single DNS record type (A, AAAA, MX, TXT, NS, CNAME, SOA, CAA, or SRV) and return the raw answers. Use for quick, targeted lookups of one record type; prefer dossier_dns for a full multi-type DNS audit in parallel, or dossier_full for a complete domain health check. Queries Cloudflare DoH (1.1.1.1/dns-query) over HTTPS, follows CNAME chains, 5 s timeout. Returns a JSON array of answer objects with name, type, and data fields. On error, returns a string describing the DNS failure.

Inputs: name (required), type (required).

dossier_corsAInspect

Send a CORS preflight OPTIONS request to https:/// and return the access-control-* response headers. Use to verify CORS policy for a specific origin-method pair, or to check whether a domain allows cross-origin requests; provide origin and method to simulate a precise preflight, or omit to use defaults (origin: https://drwho.me, method: GET). Single OPTIONS request via fetch, 5 s timeout. Returns a CheckResult: on success, {status:"ok", headers:{access-control-allow-origin,...}}; on failure, {status:"error", reason}.

Inputs: domain (required), origin, method.

dossier_dkimAInspect

Probe a domain's DKIM public keys by querying ._domainkey. for each selector. Use to verify signing configuration or discover active selectors; supply selectors when you know the ESP's selector, or omit to probe six common selectors (default, google, k1, selector1, selector2, mxvault). Issues parallel Cloudflare DoH (1.1.1.1) TXT queries per selector, 5 s timeout each. Returns a CheckResult: {status:"ok", found:[{selector, publicKey, raw},...], notFound:[...]} or {status:"error", reason}.

Inputs: domain (required), selectors.

dossier_dmarcAInspect

Retrieve and parse a domain's DMARC policy from its _dmarc. TXT record, returning all tags. Use to audit email authentication policy, verify the p (policy) and rua (reporting) settings, or confirm alignment mode; pair with dossier_spf and dossier_dkim for complete email-auth coverage. Queries _dmarc. via Cloudflare DoH (1.1.1.1), 5 s timeout; parses each tag=value pair. Returns a CheckResult: on success, {status:"ok", raw, tags:{p, rua, ruf, adkim, aspf,...}}; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_dnsAInspect

Fetch a domain's full DNS profile — A, AAAA, NS, SOA, CAA, and TXT records — all in parallel. Use as the first step of a domain audit or when you need a comprehensive DNS snapshot in one call; prefer dns_lookup for a single record type, or dossier_full for all 10 dossier checks at once. Fires six Cloudflare DoH (1.1.1.1) queries concurrently, each with a 5 s timeout. Returns a CheckResult discriminated union: on success, {status:"ok", records:{a, aaaa, ns, soa, caa, txt}}; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_fullAInspect

Run all 10 Domain Dossier checks — dns, mx, spf, dmarc, dkim, tls, redirects, headers, cors, web-surface — in parallel and return all results in a single response. Use when you need a comprehensive domain health snapshot in one call; counts as ONE paywall call regardless of how many checks run. For a single focused check, prefer the individual dossier_* tools to minimise latency. Fires all 10 checks concurrently via Cloudflare DoH or direct HTTPS, 5 s per-check timeout. Returns a JSON object keyed by check id (dns, mx, etc.), each value a CheckResult discriminated union ({status:"ok",...} or {status:"error", reason}).

Inputs: domain (required).

dossier_headersAInspect

Fetch https:/// and return all HTTP response headers, with an audit highlighting missing or misconfigured security headers. Use to review CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy; for redirect tracing use dossier_redirects instead. Single GET via fetch, 5 s timeout, captures raw response headers before any redirect is followed. Returns a CheckResult: on success, {status:"ok", headers:{...}, securityAudit:[{header, present, value},...]}; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_mxAInspect

Look up a domain's MX (mail exchanger) records and return them sorted ascending by priority. Use when verifying inbound-mail routing or as a precursor to SPF or DMARC checks; prefer dns_lookup with type=MX if you only need the raw DNS answer without the ranked view. Queries Cloudflare DoH (1.1.1.1), follows CNAME aliases, 5 s timeout. Returns a CheckResult discriminated union: on success, {status:"ok", records:[{exchange, priority},...]} sorted by priority; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_redirectsAInspect

Trace the full HTTP redirect chain starting from https:///, recording each hop's status code and destination URL. Use to debug redirect loops, verify HTTP→HTTPS upgrades, or audit link shorteners; stops at 10 hops to prevent infinite loops. Follows Location headers with fetch (no auto-redirect), 5 s per hop. Returns a CheckResult: on success, {status:"ok", hops:[{url, statusCode, redirectsTo},...], final}; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_spfAInspect

Retrieve and parse a domain's SPF record, decomposing it into mechanisms and qualifiers. Use to verify email sender policy, debug delivery failures, or check the 10-lookup limit; pair with dossier_dmarc for full email-auth coverage, or use dns_lookup with type=TXT for the raw record only. Fetches TXT records via Cloudflare DoH (1.1.1.1), 5 s timeout, locates the v=spf1 record and parses all mechanisms. Returns a CheckResult: on success, {status:"ok", raw, mechanisms:[{type, value, qualifier},...], lookupCount}; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_tlsAInspect

Fetch and inspect the TLS certificate presented by a domain on port 443, returning chain details and validity period. Use to verify certificate expiry, issuer, Subject Alternative Names, or detect mismatched or self-signed certs; not a full cipher-suite scanner. Performs a TLS handshake from the server edge, 5 s timeout; extracts the leaf certificate. Returns a CheckResult: on success, {status:"ok", subject, issuer, validFrom, validTo, daysRemaining, sans, fingerprint}; on failure, {status:"error", reason}.

Inputs: domain (required).

dossier_web_surfaceAInspect

Snapshot a domain's public web surface: robots.txt, sitemap.xml, and the home-page metadata (title, description, OpenGraph, Twitter cards). Use for SEO audits, content discovery, or verifying metadata before sharing; for HTTP headers use dossier_headers, for redirect behavior use dossier_redirects. Fetches /, /robots.txt, and /sitemap.xml concurrently via HTTPS, 5 s each; parses with a lightweight HTML parser. Returns a composite CheckResult: {status:"ok", meta:{title, description, og, twitter}, robots, sitemapPresent} or {status:"error", reason}.

Inputs: domain (required).

ip_lookupAInspect

Resolve an IPv4 or IPv6 address to its geolocation, ASN, org name, and city/country. Use when you need network or location context for a raw IP address; prefer dns_lookup or dossier_dns for hostname resolution. Queries ipinfo.io with a server-side token — the token is never exposed to callers. Returns a JSON object with fields ip, city, region, country, org, loc, and timezone. On failure, returns an error string describing what went wrong.

Inputs: ip (required).

json_formatAInspect

Validate and pretty-print a JSON string at a configurable indent width (2 or 4 spaces). Use to detect parse errors in raw JSON or to normalize minified JSON for readability; for schema validation or data transformation, apply your own logic. Runs JSON.parse + JSON.stringify locally with no network calls. On success, returns the formatted JSON string. On parse failure, returns an error message describing the position and nature of the syntax error.

Inputs: input (required), indent.

jwt_decodeAInspect

Decode a JWT (JSON Web Token) into its header, payload, and raw signature without verifying the cryptographic signature. Use to inspect token claims (sub, exp, iat, aud, etc.) or debug auth flows; do NOT use the decoded claims for access-control decisions since the signature is not validated. Splits on ".", base64url-decodes each segment, and JSON-parses header and payload — no network calls, no key lookup. Returns JSON with header, payload, and signature fields. On malformed input, returns an error message.

Inputs: token (required).

url_decodeAInspect

Decode a percent-encoded URL component back to its original string. Use to read query parameters, path segments, or form-encoded values containing %XX sequences; accepts both +-as-space (form encoding) and %20 representations. Pure local decode via decodeURIComponent with no network calls. Returns the decoded string on success. On failure (malformed %XX sequence or invalid UTF-8), returns an error message describing the problem.

Inputs: input (required).

url_encodeAInspect

Percent-encode an arbitrary string so it is safe to embed as a URL component (query value, path segment, or fragment). Use to escape characters like &, =, #, spaces, and non-ASCII before appending to a URL; uses encodeURIComponent semantics, so / is encoded — do not pass a full URL, only the component that needs escaping. Pure local transform with no network calls. Returns the percent-encoded string as plain text. Always succeeds.

Inputs: input (required).

user_agent_parseAInspect

Parse a User-Agent header string into structured browser, OS, device type, and rendering-engine components. Use to identify client capabilities from a raw UA string, e.g. when analysing server logs or request headers; does not perform any network lookups — entirely local parsing. Runs synchronously using the ua-parser-js library with no external calls. Returns a JSON object with browser.name, browser.version, os.name, os.version, device.type, device.vendor, and engine.name fields; unknown fields are empty strings.

Inputs: ua (required).

uuid_generateAInspect

Generate a single UUID in either v4 (random) or v7 (time-ordered, Unix-ms prefix) format. Use v4 for general-purpose identifiers; use v7 when UUIDs must sort chronologically by creation time (e.g. database primary keys or distributed tracing). Both versions use cryptographically random bits in their non-timestamp positions. Uses Node.js crypto.randomUUID() for v4 and a spec-compliant implementation for v7; no network calls. Returns a UUID string in canonical xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx format.

Inputs: version (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 21 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose with detailed descriptions. The base64, URL, and JWT tools handle encoding/decoding; DNS and dossier tools focus on domain analysis; and others like json_format, user_agent_parse, uuid_generate handle specific utilities. No two tools overlap in function.

    Naming Consistency4/5

    Most tools follow a consistent lowercase_underscore pattern (e.g., base64_decode, dns_lookup, url_encode). However, some deviate: dossier tools are prefixed with 'dossier_' while others are not, and 'dossier_full' uses an adjective instead of an action. Overall, naming is mostly uniform and readable.

    Tool Count4/5

    With 21 tools, the server is slightly above the typical well-scoped range (3-15). However, the tools cover a broad domain of utilities (encoding, network diagnostics, domain audits), and each tool serves a distinct purpose. The count is borderline but acceptable.

    Completeness4/5

    The toolset covers core utilities like encoding/decoding, DNS lookups, comprehensive domain dossier checks, and some general utilities. Minor gaps exist (e.g., no hashing, no bulk operations), but the surface is largely complete for its apparent purpose of network and data inspection.

    Maintenance

    ActivityMaintained
    ResponsivenessMixed handling

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      C
      maintenance
      Swiss-army-knife utility MCP server for AI agents. 18 tools for JSON validation/formatting, base64 encode/decode, hash generation, UUID generation, URL parsing, regex testing, markdown↔HTML conversion, text stats, slug generation, datetime conversion, cron parsing, text diffing, CSV↔JSON conversion, and JWT decoding. Zero API Key required
      18
      5
      -
    • A
      license
      A
      quality
      D
      maintenance
      MCP server providing 35 utility tools for AI agents including text analysis, encoding, hashing, password generation, JSON/CSV/XML parsing, regex, color, date, finance, URL metadata, SEO tags, DNS lookup, SSL inspection, and JWT decoding. Free, zero-dependency, and works with any MCP client.
      35
      64 npm
      MIT
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables AI agents to perform common utility tasks through a streamable HTTP MCP endpoint, including JSON inspection, regex testing, cron parsing, hashing, base64 encoding/decoding, URL analysis, color conversion, text diffing, CSV parsing, JWT decode/verification, Markdown-to-HTML rendering, and UUID/token generation without API keys.
      MIT