toolhq.io

skills / network and email

tls-triage

Certificate faults on a live host, including the browser caching trap that makes a broken chain look healthy.

SKILL.md

Save as .claude/skills/tls-triage/SKILL.md in a repository, or under ~/.claude/skills/tls-triage/SKILL.md to have it everywhere. The copy button takes the whole file, frontmatter included.

---
name: tls-triage
description: Diagnose TLS and certificate faults on a live host, including expiry, incomplete chains, hostname mismatches, untrusted roots and key mismatches. Use when a site shows a certificate warning, a client reports an expired or untrusted certificate, curl or a mail client fails where a browser works, or someone asks whether a chain is complete.
---

# TLS triage

Run `ssl_check` first and work from what it returns. Never state an expiry
date, issuer or chain contents from memory.

If the service is not on 443, pass the port explicitly. Mail submission on 587
and management interfaces on 8443 are common and easy to forget.

## Requires

The toolhq MCP server, for `ssl_check` and `dns_lookup`:

    claude mcp add --transport http toolhq https://toolhq.io/api/mcp

If the check is unavailable, say so and stop rather than describing a likely
certificate.

## The rule that prevents most wrong answers

**A working browser is not evidence that the chain is complete.**

Browsers cache intermediate certificates from other sites they have visited,
and some will fetch a missing one from the URL in the certificate's authority
information access extension. So a browser will often complete a chain the
server failed to send.

Almost nothing else does this. curl, Java, Python, Go and most mail servers use
exactly what the server sent. The same host therefore works in Chrome and fails
everywhere that matters, which is the most reported and most misdiagnosed TLS
symptom there is.

When someone says "it works in my browser", treat that as unverified and run
the check.

## Order of investigation

### 1. Expiry

The most common cause and the quickest to confirm. Report the exact date. If it
expires within thirty days, say so even when it is not the present fault.

### 2. Chain completeness

The most commonly misdiagnosed cause. The server must send the leaf first, then
every intermediate up to, but not including, a trusted root. Sending the root
is harmless but pointless. Omitting an intermediate breaks every client without
a cached copy.

If an intermediate is missing, the fix is a server configuration change, not a
reissue. Do not tell the user to buy or regenerate a certificate for a chain
fault.

### 3. Hostname match

The requested name must appear in the subject alternative names. The common
name alone is no longer sufficient for modern clients.

Wildcards cover exactly one label: `*.example.com` matches `www.example.com`
and does not match `a.b.example.com` or bare `example.com`.

### 4. Trust

A chain that is complete and unexpired but still untrusted means the root is
absent from that client's trust store. Internal CAs and self signed
certificates land here. The fix is distributing the root, not changing the
server.

### 5. Key and certificate agreement

If the server refuses to start or serves the wrong certificate, the private key
may not match. Compare the public key moduli rather than guessing from
filenames.

## Report back

1. The cause, in one sentence.
2. The evidence from the check: dates, issuer, and the chain as served.
3. The fix, as the specific change to make, and on which side.
4. Anything you could not verify.

what it needs

This one looks things up rather than describing them, so it needs live checks. Instructions cannot reach the network on their own, and a skill running through the Claude API has no network access at all. Add the toolhq MCP server and these become real: ssl_check, dns_lookup.

toolhq — mcp
$ claude mcp add --transport http toolhq https://toolhq.io/api/mcp

the instructions, in full

TLS triage

Run ssl_check first and work from what it returns. Never state an expiry date, issuer or chain contents from memory.

If the service is not on 443, pass the port explicitly. Mail submission on 587 and management interfaces on 8443 are common and easy to forget.

Requires

The toolhq MCP server, for ssl_check and dns_lookup:

claude mcp add --transport http toolhq https://toolhq.io/api/mcp

If the check is unavailable, say so and stop rather than describing a likely certificate.

The rule that prevents most wrong answers

A working browser is not evidence that the chain is complete.

Browsers cache intermediate certificates from other sites they have visited, and some will fetch a missing one from the URL in the certificate's authority information access extension. So a browser will often complete a chain the server failed to send.

Almost nothing else does this. curl, Java, Python, Go and most mail servers use exactly what the server sent. The same host therefore works in Chrome and fails everywhere that matters, which is the most reported and most misdiagnosed TLS symptom there is.

When someone says "it works in my browser", treat that as unverified and run the check.

Order of investigation

1. Expiry

The most common cause and the quickest to confirm. Report the exact date. If it expires within thirty days, say so even when it is not the present fault.

2. Chain completeness

The most commonly misdiagnosed cause. The server must send the leaf first, then every intermediate up to, but not including, a trusted root. Sending the root is harmless but pointless. Omitting an intermediate breaks every client without a cached copy.

If an intermediate is missing, the fix is a server configuration change, not a reissue. Do not tell the user to buy or regenerate a certificate for a chain fault.

3. Hostname match

The requested name must appear in the subject alternative names. The common name alone is no longer sufficient for modern clients.

Wildcards cover exactly one label: *.example.com matches www.example.com and does not match a.b.example.com or bare example.com.

4. Trust

A chain that is complete and unexpired but still untrusted means the root is absent from that client's trust store. Internal CAs and self signed certificates land here. The fix is distributing the root, not changing the server.

5. Key and certificate agreement

If the server refuses to start or serves the wrong certificate, the private key may not match. Compare the public key moduli rather than guessing from filenames.

Report back

  1. The cause, in one sentence.
  2. The evidence from the check: dates, issuer, and the chain as served.
  3. The fix, as the specific change to make, and on which side.
  4. Anything you could not verify.

check its answers by hand

A skill that reasons well about wrong data is still wrong. For the first few cases, run the same question through a tool that cannot be mistaken.

SSL Chain Fixer

Find a missing intermediate certificate and get a corrected fullchain.pem for your server.

Open the tool
SSL Checker

Inspect a host's TLS certificate chain, expiry, trust, protocol, and hostname match.

Open the tool
Key Matcher

Check whether a PEM private key matches a certificate. The key is parsed locally in your browser.

Open the tool
CA Matcher

Verify that a CA certificate signed an end-entity certificate. Parsed locally in your browser.

Open the tool

why it is written this way

A SKILL.md for certificate triage: why the browser is not evidence, how to read a chain correctly, and the order that finds the real cause first.

An agent skill for SSL and certificate work