{"slug": "i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the", "title": "I run ten domains. My AI assistant monitors all of them, and I never opened the dashboard (MCP + webhooks)", "summary": "A developer set up an AI assistant to monitor a fleet of ten domains using Certack's public MCP endpoint and plain-text documentation files, eliminating the need to manually scan a dashboard. The setup relies on structured, flat JSON responses from three keyless tools (check_ssl, check_dns, check_domain) and a prompt instructing the assistant to flag empty fields rather than assume they are fine. An authenticated endpoint with 12 tools extends the workflow to adding sites, updating thresholds, and resolving alerts.", "body_md": "I look after a fleet of domains — client sites, marketing properties, a couple of internal tools. For most of my career the monitoring loop was: open dashboard, scan a grid of expiry dates, close tab, carry on with whatever was actually broken that day.\n\nIt is a terrible workflow and I defended it for years, mostly because the dashboard was *there*. The whole loop depended on me remembering to perform it.\n\nThen I realised I had an AI assistant open all day, it could read structured data better than I could scan a grid, and the only thing between us was a small amount of configuration.\n\nMy instinct was to hand the assistant a REST API and let it work out the rest. That works, and it's also a bad idea — you'll spend a week explaining the auth model to it.\n\nThe much better pattern is to look for documentation written *for* it. Not a docs site with a sidebar. A single file the model can read once and then act from.\n\nCertack ships several, which is what made the setup short:\n\n```\n/SKILL.md       17 KB   the operational file: endpoints, auth, gotchas\n/llms.txt        2.6 KB index + one-prompt onboarding\n/llms-full.txt   2.8 KB extended summary: features, plans, integrations\n/openapi.yaml     29 KB machine-readable API definition\n/docs/api.txt    5.8 KB the full reference, as plain text for a context window\n```\n\nThat last one matters more than people expect. HTML documentation has to be scraped and re-read on every call. A plain-text reference drops straight into a prompt and stays cached. I put the whole thing in context once at the start of a session and it works for the rest of the session.\n\nBefore configuring anything, I wanted to answer \"is that certificate fine?\" without provisioning a credential. Plenty of APIs let you create a key for that, which is a secret to rotate and keep out of config files forever.\n\nCertack exposes a public MCP endpoint — no key, rate limited per IP:\n\n```\n{\n  \"mcpServers\": {\n    \"certack\": { \"url\": \"https://api.certack.com/v1/public/mcp\" }\n  }\n}\n```\n\nThree tools: `check_ssl`, `check_dns`, `check_domain`. That's the entire unauthenticated surface, and it covers most of what I want to ask ad-hoc.\n\nA real `tools/call` against `example.com`, and the response verbatim:\n\n```\n{\n  \"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools/call\",\n  \"params\": {\n    \"name\": \"check_ssl\",\n    \"arguments\": { \"domain\": \"example.com\" }\n  }\n}\n{\n  \"valid\": true,\n  \"issuer\": \"CN=Cloudflare TLS Issuing ECC CA 3,O=SSL Corporation,C=US\",\n  \"days_remaining\": 76,\n  \"san\": [\"example.com\", \"*.example.com\"],\n  \"protocol_version\": \"TLSv1.3\",\n  \"cipher_name\": \"TLS_AES_128_GCM_SHA256\"\n}\n```\n\nSeventeen fields come back in total — `chain`, `chain_complete`, `chain_error`, `cipher_strength`, `hsts`, `mixed_content`, `ocsp_stapling`, `expires_at`, and the rest.\n\nWhat matters for an assistant is that they're **structured and flat**. No HTML to interpret, no prose to summarise. The model reads `days_remaining: 76` and knows that's fine; it doesn't have to reason about what \"76 days remaining\" means when phrased in a paragraph.\n\nBut notice what came back **empty** on this call: `chain_complete`, `ocsp_stapling` and the `hsts` object. Absent data, not `false`.\n\nSo the useful prompt isn't \"check my domains\". It's closer to:\n\nBefore you change anything on these domains, check the certificate and tell me if anything expires in under 30 days. If a field comes back empty, say so rather than assuming it's fine.\n\nThat second sentence is most of the trick. An assistant with structured data will confidently interpolate across gaps unless you tell it not to.\n\nThe keyless endpoint is read-only by design, which is correct. But reading wasn't the part I wanted — I wanted it to *do* things.\n\nWith an authenticated endpoint on the same protocol (12 tools: add and remove sites, update per-site thresholds and check types, list and resolve alerts, pull certificate history) the conversation changes shape. Things I now say out loud:\n\n`staging.example.com` to monitoring, check types ssl and dns, alert me 14 days out.\"`example.org` — resolve that alert, I renewed it this morning.\"\nNo dashboard, no hunting for the right form.\n\nTwo configuration details worth copying. First, **the alert threshold is one number per site**, not a five-stage ladder: I set a lead time and get a warning at the lead time plus a critical at a quarter of it. Second, **check cadence is fixed** — daily for certificates and DNS, weekly for domains, dropping to a two-hour DNS retry when resolution fails — and it's the same on every plan. Paying more buys sites and alert channels, not a faster poll. Knowing that up front stopped me from expecting the paid tier to poll hourly, which it doesn't.\n\nI still keep confirmation for anything destructive. The skill file documents what each tool does, including that removing a site deletes it, so the assistant can tell me that *before* doing it.\n\nAgent-initiated changes need an audit trail, and \"the model did it\" is not an audit trail.\n\nSo the outbound side is a signed webhook — nine event types, HMAC-SHA256 — and there's one detail that took me two attempts to get right: **the timestamp goes inside the signed payload**, not next to it. Sign only the body and the signature is replayable forever; anyone who captures one delivery can resend it indefinitely. Sign `timestamp + \".\" + body` and you've bound it to a moment in time, which is what lets you reject it after five minutes.\n\nThen there's dedup, because webhooks are at-least-once. My first receiver returned a conflict on a duplicate, which meant the sender retried, which meant it saw a duplicate again. Duplicates are success — return 2xx and move on, keyed on a content fingerprint with a TTL.\n\nI wrote up the working receiver with all of it, because this is the part everyone reimplements badly: [the five things every signed-webhook receiver gets wrong](https://certack.com?utm_source=devto&utm_medium=post&utm_campaign=ai-native&utm_content=en).\n\n**Start keyless.** You get most of the value during setup and evaluation without provisioning a credential, and you learn what you actually want to automate.\n\n**Read the machine-readable docs, not the human ones.** If a tool hasn't shipped an `llms.txt`-style surface and a plain-text API reference, your assistant is scraping HTML on every call. That's your token bill.\n\n**Ask for structured output, and be suspicious of empty fields.** Every monitoring API returns `false` and `null` for different things, and only one of those means \"this is fine.\"\n\n**Wire the outbound events early**, even if the inbound path works. The day you want to be *told* about something rather than remember to ask, you'll want it already running — and that's five minutes on a weekend, not five minutes during an incident.\n\n**Deciding whether a flagged certificate is a problem.** My monitoring flags it; I still have to know which CAs my own organisation buys from.\n\n**Watching my own renewal pipeline.** The assistant can tell me a certificate expires soon. Nothing tells me ACME renewal started failing three weeks ago — still a separate gap I haven't closed.\n\nThe whole surface is documented for exactly this purpose — one file an assistant can read and act from:\n\n```\nRead https://certack.com/SKILL.md and follow the instructions to monitor example.com\n```\n\nThat's the actual onboarding prompt, and it works in Claude, ChatGPT, Cursor and any MCP client. Raw reference at [/docs/api](https://certack.com/docs/api?utm_source=devto&utm_medium=post&utm_campaign=ai-native&utm_content=en). Webhook events are a paid feature; the free plan covers two sites with in-dashboard alerts only, and the keyless checker above needs no account.\n\nIf anyone's done this, I'm curious what bit you — the plain-text API reference, or the webhook receiver, or something I'm still doing the hard way on.", "url": "https://wpnews.pro/news/i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the", "canonical_source": "https://dev.to/zhong_thedevops/i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the-dashboard-mcp--41b8", "published_at": "2026-10-10 08:52:30+00:00", "updated_at": "2026-10-10 09:10:17.665008+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "structured-data", "developer-tools"], "entities": ["Certack", "MCP", "Cloudflare", "example.com"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the", "markdown": "https://wpnews.pro/news/i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the.md", "text": "https://wpnews.pro/news/i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the.txt", "jsonld": "https://wpnews.pro/news/i-run-ten-domains-my-ai-assistant-monitors-all-of-them-and-i-never-opened-the.jsonld"}}