Pro and Enterprise

DomainGuard MCP server

One endpoint that hands Claude your monitoring data and lets it act on it: what is broken across your domains, what is holding a page back in search, where you rank on a map, and what to change. This page is the complete reference plus the playbooks Claude should follow.

Built on the Model Context Protocol, the open standard for connecting AI assistants to outside systems.

What this does

DomainGuard already checks your domains: DNS, SSL, SPF, DKIM, DMARC, HTTP headers, blacklists, vulnerabilities, uptime, on-page SEO, whole-site crawls, accessibility, local rankings, reviews, citations, backlinks, and how often AI answers cite you. The dashboard shows you the findings. The MCP server hands those same findings to Claude, so you can ask about them in plain language and get a specific edit list back.

With a read-only key it explains. Ask which certificate expires first, why invoices are landing in spam, what regressed since last month, or which of eleven sites share the same misconfiguration. With a write-capable key it also works: run the scan, check the rankings, pull the competitor gap, then compare the result against the baseline it took before you started.

One boundary worth stating plainly. We monitor your domains, we do not host them. Every tool here reports, records, or measures. Claude can tell you exactly what your DMARC record should say and why the one you have is failing — publishing it still happens at your DNS provider.

At a glance

Endpoint
/api/mcp
Transport
Streamable HTTP
Auth
Bearer nhm_…
Tools
6437 read, 27 write
Local SEO actions
39, catalogued
Sessions
None — stateless

Setting it up

1. Create an API key

In the dashboard, go to Settings, then API Keys. Pick the scopes the key should reach — domains, scans, SEO, accessibility, vulnerability, compliance, status — and copy the key when it is shown. It is shown once. On Enterprise you can also tick write access; leave it off for a key that should only ever report. Give each key an expiry if you have a date in mind.

2. Add the server

# Claude Code

claude mcp add --transport http domainguard https://nhmohio.com/api/mcp \ --header "Authorization: Bearer nhm_your_key_here"

# Claude Desktop, or any client taking a JSON config

{ "mcpServers": { "domainguard": { "type": "http", "url": "https://nhmohio.com/api/mcp", "headers": { "Authorization": "Bearer nhm_your_key_here" } } } }

Any MCP client that supports a remote server over HTTP with a custom header works the same way. There is no OAuth flow to complete and no event stream to open.

3. Confirm it works

# Ask the server what this key can do

curl -s https://nhmohio.com/api/mcp \ -H "Authorization: Bearer nhm_your_key_here" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The list that comes back is already filtered to the key's scopes and the account's plan, so it is the real answer to what this key can reach. If a tool you expected is missing, the key is missing a scope — mint a new one rather than rewording the prompt.

4. Ask it something

"Which of my domains have SSL certificates expiring in the next 30 days?" "Why might email from my domain be going to spam?" "Read the SEO results for every domain and give me one ranked fix list." "Where do we drop out of the map pack for 'emergency plumber', and why?" "Compare this month against last month and tell me what actually moved."

Plans, scopes, and what a key can reach

A key carries resource scopes, and optionally the write scope on top of them. Both are checked on every call, and the plan is re-read on every request — an account that moves from Enterprise to Pro loses write access on its next call rather than whenever someone remembers to rotate the key.

Free and Starter

No API or MCP access.

The endpoint answers 401.

Pro

Read access. 35 tools.

Everything that reads stored data, across every scope you grant.

Enterprise

Read and write. All 64 tools.

Adds the write scope: start scans, spend credits, change saved data.

ScopeWhat it unlocks
domainsInventory, history, DNS and registrar events, uptime, DMARC reporting
scansDomain scans, security checkups, dark-web monitoring
seoOn-page SEO, whole-site audits, and the entire Local SEO suite
accessibilityAudit-grade WCAG 2.2 AA evaluations
vulnscanVulnerability scans, ports, components, ownership verification
compliancePCI, HIPAA, and cyber-insurance control records
statusCustom endpoint checks and third-party service status
writeRequired on top of any of the above for anything that changes state

How to use it well

Sixty tools is enough that the order you call them in decides whether a session is useful or expensive. These are the rules we give Claude, and the sequences that actually produce a fix list.

Ten ground rules

1

Start with list_domains

Almost every tool takes a numeric domain_id, and that is where the ids come from. Never guess one.

2

Read before you scan

get_checkup_history, get_seo_results, get_vuln_scan_latest and get_local_rank_history return data already collected — free, instant, and usually enough.

