upkeep-mcp
NPM · UPKEEP-MCP · SCANNED SEP 21
Website maintenance checks: domains, SSL, uptime, technical SEO and accessibility
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- 0 of 9 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency100
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to tiagocalado86/upkeep-mcp). View diagnostics → Pass
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 14 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability76
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 3659 tokens (~406/item across 9 items; 8 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management53
- Stability observed for 16 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 8 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 9 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
How do I install the upkeep-mcp server?
upkeep-mcp runs locally as an npm package, launched with npx -y upkeep-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · upkeep-mcp
claude mcp add tiagocalado86-upkeep-mcp -- npx -y upkeep-mcp
{
"mcpServers": {
"tiagocalado86-upkeep-mcp": {
"command": "npx",
"args": [
"-y",
"upkeep-mcp"
]
}
}
} {
"servers": {
"tiagocalado86-upkeep-mcp": {
"command": "npx",
"args": [
"-y",
"upkeep-mcp"
]
}
}
} codex mcp add tiagocalado86-upkeep-mcp -- npx -y upkeep-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"tiagocalado86-upkeep-mcp": {
"type": "local",
"command": [
"npx",
"-y",
"upkeep-mcp"
],
"enabled": true
}
}
} openclaw mcp add tiagocalado86-upkeep-mcp --command npx --arg -y --arg upkeep-mcp
mcp_servers:
tiagocalado86-upkeep-mcp:
command: "npx"
args: ["-y", "upkeep-mcp"] {
"McpServers": {
"tiagocalado86-upkeep-mcp": {
"Transport": "stdio",
"Command": "npx",
"Arguments": [
"-y",
"upkeep-mcp"
]
}
}
} assistant mcp add tiagocalado86-upkeep-mcp -t stdio -c npx -a -y upkeep-mcp
{
"mcpServers": {
"tiagocalado86-upkeep-mcp": {
"command": "npx",
"args": [
"-y",
"upkeep-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 20 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.
- 18 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.
- 16 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.
- 14 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.
- 12 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.
- 9 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.
- 8 Sept 26 +26
- Malware scan: unverified → pass ▲ security
- Known CVEs: unverified → pass ▲ security
- Dependency health: unverified → 1.00 ▲ functional
- 7 Sept 26 −10
- Known CVEs: pass → unverified ▼ security
- Schema quality: 358 → 406 ▼ functional
- Dependency health: 1.00 → unverified ▼ functional
- Package version: 0.5.0 → 0.6.1 functional
- Package version: 0.5.0 → 0.6.0 functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 21 Sept 2026 · Analysed npm/upkeep-mcp@0.6.1
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | npm |
| Reason | Verified |
| Discovered via | Registry attestation endpoint |
| Source repo | tiagocalado86/upkeep-mcp |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/tiagocalado86/upkeep-mcp/.github/workflows/release.yml@refs/tags/v0.6.1 |
| Rekor log index | 2744845102 |
| Predicate type | https://slsa.dev/provenance/v1 |
| Subject digest | sha512:c7679d3dff0d723dd265285e3929412b49704250facef4cf69d0dc594b0790f3f8bb357b7ded28e01080ff2617100bdd7e367a4a89793ad52cba9ad42 |
Background: How many MCP packages publish verified provenance →
Dependencies 9 packages
| Packages resolved | 9 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
accessibility_audit WCAG violations on one page ~403
Opens one page in a real browser and runs axe-core over it, reporting the WCAG rules it fails, how many elements fail each one, and where they are. Use it to answer "does this page meet WCAG 2.2 AA?", "what would an accessibility audit flag?" or "which of these fixes matters most?". It is the check to run before a site goes live, and when a client asks about accessibility obligations. Do not use it for metadata, headings or broken links, which seo_audit reports without a browser and far faster. It audits one page, not a site, and it renders that page: it is much slower than every other tool here. It needs a browser. Nothing else in this server does, so if none is installed this tool says so and names the one command that fixes it, while every other check keeps working. A hosted instance runs it too: the published image ships a browser, and every request that browser makes goes through the same public-address and web-port rules as the rest of this server. Automated rules find roughly a third of accessibility problems. A page with no violations is a page that passed the machine-checkable part, which is not the same as being usable, and the count of undecided rules is reported for exactly that reason. robots.txt is obeyed. Returns findings ordered by urgency, worst first.
| Name | Type | Req | Description |
|---|---|---|---|
| standard | string | – | Which rules to run. Defaults to "wcag2aa", the level most accessibility policies and procurement rules are written against. Each level includes the ones below it. "best-practice" runs axe's non-WCAG… |
| url | string | yes | The page to audit, e.g. "https://example.com/contact". A bare domain is accepted and read over HTTPS. One page is audited, not a site. |
| Name | Type | Req | Description |
|---|---|---|---|
| affectedElements | integer | yes | How many elements failed a rule, counting repeats. |
| audited | boolean | yes | Whether the page was audited at all. False when robots.txt forbids it. |
| axeVersion | string|null | yes | Which axe-core did the judging, so a result can be reproduced. |
| checkedAt | string | yes | When the audit ran, ISO 8601 in UTC. |
| finalUrl | string|null | yes | Where the browser ended up. |
| findings | array | yes | What needs attention, worst first. |
| incompleteCount | integer | yes | Rules axe could not decide on its own. These are not passes: they are the ones needing a person, and a page with none is unusual rather than perfect. |
| pageTitle | string|null | yes | The title as rendered, which markup alone may not show. |
| passCount | integer | yes | How many rules passed. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| standard | string | yes | Which standard was asked for. |
| url | string | yes | The URL that was requested. |
| violationCount | integer | yes | How many rules failed. |
| violations | array | yes | Every rule that failed, worst impact first. |
No examples provided.
domain_check Domain registration and DNS ~604
Reports when a domain registration expires, who the registrar is, and how the domain is configured in DNS — nameservers, address records, mail exchangers, TXT and CAA records, whether the delegation is signed with DNSSEC, and what its SPF and DMARC records say about who may send email as it. Use it to answer "is this domain about to lapse?", "who do we renew this with?", "where does this domain point?" or "why does the apex not work when www does?". It is the right first call when a site has gone dark for no obvious reason. Use it too for "why is this client's email going to spam?" or "can someone spoof this domain?" — SPF and DMARC are read from the domain's own DNS. It also asks each of the domain's own nameservers, directly, whether they agree about the zone. That answers "why does this site work for some people and not others?" and "is this old nameserver still in the delegation?" — a question no recursive resolver can answer, because it replies with whatever one server told it and does not say which. Pass checkNameservers: false to skip it. Do not use it to check whether a website responds — that is uptime_check — or to inspect an SSL certificate, which is ssl_check. It reads only what registries and DNS publish. It reports no DKIM: finding a DKIM key needs its selector, and a selector cannot be discovered without guessing at names, which this project will not do. Registration data comes from RDAP. Some country registries (.de, .nl, .no, .au, .fi) publish no expiry date at all; the result says so explicitly rather than reporting a gap as if it were an unknown. An expiry inside 30 days is reported as a warning and inside seven days as critical — a manual renewal needs that much lead time. Returns findings ordered by how much attention they need, worst first.
| Name | Type | Req | Description |
|---|---|---|---|
| checkNameservers | boolean | – | Whether to ask the domain's own nameservers whether they agree about it, which no recursive resolver can answer. Costs one DNS query over TCP to each nameserver the domain publishes, in parallel, and… |
| domain | string | yes | The domain to check, e.g. "example.com" — no scheme, no trailing slash. A full URL such as "https://example.com/pricing" is also accepted and reduced to its hostname. Internationalised names ("café.p… |
| Name | Type | Req | Description |
|---|---|---|---|
| checkedAt | string | yes | When the check ran, ISO 8601 in UTC. |
| dns | object | yes | DNS records for the registrable domain. |
| dnsResolved | boolean | yes | Whether the DNS lookup answered at all. When false every field under "dns" is empty because nothing could be read, not because the domain has no records. |
| dnssec | object | yes | Whether the delegation is signed. This is not a validation of the DNSSEC chain. |
| domain | string | yes | The hostname that was checked, in ASCII (punycode) form. |
| object | yes | Email authentication, read from the domain's own TXT records. DKIM is not reported: finding a DKIM key needs its selector, which cannot be discovered without guessing. | |
| findings | array | yes | What needs attention, worst first. |
| nameservers | object | yes | What the domain's own nameservers said when each was asked directly, over TCP port 53 with recursion off. This is the only way to see a nameserver left in the delegation after a migration, or a zone… |
| registrableDomain | string | yes | The domain registration was checked against, e.g. "example.co.uk". |
| registration | object | yes | What the registry publishes about this registration. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| unicodeDomain | string|null | yes | The Unicode form when the domain is internationalised, otherwise null. |
No examples provided.
health Server health ~127
Confirms that the upkeep-mcp server is running and reports which version it is. Use this to verify the connection after installing or reconfiguring the server, or when another upkeep-mcp tool behaves unexpectedly and you need to establish whether the server itself is reachable. Do not use it to check whether a website is up — it says nothing about any domain or URL, only about this server process. Use uptime_check for websites. Returns the server name and version, the Node.js version it runs under, how long the process has been alive, and the time of the check.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| checkedAt | string | yes | When the report was produced, ISO 8601 with timezone. |
| node | string | yes | Node.js version the server runs under, e.g. "v20.11.0". |
| server | string | yes | Server name, e.g. "upkeep-mcp". |
| status | string | yes | Always "ok". If the server can answer, it is healthy. |
| uptimeSeconds | integer | yes | Whole seconds since the server process started. |
| version | string | yes | Server version, e.g. "0.1.0". |
No examples provided.
portfolio_report Whole portfolio, ranked by urgency ~636
Runs the maintenance checks across every site in a portfolio and returns one report ordered by what needs action first: what is down, what expires soonest, what regressed since the last run. Use it to answer "what needs attention this week?", "is anything down?" or "what do I put in this quarter's report?" across a whole client list. It is the right call whenever the question is about more than one site — running domain_check, ssl_check and uptime_check once per site by hand is what this replaces. The portfolio comes from the "sites" argument, or from a local JSON file ("sites.json" by default) whose format is documented in sites.example.json. Pass "checks" to override what each site asks for — ["uptime"] answers "is anything down right now?" in a fraction of the time — and "tags" to report on part of the portfolio. Do not use it to answer a question about one site: domain_check, ssl_check, uptime_check and seo_audit answer those directly and in a fraction of the time. It runs checks and reports; it never changes a site, and it never writes to the portfolio file. A site that cannot be checked is reported as a finding, never as a failure of the whole report. Only a portfolio that cannot be read at all is an error. What changed since the previous run is compared against one recorded snapshot. By default that snapshot lives in memory and is lost when this server restarts; a portfolio file may add a "history" path, and then the snapshot is written there and comparisons survive a restart for up to 90 days. Nothing is written unless the portfolio asks for it. Either way the report says what it had to compare against, and why it had nothing when it had nothing, rather than implying nothing changed. Only sites that both runs measured the same way are compared, so a quick uptime-only pass never invents regressions in the run after it.
| Name | Type | Req | Description |
|---|---|---|---|
| checks | array | – | Run exactly these checks for every site, ignoring what the file says. Use it for a quick pass — ["uptime"] answers "is anything down right now?" in a fraction of the time. |
| file | string | – | Path to a portfolio JSON file, e.g. "/Users/you/sites.json". Give the full path: a relative one is resolved against the directory this server was started in, which for a desktop client is usually "/"… |
| sites | array | – | The portfolio, passed inline. Use this for a one-off report over a handful of sites. When omitted, the portfolio is read from the local file instead. |
| tags | array | – | Only report on sites carrying at least one of these tags, e.g. ["retainer"]. Matched case-insensitively. Omit to report on the whole portfolio. |
| Name | Type | Req | Description |
|---|---|---|---|
| changes | object | yes | What changed since the previous run in this server process. |
| file | string|null | yes | The file it was read from, when it was read from one. |
| generatedAt | string | yes | When the report was produced, ISO 8601 in UTC. |
| needsAttention | array | yes | Everything worth acting on, worst first. This is the list the report exists to produce. |
| notes | array | yes | Anything the report could not do, said plainly rather than left out. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| siteCount | integer | yes | How many sites the report covers, after any tag filter. |
| sites | array | yes | Every site, most urgent first. |
| source | string | yes | Where the portfolio came from. |
| summary | object | yes | How many sites landed at each severity. |
No examples provided.
seo_audit Technical SEO of one page ~467
Reads one page and reports the technical SEO facts a maintenance retainer is judged on: title and meta description, heading structure, canonical, Open Graph, hreflang, language, viewport, images with no alt text, the state of robots.txt and the sitemap, and which internal links are broken. The sitemap is checked against the rules of the sitemaps protocol, so a file that exists but that consumers drop is reported as broken rather than as present. Use it to answer "why is this page not being indexed?", "does this page have the metadata it needs?" or "are there broken links on the homepage?". It is the check to run before a quarterly report, and after a site rebuild. Do not use it to check whether a site is up, which is uptime_check, or to inspect a certificate, which is ssl_check. It audits one page: it does not crawl a site, and it judges only what is in the HTML, never how a page ranks. robots.txt is read first and obeyed. A page this crawler is not allowed to read is reported as such and is not requested — and neither are internal links it forbids. An unreadable robots.txt is treated as forbidding everything, per RFC 9309. Link checking is one HTTP request per link, paced politely, so an audit with links takes seconds rather than milliseconds; pass checkLinks: false when speed matters more. Returns findings ordered by urgency, worst first.
| Name | Type | Req | Description |
|---|---|---|---|
| checkLinks | boolean | – | Whether to request each internal link to find broken ones. Defaults to true. Set it to false for a fast metadata-only audit: link checking is one request per link and is what makes this tool take sec… |
| maxLinks | integer | – | How many internal links to check at most. Defaults to 25. Links beyond the limit are counted and reported as unchecked, never silently ignored. |
| url | string | yes | The page to audit, e.g. "https://example.com/pricing". A bare domain such as "example.com" is accepted and read over HTTPS. One page is audited, not a whole site, so pass the page you care about; the… |
| Name | Type | Req | Description |
|---|---|---|---|
| checkedAt | string | yes | When the audit ran, ISO 8601 in UTC. |
| contentType | string|null | yes | Content type, without parameters, e.g. "text/html". |
| fetched | boolean | yes | Whether the page was read at all. False when robots.txt forbids it. |
| finalUrl | string|null | yes | Where it ended up after redirects. |
| findings | array | yes | What needs attention, worst first. |
| links | object | yes | Internal link health. Only internal links are requested; external ones are counted. |
| page | object | yes | What the document itself says. |
| robots | object | yes | What the host publishes about crawling, and what it means for this audit. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| sitemap | object | yes | The sitemap declared in robots.txt, or /sitemap.xml when none is declared. |
| status | – | yes | HTTP status of the page. |
| truncated | boolean | yes | Whether the document was longer than the read limit and was cut off. |
| url | string | yes | The URL that was requested. |
No examples provided.
site_crawl Technical SEO across a site ~575
Walks a site from a starting page and reports what only a crawl can see: pages sharing a title or a meta description, internal links that are broken and which page links to them, pages asking not to be indexed, and how much of the site was reachable at all. Use it after a site rebuild or a migration, and before a quarterly report — the findings here are the ones a client never notices and a search engine always does. Use it to answer "why are these pages competing with each other?", "are there broken links", anywhere on the site?" or "is anything still marked noindex from staging?". Do not use it to audit one page in depth — that is seo_audit, which reports canonical, Open Graph, hreflang, images without alt text and the sitemap for a single URL. Do not use it to check whether a site is up (uptime_check) or to inspect a certificate (ssl_check). It judges only what is in the HTML, never how a page ranks. It stays on one origin: https://example.com and https://www.example.com are different origins and only the one you start from is visited. robots.txt is read first and obeyed for every URL before it is requested. An unreadable robots.txt is treated as forbidding everything, per RFC 9309, and the crawl reports that rather than proceeding. It costs one request per page, paced at one every half second per host, so 25 pages is about fifteen seconds. Three budgets bound it — pages, depth, and a two-minute deadline — and whichever one stopped the crawl is reported along with how many URLs were left unvisited, because a report that does not say it saw a quarter of the site is worse than no report.
| Name | Type | Req | Description |
|---|---|---|---|
| maxDepth | integer | – | How many links deep from the starting page to follow. Defaults to 3. 0 fetches only the starting page. Three reaches everything a small business site has; past that the page budget is the real bound… |
| maxPages | integer | – | How many pages to fetch. Defaults to 25, at most 100. Every page is one request paced at one every half second, so this is the cost: 25 pages is about fifteen seconds, 100 about a minute. Pages found… |
| url | string | yes | The page to start from, e.g. "https://example.com/" — a full URL with scheme. The crawl stays on this URL's origin, so start at the address the site actually serves: https://example.com and https://w… |
| Name | Type | Req | Description |
|---|---|---|---|
| broken | array | yes | Internal links that did not answer with a usable status, with the page each was found on — which is the half of a broken link report that makes it fixable. |
| checkedAt | string | yes | When the crawl ran, ISO 8601 in UTC. |
| crawl | object | yes | What the crawl covered, and what it did not. |
| duplicates | object | yes | What only a crawl can see. One page cannot tell you that its title is the same as forty others', and that is the commonest reason a site's pages compete with each other in search results. |
| findings | array | yes | What needs attention, worst first. |
| origin | string | yes | The origin it stayed on, e.g. "https://example.com". |
| pages | array | yes | Every page fetched, in the order they were visited. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| startUrl | string | yes | The URL the crawl was asked to start from. |
No examples provided.
ssl_check SSL certificate ~458
Inspects the TLS certificate a host actually serves: when it expires, who issued it, whether the chain verifies, which hostnames it covers, and which TLS version was negotiated. Use it to answer "when does this certificate need renewing?", "why does the browser warn about this site?" or "does the certificate cover www as well as the bare domain?" — the last being one of the most common real-world misconfigurations, along with a missing intermediate certificate, which is reported as UNABLE_TO_VERIFY_LEAF_SIGNATURE. Do not use it for domain registration expiry, which is a different date entirely — that is domain_check. It connects to the host but does not request a page; use uptime_check for that. Certificates that are expired, self-signed or untrusted are inspected and reported rather than refused. Revocation is checked over OCSP, preferring the response a server staples to the handshake and otherwise asking the issuing authority directly; the answer is only believed once its signature verifies against that authority. Many healthy certificates cannot be checked at all, because since 2025 the two largest issuers publish no OCSP responder and distribute revocation by CRL instead — that is reported as an unavailable reason rather than as a problem with the site, and produces no finding. Certificate revocation lists are not downloaded. A certificate is reported as a warning inside 14 days and as critical inside seven. That window is deliberately shorter than the one domain_check uses for registrations: ACME clients renew with 30 days left, so 28 days remaining is a healthy site in the middle of a normal renewal, not a problem. Returns findings ordered by urgency, worst first.
| Name | Type | Req | Description |
|---|---|---|---|
| domain | string | yes | The host whose certificate should be inspected, e.g. "example.com" — no scheme, no trailing slash. A full URL is also accepted and reduced to its hostname. The certificate is read for exactly this ho… |
| port | integer | – | TCP port to connect to. Defaults to 443. Use 8443, 993 and so on for other services. |
| Name | Type | Req | Description |
|---|---|---|---|
| chain | object | yes | The certificate chain and whether it verified. |
| checkedAt | string | yes | When the check ran, ISO 8601 in UTC. |
| coverage | object | yes | Which hostnames this certificate is valid for. |
| daysUntilExpiry | – | yes | Whole days until the certificate expires, negative if already expired. Floored, so a certificate expiring in a few hours reads as 0. |
| expiresAt | – | yes | When the certificate expires, ISO 8601 UTC. |
| findings | array | yes | What needs attention, worst first. |
| fingerprintSha256 | string|null | yes | SHA-256 fingerprint of the certificate. |
| host | string | yes | The host that was contacted, in ASCII (punycode) form. |
| issuedAt | – | yes | Start of the certificate validity, ISO 8601 UTC. |
| issuer | string|null | yes | Issuer common name, e.g. "R11" or "GTS CA 1P5". |
| port | integer | yes | The port that was contacted. |
| revocation | object | yes | Whether the certificate has been revoked, and how confidently that was established. |
| serialNumber | string|null | yes | Certificate serial number, hexadecimal. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| subject | string|null | yes | Subject common name. |
| tls | object | yes | What the handshake negotiated. |
No examples provided.
uptime_check Site reachability and headers ~322
Requests a page and reports whether it answered, how long it took, the full redirect chain it went through, whether plain HTTP is upgraded to HTTPS, and which security headers came back. Use it to answer "is this site up?", "why does this URL take four redirects to load?", "does http:// still work and should it?" or "does this site send HSTS?". It is the check to run when a client reports that a page is down or slow. Do not use it to inspect a certificate — that is ssl_check — or for registration and DNS, which is domain_check. It fetches one page, not a whole site: use seo_audit for crawling. Redirects are followed one hop at a time so the whole chain is visible, up to ten hops. Response time is wall clock to the first response headers and includes DNS, TCP and TLS setup, so it is not a measure of server processing time. Status codes are graded rather than lumped together: 5xx, 404 and 410 are critical, 401 and 403 are a warning because they are normal for a staging site, and 429 is reported as unknown because a throttled check establishes nothing about real availability. Returns findings ordered by urgency, worst first.
| Name | Type | Req | Description |
|---|---|---|---|
| url | string | yes | The page to request, e.g. "https://example.com". A bare domain such as "example.com" is accepted and tried over HTTPS. Include the path when a specific page matters; the homepage is checked otherwise. |
| Name | Type | Req | Description |
|---|---|---|---|
| checkedAt | string | yes | When the check ran, ISO 8601 in UTC. |
| finalUrl | string|null | yes | Where the redirect chain ended. |
| findings | array | yes | What needs attention, worst first. |
| hsts | object | yes | The HSTS policy, read from the HTTPS response only. |
| https | object | yes | Whether visitors arriving over plain HTTP are moved to HTTPS. |
| reachable | boolean | yes | Whether the server answered at all. |
| redirects | object | yes | The redirect chain, followed manually one hop at a time. |
| responseTimeMs | – | yes | Wall-clock milliseconds to the first response headers. Includes DNS, TCP and TLS setup, so it is not server processing time. |
| securityHeaders | object | yes | Security-relevant response headers. |
| severity | string | yes | How much attention this needs. "critical" means act now; "warning" means act this month; "unknown" means the check could not establish the fact, which is not the same as it being fine. |
| status | – | yes | Status code at the end of the redirect chain. |
| url | string | yes | The URL that was requested first. |
No examples provided.
What is the upkeep-mcp server?
upkeep-mcp is listed in the public MCP registry as io.github.tiagocalado86/upkeep-mcp. Website maintenance checks: domains, SSL, uptime, technical SEO and accessibility. This page covers its npm package (upkeep-mcp).
Is the upkeep-mcp server safe to use?
upkeep-mcp scores 89 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the upkeep-mcp server expose?
upkeep-mcp exposes 8 tools: health, domain_check, ssl_check, uptime_check, seo_audit, and 3 more. Their descriptions and schemas cost roughly 3,592 tokens of context every time the server is loaded.
Is the upkeep-mcp server still maintained?
upkeep-mcp is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the upkeep-mcp server under?
upkeep-mcp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.