Skip to main content
Glama

Devops Check Certs

devops_check_certs
Read-onlyIdempotent

Inspect SSL/TLS certificate health for one or more domains by performing a real TLS handshake. Works for any internet-accessible domain — no vendor registry required. Reports days to expiry (flagged at < 30 days warning and < 7 days critical), certificate subject and SANs, issuer, hostname coverage, chain-trust verification, TLS protocol version negotiated (flags TLS 1.0/1.1 as insecure), cipher suite, and HSTS presence. The handshake completes even for a certificate clients would reject, so a broken certificate is reported rather than hidden behind a connection error: a hostname mismatch surfaces in cert.hostname_verification_error and a chain-trust failure (self-signed, untrusted root) in cert.authorization_error, both status "critical". If a domain fails to connect at all, check devops_check_dns first — the name may not resolve.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
portNoTLS port. Defaults to 443. Use 8443 or custom ports for non-standard HTTPS endpoints.
domainsYesDomains to inspect. Do not include "https://" — pass the bare hostname. Up to 10 per call.
timeout_msNoConnection timeout per domain in milliseconds. Defaults to the DEVOPS_STATUS_CERT_TIMEOUT_MS env var (5000 when unset). Increase for slow or geographically distant endpoints.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
resultsNoPer-domain certificate inspection results.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "results"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `invalid_domain`: A domain string contains a protocol prefix or invalid characters. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "invalid_domain"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "results"
      -]
  2. Changed3 schema fields changed
    • changedOutput schema / properties / results / items / properties / cert / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "chain_depth": {
      -        "description": "Number of certificates in the chain (1 = self-signed).",
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "days_until_expiry": {
      -        "description": "Days remaining until certificate expiry. Negative = already expired.",
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "issuer": {
      -        "description": "Issuer common name.",
      -        "type": "string"
      -      },
      -      "san": {
      -        "description": "Subject Alternative Names covered by this certificate.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "serial": {
      -        "description": "Certificate serial number.",
      -        "type": "string"
      -      },
      -      "subject": {
      -        "description": "Certificate subject CN.",
      -        "type": "string"
      -      },
      -      "valid_from": {
      -        "description": "ISO 8601 UTC timestamp of certificate validity start.",
      -        "type": "string"
      -      },
      -      "valid_until": {
      -        "description": "ISO 8601 UTC timestamp of certificate expiry.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "subject",
      -      "san",
      -      "issuer",
      -      "valid_from",
      -      "valid_until",
      -      "days_until_expiry",
      -      "chain_depth",
      -      "serial"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "authorization_error": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "OpenSSL chain-verification code when the certificate chain does not validate against the system trust store, or null when it validates. Common values: \"DEPTH_ZERO_SELF_SIGNED_CERT\" (self-signed leaf), \"SELF_SIGNED_CERT_IN_CHAIN\" / \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\" (issuing root not trusted), \"CERT_HAS_EXPIRED\" (also reported in \"days_until_expiry\"). This is the authoritative chain-trust signal — the issuer and subject fields alone cannot detect an untrusted root."
      +      },
      +      "chain_depth": {
      +        "anyOf": [
      +          {
      +            "maximum": 9007199254740991,
      +            "minimum": -9007199254740991,
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Number of certificates the server sent, counting the leaf. Null when the runtime does not expose the issuer chain — read \"chain_depth_unavailable_reason\" in that case. Not a self-signed indicator: use \"authorization_error\" for that."
      +      },
      +      "chain_depth_unavailable_reason": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Why \"chain_depth\" is null, or null when a depth was measured. Absence of a depth is a runtime limitation, not a finding about the certificate."
      +      },
      +      "days_until_expiry": {
      +        "description": "Days remaining until certificate expiry. Negative = already expired.",
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "hostname_verification_error": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Node's hostname-verification message when the requested domain is not covered by the certificate's CN or SANs (e.g. \"Hostname/IP does not match certificate's altnames: …\"), or null when the hostname is covered. A non-null value means ordinary clients reject this certificate for this hostname; compare against the \"san\" list to see what it does cover."
      +      },
      +      "issuer": {
      +        "description": "Issuer common name.",
      +        "type": "string"
      +      },
      +      "san": {
      +        "description": "Subject Alternative Names covered by this certificate.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "serial": {
      +        "description": "Certificate serial number.",
      +        "type": "string"
      +      },
      +      "subject": {
      +        "description": "Certificate subject CN.",
      +        "type": "string"
      +      },
      +      "valid_from": {
      +        "description": "ISO 8601 UTC timestamp of certificate validity start.",
      +        "type": "string"
      +      },
      +      "valid_until": {
      +        "description": "ISO 8601 UTC timestamp of certificate expiry.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "subject",
      +      "san",
      +      "issuer",
      +      "valid_from",
      +      "valid_until",
      +      "days_until_expiry",
      +      "chain_depth",
      +      "chain_depth_unavailable_reason",
      +      "hostname_verification_error",
      +      "authorization_error",
      +      "serial"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / results / items / properties / flags / description
      Previous value: -"Human-readable warnings and issues found: \"expires in 12 days\", \"TLS 1.1 in use\", \"self-signed certificate\", \"HSTS present\", etc."New value: +"Human-readable warnings and issues found: \"Expires in 12 days (warning)\", \"Certificate expired 40 days ago\", \"Hostname mismatch — the certificate does not cover api.example.com; clients will reject it\", \"Certificate chain not trusted (SELF_SIGNED_CERT_IN_CHAIN); clients will reject it\", \"Self-signed certificate\", \"Insecure TLS version in use: TLSv1.1\", \"HSTS present\" / \"HSTS not configured\"."
    • changedOutput schema / properties / results / items / properties / status / description
      Previous value: -"Overall status: ok, warning (< 30 days), critical (< 7 days or insecure TLS), or error (connection failed)."New value: +"Overall status. \"critical\" — the certificate expires in < 7 days or has already expired, the hostname is not covered by the certificate, chain verification failed (self-signed or untrusted root), or an insecure TLS version was negotiated; every one of these is rejected by ordinary clients. \"warning\" — expires in < 30 days. \"ok\" — none of the above. \"error\" — the connection failed and no certificate was retrieved."
  3. Changed2 schema fields changed
    • addedInput schema / properties / domains / items / minLength
      Added value: +1
    • removedInput schema / properties / domains / items / pattern
      Removed value: -"^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
  4. Changed1 schema field changed
    • changedInput schema / properties / timeout_ms / description
      Previous value: -"Connection timeout per domain in milliseconds. Increase for slow or geographically distant endpoints."New value: +"Connection timeout per domain in milliseconds. Defaults to the DEVOPS_STATUS_CERT_TIMEOUT_MS env var (5000 when unset). Increase for slow or geographically distant endpoints."
  5. Added

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations mark this as readOnly, openWorld, and idempotent, but the description adds substantial behavioral context: the handshake completes even for broken certificates, failure modes are surfaced as specific fields (cert.hostname_verification_error, cert.authorization_error) with 'critical' status, and TLS 1.0/1.1 are flagged insecure. This goes far beyond the annotations and clarifies edge-case behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a dense paragraph where every clause adds value: it front-loads the core purpose, enumerates reported attributes, explains graceful handling of broken certs, and ends with a concrete fallback. There is no redundancy or filler; each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (certificate attributes, TLS versions, HSTS, chain trust), the description covers the full behavioral scope, including failure modes and how they are reported. An output schema exists but the description adds meaning to fields like hostname_verification_error and authorization_error. The fallback hint completes the contextual picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents domains, port, and timeout_ms with usage tips (e.g., 'Do not include https://'). The description adds no parameter-specific meaning beyond the schema; it mentions 'one or more domains' but that is already reflected in the schema's minItems. The baseline of 3 is appropriate since the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Inspect SSL/TLS certificate health') and states it performs a real TLS handshake on any internet-accessible domain. It clearly distinguishes the tool's scope from siblings by noting it works without a vendor registry, and later points to devops_check_dns as an alternative for connection failures.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly gives when to use the tool (any domain, no registry needed), what it reports, and when to fall back to a sibling ('If a domain fails to connect at all, check devops_check_dns first'). This is a clear, actionable usage guide that routes an agent to the correct sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.4/5.0
Disambiguation5/5

Each tool targets a distinct aspect of DevOps status monitoring: certificate health, DNS resolution, incident history, vendor discovery, current status, action suggestions, and stack monitoring. Even the overlapping status_check and watch_stack have clear differences (arbitrary targets vs saved stacks). No ambiguity.

Naming Consistency4/5

All tools share the devops_ prefix and mostly follow a verb_noun pattern (check_certs, check_dns, get_incidents, list_vendors, suggest_action, watch_stack). The exception is devops_status_check, which inverts to noun_verb, but it's still readable and doesn't cause confusion.

Tool Count5/5

7 tools is well within the 3-15 sweet spot for a domain-specific server. Each tool covers a necessary function with no redundancy or bloat, making the surface area easy to navigate.

Completeness4/5

The tool set covers the core lifecycle of DevOps status monitoring: discovery, health checks, incident lookup, certificate and DNS checks, and actionable recommendations. Minor gaps like a dedicated tool for viewing a single incident in isolation are mitigated by filtering in get_incidents. The stack management is a bonus that adds convenience.