3

Know what spends

Anything named run_, start_, check_ or verify_ does real work. So do get_domain_email_security, discover_domain_subdomains and get_scan_ownership_verification, which perform live lookups.

4

Quote before spending

get_local_seo_credits for the balance, get_local_seo_catalog for what an action costs and requires. Say the cost before the first paid call of a session.

5

Fresh request_key every paid run

Eight to a hundred characters of letters, digits, dots, underscores, and hyphens. Reuse one only to retry the identical request.

6

Recover, do not re-run

After a timeout, get_local_seo_operation with the same key returns the saved or in-flight result. A new key charges again.

7

Poll asynchronous scans

start_vuln_scan, start_site_audit and start_accessibility_audit return an id immediately and finish in the background. Leave real time between polls.

8

Confirm deletions in words

delete_domain erases a domain's whole history and cannot be undone. Name the exact thing and get a yes.

9

Say who applies the fix

The registrar, the DNS provider, the CMS, or Google Business Profile. A finding without an owner is not a fix.

10

Never invent a number

Scores, positions, volumes and prices come from tool output. If a tool did not return it, say it is not measured.

Playbooks

Each one is a sequence that ends in something the user can act on. Every one of them opens with free reads.

Triage the whole portfolio

The first session on an account. Costs nothing — every call here reads data already collected.

list_domains
  ├─ get_domain_history      → getting worse, or always been this way?
  ├─ get_checkup_history     → what is broken, with severity
  └─ get_seo_results         → titles, descriptions, headings, violations
get_domain_events            → anything hijack-shaped across the account
get_downtime_events          → was anything actually down

Report one ranked list across the portfolio, severity first and then by how many domains share the finding. Fixing the one misconfiguration that appears on nine sites beats fixing nine unrelated things, and that ordering is only visible when you read the whole account at once.

Make a page rank — the technical loop

The order matters. A page cannot rank if it cannot be crawled, cannot be trusted, or cannot be read.

get_seo_results     → title, meta description, H1 and heading structure,
                       accessibility violations that also block crawling
get_checkup_history → HTTPS, redirects, response headers, exposed files
get_seo_history     → has the score been moving, and in which direction
  ↓  hand the user a specific edit list, then wait for them to publish
run_seo_scan        → re-score
get_seo_results     → confirm the finding cleared
get_seo_history     → confirm the number moved

Read the SEO result for what it names, not for its score. A missing meta description, a title duplicated across a template, two H1s, a skipped heading level — each of those is a concrete edit with an owner. “Score is 71” is not. Batch the edits and scan once: free accounts get one manual scan a day.

Audit the whole site, not one page

A crawl of the sitemap or same-site links, checking every discovered page. Asynchronous — start, poll, read.

start_site_audit      { domain_id, max_pages }  → audit_id
get_site_audit_status { audit_id }              → poll; minutes, not seconds
get_site_audit_results{ audit_id }              → page-level findings

Cluster before reporting. Three hundred crawled pages do not produce three hundred problems — they produce perhaps six template defects repeated three hundred times. Sort by pages affected multiplied by severity, name the template or page type where it can be inferred, and the fix list goes from unusable to a morning's work.

Get into the local map pack

The highest-leverage sequence for a business that serves a place. Set up once, then measure and diagnose.

Setup, once per domain
  get_local_seo_profile        → is there a profile at all?
  save_local_seo_profile       → business_name, location ("Akron, OH"),
                                 is_service_business, radius_miles, and
                                 street_address + phone if you will ever
                                 want citation checks
  add_local_keyword_target     → phrases a customer would actually type,
                                 up to 25 per domain

Measure
  get_local_rank_history       → free; is there recent data already?
  get_local_seo_credits        → check the balance before spending
  check_local_ranks            → live positions, local pack. For the organic
                                 column too, or one phrase only, use
                                 run_local_seo_action rank_check with
                                 surfaces and keywords
  run_geogrid_scan             → where the ranking holds across the area

Diagnose
  run_local_seo_action profile_health   → what the profile is missing
  run_local_seo_action citations        → name/address/phone consistency
  run_local_seo_action competitor_gap   → who beats you, and on what
  run_local_seo_action reviews          → recent and unanswered reviews

