# pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12 without a key byte leaving (npm · pkinative-mcp)

PKI MCP server: inspect, verify, issue, sign X.509, CSR, CRL, OCSP, CMS, TSP, PKCS#12. 34 tools

- Trust score: 81/100 (high trust)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-22

## Components

- npm · `pkinative-mcp`: 81/100 (this document), [markdown](https://verifymcp.io/servers/nizoka-pkinative-mcp/pkinative-mcp.md), [page](https://verifymcp.io/servers/nizoka-pkinative-mcp/pkinative-mcp)

## Channel facts

- Registry: `npm`
- Package: `pkinative-mcp`
- Version: `1.0.0`
- Transport: `stdio`

## Trust breakdown

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. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-22.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 0 of 4 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 100/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to Nizoka/pkinative-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 4 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 71/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 30550 tokens (~898/item across 34 items; 34 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 34 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 35 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… server?

pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… runs locally as an npm package, launched with npx -y pkinative-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add nizoka-pkinative-mcp -- npx -y pkinative-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "nizoka-pkinative-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "pkinative-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "nizoka-pkinative-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "pkinative-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add nizoka-pkinative-mcp -- npx -y pkinative-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "nizoka-pkinative-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "pkinative-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add nizoka-pkinative-mcp --command npx --arg -y --arg pkinative-mcp
```

### Hermes

```yaml
mcp_servers:
  nizoka-pkinative-mcp:
    command: "npx"
    args: ["-y", "pkinative-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "nizoka-pkinative-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "pkinative-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add nizoka-pkinative-mcp -t stdio -c npx -a -y pkinative-mcp
```

### Other

```json
{
  "mcpServers": {
    "nizoka-pkinative-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "pkinative-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-18 (score 81, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-10-17 (score 66)

First indexed and scored.

## MCP tools (34)

### `convert_pem` (~982 tokens)

Convert PEM (list and extract blocks, or wrap DER)

The RFC 7468 layer. mode:'decode' lists every block of a PEM text (index, label, DER size, offset, RFC 1421 headers under pemMode:'lax', SHA-256 of the DER) — `label` keeps one kind, `extractIndex` also delivers that block as an artefact (encoding 'der' by default, 'pem' or 'hex'; inline as an embedded resource, or as a sandbox file with outputMode:'file' + outputPath, never overwritten). mode:'encode' wraps DER bytes (derBase64 or a DER file path) into one strict PEM block under `label` (required) and delivers it as the artefact (64-character lines, LF). A private-key block (PRIVATE KEY, ENCRYPTED PRIVATE KEY, RSA/EC/DSA PRIVATE KEY) is listed by label and size but never extracted, and never produced: SECURITY_VIOLATION (use inspect_private_key) — DER that parses as a PKCS#8 key or a PKCS#12 file is refused under ANY label. Refuses: derBase64 in decode, pem in encode, an encoding other than 'pem' in encode, a file output without extractIndex (VALIDATION_ERROR); an index past the last block (NOT_FOUND); a label absent from the text (PKI_PEM_UNEXPECTED_LABEL); a malformed text (PKI_PEM_* — pemMode:'lax' tolerates whitespace, line length and headers; a missing base64 padding is refused in both modes). Token-frugal: verbosity:'summary' (count + labels), fields:[…].

Input parameters:

- `encoding` (string): Artefact encoding. decode + extractIndex: 'der' (default, raw bytes), 'pem' (the block re-emitted strictly) or 'hex' (inline only, ≤ 64 KiB). encode: always 'pem' (anything else is VALIDATION_ERROR).
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `extractIndex` (integer): decode: also deliver the block with this index (its position in the text, as listed) as an artefact in `encoding`. A private-key block cannot be extracted (SECURITY_VIOLATION).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `input` (object, required): The PEM text (decode: pem or a path to a PEM file) or the DER bytes (encode: derBase64 or a path to a DER file): exactly one of pem / derBase64 / path.
- `label` (string): decode: list only the blocks with this label. encode: the label of the block (required; e.g. 'CERTIFICATE'). Upper-case words and digits separated by single spaces; a private-key label is refused (SE…
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `mode` (string, required): 'decode' lists the blocks of a PEM text (and extracts one with extractIndex); 'encode' wraps DER bytes into one PEM block.
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.der .crt .cer .csr .crl .p7s .bin … for der; .pem for pem). Key-bearing extensions (.key .p8 .p…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `artefact` (object): The artefact delivered alongside the report: its facts here, its bytes once as the embedded resource (or the resource_link in file mode).
- `blocks` (array): decode: every block of the text (or those with `label`), in order. A private-key block is listed by label and size only.
- `count` (integer): decode: number of blocks listed.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `extracted` (object): decode: the block delivered as the artefact.
- `label` (string): encode: the label written.
- `labels` (array): decode: the label of every block listed.
- `mode` (string)
- `sha256` (string): encode: SHA-256 of the DER wrapped (lowercase hex).
- `sizeBytes` (integer): encode: the DER size wrapped.

### `resolve_oid` (~851 tokens)

Resolve OID (name, validate, list, encode, decode)

Object identifiers in one call. mode:'name' → the registered name of each dotted OID (null when unregistered; ≤ 1000 per call); 'validate' → X.660 validity of each (at least two arcs, first arc 0–2, second ≤ 39 under 0 and 1, no leading zeros — reported, never an error); 'list' → the engine's registry (oid, name, standard), filtered by a case-insensitive substring of the name or the OID, paged with offset / limit (default 200, ≤ 2000); 'encode' → the X.690 bytes of each OID as hex, form 'content' (base-128 content octets, default) or 'tlv' (tag + length + content), relative:true for a RELATIVE-OID (tlv only); 'decode' → the dotted OID of hex octets (content, or a whole TLV with form:'tlv') with its name. Refuses: a member outside its mode, relative without form:'tlv' (VALIDATION_ERROR); an invalid OID in encode (PKI_OID_INVALID — validate reports it instead); malformed octets in decode (PKI_OID_INVALID, PKI_ASN1_*). Token-frugal: verbosity:'summary', fields:[…].

Input parameters:

- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `filter` (string): list: case-insensitive substring of the name or the dotted OID.
- `form` (string): encode / decode: 'content' (the base-128 content octets only) or 'tlv' (tag + length + content, i.e. the whole DER value).
- `hex` (string): decode: the octets to decode (content octets, or the whole TLV with form:'tlv'). Hexadecimal (an 0x prefix, colons and spaces are tolerated).
- `input` (object): decode: the encoded OBJECT IDENTIFIER as a whole DER TLV (or any PEM block holding one): exactly one of pem / derBase64 / path. Exclusive with hex; implies form:'tlv'.
- `limit` (integer): list: page size (≤ 2000).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `mode` (string, required): 'name' (registered names), 'validate' (X.660 validity), 'list' (the registry, paged), 'encode' (dotted → hex), 'decode' (hex → dotted + name).
- `offset` (integer): list: first entry returned.
- `oids` (array): name / validate / encode: the dotted OIDs (≤ 1000).
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `relative` (boolean): encode / decode: a RELATIVE-OID (X.690 §8.20, universal tag 13) instead of an OBJECT IDENTIFIER — needs form:'tlv' (the engine encodes a relative OID as a whole TLV only).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `allValid` (boolean): validate: true when every OID is valid.
- `count` (integer): Number of OIDs / entries in the result.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `entries` (array): list: the page of registry entries.
- `hasMore` (boolean)
- `limit` (integer)
- `mode` (string)
- `name` (string|null): decode: the registered name (null when unregistered or relative).
- `offset` (integer)
- `oid` (string): decode: the dotted OID.
- `oids` (array): name: { oid, name|null }; validate: { oid, valid }; encode: { oid, hex }.
- `total` (integer): list: entries matching the filter.

### `compute_fingerprint` (~812 tokens)

Compute fingerprint (DER digest, key identifier, SHAKE256)

Read-only digest of ONE object. mode:'fingerprint' (default) hashes the exact DER of the input (SHA-256 by default; SHA-1 / SHA-384 / SHA-512; webcrypto:true uses Web Crypto, same result) — what openssl x509 -fingerprint prints; mode:'key-id' computes the RFC 5280 §4.2.1.2 key identifier (SHA-1 by default, or SHA-256) of the public key found in a certificate, a CSR or a PUBLIC KEY, reporting where it came from; mode:'shake256' squeezes outputLength bytes (default 32, ≤ 1048576) of SHAKE256 — the digest of an Ed448 CMS signer. `hex` is lowercase without separators, `formatted` follows separator (':' default) and letterCase (upper default). Any PEM label or DER is accepted (a private key may be digested: the digest reveals nothing and no input byte is returned); a bundle of several blocks is refused (extract one with convert_pem). Refuses: an algorithm outside its mode, SHA-384/512 for a key identifier, outputLength or webcrypto outside their mode (VALIDATION_ERROR); key-id on an object that holds no public key (PKI_X509_* / PKI_ASN1_*). Token-frugal: verbosity:'summary', fields:[…].

Input parameters:

- `algorithm` (string): fingerprint: SHA-1 | SHA-256 (default) | SHA-384 | SHA-512. key-id: SHA-1 (default, RFC 5280 method 1) | SHA-256. Not for shake256.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `input` (object, required): The object to digest (any PEM label, or DER): exactly one of pem / derBase64 / path. A bundle of several blocks is refused: extract one with convert_pem.
- `letterCase` (string): Hex case of `formatted` (`hex` is always lowercase).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `mode` (string): 'fingerprint' (default): the digest of the exact DER. 'key-id': the RFC 5280 §4.2.1.2 identifier of the public key of a certificate, a CSR or a PUBLIC KEY. 'shake256': SHAKE256 output of `outputLengt…
- `outputLength` (integer): shake256 only: output bytes (default 32, ≤ 1048576; 64 for an Ed448 CMS signer).
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `separator` (string): Placed between octets of `formatted` (default ':'; '' for none).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).
- `webcrypto` (boolean): fingerprint only: digest through Web Crypto instead of the pure-TypeScript hashes (identical result).

Output parameters:

- `algorithm` (string): SHA-1 | SHA-256 | SHA-384 | SHA-512, or 'SHAKE256'.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `formatted` (string): The digest with the separator and case asked for (AB:CD:… by default).
- `from` (string): key-id: where the public key came from.
- `hex` (string): The digest as lowercase hex, no separator.
- `label` (string|null): The PEM label of the input, null for DER.
- `mode` (string)
- `outputLength` (integer): shake256: the output length in bytes.
- `sizeBytes` (integer): Bytes digested: the DER of the input (fingerprint, shake256) or the public key bits (key-id).

### `decode_asn1` (~1269 tokens)

Decode ASN.1 (node tree, typed read, re-encode)

Read-only X.690 view of any DER object (BER with encodingRules:'ber'): the node tree — offset, header and content lengths, tag class / number / name, constructed flag, child count, a hex preview of each primitive (maxPreviewBytes, default 32) and the dotted value + registered name of every OBJECT IDENTIFIER — depth-first, capped at 20000 nodes (truncated:true). `nodePath` ('0.2.1' = child indices from the root; each node's `path` is what to pass) narrows to a subtree; `read` applies a typed reader to the selected node (boolean, integer, small-integer, enumerated, null, bit-string, octet-string, oid, relative-oid, string with stringType for an IMPLICIT tag, time with timeType) and returns `value` in wire form (bigint as decimal string, bytes as hex, time as epoch ms + ISO); `reencode:true` re-encodes the selected node through the engine and delivers it as an artefact (der / hex / pem for a labelled whole input; inline or a sandbox file) with reencode.identical; `sequence:true` decodes several top-level values back to back; allowTrailingData:true tolerates bytes after a single value. Refuses a private key or a PKCS#12 file — by PEM label, or when the DER parses as PKCS#8 / PKCS#12 — with SECURITY_VIOLATION (inspect_private_key / inspect_pkcs12 report them safely); a missing nodePath step is NOT_FOUND naming the range; a wrong reader tag is PKI_ASN1_UNEXPECTED_TAG; an IMPLICIT string / time without stringType / timeType is PKI_API_MISUSE; X.690 violations are PKI_ASN1_* (BER forms: encodingRules:'ber'). Token-frugal: verbosity:'summary' (node count, root tag, value), fields:['nodes.path','nodes.tagName'].

Input parameters:

- `allowTrailingData` (boolean): Accept bytes after the outermost value instead of PKI_ASN1_TRAILING_DATA (single value only; sequence:true decodes them instead).
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'der'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `input` (object, required): The DER / BER object (any PEM label except a private key, or DER): exactly one of pem / derBase64 / path. A private key or a PKCS#12 file is refused (SECURITY_VIOLATION).
- `label` (string): reencode + encoding:'pem': the PEM label of the artefact (required when the input had no label or nodePath selects a sub-node; upper-case words and digits). A private-key label is refused.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `maxPreviewBytes` (integer): Content bytes of a primitive shown in `preview` (hex; 0 hides previews; default 32).
- `nodePath` (string): Child indices from the root, dot-separated ('0.2.1' = children[0].children[2].children[1]): the subtree listed, read or re-encoded. Omitted: the root. NOT_FOUND names the available range.
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.der .bin .asn1 for der; .pem for pem). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `read` (string): Apply this typed reader to the selected node (the root without nodePath) and return `value`; a wrong tag is PKI_ASN1_UNEXPECTED_TAG.
- `reencode` (boolean): Re-encode the selected node through the engine encoder and deliver it as an artefact (`encoding` der by default, hex, or pem under the input label or `label`); `reencode.identical` says whether the b…
- `sequence` (boolean): The input is several top-level values back to back: decode each (exclusive with nodePath / read / reencode).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `stringType` (string): read:'string' on an IMPLICIT-tagged node: the charset to decode with (required then — PKI_API_MISUSE otherwise).
- `timeType` (string): read:'time' on an IMPLICIT-tagged node: the time type (required then).
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `artefact` (object): The artefact delivered alongside the report: its facts here, its bytes once as the embedded resource (or the resource_link in file mode).
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `identical` (boolean): reencode: the bytes are identical.
- `label` (string|null): The PEM label of the input, null for DER.
- `nodeCount` (integer)
- `nodes` (array): The selected subtree (or every top-level tree with sequence:true), depth-first in input order.
- `reencode` (object)
- `rootTag` (string|null): tagName of the first node listed (null when nothing was listed).
- `sizeBytes` (integer): Bytes of the input object.
- `truncated` (boolean): true when the listing stopped at 20000 nodes (use nodePath to walk the rest).
- `value` (object): read: the typed value. boolean → boolean; integer / enumerated → decimal string; small-integer → number; null → null; bit-string → { hex, unusedBits }; octet-string → hex; oid / relative-oid → dotted…

### `encode_asn1` (~978 tokens)

Encode ASN.1 (JSON node spec to DER)

Encode a JSON node spec into DER through the engine's own encoders: `spec` is one node { type, … } — boolean (value), integer / enumerated (value: integer, decimal or 0x-hex string, negative allowed), null, bit-string (hex, unusedBits), named-bits (bits[]), octet-string (hex), oid / relative-oid (value), string (stringType utf8|numeric|printable|teletex|ia5|visible|universal|bmp, value), time (value: ISO instant or epoch ms; timeType UTCTime|GeneralizedTime|rfc5280 — the RFC 5280 rule by default), sequence / set / set-of (children[]; set-of is sorted as DER requires), explicit / implicit (tag, class universal|application|context|private, inner), tlv (class, tag, constructed, hex) and der (hex of one pre-encoded value, checked). Nesting is bounded by limits.maxDepth (PKI_LIMIT_EXCEEDED). The bytes are decoded back for the summary (root tag, node count). Output DER (default), hex (inline, ≤ 64 KiB) or PEM under `label`, inline as an embedded resource or as a sandbox file (never overwritten). Refuses a malformed node naming its JSON path ($.children[1].value …), a PEM encoding without label, a private-key label, a value that parses as a PKCS#8 key or a PKCS#12 file (SECURITY_VIOLATION — nothing here produces key material); a value the engine cannot encode is PKI_ASN1_* / PKI_OID_INVALID. Deterministic: the same spec gives the same bytes. The inverse of decode_asn1 (its tree uses the same vocabulary).

Input parameters:

- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'der'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `label` (string): The PEM label for encoding:'pem' (required then; upper-case words and digits). A private-key label is refused.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.der .bin .asn1 for der; .pem for pem). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `spec` (object, required): An ASN.1 node spec: { type, … } with type one of boolean (value), integer / enumerated (value: integer or decimal / 0x-hex string), null, bit-string (hex, unusedBits), named-bits (bits[]), octet-stri…
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `inspect_certificate` (~684 tokens)

Inspect certificate (RFC 5280 report, extensions, fingerprints, signature check)

Read-only RFC 5280 report of ONE certificate in one call: version, serial, signature algorithm, issuer and subject (RFC 4514 + RDNs), validity (epoch ms + ISO), public key (kind, bits, curve / modulus / exponent), every extension decoded (the 19 kinds pkinative knows; rawExtensions:true keeps them undecoded), self-issued flag, fingerprints (SHA-256 by default), and every engine diagnostic. `extension:'subjectAltName'` returns that one extension. `issuer` or `checkSelfSignature:true` adds a signature check — ONE signature against ONE key, which is NOT trust: verify_certificate_chain is the RFC 5280 §6 verdict (anchors, validity at an instant, names, policies, revocation). Token-frugal: verbosity:'summary', fields:[…]. Input: pem / derBase64 / path.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `certificate` (object, required): The certificate (CERTIFICATE PEM or DER): exactly one of pem / derBase64 / path.
- `checkSelfSignature` (boolean): Check the certificate against its own key (a self-signed root). Exclusive with issuer.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `extension` (string): Return only this decoded extension (NOT_FOUND when absent). Exclusive with rawExtensions.
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `fingerprints` (array): Digests of the DER to report.
- `issuer` (object): The issuer certificate to check the signature against: exactly one of pem / derBase64 / path. Exclusive with checkSelfSignature. A valid signature is NOT trust: run verify_certificate_chain for that.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `rawExtensions` (boolean): Keep every extension undecoded (kind raw, valueDer as hex) — the way past PKI_X509_EXTENSION_MALFORMED.
- `requireAlgorithmMatch` (boolean): Require the outer signatureAlgorithm to equal the TBS signature algorithm (RFC 5280 §4.1.1.2).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `extension` (object): The one extension asked for with `extension`.
- `extensionKinds` (array)
- `extensions` (array)
- `fingerprints` (object): Colon-separated uppercase hex digests of the DER, by algorithm.
- `issuer` (object)
- `issuerString` (string): RFC 4514 issuer.
- `notAfter` (string)
- `notBefore` (string)
- `publicKey` (string)
- `selfIssued` (boolean): issuer DER equals subject DER (self-issued; a self-SIGNATURE is a separate check).
- `serialNumber` (object)
- `serialNumberHex` (string)
- `signature` (object): The signature check asked for (issuer or self). ONE signature against ONE key — not a trust verdict.
- `signatureAlgorithm` (object)
- `signatureValid` (boolean)
- `sizeBytes` (integer)
- `subject` (object)
- `subjectPublicKeyInfo` (object)
- `subjectString` (string): RFC 4514 subject.
- `validity` (object)
- `version` (integer)

### `create_certificate` (~954 tokens)

Create certificate (CA or leaf, from a JSON spec, Web Crypto signed)

Issue an X.509 v3 certificate from `spec` (subject, validity, extensions — basicConstraints, keyUsage, extendedKeyUsage, subjectAltName, issuerAltName, SKI / AKI, raw), signed through `signer` (a PKCS#8 key or a PKCS#12 file, imported as a NON-EXTRACTABLE Web Crypto key — nothing generates or exports a key here). Self-signed when no `issuerCertificate` is given (the subject key is derived from a plain signer.key, or taken from `subjectPublicKey`); issued when `issuerCertificate` is given (`subjectPublicKey` = a certificate, a CSR or a PUBLIC KEY is then required; the AKI is computed from the issuer). Serial 'random' by default (node:crypto, reported as summary.randomSerial), notBefore defaults to PKINATIVE_MCP_AT or now (whole seconds) — pin both for reproducible bytes. The new certificate is verified against the issuer (or itself) BEFORE it is returned (KEY_MISMATCH otherwise). RSA keys need signer.rsaScheme; SHA-1 needs allowSha1:true. Output PEM (default), DER or hex, inline or as a sandbox file (never overwritten).

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'pem'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `issuerCertificate` (object): The issuing CA certificate: exactly one of pem / derBase64 / path. Omitted: the certificate is self-signed (issuer = subject, the signing key must be the subject's).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.pem for pem; .crt .cer .der for der). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `signer` (object, required): The signing key: exactly one of `key` (a PKCS#8 private key, plain or PBES2-encrypted, PEM or DER) or `p12` (a PKCS#12 file, PBES2 + PBMAC1 only). The key is imported into a NON-EXTRACTABLE Web Crypt…
- `spec` (object, required): What to write into the certificate. Unknown members are refused.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `subjectPublicKey` (object): The subject public key: a certificate, a CSR (CERTIFICATE REQUEST) or a PUBLIC KEY (SPKI): exactly one of pem / derBase64 / path. Omitted: derived from a PLAIN signer.key (self-signed only).

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `encode_x509_structure` (~1456 tokens)

Encode X.509 structure (one building block to DER, from a JSON spec)

Encode ONE X.509 building block to DER through pkinative's structural encoders, deterministically (the same spec gives the same bytes): `structure` is name, name-attribute, validity, spki, algorithm-identifier, attribute, extension, extensions, basic-constraints, key-usage, extended-key-usage, subject-alt-name, subject-key-identifier, authority-key-identifier or signature-algorithm; `spec` holds that structure's members (closed objects — an unknown or missing member is refused with VALIDATION_ERROR naming `spec <path>`; validity takes explicit notBefore AND notAfter, never an implicit now; a key identifier comes as hex or is computed from a certificate / CSR / PUBLIC KEY input). signature-algorithm takes `signer` instead of a spec (the key is imported NON-EXTRACTABLE and only its algorithm is read: ECDSA, Ed25519/Ed448, RSA with the REQUIRED rsaScheme — KEY_TYPE_REQUIRED for an encrypted key without keyType, SECRET_REQUIRED without a password). Output hex by default (structuredContent.hex, ≤ 64 KiB), or DER / PEM (PEM needs `label`), inline or as a sandbox file (never overwritten). The bytes are a fragment, not a signed object: nothing here signs. Use encode_asn1 for arbitrary ASN.1 and create_certificate / create_csr for whole objects.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'hex'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `label` (string): The RFC 7468 label for encoding:'pem' (required then, refused otherwise); a key-bearing label is refused.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.der .bin .asn1 for der; .pem for pem). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `signer` (object): signature-algorithm only: The signing key: exactly one of `key` (a PKCS#8 private key, plain or PBES2-encrypted, PEM or DER) or `p12` (a PKCS#12 file, PBES2 + PBMAC1 only). The key is imported into a…
- `spec`: The structure's members (a closed object; an unknown member is refused with VALIDATION_ERROR naming it). name: a distinguished name — { "C": "FR", "O": "Acme", "CN": "x" } or an array of RDNs [[{ "ty…
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `structure` (string, required): The X.509 building block to encode.

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `decode_extension` (~647 tokens)

Decode extension (one extnValue by OID, the 19 known kinds)

Read-only decode of ONE X.509 extension value by its OID — the bytes INSIDE extnValue's OCTET STRING, as `valueHex` or `value` (DER by derBase64 / sandbox path) — exactly as inspect_certificate decodes a certificate's extensions: the 19 known kinds (basicConstraints, keyUsage, extendedKeyUsage, subjectAltName, nameConstraints, certificatePolicies, crlDistributionPoints, authorityInfoAccess, SCT list, …) come back with their members, any other OID as kind 'unknown' with its size; `critical` (default false) is reported and checked against the kind's RFC 5280 rule (a diagnostic, not a refusal). A value that is not well-formed for that OID is refused with PKI_X509_EXTENSION_MALFORMED (remedy: decode_asn1 for the plain tree). Token-frugal: verbosity:'summary', fields:[…]. The input is not a whole Extension SEQUENCE: pass the extnValue content, as inspect_certificate rawExtensions:true reports it in valueDer.

Input parameters:

- `critical` (boolean): The criticality to report and to check against the kind (a kind RFC 5280 requires critical or non-critical gets a diagnostic).
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `oid` (string, required): The extension OID (2.5.29.19 basicConstraints, 2.5.29.17 subjectAltName, …) — it selects the decoder.
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `value` (object): The extnValue content as DER bytes (derBase64, or a sandbox .der / .bin / .asn1 file): exactly one of pem / derBase64 / path. Exclusive with valueHex.
- `valueHex` (string): The extnValue content (the DER inside the OCTET STRING) as hex. Exclusive with value. Hexadecimal (an 0x prefix, colons and spaces are tolerated).
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `critical` (boolean)
- `decoded` (object): The decoded members of the kind (cA / pathLenConstraint, usages, purposes, names, keyIdentifier, …); empty for an unknown OID.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `kind` (string): One of the 19 decoded kinds, or unknown.
- `name` (string|null): The registry name of the OID.
- `oid` (string)
- `sizeBytes` (integer): Size of the value DER.

### `check_certificate_name` (~758 tokens)

Check certificate name (RFC 6125 host / IP identity, or one name match)

The RFC 6125 identity verdict, two forms. Certificate form: `certificate` + exactly one of `host` (DNS name as it appeared in the URL) / `ip` — is the certificate valid for that identity (subjectAltName dNSName / iPAddress; wildcards under `allowWildcards`, default true; `allowCommonNameFallback`, default false, reads a CN-only certificate's commonName and then needs `chain` — the issuing CAs, leaf's issuer first — so the CN is held to their dNSName name constraints as a SAN would be). Match form: `presented` (the certificate's dNSName, possibly a wildcard) + `reference` — one RFC 6125 §6.4 name comparison, no certificate. A negative verdict is valid:false + reasons[] (PKI_REASON_NAME_MISMATCH, …) in structuredContent — never isError. The name only: it is not trust (verify_certificate_chain with serverName is the full verdict), not validity, not revocation. Token-frugal: verbosity:'summary'.

Input parameters:

- `allowCommonNameFallback` (boolean): Fall back to the subject commonName when the certificate carries no dNSName and no iPAddress (CA/Browser Forum forbids CN-only certificates since 2017; needs chain). Default false.
- `allowWildcards` (boolean): Accept a wildcard name (*.example.test) at all. Default true; false is right for an internal PKI that issues none.
- `certificate` (object): The certificate to judge (certificate form): exactly one of pem / derBase64 / path. With exactly one of host / ip. Exclusive with presented / reference.
- `chain` (array): The issuing certificates, leaf's issuer first (every PEM block of every item is taken). Optional; read only by the commonName fallback, which holds a CN read as a host name to the dNSName name constr…
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `host` (string): The reference DNS name as it appeared in the URL (one trailing dot is ignored). Exclusive with ip.
- `ip` (string): The reference IPv4 or IPv6 address. Exclusive with host.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `presented` (string): Match form: the certificate's dNSName, possibly a wildcard. With reference; exclusive with certificate / host / ip / chain.
- `reference` (string): Match form: the reference host name.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `form` (string)
- `match` (boolean): Match form: whether presented matches reference.
- `presented` (string): Match form: the presented name.
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `reference` (object): The reference identity judged.
- `subject` (string): Certificate form: RFC 4514 subject of the certificate.
- `valid` (boolean): The verdict (the match outcome in the match form). false is a negative verdict, never an error.

### `check_certificate_purpose` (~684 tokens)

Check certificate purpose (extended key usage along the path)

The RFC 5280 §4.2.1.12 purpose verdict: may `certificate` be used for `purpose` (serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, ocspSigning, any, or a dotted KeyPurposeId OID)? The path judged is [certificate, ...chain] (issuers, leaf's issuer first): under `restrictIssuers` (default true, what every Web PKI validator does) a CA's own extKeyUsage restricts what it issued; `requireExplicitPurpose` (default false) refuses a certificate with no extKeyUsage instead of reading its absence as unrestricted. A negative verdict is valid:false + reasons[] (PKI_REASON_PURPOSE_NOT_PERMITTED with the path[i] element) in structuredContent — never isError; an unknown purpose name is VALIDATION_ERROR. The purpose only: not trust, validity, names or revocation (verify_certificate_chain with purposes is the full verdict). Token-frugal: verbosity:'summary'.

Input parameters:

- `certificate` (object, required): The end-entity certificate to judge: exactly one of pem / derBase64 / path.
- `chain` (array): The issuing certificates, leaf's issuer first (the path is [certificate, ...chain]) (every PEM block of every item is taken). Optional; their extKeyUsage restricts the leaf under restrictIssuers.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `purpose` (string, required): The purpose needed: serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, ocspSigning, any, or a dotted KeyPurposeId OID.
- `requireExplicitPurpose` (boolean): Require the certificate to carry extKeyUsage and name the purpose explicitly (the stricter Web PKI reading); default false = no extKeyUsage means unrestricted (RFC 5280 §4.2.1.12).
- `restrictIssuers` (boolean): Apply a CA's own extKeyUsage to what it issued (what every Web PKI validator does; no sentence of RFC 5280 requires it). Default true; false is the literal-RFC reading.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `pathLength` (integer): 1 + the chain certificates (reasons name path[i]).
- `purpose` (string): The purpose as given.
- `purposeName` (string|null): The registry name of that OID.
- `purposeOid` (string): The KeyPurposeId OID judged.
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `subject` (string): RFC 4514 subject of the certificate.
- `valid` (boolean): The verdict. false is a negative verdict (reasons[]), never an error.

### `inspect_csr` (~614 tokens)

Inspect CSR (RFC 2986 report, requested extensions, proof of possession)

Read-only RFC 2986 report of ONE PKCS#10 certification request: subject (RFC 4514 + RDNs), public key (kind, bits, curve / modulus), every attribute, the extensions requested through extensionRequest decoded as a certificate's would be (rawExtensions:true keeps them undecoded), whether a challengePassword is present (never its text), the signature algorithm, and — by default (`verify`, one Web Crypto verification) — the proof of possession: signature.valid tells whether the request was signed by the key it carries, with reasons[] (PKI_REASON_SIGNATURE_NOT_CHECKED for SHA-1 without allowSha1:true). That is NOT trust: no CA signed a CSR, and a CA is free to ignore every extension it asks for. Pair with create_certificate (subjectPublicKey = the request) to issue from it. Token-frugal: verbosity:'summary' (subject, key kind, extension kinds, signatureValid), fields:[…]. Input: pem / derBase64 / path (.csr .p10 .der .pem).

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `rawExtensions` (boolean): Keep every requested extension undecoded (kind raw, valueDer as hex) — the way past PKI_X509_EXTENSION_MALFORMED.
- `request` (object, required): The PKCS#10 request (CERTIFICATE REQUEST PEM or DER): exactly one of pem / derBase64 / path.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).
- `verify` (boolean): Verify the request's signature under the key it carries (proof of possession; one Web Crypto verification). false skips it.

Output parameters:

- `attributes` (array): Every attribute in encoded order (extensionRequest, challengePassword, …).
- `challengePassword` (boolean): Whether a challengePassword attribute is present (its text is attacker-controlled and never reported).
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `extensionKinds` (array)
- `extensions` (array|null): The extensions requested through extensionRequest (RFC 2985 §5.4.2), decoded; null when the request asks for none. A CA is free to ignore them.
- `publicKey` (string)
- `signature` (object): The proof of possession (verify:true): the signature under the key the request carries. Not trust — a CSR is unsigned by any CA.
- `signatureAlgorithm` (object)
- `signatureValid` (boolean)
- `sizeBytes` (integer)
- `subject` (object)
- `subjectPublicKeyInfo` (object)
- `subjectString` (string): RFC 4514 subject.
- `version` (integer): v1 (encoded 0), the only version RFC 2986 defines.

### `create_csr` (~978 tokens)

Create CSR (PKCS#10 request from a JSON spec, Web Crypto signed)

Build a PKCS#10 certification request (RFC 2986) from `spec` (subject; the extensions to request — subjectAltName, keyUsage, extendedKeyUsage, basicConstraints, subjectKeyIdentifier, raw — carried in extensionRequest; issuerAltName / authorityKeyIdentifier are refused as the issuer's), signed through `signer` (a PKCS#8 key or a PKCS#12 file imported as a NON-EXTRACTABLE Web Crypto key; nothing generates or exports a key here). The public key certified is the signing key's own: derived from a plain signer.key, taken from the PKCS#12 certificate, or given as `subjectPublicKey` (a certificate, a CSR or a PUBLIC KEY — required for an encrypted PKCS#8 key, whose type then comes from it). The proof of possession is verified BEFORE the request is returned: KEY_MISMATCH when the key and the public key differ. RSA keys need signer.rsaScheme; an encrypted key needs signer.password (or PKINATIVE_MCP_PASSWORD); SHA-1 needs allowSha1:true. ECDSA / RSA-PSS signatures are randomised (PRODUCES). Output PEM (default), DER or hex, inline or as a sandbox file (never overwritten). inspect_csr reads it back; create_certificate issues from it (subjectPublicKey = the request).

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'pem'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.pem for pem; .csr .p10 .der for der). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `signer` (object, required): The signing key: exactly one of `key` (a PKCS#8 private key, plain or PBES2-encrypted, PEM or DER) or `p12` (a PKCS#12 file, PBES2 + PBMAC1 only). The key is imported into a NON-EXTRACTABLE Web Crypt…
- `spec` (object, required): What to write into the request: the subject and the extensions to ask for. Unknown members are refused.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `subjectPublicKey` (object): The public key to certify: a certificate, a CSR (CERTIFICATE REQUEST) or a PUBLIC KEY (SPKI): exactly one of pem / derBase64 / path. Omitted: derived from a PLAIN signer.key or taken from the PKCS#12…

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `verify_certificate_chain` (~1037 tokens)

Verify certificate chain (the RFC 5280 §6 verdict, offline revocation)

The one-call trust verdict for a certificate: builds a path from `leaf` through `candidates` to one of YOUR `trustAnchors`, verifies every signature, validates the path at `at` (RFC 5280 §6: validity, basic constraints, key usage, name constraints, policies — `policy` inputs), checks `serverName` (RFC 6125 host or IP) and `purposes` (extended key usage along the path), and judges revocation from the CRL / OCSP bytes YOU supply (`crls`, `ocspResponses`; `requireRevocation:true` demands evidence for every certificate below the anchor; this server never fetches). A negative verdict is valid:false + reasons[] (PKI_REASON_* codes) in structuredContent — never isError; isError is reserved for inputs the engine refuses. Pin `at` (ISO 8601) for a reproducible, cacheable verdict; `evaluatedAt` echoes the instant used. Token-frugal: verbosity:'summary' (valid, reasonCodes, pathLength). Prefer it over inspect_certificate.signature for any trust question; build_certificate_path / validate_certificate_path explain a failing path.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `candidates` (array): Untrusted intermediate certificates the path may use (every PEM block of every item is taken). Optional; the certificates embedded in a CMS message are also candidates.
- `crls` (array): CRLs (DER or X509 CRL PEM) for offline revocation (every PEM block of every item is taken). Optional; this server never fetches a CRL — pass the bytes you obtained.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `leaf` (object, required): The end-entity certificate to judge: exactly one of pem / derBase64 / path.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `ocspNonce` (string): The nonce you put in the OCSP request (1–32 bytes), to be matched in the responses. Hexadecimal (an 0x prefix, colons and spaces are tolerated).
- `ocspResponses` (array): OCSP responses (DER) for offline revocation (every PEM block of every item is taken). Optional; this server never queries a responder — pass the bytes you obtained.
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `policy` (object): RFC 5280 §6.1.1 policy inputs.
- `purposes` (array): Extended key usages the leaf must allow: serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, ocspSigning, any, or a dotted OID.
- `requireOcspNonce` (boolean): Refuse an OCSP response that does not echo the nonce.
- `requireRevocation` (boolean): Require fresh revocation evidence for the end-entity certificate (PKI_REASON_REVOCATION_UNKNOWN otherwise — the engine demands it for the leaf; an intermediate is judged from the evidence you pass);…
- `serverName` (object): The identity the leaf must be valid for (RFC 6125): exactly one of host / ip.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `trustAnchors` (array, required): Trust anchors (root certificates you trust) (every PEM block of every item is taken). At least one is required: a verdict is relative to the anchors you name.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `evaluatedAt` (string): The ISO instant the verdict was evaluated at — re-pass it as `at` to reproduce the verdict.
- `evaluatedAtSource` (string)
- `explored` (integer): Candidate paths explored (bounded by limits.maxPathsExplored).
- `path` (array): The path found, leaf first, up to (and including) the trust anchor.
- `pathLength` (integer)
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `revocationEvidence` (object)
- `signatureVerifications` (integer)
- `valid` (boolean): The verdict. false is a negative verdict (reasons[]), never an error.

### `build_certificate_path` (~744 tokens)

Build certificate path (discovery to a trust anchor, signatures NOT checked)

Path discovery only (RFC 5280 §6 path building): walks from `leaf` through the untrusted `candidates` to one of YOUR `trustAnchors` under the structural rules evaluated at `at` (validity, basic constraints, key usage, name constraints, the `policy` inputs; `purposes` steer discovery but the leaf's extended key usage is judged by verify_certificate_chain, not here) and reports the path it found, leaf first up to the anchor. NO signature is verified: the engine marks every link PKI_REASON_SIGNATURE_NOT_CHECKED, so `valid` is always false and the verdict of this tool is `found` (a path reached an anchor, `structuralReasons` empty); the leaf alone with PKI_REASON_NO_TRUST_ANCHOR when none did. Use it to learn which intermediates a chain needs, then validate_certificate_path (ordered path, signatures) or verify_certificate_chain (the full verdict with revocation). Never isError for a negative result. Pin `at` for a reproducible, cacheable result. Token-frugal: verbosity:'summary' (found, structuralReasonCodes, pathLength).

Input parameters:

- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `candidates` (array): Untrusted intermediate certificates the path may use (every PEM block of every item is taken). Optional; the certificates embedded in a CMS message are also candidates.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `leaf` (object, required): The end-entity certificate to start from: exactly one of pem / derBase64 / path.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `policy` (object): RFC 5280 §6.1.1 policy inputs.
- `purposes` (array): Extended key usages the leaf must allow: serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, ocspSigning, any, or a dotted OID.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `trustAnchors` (array, required): Trust anchors (root certificates you trust) (every PEM block of every item is taken). At least one is required: a verdict is relative to the anchors you name.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `evaluatedAt` (string): The ISO instant used — re-pass it as `at` to reproduce the result.
- `evaluatedAtSource` (string)
- `explored` (integer): Candidate paths explored (bounded by limits.maxPathsExplored).
- `found` (boolean): A path from the leaf to one of the trust anchors was found and passes the structural rules (structuralReasons empty). This is the verdict of THIS tool; the signatures are not checked.
- `path` (array): The path found, leaf first, up to (and including) the trust anchor; the leaf alone (with the reason) when no anchor was reached.
- `pathLength` (integer)
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `signaturesChecked` (boolean): Always false: run validate_certificate_path or verify_certificate_chain for the signatures.
- `structuralReasonCodes` (array)
- `structuralReasons` (array): reasons[] without the PKI_REASON_SIGNATURE_NOT_CHECKED markers: what actually stopped the walk (empty when found).
- `valid` (boolean): The engine verdict — always false here, because no signature was verified (PKI_REASON_SIGNATURE_NOT_CHECKED on every link). Read `found`.

### `validate_certificate_path` (~768 tokens)

Validate certificate path (RFC 5280 §6.1 on an ordered path, link signatures)

RFC 5280 §6.1 validation of a path YOU ordered (`path`, leaf first, then each issuer) against YOUR `trustAnchors` at `at`: validity, basic constraints, key usage, name constraints and the `policy` inputs. By default every link signature is verified first — certificate i against i+1, the last against the anchor whose subject matches its issuer — and reported per link in signatures[] (PKI_REASON_SIGNATURE_INVALID fails the verdict). `checkSignatures:false` gives a structural verdict: `valid` stays false (PKI_REASON_SIGNATURE_NOT_CHECKED on every link) and `failingReasons` carries what actually fails; `signaturesChecked` says which one you got. No revocation here (verify_certificate_chain judges CRL / OCSP evidence; check_crl_revocation / check_ocsp_status judge one certificate). A negative verdict is valid:false + reasons[], never isError. Pin `at` for a reproducible, cacheable verdict. SHA-1 signatures need allowSha1:true. Token-frugal: verbosity:'summary'.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `checkSignatures` (boolean): Verify every link signature before validating (certificate i against i+1, the last against the anchor whose subject is its issuer). false = structural verdict only: PKI_REASON_SIGNATURE_NOT_CHECKED s…
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `path` (array, required): The path to validate, leaf FIRST, then each issuer up to (but not necessarily including) the anchor (every PEM block of every item is taken). Every PEM block of every item is taken, in order.
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `policy` (object): RFC 5280 §6.1.1 policy inputs.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `trustAnchors` (array, required): Trust anchors (root certificates you trust) (every PEM block of every item is taken). At least one is required: a verdict is relative to the anchors you name.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `evaluatedAt` (string): The ISO instant used — re-pass it as `at` to reproduce the verdict.
- `evaluatedAtSource` (string)
- `failingReasonCodes` (array)
- `failingReasons` (array): The reasons that fail THIS call: reasons[] as is when the signatures were checked, minus the PKI_REASON_SIGNATURE_NOT_CHECKED markers otherwise. Empty = the path validates (structurally, when signatu…
- `path` (array): The path as validated, leaf first, up to (and including) the trust anchor it reached.
- `pathLength` (integer)
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `signatureVerdicts` (array)
- `signatures` (array): One row per certificate of the input path: the issuer it was verified against (the next certificate, or the matching anchor) and the verdict; not-checked when no issuer was found or checkSignatures i…
- `signaturesChecked` (boolean)
- `valid` (boolean): The engine verdict. With checkSignatures:false it is always false (every link is PKI_REASON_SIGNATURE_NOT_CHECKED): read failingReasons for the structural verdict.

### `inspect_crl` (~628 tokens)

Inspect CRL (RFC 5280 §5 report, one entry lookup, signature check)

Read-only RFC 5280 §5 report of ONE certificate revocation list: version, issuer (RFC 4514 + RDNs), signature algorithm, thisUpdate / nextUpdate, CRL number, delta indicator and base CRL number, issuing distribution point, entry count (the entries are counted by walking, never all decoded — bounded by limits.maxRevokedCertificates), every extension decoded, size, diagnostics. `find` looks ONE serial up (serialHex, or a certificate whose serial and issuer are used) and returns `entry` (revoked, revocationDate, reason, invalidityDate, entry extensions). `issuer` adds a signature check — ONE signature against ONE key, not a verdict: check_crl_revocation judges a certificate against the list (freshness, scope, delta), verify_certificate_chain judges the whole chain. Token-frugal: verbosity:'summary' (issuerString, thisUpdateIso, nextUpdateIso, crlNumber, entryCount, isDelta, revoked, signatureValid). Input: pem / derBase64 / path.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `crl` (object, required): The CRL (X509 CRL PEM or DER): exactly one of pem / derBase64 / path.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `find` (object): Look one serial up in the list (the entries are walked, never all decoded): exactly one of serialHex / certificate.
- `issuer` (object): The CRL issuer certificate to check the signature against: exactly one of pem / derBase64 / path. A valid signature is NOT trust: check_crl_revocation / verify_certificate_chain judge revocation.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `baseCrlNumber` (string|null): The base CRL number a delta applies to (decimal); null otherwise.
- `crlNumber` (string|null): Decimal (RFC 5280 §5.2.3); null when absent.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `entry` (object): The lookup asked for with `find`: whether the serial is listed, and the entry when it is.
- `entryCount` (integer): Entries in revokedCertificates (counted by walking, bounded by limits.maxRevokedCertificates).
- `extensions` (array)
- `isDelta` (boolean): Carries a deltaCRLIndicator (RFC 5280 §5.2.4).
- `issuer` (object)
- `issuerString` (string): RFC 4514 issuer.
- `issuingDistributionPoint` (object|null): RFC 5280 §5.2.5, decoded (fullName, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts); null when absent = the list covers everything its CA issued.
- `nextUpdate` (object|null)
- `nextUpdateIso` (string|null)
- `revoked` (boolean)
- `signature` (object): The signature check asked for with `issuer`. ONE signature against ONE key — not a trust verdict.
- `signatureAlgorithm` (object)
- `signatureValid` (boolean)
- `sizeBytes` (integer)
- `thisUpdate` (object)
- `thisUpdateIso` (string)
- `version` (integer)

### `check_crl_revocation` (~842 tokens)

Check CRL revocation (one certificate against one CRL, optional delta)

The RFC 5280 §6.3 revocation verdict of ONE `certificate` against ONE base `crl` you fetched (this server never fetches), evaluated at `at`: the list must be in scope for the certificate (issuer, issuing distribution point, reasons), fresh (nextUpdate, or `staleTolerance` ms past it), signature-verified, and the serial must not be listed (PKI_REASON_REVOKED with the reason otherwise). `delta` applies a delta CRL over the base (it must carry a deltaCRLIndicator — VALIDATION_ERROR otherwise — and name the base's number). `issuer` is the CRL issuer certificate: the base (and delta) signatures are verified against it and reported as signatureVerified / deltaSignatureVerified; without it the engine refuses the unverified list, so pass it for a real verdict. valid:false + reasons[] is a verdict, never isError. Pin `at` for a reproducible, cacheable verdict. SHA-1 signatures need allowSha1:true. Token-frugal: verbosity:'summary'. inspect_crl shows the list's facts; verify_certificate_chain with crls:[…] is the whole-chain form.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `certificate` (object, required): The certificate to check: exactly one of pem / derBase64 / path.
- `crl` (object, required): The base CRL (X509 CRL PEM or DER): exactly one of pem / derBase64 / path.
- `delta` (object): A delta CRL applied over the base: exactly one of pem / derBase64 / path. Must carry a deltaCRLIndicator (VALIDATION_ERROR otherwise); its base CRL number is checked against the base.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `issuer` (object): The CRL issuer certificate: exactly one of pem / derBase64 / path. The base (and delta) signatures are verified against it and reported to the engine as signatureVerified. Omitted: the signatures are…
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `staleTolerance` (integer): Milliseconds past nextUpdate the evidence is still accepted (default: the engine policy, none).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `crlNumber` (string|null): The base CRL number (decimal), null when absent.
- `deltaCrlNumber` (string|null): The delta CRL number (present only with `delta`).
- `deltaSignatureVerified` (boolean|null): The delta CRL signature against `issuer` (present only with `delta`).
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `evaluatedAt` (string): The ISO instant used — re-pass it as `at` to reproduce the verdict.
- `evaluatedAtSource` (string)
- `isDelta` (boolean): Whether the BASE list itself carries a deltaCRLIndicator (false for a proper base CRL).
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `signatureVerified` (boolean|null): The base CRL signature against `issuer`; null when no issuer was given (then the engine reports the list as unverified).
- `valid` (boolean): true = the certificate is not revoked according to fresh, in-scope, signature-verified evidence. false is a negative verdict (reasons[]), never an error.

### `create_ocsp_request` (~882 tokens)

Create OCSP request (RFC 6960 DER, SHA-1 or SHA-256 CertID, nonce)

Build the DER OCSPRequest (RFC 6960 §4.1) asking a responder for the status of `certificate`, identified by the CertID computed from `issuer` (the CA that issued it — its name and key hashes) and the serial. `hashAlgorithm` 'SHA-1' (default, the engine default and what every responder answers) or 'SHA-256' (recommended where the responder supports it). `nonce` adds the RFC 8954 nonce extension: 'random' (16 bytes from node:crypto, summary.randomNonce:true) or your own hex (1–32 bytes); keep summary.nonceHex to demand it back with check_ocsp_status. `certIdOnly:true` returns the bare CertID (der / hex). This server never sends anything: POST the bytes yourself (Content-Type application/ocsp-request) to the URL in the certificate's authorityInfoAccess (inspect_certificate), then judge the answer with check_ocsp_status { response, certificate, issuer, nonce }. summary.certIdHex is the CertID to match in the response. Output DER (default, .orq), PEM or hex, inline or as a sandbox file (never overwritten).

Input parameters:

- `certIdOnly` (boolean): Return the bare DER CertID (RFC 6960 §4.1.1) instead of the request (der or hex only — a CertID has no PEM label).
- `certificate` (object, required): The certificate whose status to ask for: exactly one of pem / derBase64 / path.
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'der'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `hashAlgorithm` (string): The CertID hash. 'SHA-1' (default — the engine default and what every responder answers; RFC 6960 §4.3) or 'SHA-256' (recommended, RFC 6960 §4.3 / RFC 5019 note: some responders still answer SHA-1 on…
- `issuer` (object, required): The CA certificate that issued it (its name and key are hashed into the CertID): exactly one of pem / derBase64 / path.
- `label` (string): The PEM label for encoding:'pem' (default OCSP REQUEST; upper-case words and digits). A private-key label is refused.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `nonce`: The RFC 8954 nonce extension: 'random', or hex of 1–32 bytes. Omitted: no nonce. Keep summary.nonceHex to match the response (check_ocsp_status nonce).
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.orq .der .bin for der). Key-bearing extensions (.key .p8 .p12 .pfx) are refused: nothing here w…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `inspect_ocsp_response` (~588 tokens)

Inspect OCSP response (RFC 6960 report, signature check)

Read-only RFC 6960 §4.2 report of ONE OCSP response (the DER a responder returned): the response status (only successful carries an answer), the BasicOCSPResponse — responder id (by name or by key hash), producedAt, every SingleResponse (CertID: hash algorithm, issuer name / key hashes, serial; status good / revoked with time and reason / unknown; thisUpdate, nextUpdate, extensions), response extensions, the embedded certificates, the signature algorithm — whether an RFC 8954 nonce is echoed, and diagnostics (bounded by limits.maxOcspSingleResponses). `responder` adds a signature check against that certificate; omitted, the embedded certificates are tried and the one that verifies is named. ONE signature against ONE key is NOT a status verdict: check_ocsp_status matches the CertID, judges the responder's authorisation (RFC 6960 §4.2.2.2), freshness and nonce. Token-frugal: verbosity:'summary' (status, responses[serialNumber, status], noncePresent, signatureValid). Input: derBase64 / path (or PEM).

Input parameters:

- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `responder` (object): The responder certificate to check the signature against: exactly one of pem / derBase64 / path. Omitted: the certificates embedded in the response are tried (signature.source embedded). A valid sign…
- `response` (object, required): The OCSP response (DER, as the responder returned it): exactly one of pem / derBase64 / path.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `basicResponse` (object|null): The BasicOCSPResponse; null when the status is not successful.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `noncePresent` (boolean): A nonce extension is present on the response.
- `responses` (array)
- `signature` (object): The signature check: against `responder`, or the first embedded certificate whose key verifies. ONE signature against ONE key — authorisation is judged by check_ocsp_status.
- `signatureValid` (boolean)
- `sizeBytes` (integer)
- `status` (string): OCSPResponseStatus (RFC 6960 §4.2.1). Only successful carries a signed answer.

### `check_ocsp_status` (~1023 tokens)

Check OCSP status (one response for one certificate: CertID, responder, freshness, nonce)

The RFC 6960 verdict of ONE OCSP `response` you fetched (this server never queries a responder) for ONE `certificate`: the CertID is recomputed from `issuer` (with the hash the response used, or `hashAlgorithm`) and must be answered; the signature is verified with `responder`, else the certificates embedded in the response, else the issuer itself; the signer must be authorised (RFC 6960 §4.2.2.2: the CA, a delegate the CA issued carrying id-kp-OCSPSigning, or `responderTrusted:true` for a trust you hold out of band); then the engine judges the status (good; PKI_REASON_REVOKED / unknown otherwise), freshness at `at` (thisUpdate / nextUpdate / producedAt, `staleTolerance` and `futureTolerance` ms), and the nonce (`nonce` must be echoed; `requireNonce:true` refuses a response without one). A non-successful response status is a negative verdict with status null. valid:false + reasons[] is a verdict, never isError. Pin `at` for a reproducible, cacheable verdict. Token-frugal: verbosity:'summary' (valid, reasonCodes, status, signatureVerified, responderAuthorized, responder). create_ocsp_request builds the request you POST; inspect_ocsp_response shows the facts without a verdict.

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `certificate` (object, required): The certificate whose status is asked: exactly one of pem / derBase64 / path.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `futureTolerance` (integer): Milliseconds a thisUpdate / producedAt may lie after `at` (clock skew) and still be accepted (default: the engine policy).
- `hashAlgorithm` (string): The CertID hash to recompute with. Default: the one the response used for this serial, else SHA-1.
- `issuer` (object, required): The CA certificate that issued it: exactly one of pem / derBase64 / path. Its name and key hashes form the CertID to match, and it is the authority a responder must be (or be delegated by).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `nonce` (string): The nonce you put in the request (1–32 bytes; create_ocsp_request summary.nonceHex): the response must echo it. Hexadecimal (an 0x prefix, colons and spaces are tolerated).
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `requireNonce` (boolean): Refuse a response that carries no nonce (RFC 8954).
- `responder` (object): The responder certificate to verify the signature with: exactly one of pem / derBase64 / path. Omitted: the certificates embedded in the response are tried, then the issuer itself.
- `responderTrusted` (boolean): State an out-of-band trust in the responder (RFC 6960 §4.2.2.2 third case): responderAuthorized is then true whatever its certificate says.
- `response` (object, required): The OCSP response (DER, as the responder returned it): exactly one of pem / derBase64 / path.
- `staleTolerance` (integer): Milliseconds past nextUpdate the evidence is still accepted (default: the engine policy, none).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `certIdHex` (string): The recomputed DER CertID (hex).
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `evaluatedAt` (string): The ISO instant used — re-pass it as `at` to reproduce the verdict.
- `evaluatedAtSource` (string)
- `hashAlgorithm` (string): The hash the CertID was recomputed with.
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `responder` (string|null): The subject of the certificate that verified the signature.
- `responderAuthorized` (boolean): The signer is the CA itself, a delegate the CA issued with id-kp-OCSPSigning, or responderTrusted was set.
- `responderSource` (string|null): Where the signer came from: the `responder` input, the certificates embedded in the response, or the issuer itself.
- `signatureVerified` (boolean): A responder candidate verified the response signature.
- `status` (string|null): The status the response gives for this serial; null when the response holds no answer for it.
- `valid` (boolean): true = a fresh, correctly signed, authorised answer says good. false is a negative verdict (reasons[]: revoked, unknown, stale, unauthorised, unverified, nonce …), never an error.

### `sign_cms` (~1458 tokens)

Sign CMS (RFC 5652 SignedData, attached or detached, Web Crypto signed)

Produce an RFC 5652 SignedData over `content` (attached, or `detached:true`) or over a precomputed `contentDigest` (detached only — the PDF /ByteRange case), with ONE signer: `signer` (a PKCS#8 key or a PKCS#12 file, imported as a NON-EXTRACTABLE Web Crypto key — nothing generates or exports a key here) and `certificate` (required with signer.key; a PKCS#12 bag's certificate serves otherwise), `chain` and `crls` parsed (never embedded unread) then embedded. Signed attributes are always written: contentType, messageDigest, signingTime (default PKINATIVE_MCP_AT or now, whole seconds; 'none' omits it — pin it for reproducible bytes), SigningCertificateV2 and CMSAlgorithmProtection (on by default; CAdES / PAdES need them), plus your `signedAttributes` / `unsignedAttributes` (DER Attributes as hex). `sid` defaults to issuerAndSerialNumber (keep it unless the reader is known). The new signature is verified against the signer certificate BEFORE it is returned (KEY_MISMATCH otherwise). RSA keys need signer.rsaScheme; SHA-1 needs allowSha1:true. Output DER (default; .p7s), PEM (label CMS) or hex, inline or as a sandbox file (never overwritten). Add a counter time-stamp afterwards with amend_cms.

Input parameters:

- `algorithmProtection` (boolean): Write CMSAlgorithmProtection (RFC 6211, RFC 8933 §4).
- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `certificate` (object): The signer certificate: exactly one of pem / derBase64 / path. Required with signer.key; optional with signer.p12 (the bag's certificate is used, and this one wins when both are given).
- `chain` (array): Further certificates to embed (the chain) (every PEM block of every item is taken). The signer certificate is always embedded once; a PKCS#12 bag's other certificates are added too.
- `content` (object): The content to sign (hashed with the signer's digest; embedded unless detached): exactly one of text / base64 / path.
- `contentDigest` (string): The content's digest, already computed with the signer's digest algorithm (the PDF /ByteRange case). Requires detached:true. Exclusive with content. Hexadecimal (an 0x prefix, colons and spaces are t…
- `contentType` (string): The eContentType (dotted OID). Default id-data (1.2.840.113549.1.7.1); any other makes a version 3 SignedData.
- `crls` (array): CRLs to embed (DER or X509 CRL PEM) (every PEM block of every item is taken).
- `detached` (boolean): Omit the content from the SignedData (the signature travels without what it signs; most S/MIME and every PDF signature).
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'der'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.p7s .p7m .p7b .cms .der for der; .pem for pem). Key-bearing extensions (.key .p8 .p12 .pfx) are…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `sid` (string): How the SignerInfo names the certificate. Keep issuerAndSerialNumber unless the reader is known: subjectKeyIdentifier (version 3) is refused by some deployed readers and needs the certificate's SKI e…
- `signedAttributes` (array): Further signed attributes, each one DER Attribute as hex, written verbatim. A type the builder writes itself, a repeated type or a countersignature is refused (PKI_API_MISUSE).
- `signer` (object, required): The signing key: exactly one of `key` (a PKCS#8 private key, plain or PBES2-encrypted, PEM or DER) or `p12` (a PKCS#12 file, PBES2 + PBMAC1 only). The key is imported into a NON-EXTRACTABLE Web Crypt…
- `signingCertificateV2` (boolean): Write the ESS SigningCertificateV2 attribute (RFC 5035), binding the signature to this certificate — CAdES, PAdES and RFC 3161 require it.
- `signingTime` (string): The claimed signing time: an ISO 8601 instant, epoch milliseconds, 'now', or 'none' to omit the attribute (PAdES forbids it, S/MIME expects it). Whole seconds. Omitted: PKINATIVE_MCP_AT when pinned,…
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `unsignedAttributes` (array): Unsigned attributes, each one DER Attribute as hex (a time-stamp token already in hand: amend_cms add-timestamp checks the imprint first). A signed-only type is refused.

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `verify_cms` (~1238 tokens)

Verify CMS SignedData (the RFC 5652 verdict: signers, chains, time-stamps, revocation)

The one-call verdict on a CMS SignedData (a .p7s, an S/MIME body, a PDF /Contents): for EVERY signer, the signed attributes (contentType, messageDigest, ESS signing-certificate, CMSAlgorithmProtection), the content digest (attached, or `content` / `contentDigest` for a detached signature — a detached signature without its content is NOT valid), the signature, the certificate's chain through `candidates` and the embedded certificates to one of YOUR `trustAnchors` at `at` (RFC 5280 §6, `purposes` along the path), every counter time-stamp (RFC 3161, verified like verify_timestamp), and revocation from the CRL / OCSP bytes YOU supply plus those the message carries (`requireRevocation:true` demands evidence; this server never fetches). `atTimeStamp:true` is long-term validation: a signer's chain is judged at its verified time-stamp instead of `at`. `requireSigningCertificate` / `requireAlgorithmProtection` enforce the CAdES / RFC 8933 profile. A negative verdict is valid:false + reasons[] (PKI_REASON_* codes, per signer too; `intact` tells unaltered from untrusted) — never isError; isError is for inputs the engine refuses (content given for an attached message, both content and contentDigest). Pin `at` for a reproducible, cacheable verdict. Token-frugal: verbosity:'summary' (valid, reasonCodes, per-signer codes).

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `allowTrailingData` (boolean): Ignore bytes after the ContentInfo (the zero padding of a PDF /Contents). Default false: trailing bytes are PKI_ASN1_TRAILING_DATA.
- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `atTimeStamp` (boolean): Judge each signer's chain at the time its own VERIFIED counter time-stamp proves (long-term validation) instead of `at`; a signer without a valid time-stamp is still judged at `at`, and the TSA's cha…
- `candidates` (array): Untrusted intermediate certificates the path may use (every PEM block of every item is taken). Optional; the certificates embedded in a CMS message are also candidates.
- `content` (object): The detached content (required for a detached signature; refused for an attached one): exactly one of text / base64 / path.
- `contentDigest` (string): The detached content's digest (computed with the signer's digest algorithm) instead of the content — the PDF /ByteRange case. Exclusive with content. Hexadecimal (an 0x prefix, colons and spaces are…
- `crls` (array): CRLs (DER or X509 CRL PEM) for offline revocation, added to those the message carries. Optional; this server never fetches a CRL.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `ocspResponses` (array): OCSP responses (DER), added to those the message carries. Optional; this server never queries a responder.
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `purposes` (array): Extended key usages every signer's chain must permit (emailProtection for S/MIME): serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, ocspSigning, any, or a dotted OID.
- `requireAlgorithmProtection` (boolean): Require every signer to carry CMSAlgorithmProtection (RFC 6211).
- `requireRevocation` (boolean): Require fresh revocation evidence for the end-entity certificate (PKI_REASON_REVOCATION_UNKNOWN otherwise — the engine demands it for the leaf; an intermediate is judged from the evidence you pass);…
- `requireSigningCertificate` (boolean): Require every signer to name its certificate in an ESS signing-certificate attribute (CAdES / PAdES).
- `signedData` (object, required): The CMS SignedData to judge (CMS / PKCS7 PEM, or DER: .p7s .p7m): exactly one of pem / derBase64 / path.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `trustAnchors` (array, required): Trust anchors (root certificates you trust) (every PEM block of every item is taken). At least one is required: a verdict is relative to the anchors you name.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `atTimeStamp` (boolean)
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `evaluatedAt` (string): The ISO instant the chains were judged at — re-pass it as `at` to reproduce the verdict.
- `evaluatedAtSource` (string)
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `signatureVerifications` (integer): Signature verifications performed, chains and time-stamps included.
- `signerCount` (integer)
- `signers` (array): One verdict per signer, in encoded order.
- `valid` (boolean): At least one signer and EVERY signer valid. false is a negative verdict (reasons[]), never an error.

### `inspect_cms` (~756 tokens)

Inspect CMS SignedData (RFC 5652 report, signers, attributes, signature values)

Read-only RFC 5652 report of ONE CMS SignedData (.p7s / .p7m / .p7b, CMS or PKCS7 PEM, or a PDF /Contents): version, content type, attached content length (null = detached), digest algorithms, the embedded certificates (subject / issuer / serial), CRL and OCSP counts, and every signer — identifier (issuer + serial or key id), algorithms, signing time as CLAIMED, ESS signing-certificate, CMSAlgorithmProtection, signed and unsigned attributes (oid, name, value count), counter time-stamp count and the signature value as hex (what a counter time-stamp stamps: fields:['signerInfos.signature'], hash it, create_timestamp_request digestHex). `signerCertificate` (+ `signerIndex`, and `content` for a signer without signed attributes) adds signerSignature.valid — ONE signer against ONE key, a key check and NOT the verdict: verify_cms judges trust, digests, time-stamps and revocation. Trailing bytes are refused unless allowTrailingData:true; BER producers need encodingRules:'ber'. Refuses: NOT_FOUND for a signerIndex past the last signer, PKI_* for an unreadable structure. Token-frugal: verbosity:'summary', fields:[…].

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `allowTrailingData` (boolean): Ignore bytes after the ContentInfo (the zero padding of a PDF /Contents). Default false: trailing bytes are PKI_ASN1_TRAILING_DATA.
- `content` (object): The detached content, for a signer WITHOUT signed attributes (such a signer signs the content itself); ignored otherwise: exactly one of text / base64 / path.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `signedData` (object, required): The CMS SignedData (CMS / PKCS7 PEM, or DER: .p7s .p7m .p7b): exactly one of pem / derBase64 / path.
- `signerCertificate` (object): The certificate to check ONE signer's signature against: exactly one of pem / derBase64 / path. A valid signature is a key check, NOT trust: verify_cms is the verdict.
- `signerIndex` (integer): Which signer the signature check targets (encoded order; NOT_FOUND past the last).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `certificates` (array): The embedded certificates (a claim by whoever assembled the message).
- `contentLength` (integer|null): Bytes of the encapsulated content; null when the signature is detached.
- `contentType` (object)
- `contentTypeOid` (string)
- `crlCount` (integer)
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `digestAlgorithms` (array)
- `ocspResponseCount` (integer)
- `signerCount` (integer)
- `signerInfos` (array)
- `signerSignature` (object): The signature check asked for with signerCertificate: ONE signer against ONE key. A key check, not the verdict (verify_cms).
- `signerSignatureValid` (boolean)
- `signers` (array)
- `sizeBytes` (integer)
- `version` (integer)

### `amend_cms` (~934 tokens)

Amend CMS (add an unsigned attribute or an RFC 3161 counter time-stamp)

The one edit a signed message legitimately receives afterwards, every signed octet unchanged: operation 'add-unsigned-attribute' appends `attribute` (one DER Attribute as hex) to signer `signerIndex`'s unsigned attributes; 'add-timestamp' appends `token` — a TimeStampToken, or the whole TimeStampResp a TSA returned (unwrapped; a declined response is refused) — as id-aa-signatureTimeStampToken (CAdES-T / PAdES B-T). A counter time-stamp stamps the signer's SIGNATURE VALUE, not the document: the token's imprint is checked against that value BEFORE anything is written and a token over anything else is refused with VALIDATION_ERROR (data.detail PKI_REASON_TSP_IMPRINT_MISMATCH, with the remedy: inspect_cms fields:['signerInfos.signature'] → hash → create_timestamp_request digestHex → POST to your TSA yourself → amend_cms). Trust is not judged here (verify_cms is). Deterministic for the same inputs. Refuses: NOT_FOUND for a signerIndex past the last signer, PKI_API_MISUSE for a signed-only attribute type, PKI_* for unreadable bytes. Output DER (default), PEM (CMS) or hex, inline or as a sandbox file (never overwritten).

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `attribute` (string): One DER Attribute (SEQUENCE { type, SET OF values }) for add-unsigned-attribute. A type RFC 5652 allows only signed is refused (PKI_API_MISUSE). Hexadecimal (an 0x prefix, colons and spaces are toler…
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'der'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `operation` (string, required): 'add-unsigned-attribute' writes `attribute` verbatim; 'add-timestamp' writes `token` as id-aa-signatureTimeStampToken after checking its imprint.
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.p7s .p7m .p7b .cms .der for der; .pem for pem). Key-bearing extensions (.key .p8 .p12 .pfx) are…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `signedData` (object, required): The CMS SignedData to amend (CMS / PKCS7 PEM, or DER: .p7s .p7m): exactly one of pem / derBase64 / path.
- `signerIndex` (integer): Which signer receives the attribute (encoded order; NOT_FOUND past the last).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `token` (object): The time-stamp for add-timestamp: a TimeStampToken (.tst) or the whole TimeStampResp (.tsr, unwrapped to its token; a declined response is refused): exactly one of pem / derBase64 / path.

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `create_timestamp_request` (~868 tokens)

Create time-stamp request (RFC 3161 TimeStampReq over data or a digest)

Build the RFC 3161 TimeStampReq you POST to a TSA yourself (Content-Type application/timestamp-query; this server never talks to a network): the message imprint is `hashAlgorithm` (SHA-256 default, SHA-384, SHA-512) over `data`, or `digestHex` already computed with it (wrong length → VALIDATION_ERROR). `nonce:'random'` draws 63 bits from node:crypto (summary.randomNonce:true; never cached) — without a nonce nothing ties the response to THIS request; a decimal or 0x-hex value pins it. `policy` names the TSA policy, `certReq` (default true) asks for the TSA certificate in the token. For a counter time-stamp over a CMS signature, the data is the signer's SIGNATURE VALUE (inspect_cms fields:['signerInfos.signature']), never the document. Keep the request bytes (or summary.imprintHex and nonce): verify_timestamp checks the response against them. Output DER (default; .tsq), PEM or hex, inline or as a sandbox file (never overwritten).

Input parameters:

- `certReq` (boolean): Ask the TSA to include its certificate in the token (what verify_timestamp needs unless you pass candidates).
- `data` (object): The data to time-stamp (hashed here with hashAlgorithm; for a counter time-stamp, the signer's signature value from inspect_cms): exactly one of text / base64 / path.
- `digestHex` (string): The digest to stamp, already computed with hashAlgorithm (its length must match). Exclusive with data. Hexadecimal (an 0x prefix, colons and spaces are tolerated).
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'der'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `hashAlgorithm` (string): The message imprint algorithm.
- `label` (string): The PEM label for encoding:'pem' (default TIMESTAMP REQUEST; upper-case words and digits). A private-key label is refused.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `nonce` (string): A nonce the TSA must echo (RFC 3161 §2.4.1): 'random' (63 bits from node:crypto — summary.randomNonce reports it; such a call is never cached), a decimal or an 0x-hex integer. Without one, nothing ti…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.tsq .der .bin for der; .pem for pem). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `policy` (string): The TSA policy to issue under (dotted OID); the TSA's default when absent.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].

Output parameters:

- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encoding` (string)
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `hex` (string): The artefact as lowercase hex (when encoding='hex').
- `mode` (string)
- `sha256` (string): SHA-256 of the DER bytes (lowercase hex) — the reproducibility proof.
- `sizeBytes` (integer): Size of the DER artefact.
- `summary` (object)

### `inspect_timestamp` (~566 tokens)

Inspect time-stamp (RFC 3161 response, token or TSTInfo)

Read-only RFC 3161 report of a TimeStampResp (.tsr: status, statusStrings, failInfo, and the token when granted), a TimeStampToken (.tst) or a bare TSTInfo — auto-detected in that order unless `as` names one. The TSTInfo view: policy, message imprint (algorithm + hex), serial, genTime (epoch ms + ISO), accuracy (null = undeclared), ordering, nonce (decimal), the TSA name as STATED (a hint, not an identity), extensions; the token view adds its CMS envelope (signer count, embedded certificates). Parsing proves nothing — verify_timestamp is the verdict (imprint, TSA signature, chain, revocation). Refuses with the PKI_* cause when the bytes are none of the three (as:'…' shows one reading's exact refusal); strict:true escalates the first engine warning (OpenSSL tokens carry PKI_DIAG_CMS_SET_NOT_SORTED). Token-frugal: verbosity:'summary' (status, genTime, serial, imprint).

Input parameters:

- `as` (string): Read the input as this structure. Omitted: auto-detected in the order response, token, tstinfo (the result's `as` says which).
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `input` (object, required): The time-stamp object: a TimeStampResp (.tsr), a TimeStampToken (.tst) or a bare TSTInfo (DER, or any PEM block): exactly one of pem / derBase64 / path.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `as` (string): What the input was read as.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `genTime` (string)
- `hashAlgorithm` (string|null)
- `imprintHex` (string)
- `serialNumber` (string)
- `sizeBytes` (integer)
- `status` (object): The PKIStatusInfo of a response. Only granted / grantedWithMods carry a token.
- `statusCode` (string)
- `token` (object): The token (of a granted response, or the input itself): what it asserts and its CMS envelope.
- `tstInfo` (object): The bare TSTInfo (as:'tstinfo').

### `verify_timestamp` (~1150 tokens)

Verify time-stamp (the RFC 3161 verdict: imprint, TSA signature, chain, revocation)

The one-call verdict on an RFC 3161 time-stamp: exactly one of `token` (a TimeStampToken, .tst) or `response` (the whole TimeStampResp, .tsr — a declined response is PKI_REASON_TSP_NOT_GRANTED), judged against what YOU say was stamped — `request` (the .tsq you sent: imprint, nonce and policy are all checked, the only way to catch a replay), `data` (hashed with the token's own algorithm) or `digestHex`; at least one is required, because a token verified without what it stamps proves nothing (VALIDATION_ERROR otherwise). The TSA's signature is verified, its certificate must chain to one of YOUR `trustAnchors` (through `candidates` and the certificates the token carries) at `at` with a critical timeStamping EKU (allowNonCriticalTimeStampingEku:true for deployed TSAs that are not), and revocation is judged from the CRL / OCSP bytes YOU supply (`requireRevocation:true` demands evidence). A negative verdict is valid:false + reasons[] (PKI_REASON_* codes) — never isError. genTime / earliest / latest (accuracy applied) are established only when valid. Pin `at` for a reproducible, cacheable verdict. Token-frugal: verbosity:'summary'.

Input parameters:

- `allowNonCriticalTimeStampingEku` (boolean): Accept a TSA whose extKeyUsage names timeStamping but is not critical (RFC 3161 §2.3 requires it critical; some deployed TSAs are not).
- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `at` (string): The instant the verdict is evaluated at. An ISO 8601 date-time (UTC unless zoned; e.g. 2027-01-01T00:00:00Z), epoch milliseconds as digits, or 'now'. Omitted: PKINATIVE_MCP_AT when the operator pinne…
- `candidates` (array): Untrusted certificates the TSA's path may use (every PEM block of every item is taken). Optional; the certificates the token carries are also candidates.
- `crls` (array): CRLs (DER or X509 CRL PEM) for offline revocation (every PEM block of every item is taken). Optional; this server never fetches a CRL — pass the bytes you obtained.
- `data` (object): The data that was stamped (hashed with the token's own imprint algorithm): exactly one of text / base64 / path.
- `digestHex` (string): The digest that was stamped, when you hold that rather than the data. Exclusive with data. Hexadecimal (an 0x prefix, colons and spaces are tolerated).
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `ocspResponses` (array): OCSP responses (DER) for offline revocation (every PEM block of every item is taken). Optional; this server never queries a responder — pass the bytes you obtained.
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `request` (object): The TimeStampReq you sent (.tsq): exactly one of pem / derBase64 / path. The strongest statement of what was stamped: imprint, nonce and policy are all checked; the only way to catch a replayed respo…
- `requireRevocation` (boolean): Require fresh revocation evidence for the end-entity certificate (PKI_REASON_REVOCATION_UNKNOWN otherwise — the engine demands it for the leaf; an intermediate is judged from the evidence you pass);…
- `response` (object): The whole TimeStampResp the TSA returned (.tsr): exactly one of pem / derBase64 / path. Exclusive with token. A response that granted nothing is PKI_REASON_TSP_NOT_GRANTED.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `token` (object): The TimeStampToken (a ContentInfo over a TSTInfo; .tst): exactly one of pem / derBase64 / path. Exclusive with response.
- `trustAnchors` (array, required): Trust anchors (root certificates you trust) (every PEM block of every item is taken). At least one is required: a verdict is relative to the anchors you name.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `chain` (object|null): The chain judged by verify_certificate_chain, or null when there was no certificate to judge.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `earliest` (string|null): genTime minus the declared accuracy.
- `evaluatedAt` (string): The ISO instant the TSA chain was judged at — re-pass it as `at` to reproduce the verdict.
- `evaluatedAtSource` (string)
- `genTime` (string|null): The time the TSA asserts (ISO 8601) — established only when valid.
- `latest` (string|null): genTime plus the declared accuracy — the instant an LTV check compares against.
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `signatureVerifications` (integer)
- `tsa` (object|null): The TSA certificate whose key verified the token, or null.
- `valid` (boolean): Whether the token is evidence that the expected hash existed at genTime. false is a negative verdict (reasons[]), never an error.

### `inspect_private_key` (~1051 tokens)

Inspect private key (PKCS#8 description, optional import proof, no key byte)

Describe a PKCS#8 private key WITHOUT its password: format ('pkcs8' or 'encrypted-pkcs8'), version, kind (ec / rsa / rsa-pss / ed25519 / ed448 / x25519 / x448 / ml-dsa / unknown), curve, algorithm OID and name, attributes, whether a public key is embedded; for an encrypted key the PBES2 parameters (PBKDF2 iterations, PRF, AES key size, salt length, ciphertext size) or the name of a scheme pkinative refuses (PKCS#12 / PKCS#5 v1.5 ciphers). `tryImport:true` additionally imports the key into a NON-EXTRACTABLE Web Crypto key and reports the handle (type, algorithm, usages) — an encrypted key then needs `password` (or PKINATIVE_MCP_PASSWORD; SECRET_REQUIRED) and `keyType` (KEY_TYPE_REQUIRED), an RSA key needs `rsaScheme` (RSA_SCHEME_REQUIRED, no default); a wrong password is PKI_CRYPTO_DECRYPTION_FAILED and a legacy cipher PKI_KEY_ENCRYPTION_UNSUPPORTED with the openssl pkcs8 remedy. No result ever carries a key byte, a scalar or the password: the report is an allow-list view and the key never leaves the engine (nothing exports or writes a key here). A PUBLIC KEY or a non-PKCS#8 DER is refused with the PKI_* cause. A call carrying a password is never cached. Token-frugal: verbosity:'summary' (format, kind, curve, encrypted, scheme, imported). Input: pem / derBase64 / path. inspect_pkcs12 is its PKCS#12 counterpart; use it before sign_cms / create_csr to learn what a signer needs (keyType, rsaScheme).

Input parameters:

- `allowSha1` (boolean): Accept or produce SHA-1 signatures (legacy material you already trust). Default false: refused with PKI_CRYPTO_ALGORITHM_REFUSED on read, VALIDATION_ERROR on write.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `hash` (string): Signature hash of the imported key. Default: the curve's hash for ECDSA (SHA-256/384/512), SHA-256 for RSA; refused for Ed25519 / Ed448. 'SHA-1' needs allowSha1:true. With tryImport:true only.
- `key` (object, required): The PKCS#8 private key (PRIVATE KEY or ENCRYPTED PRIVATE KEY PEM, or DER): exactly one of pem / derBase64 / path. A SEC1 / PKCS#1 key must be converted first (openssl pkcs8 -topk8).
- `keyType` (string): The type of an ENCRYPTED key (it reveals its type only once decrypted). With tryImport:true only; KEY_TYPE_REQUIRED when missing for an encrypted key.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `password` (string): The password of an encrypted PKCS#8 key or a PKCS#12 file (UTF-8). Never echoed, logged or cached. Alternatively set PKINATIVE_MCP_PASSWORD in the server environment and omit this input (never both)…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `rsaScheme` (string): REQUIRED to import an RSA key: 'pkcs1' (RSASSA-PKCS1-v1_5) or 'pss' (RSA-PSS); pkinative has no default (RSA_SCHEME_REQUIRED). With tryImport:true only.
- `saltLength` (integer): RSA-PSS salt length in bytes (rsaScheme:'pss' only; default: the hash length). With tryImport:true only.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `tryImport` (boolean): Also import the key into a NON-EXTRACTABLE Web Crypto key and describe the handle (never exported). An encrypted key then needs password and keyType; an RSA key needs rsaScheme.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `algorithm` (string)
- `algorithmName` (string|null): The name of the key algorithm OID (ecPublicKey, rsaEncryption, Ed25519 …), plain keys only.
- `attributes` (array)
- `curve` (string|null)
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `encrypted` (boolean): true for an ENCRYPTED PRIVATE KEY (format encrypted-pkcs8).
- `encryptedBytes` (integer)
- `encryption` (object)
- `format` (string)
- `imported`: The import proof (full), or its ok flag (summary).
- `kind` (string|null)
- `publicKey` (boolean)
- `scheme` (string|null): The password-based encryption scheme of an encrypted key.
- `sizeBytes` (integer): Size of the DER structure (ciphertext included for an encrypted key).
- `version` (integer)

### `inspect_pkcs12` (~762 tokens)

Inspect PKCS#12 (MAC kind, SafeContents, bags; optional MAC check and opening, no key byte)

Describe a PKCS#12 (.p12 / .pfx) WITHOUT its password: version, the MAC construction (kind 'pbmac1' RFC 9579 with its PBKDF2 / HMAC parameters, or 'pkcs12-kdf' — the RFC 7292 Appendix B MAC pkinative never verifies; null when the file has none), every SafeContents with its encryption scheme (PBES2 parameters, or the name of a legacy RC2 / 3DES scheme pkinative refuses), and the bags of the unencrypted SafeContents. With `password` (or PKINATIVE_MCP_PASSWORD): `macVerified` (true / false — a wrong password or an altered file is a REPORT, not an error; null without a MAC) and `opened`: every SafeContents opened, each bag as an allow-list view — a certBag by subject / issuer / serial, a keyBag or pkcs8ShroudedKeyBag by its algorithm, curve and encryption parameters, a crlBag by size. No result ever carries a key byte, a bag value or the password, not even from an unencrypted keyBag. Refusals: a wrong password on an ENCRYPTED SafeContents is PKI_CRYPTO_DECRYPTION_FAILED; a legacy MAC PKI_KEY_MAC_UNSUPPORTED and a legacy cipher PKI_KEY_ENCRYPTION_UNSUPPORTED (only when a password asks for them), each with the OpenSSL 3.4 conversion remedy; a public-key integrity-mode file PKI_KEY_MAC_UNSUPPORTED at parse. Nothing is imported here: open_pkcs12 is the one-call verdict with non-extractable key import. limits.maxPkcs12Bags and maxPkcs12KdfIterations bound the file's declared cost. Token-frugal: verbosity:'summary' (macKind, macVerified, contentCount, bagCount, bagKinds).

Input parameters:

- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `password` (string): The password of an encrypted PKCS#8 key or a PKCS#12 file (UTF-8). Never echoed, logged or cached. Alternatively set PKINATIVE_MCP_PASSWORD in the server environment and omit this input (never both)…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `pkcs12` (object, required): The PKCS#12 file (.p12 / .pfx; DER, or BER with encodingRules:'ber' for a Windows-written PFX): exactly one of pem / derBase64 / path.
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `bagCount` (integer): Bags listed: those of `opened` when a password was given, else those of the plain SafeContents.
- `bagKinds` (array)
- `contentCount` (integer)
- `contents` (array): The AuthenticatedSafe entries, in encoded order.
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `mac` (object|null): The MacData, or null when the file carries none (its integrity cannot be verified).
- `macKind` (string|null)
- `macVerified` (boolean|null): With password: true when the PBMAC1 MAC matches, false for a wrong password or an altered file (a report, not an error); null when the file has no MAC.
- `opened` (array): With password: every SafeContents opened (the encrypted ones decrypted), its bags as allow-list views.
- `sizeBytes` (integer)
- `version` (integer)

### `open_pkcs12` (~1184 tokens)

Open PKCS#12 (MAC, decryption, non-extractable key import, certificates; optional PEM bundle)

Open a PKCS#12 (.p12 / .pfx) in one call with `password` (or PKINATIVE_MCP_PASSWORD; SECRET_REQUIRED without one): the RFC 9579 PBMAC1 MAC is verified, every PBES2 SafeContents decrypted, every key unwrapped by the host straight into a NON-EXTRACTABLE Web Crypto key — described (algorithm, handle type, usages) and never exported — every certificate parsed (compact refs) and every CRL counted. The verdict is valid + integrity ('verified' | 'unverified' | 'mismatch') + reasons[]; a negative verdict is a REPORT, never isError: a wrong password or altered file → integrity 'mismatch' + PKI_REASON_PKCS12_MAC_MISMATCH (nothing decrypted); a legacy RC2 / 3DES file → PKI_REASON_PKCS12_ENCRYPTION_UNSUPPORTED (convert it once with openssl pkcs12 -legacy then -export -pbmac1_pbkdf2); no MAC or a legacy MAC → PKI_REASON_PKCS12_INTEGRITY_UNVERIFIED unless allowUnverifiedIntegrity:true (trusted origin only); an RSA key without `rsaScheme` ('pkcs1' | 'pss', hash default SHA-256; no default scheme) → PKI_REASON_PKCS12_RSA_SCHEME_UNSPECIFIED with that key's signingKey null. `exportCertificates:true` attaches a PEM bundle of the certificates then the CRLs (PEM only; inline embedded resource or a sandbox .pem file, never overwritten) — only from a file that opened; nothing is exported otherwise, and never a key. No result carries a key byte, a bag value or the password; a call with a password is never cached. Token-frugal: verbosity:'summary' (valid, integrity, reasonCodes, counts). Prefer inspect_pkcs12 first: it describes the file (MAC kind, bags) without any password.

Input parameters:

- `allowUnverifiedIntegrity` (boolean): Accept a file whose integrity cannot be checked (no MAC, or the legacy RFC 7292 Appendix B MAC) and report it valid — only for a file whose origin you trust: without a MAC any unencrypted bag can be…
- `encoding` (string): Artefact encoding: 'pem' (RFC 7468 text), 'der' (raw bytes), 'hex' (lowercase hex in structuredContent, inline only, ≤ 64 KiB). Default 'pem'.
- `encodingRules` (string): 'der' (strict X.690 DER, default) or 'ber' (indefinite / non-minimal lengths and constructed strings, as legacy CMS producers write).
- `exportCertificates` (boolean): Attach a PEM bundle of the certificates (CERTIFICATE blocks) then the CRLs (X509 CRL blocks) as the `artefact` — only from a file that opened (valid:true); never a key.
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `hash` (string): The hash of the RSA signature algorithm (with rsaScheme only). Default 'SHA-256'.
- `limits` (object): Raise pkinative's 22 named security bounds for this call (trusted input only; absent keys keep the engine defaults). A value above an operator ceiling (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MA…
- `outputMode` (string): 'base64' (default) returns the artefact inline as an embedded resource (≤ 50 MiB). 'file' writes it inside PKINATIVE_MCP_OUTPUT_DIR (never overwrites; ≤ 1 GiB) and returns a resource_link.
- `outputPath` (string): Relative path inside the sandbox (only when outputMode='file'); the extension must match the encoding (.pem only — a bundle has no DER form). Key-bearing extensions (.key .p8 .p12 .pfx) are refused:…
- `password` (string): The password of an encrypted PKCS#8 key or a PKCS#12 file (UTF-8). Never echoed, logged or cached. Alternatively set PKINATIVE_MCP_PASSWORD in the server environment and omit this input (never both)…
- `pemMode` (string): 'strict' (RFC 7468 exactly, default) or 'lax' (tolerates whitespace, line length and RFC 1421 headers).
- `pkcs12` (object, required): The PKCS#12 file (.p12 / .pfx; DER, or BER with encodingRules:'ber' for a Windows-written PFX): exactly one of pem / derBase64 / path.
- `rsaScheme` (string): What an RSA key will sign with: 'pkcs1' (RSASSA-PKCS1-v1_5) or 'pss' (RSA-PSS). No default: without it an RSA key is not imported and the verdict says PKI_REASON_PKCS12_RSA_SCHEME_UNSPECIFIED. Ignore…
- `strict` (boolean): Escalate the first engine warning to a PKI_STRICT_DIAGNOSTIC error instead of listing it in diagnostics[].
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `artefact` (object): With exportCertificates:true on a file that opened: the PEM bundle (certificates then CRLs), delivered once as the embedded resource (text) or the resource_link; summary counts the blocks.
- `certificateCount` (integer)
- `certificates` (array): Every certificate that parsed, in encoded order — the keys' own and any chain the file carries.
- `crlCount` (integer)
- `diagnosticCount` (integer)
- `diagnosticCounts` (object): Occurrences per diagnostic code.
- `diagnostics` (array): Non-fatal concerns the engine raised (PKI_DIAG_*, de-duplicated, at most 200; explain_code explains one).
- `diagnosticsTruncated` (boolean): true when distinct diagnostics beyond the 200 listed were dropped.
- `exportSkipped` (boolean): exportCertificates was asked but the file did not open (valid:false): nothing was exported.
- `integrity` (string): 'verified' for a matching PBMAC1 MAC; 'unverified' when it could not be checked (no MAC, legacy MAC); 'mismatch' for a wrong password or an altered file — nothing was decrypted then.
- `keyCount` (integer)
- `keys` (array): Every private key bag, in encoded order: where it was, its names, the certificate sharing its localKeyId, and the non-extractable Web Crypto handle described (never exported).
- `reasonCodes` (array)
- `reasons` (array): Why the verdict is negative (empty when valid): the engine PKI_REASON_* codes, each with the standard it cites and the path of the offending element. A reason is returned, never thrown.
- `valid` (boolean): Everything opened and the integrity verified (or explicitly waived). false is a negative verdict (reasons[]), never an error.

### `describe_engine` (~263 tokens)

Describe engine & server capabilities

Offline preflight (no input needed): server / engine / tool-API versions, whether this host's Web Crypto can verify, sign and decrypt (canVerify / canSign / canDecrypt) and satisfies the engine's Node floor, where randomness comes from, the engine's 22 default limits, the operator ceilings (PKINATIVE_MCP_MAX_INPUT_BYTES, PKINATIVE_MCP_MAX_KDF_ITERATIONS, PKINATIVE_MCP_MAX_PATHS_EXPLORED), every server cap, the sandbox / cache / PKINATIVE_MCP_AT state and the extension allow-lists, the 57 PKI_* error codes (with class), 43 PKI_REASON_* and 97 PKI_DIAG_* codes, the wrapper codes, the purposes and key-usage names, the doctrine refusals (what this server will NOT do and the remedy) and the engine surface deliberately not exposed as inputs. network is always 'none'. Call it first in a session, or whenever a cap / ceiling refusal needs interpreting.

Input parameters:

- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `capabilities` (object)
- `caps` (object)
- `ceilings` (object)
- `defaultLimits` (object)
- `engine` (object)
- `network` (string)
- `randomness` (object)
- `refusals` (array)
- `registries` (object)
- `sandbox` (object)
- `server` (object)
- `unexposed` (array)

### `explain_code` (~273 tokens)

Explain a code (errors, reasons, diagnostics, wrapper codes)

Explain any code this server can emit, from the registries vendored at the pkinative v1.0.0 tag: the 57 PKI_* engine error codes (coarse class, PkiError subclass, when raised, CWE, the engine's remedy and the MCP input that lifts it), the 43 PKI_REASON_* codes a verdict returns, the 97 PKI_DIAG_* diagnostics (with severity) and the wrapper's own codes (VALIDATION_ERROR, SECURITY_VIOLATION, LIMIT_CEILING_EXCEEDED, SECRET_REQUIRED, …). list:true enumerates (kind filters one vocabulary). Branch on codes, never on message text.

Input parameters:

- `code` (string): The code to explain (PKI_*, PKI_REASON_*, PKI_DIAG_* or a wrapper code such as SECURITY_VIOLATION). Omit with list:true to enumerate.
- `fields` (array): Dot-paths to keep after verbosity (arrays map over elements); unmatched paths land in _meta.unmatchedFields.
- `kind` (string): Restrict a listing to one vocabulary.
- `list` (boolean): List the codes (optionally of one kind) instead of explaining one.
- `verbosity` (string): 'summary' keeps the scalar fields only (token-frugal).

Output parameters:

- `code` (string)
- `codes` (array)
- `count` (integer)
- `cwe` (string)
- `engineClass` (string): The PkiError subclass.
- `errorClass` (string): The coarse class (usage, input, parse, security, limit, unsupported, crypto, password, check, internal).
- `kind` (string)
- `remedy` (object)
- `severity` (string)
- `since` (string)
- `standard` (string)
- `summary` (string): When the code is raised / returned.

### `draft_governance_issue` (~542 tokens)

Draft a governance-compliant GitHub issue (HITL)

Produce a LOCAL GitHub issue draft + compliance report for pkinative / pkinative-cli / pkinative-mcp and NEVER submit it — the agent drafts, a human reviews and files it under their own identity (Human-In-The-Loop contract, .github/AGENT_RULES.md). No GitHub write path and no network path exist in this server. The draft is checked against the zero-dependency + reproduction + no-secret policy; a violation (new runtime dependency, an embedded private key or password, missing reproduction, duplicateSearchPerformed:false) throws GOVERNANCE_VIOLATION. targetRepo 'pkinative' for engine behaviour (parsing, verification, limits, refusals), 'pkinative-cli' for the CLI, 'pkinative-mcp' for wrapper behaviour (schemas, sandbox, transport). Returns markdown inline (outputMode:'file' also writes a .md inside the sandbox). Use it only after reproducing a defect with TEST material. Present the draft AND the report to the user, then STOP.

Input parameters:

- `actualBehavior` (string): What actually happened (defaults to the reproduction result when omitted).
- `affectedPackages` (array): Packages impacted by this issue (e.g. ["pkinative-mcp"], ["pkinative"]).
- `duplicateSearchPerformed` (boolean, required): MUST be true: confirms you searched open AND closed issues/PRs for duplicates before drafting.
- `expectedBehavior` (string, required): What you expected to happen instead.
- `issueType` (string, required): Issue category: 'bug' | 'feature' | 'security' | 'docs' | 'performance'.
- `outputMode` (string): 'inline' (default) returns the draft markdown in the response. 'file' additionally writes it to the sandbox (requires PKINATIVE_MCP_OUTPUT_DIR); outputPath must be a relative .md path.
- `outputPath` (string): Relative .md path inside the sandbox (only when outputMode='file').
- `reproduction` (object, required): The minimal, locally-executed reproduction that justifies this issue (test material only).
- `summary` (string, required): One or two paragraphs describing the problem or proposal. Never a private key or a password.
- `targetRepo` (string): Destination repository label for the draft (documentation only — the server never contacts it). 'pkinative-mcp' (wrapper: schemas, sandbox, transport), 'pkinative' (engine: parsing, verification, lim…
- `title` (string, required): Concise issue title (imperative, no trailing period).

Output parameters:

- `compliance` (object)
- `draftMarkdown` (string): The full draft, ready for a human to review and submit.
- `filePath` (string): Sandboxed absolute path (when outputMode='file').
- `issueType` (string)
- `outputMode` (string)
- `sizeBytes` (integer)
- `targetRepo` (string)
- `title` (string)
- `warnings` (array)

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/nizoka-pkinative-mcp/pkinative-mcp#diagnostics

## Score history

- 2026-10-22: 81
- 2026-10-21: 81
- 2026-10-20: 81
- 2026-10-19: 81
- 2026-10-18: 81
- 2026-10-17: 66

## Common questions

### What is the pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… server?

pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… is listed in the public MCP registry as io.github.Nizoka/pkinative-mcp. PKI MCP server: inspect, verify, issue, sign X.509, CSR, CRL, OCSP, CMS, TSP, PKCS#12. 34 tools. This page covers its npm package (pkinative-mcp).

### Is the pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… server safe to use?

pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… scores 81 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 22 October 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 pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… server expose?

pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… exposes 34 tools: convert_pem, resolve_oid, compute_fingerprint, decode_asn1, encode_asn1, and 29 more. Their descriptions and schemas cost roughly 29,224 tokens of context every time the server is loaded.

### Is the pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… server still maintained?

pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… is still listed as active in the MCP registry. We last reached this channel on 22 October 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 pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… server under?

pkinative MCP — X.509, CMS, OCSP, time-stamps and PKCS#12… declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/pkinative-mcp
- Socket report: https://socket.dev/npm/package/pkinative-mcp
- Repository: https://github.com/Nizoka/pkinative-mcp
- Changelog RSS feed: https://verifymcp.io/servers/nizoka-pkinative-mcp/pkinative-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/nizoka-pkinative-mcp/pkinative-mcp.json
- HTML version of this page: https://verifymcp.io/servers/nizoka-pkinative-mcp/pkinative-mcp