How to read a geogrid. A business ranks best at its own pin and decays outward. Strong at the centre and dead three miles out is a proximity problem — the answer is location-specific content and citations, not more keywords. Weak everywhere, including at the pin, is a profile or trust problem: go to profile health and citations first, because no amount of content fixes a profile Google does not trust.

A saved profile is the prerequisite for both rank checks and map scans. The service radius defaults to three miles and tops out at five hundred.

Find phrases worth targeting

Research before tracking, and a baseline before any work starts.

get_local_seo_catalog                        → inputs and cost
run_local_seo_action keyword_opportunities   → local searches to consider
run_local_seo_action keyword_suggestions     → expand a seed phrase
run_local_seo_action keyword_search_volume   → is there real demand
run_local_seo_action keywords_for_site       → what this domain already
                                               associates with
run_local_seo_action keywords_related        → adjacent phrases
run_local_seo_action keyword_trends          → rising, or dying
  ↓
add_local_keyword_target  → the survivors
check_local_ranks         → the baseline, before anything changes

Take the baseline before the user changes anything. Without it there is nothing to compare against in three months, and the work cannot be shown to have worked — which is usually the thing that decides whether it continues.

Beat a specific competitor

Four reads of the same rival from different angles, turned into three things to do this month.

run_local_seo_action competitor_gap      → ranking, review, citation gap
run_local_seo_action backlinks_gap       → links they have, you do not
run_local_seo_action business_listings   → the shape of the local field
run_local_seo_action competitor_ads      → what they pay to say
run_local_seo_action local_authority     → your own signals in one score

Convert the gap into three actions, not thirty. Link gaps are the slowest to close and the most durable once closed; review count and profile completeness are the fastest and the most visible to a searcher deciding between two names.

Be visible in AI answers

Increasingly the click never happens — the answer does. That is measurable, and it is a different surface from the ten blue links.

run_local_seo_action ai_visibility     → how often answers surface this site
run_local_seo_action serp_ai_overview  → does the search trigger an AI
                                         Overview, and what does it cite
run_local_seo_action serp_ai_mode      → the AI answer, with references
run_local_seo_action ai_mentions       → which brands and sources get named
run_local_seo_action ai_top_sources    → what these systems rely on
run_local_seo_action ai_top_pages      → the pages they surface most
run_local_seo_action ai_compare        → you versus competitors, by phrase

The actionable output is almost always the cited sources, not the answer text. When the same three directories or publications are cited across every phrase in a category, being present and accurate on those three is the work — and it is work that pays off in ordinary search too.

Reputation and links

The two cheapest wins in local search, and the warmest outreach list that exists.

run_local_seo_action reviews                → recent reviews, owner replies
run_local_seo_action review_velocity        → rate of arrival, not total
run_local_seo_action multi_platform_reviews → beyond Google
run_local_seo_action reputation_audit       → quality, quantity, recency
run_local_seo_action business_qa            → public questions, often unanswered
run_local_seo_action backlinks_summary      → the link signals you have
run_local_seo_action backlinks_gap          → what competitors have
run_local_seo_action brand_mentions         → named, but not linked

Unanswered reviews and unanswered public questions are both visible to searchers and both free to fix. Unlinked brand mentions are the warmest outreach list there is — the site already decided to mention the business, so the ask is small.

Email that reaches the inbox

Not a ranking factor, but the fastest way to lose a customer who already found you — and the most common thing a monitored portfolio gets wrong.

get_domain_email_security { domain_id } → live SPF, DKIM, DMARC, MX,
                                          MTA-STS, TLS-RPT
get_dmarc_setup_status    { domain }    → the authoritative checklist
get_dmarc_summary         { domain }    → 30-day volume and alignment
get_dmarc_diagnostics     { domain }    → ranked, with sender attribution

Read the diagnostics before recommending a policy change. Moving a domain to p=reject while a legitimate sender is failing alignment stops that sender's mail on the next send. The diagnostics name which sender, which is the whole reason to look before you leap.

Security findings that are also search problems

Mixed content, an expired certificate, a blacklist entry, a compromised page. These belong in the SEO report, not a separate one.

get_checkup_history                 → stored and free; start here
run_domain_checkup { domain }       → live. Your own domain gets the full
                                      check; any other hostname gets only
                                      the passive checks
get_vuln_scan_latest                → most recent completed scan
start_vuln_scan                     → quick | standard | port-scan |
                                      deep | extreme
get_vuln_scan_results { scan_id }   → poll for findings

Active scanning first needs proof of control:
  get_scan_ownership_verification   → creates or returns the challenge
    ↓  user publishes the DNS record or file
  verify_scan_ownership             → records the proof

Ownership verification is not paperwork. Deep and extreme profiles send real traffic at a real server, and the proof is what separates scanning your own site from scanning someone else's.

Prove the work worked

Every engagement should end here, against the baseline taken at the start.

get_seo_history          → score movement over the period
get_local_rank_history   → position per phrase, per check
get_geogrid_scans        → the map before, and the map after
get_domain_history       → everything else that changed
get_uptime_snapshots + get_downtime_events → availability

Cite the dates, and say plainly where nothing moved. Positions move for reasons nobody controls; a report claiming every change was caused by the work is the one nobody believes twice.

Tool reference

All 64 tools: 37 that read stored data and 27 that change something, run a live lookup, or spend credits. A key is only offered the subset its scopes and plan allow, so the list your client shows may be shorter than this one.

Fields marked ? are optional. Every tool runs through the same ownership checks as the dashboard, so a key reaches its own account and nothing else.

Domains, DNS, and deliverability

scope: domains

The inventory and everything recorded about it. list_domains is the entry point to the whole server — its numeric ids are what the other tools take.

ToolAccessInputsWhat it returns
list_domainsreadEvery domain on the account with its health score, last scan time, and SSL expiry. Start here.
get_domain_historyreaddomain_idRecorded results for one domain over time — when something regressed and by how much.
get_dns_change_eventsreadDNS changes across the account, so a new change can be told apart from a long-standing finding.
get_domain_eventsreadHijack Guard events with severity and lifecycle: DNS, registrar, certificate, and hosting changes.
get_uptime_snapshotsreadRecent uptime probe observations across the portfolio.
get_downtime_eventsreadRecorded outage windows and whether they recovered.
get_dmarc_summaryreaddomainThirty-day aggregate report volume and alignment rate for one monitored domain.
get_dmarc_diagnosticsreaddomainRanked deliverability diagnostics joining DNS, reports, and sender attribution.
get_dmarc_setup_statusreaddomainThe authoritative SPF, DKIM, DMARC, report-arrival, and inbox-routing checklist.
add_domainwritedomainStart monitoring a new domain. Returns 403 once the plan's domain limit is reached.
update_domainwritedomain_id, domain_group?, notes?, ignore_mail?, ignore_autoscan?Change one domain's group, notes, or which checks it skips. Only the fields passed are changed.
delete_domaindestructivedomain_idPermanently removes the domain and its entire scan history. Re-adding does not recover it.
get_domain_email_securitywritedomain_idFresh SPF, DKIM, DMARC, MX, MTA-STS, and TLS-RPT evidence. Performs live DNS lookups, so it counts as a write.
discover_domain_subdomainswritedomain_idPassive subdomain discovery from certificate transparency and DNS. Does not probe the hosts it finds.

Scans, checkups, and dark web

scope: scans

Security checkups and breach monitoring. The stored history is almost always enough — reach for a live run only when something has just changed.

ToolAccessInputsWhat it returns
get_checkup_historyreaddomain_idPast security checkups with every individual finding and its severity. The richest single answer to “what is wrong with this site”.
get_dark_web_statusreadCached breach-monitoring results for the account, with no upstream lookup.
list_dark_web_domain_monitorsreadVerified whole-domain breach monitors and their latest scan state.
run_domain_scanwritedomain_idDomain health, security checkup, and single-page SEO in one pass. Does not run vulnerability, whole-site, dark-web, or audit-grade accessibility scans.
run_domain_checkupwritedomainA live checkup. On your own domain this includes the exposed-file probe; on any other hostname only the passive checks run.
run_dark_web_scanwriteRefresh every monitored email address against the breach index. Spends the manual-scan allowance.
run_dark_web_domain_scanwriteRefresh every verified whole-domain breach monitor.

SEO — one page and the whole site

scope: seo

What a page says about itself, and what a crawl of every page finds. The site audit is asynchronous: start it, poll the status, then read the results.

ToolAccessInputsWhat it returns
get_seo_resultsreaddomain_idThe latest SEO and accessibility scan: page titles, meta descriptions, heading structure, and violations.
get_seo_historyreaddomain_idSEO scores over time, so a change can be shown to have moved the number.
get_site_audit_statusreadaudit_idProgress of a whole-site crawl.
get_site_audit_resultsreadaudit_idPage-level findings from a whole-site crawl.
run_seo_scanwritedomain_idRe-score a site after publishing changes. Free accounts get one manual scan a day; a second returns 429.
start_site_auditwritedomain_id, max_pages?Crawl the sitemap or same-site links and check every discovered page. Returns an audit id immediately.

Local SEO — rankings, maps, reviews, competitors

scope: seo

The suite behind local search. A saved business profile is the prerequisite for everything that measures a position, and the catalog is the authority on what each action needs and costs.

ToolAccessInputsWhat it returns
get_local_seo_profilereaddomain_idThe saved business profile: name, location, service radius, and targeting mode.
get_local_keyword_targetsreaddomain_idThe phrases currently tracked for this domain.
get_local_rank_historyreaddomain_idRecorded positions for each tracked phrase on each past check.
get_geogrid_scansreaddomain_idPast map-grid scans showing where across the service area rankings hold and where they fall away.
get_local_seo_catalogreadAll 39 catalogued actions with their exact inputs, prerequisites, price basis, and caching rules. Call this before running one.
get_local_seo_operationreadrequest_keyRecover a paid action after a timeout instead of paying for it twice.
get_local_seo_creditsreadRemaining rank-check and map-scan credits on the account.
save_local_seo_profilewritedomain_id, business_name, location, targeting?, radius_miles?, is_service_business?, street_address?, phone?Create or update the business profile. Required before rank checks and map scans will run.
add_local_keyword_targetwritedomain_id, keyword, targeting?Track a phrase. Up to 25 per domain; adding the same phrase twice does nothing.
delete_local_keyword_targetdestructivekeyword_idStop tracking a phrase. The rank history already recorded is kept.
check_local_rankswritedomain_id, request_keyLive positions for every tracked phrase, measuring the local pack. Costs one credit per phrase per surface.
run_geogrid_scanwritedomain_id, keyword, grid_size?, request_keyCheck one phrase from many points across the service area on a 5×5, 7×7, or 9×9 grid.
run_local_seo_actionwriteaction_id, request_key, inputRun any action from the catalog — reviews, citations, keyword research, competitor gap, backlinks, AI visibility, full audits.

Accessibility

scope: accessibility

Audit-grade WCAG 2.2 AA evaluation in a real browser. Separate from the accessibility violations that come back with an ordinary SEO scan, and separately scoped so a key can have one without the other.

ToolAccessInputsWhat it returns
quote_accessibility_auditreaddomain_idCost, available credits, page cap, and whether an audit can start right now.
list_accessibility_auditsreaddomain_id?, limit?Recent evaluations, optionally narrowed to one domain.
get_accessibility_auditreadaudit_idPages, axe findings, WCAG rollups, manual-review coverage, and regression data for one audit.
start_accessibility_auditwritedomain_id, request_key, max_pages?, viewport?Queue a browser evaluation. Spends accessibility credits, so the request key matters.

Vulnerability and exposure

scope: vulnscan

Active scanning needs proof that the account controls the domain. Get the challenge, publish it, verify it, then scan.

ToolAccessInputsWhat it returns
get_vuln_scan_latestreaddomain_idThe most recent completed scan with its findings and severities.
get_vuln_scan_resultsreadscan_idFindings for one scan by id. This is how you poll a scan you just started.
get_vuln_scan_historyreaddomain_idThe last twenty scans with status, profile, timing, and severity summary.
get_vulnerability_assetsreaddomain_idEvery public hostname discovered for a domain and the finding counts attached to each.
get_open_portsreaddomain_idPer-host port, service, banner, version, and risk observations.
list_lookalikesreaddomain_idDomains registered by other people to imitate yours, each with a risk band and the evidence behind it — plus how much of the variation space the scan actually covered.
get_lookalike_eventsreaddomain_idWhat changed about those impostors over time: one appearing, one gaining the ability to receive email, one becoming more dangerous.
run_lookalike_scanwritedomain_idGenerate variations of a domain and check which are registered. Takes up to a minute; prefer the stored list unless a fresh check is wanted.
set_lookalike_verdictwritedomain_id, lookalike, verdict?Say what one impostor is so it stops being reported: ours, unrelated, or known. Omit the verdict to clear it.
get_observed_componentsreadThe portfolio's technology inventory with version confidence where a version was actually observed.
get_scan_ownership_verificationwritedomain_idReturn the DNS, file, or email proof required before active scanning, creating a challenge if none exists.
verify_scan_ownershipwritedomain_idRe-check the published proof and record verification when it is found.
start_vuln_scanwritedomain_id, scan_type?, scan_profile?, target_hosts?Quick through extreme, optionally limited to selected hosts. Returns a scan id; the scan runs in the background.

Compliance evidence

scope: compliance

PCI, HIPAA, and cyber-insurance controls. These records are audit evidence — notes should quote the account owner's own wording rather than paraphrase it.

ToolAccessInputsWhat it returns
get_compliance_recordsreadThe compliance checklist with each control's current status and notes.
update_compliance_itemwriterecord_id, status, notes?Set one control to unanswered, met, partial, not met, or n/a. "Not met" is a recorded gap, not a blank. Uses the record id, not the item id.

Uptime and dependencies

scope: status

Custom endpoint checks you define, plus the live status of third-party providers — the fastest way to separate a problem with your site from an incident at your host.

ToolAccessInputsWhat it returns
list_status_checksreadCustom endpoint checks with their URLs and most recent result.
get_status_servicesreadCurrent status of the third-party providers this account tracks.
create_status_checkwritename, urlAdd a check that polls a URL on a schedule and records whether it responded.
run_status_checkwritecheck_idRun one saved check immediately rather than waiting for its next poll.
delete_status_checkdestructivecheck_idRemove a custom check.

The Local SEO catalog

Thirteen tools cover local search directly. Behind run_local_seo_action sit another 39 catalogued actions, and get_local_seo_catalog is the authority on all of them: exact required inputs, prerequisites, price basis, and whether a saved result can be reopened for free. Call it before running an action rather than assuming a shape — the catalog is the contract, and it can gain entries between deploys of this page.

# The shape of a catalogued run

run_local_seo_action { action_id: "competitor_gap", // from get_local_seo_catalog request_key: "dg-compgap-20260829-x1", // fresh, 8-100 chars [A-Za-z0-9._-] input: { domain_id: 12 } // exactly the catalog's fields }
AreaAction ids
Profile and reputationprofile_health · business_profile · business_qa · reviews · review_velocity · multi_platform_reviews · reputation_audit
Rankings and mapsrank_check · geogrid · serp_local_finder · serp_maps · serp_lsa
Keyword researchkeyword_suggestions · keyword_search_volume · keyword_opportunities · keywords_for_site · keywords_related · keyword_trends
AI search visibilityai_visibility · serp_ai_overview · serp_ai_mode · ai_mentions · ai_top_pages · ai_top_sources · ai_compare · ai_keyword_data · ai_llm_response · ai_scraper
Authority and linksbacklinks_summary · backlinks_gap · local_authority · brand_mentions
Competitioncompetitor_gap · competitor_ads · business_listings
Auditslocal_audit · citation_audit · citations · page_audit

Some actions cache: reopening a saved result is free and refreshing buys a new one. The catalog says which, per action. Prefer the saved result unless the question genuinely needs current data.

rank_check deserves a note

check_local_ranks is the quick path and measures the local pack only. The catalogued action measures more and is priced accordingly — one credit per phrase per surface. surfaces chooses where to measure, and keywords narrows the run; omit it and every saved phrase is checked, so twenty tracked phrases across both surfaces is forty credits. Quote it first, and narrow the list when the user asked about one phrase.

run_local_seo_action { action_id: "rank_check", request_key: "dg-ranks-20260829-b2", input: { domain_id: 12, surfaces: ["local_pack", "organic"], // both, or just one keywords: ["emergency plumber akron"] // omit to check every saved phrase } }

When something goes wrong

A tool that fails comes back as an ordinary result carrying isError and a readable reason, not as a protocol error — so an assistant can read why and adapt instead of ending the turn. Only transport-level problems return a non-200 status.

What you seeWhat it meansWhat to do
401Key missing, malformed, revoked, expired, or the plan does not include API access.Check Settings, API Keys, and the plan. Do not retry.
401 “requires a DomainGuard API key”A dashboard session token was sent instead of a key.MCP takes an nhm_ key only. Sessions are refused so a stolen browser token cannot drive it.
403 Forbidden originThe Origin header failed validation.A client configuration problem, not a credential problem.
405 on an authenticated GETCorrect. There is no SSE stream to open. An unauthenticated GET answers 401 first, because the key is checked before the method.Use POST.
429The key's hourly rate limit, or a per-plan manual-scan limit.Wait. Free plans allow one manual SEO scan per day.
isError: “missing the … scope”The key does not carry that resource scope.Mint a key with the scope. Retrying will not help.
isError: “read-only”The tool changes state and the key has no write scope.Use the read equivalent, or upgrade to Enterprise.
409 idempotency_mismatchThat request_key was already used for a different request.Generate a fresh key for a genuinely new run.
Timeout on a paid actionWhether it ran is unknown.Call get_local_seo_operation with the same request_key. Never re-run blind.
A scan returns with no findingsIt is asynchronous and still running.Poll the matching results tool.
“requires ownership verification”Active scanning needs proof of control.get_scan_ownership_verification, publish the proof, then verify_scan_ownership.

Protocol notes

One endpoint

POST /api/mcp, speaking JSON-RPC 2.0. GET answers 405 with Allow: POST — there is no event stream to open, and saying so is more honest than holding one open with nothing to send.

Both protocol eras

The stateless 2026-07-28 revision and the handshake revisions 2025-11-25, 2025-06-18, and 2025-03-26 are all served, from the same code path. Holding no session state is what makes supporting both cheap.

Methods

initialize, server/discover, tools/list, tools/call, and ping. resources/list and prompts/list answer empty rather than not-found, so a client probing capabilities does not treat the server as broken.

No sessions

No Mcp-Session-Id, nothing remembered between calls. Each request stands alone and carries its own authentication.

No batching

JSON-RPC batching was removed from the spec in the 2025-06-18 revision and is rejected here. Notifications receive 202 with no body.

Cacheable tool lists

tools/list results are marked private and scope-dependent. A shared intermediary must never serve one key's tool list to another.

Give this to Claude

Everything on this page is also published as one plain-text file written for an assistant to read. Point Claude at the URL, or paste the block below into your project's CLAUDE.md so every session starts knowing the rules instead of discovering them by spending credits.

The full operating guide

https://nhmohio.com/mcp/claude-guide.md
Open the guide

# Paste into CLAUDE.md

## DomainGuard MCP The `domainguard` MCP server is connected. It reads and refreshes monitoring data for the domains on this account: DNS, SSL, mail authentication, security checkups, on-page and site-wide SEO, accessibility, local rankings, reviews, citations, backlinks, and AI search visibility. Rules: - Start with `list_domains`; every other tool needs the numeric `domain_id`. - Read stored results (`get_checkup_history`, `get_seo_results`, `get_vuln_scan_latest`, `get_local_rank_history`) before running any scan. - `run_*`, `start_*`, `check_*` and `verify_*` cost time or credits. So do `get_domain_email_security`, `discover_domain_subdomains` and `get_scan_ownership_verification`. Say the cost before spending. - Call `get_local_seo_catalog` before `run_local_seo_action`; it is the authority on inputs and price. - Every paid action needs a fresh `request_key` (8-100 chars, [A-Za-z0-9._-]). After a timeout use `get_local_seo_operation`, never a re-run. - `start_vuln_scan`, `start_site_audit` and `start_accessibility_audit` are asynchronous — poll their results tools. - Confirm `delete_domain`, `delete_local_keyword_target` and `delete_status_check` in words before calling them. - DomainGuard monitors these domains, it does not host them. Deliver the diagnosis plus the exact change, and say where the user applies it — registrar, DNS provider, CMS, or Google Business Profile. - Never estimate a score, position, volume, or price that a tool did not return. Full guide: https://nhmohio.com/mcp/claude-guide.md

How access is limited

Your account only

Every tool runs through the same ownership checks as the dashboard. A key reaches the domains on its own account and nothing else.

Scopes decide the tool list

Tools outside a key's scopes are never offered and cannot be called. Mint one key per use and give each only what it needs.

Read-only means read-only

Without the write scope, an assistant cannot start live lookups or scans, spend credits, or change configuration. Write is a separate tick box, and only on Enterprise.

Keys cannot mint keys

An API key is refused at the key-management endpoints, so a narrow key handed to an agent can never issue itself a broader one. That stays a dashboard action.

Sessions are refused

The MCP endpoint takes an API key and nothing else. A browser token obtained through XSS cannot drive it.

Revocable and rate limited

Revoke a key and it stops working immediately. Each key carries its own hourly limit, and you can set an expiry date when you create it.

Point Claude at your domains

Pro reads your account. Enterprise reads it and acts on it. Both take about a minute to set up.