MCP tool explorer
What an AI assistant gets when you wire pkinative-mcp 1.0.0 into Claude Desktop, Claude Code, Cursor, VS Code or any other Model Context Protocol client: 34 tools in six groups, seven prompts and the sandboxed pkinative://output/{+path} resources, over stdio or loopback Streamable HTTP, with no network access, ever.
Each card below shows what the tool is for, a prompt that makes an assistant reach for it, the tools/call arguments it would send — they validate against the server's own schemas — and a Run button that performs the engine call behind the tool in this tab, on the published pkinative build. No install, no model, nothing uploaded. The MCP guide holds the full reference.
Configure your client
Paste the snippet into your client's MCP configuration and restart it. npx -y fetches the server on first use; it needs Node.js 22.22.2, 24.14.1 or 25.8.2 and later (the engine's floor). PKINATIVE_MCP_OUTPUT_DIR is optional: without it every tool works on inline PEM or base64 and nothing touches the filesystem.
// claude_desktop_config.json — ~/Library/Application Support/Claude/ (macOS), %APPDATA%\Claude\ (Windows)
{
"mcpServers": {
"pkinative": {
"command": "npx",
"args": ["-y", "pkinative-mcp"],
"env": {
"PKINATIVE_MCP_OUTPUT_DIR": "/Users/you/Documents/mcp-pki"
}
}
}
}// .mcp.json at the root of the project
{
"mcpServers": {
"pkinative": {
"type": "stdio",
"command": "npx",
"args": ["-y", "pkinative-mcp"],
"env": { "PKINATIVE_MCP_OUTPUT_DIR": "/absolute/path/to/your/project/.mcp-pki" }
}
}
}// ~/.cursor/mcp.json
{
"mcpServers": {
"pkinative": {
"command": "npx",
"args": ["-y", "pkinative-mcp"],
"env": { "PKINATIVE_MCP_OUTPUT_DIR": "/Users/you/Documents/mcp-pki" }
}
}
}// .vscode/mcp.json — the top-level key is "servers"
{
"servers": {
"pkinative": {
"type": "stdio",
"command": "npx",
"args": ["-y", "pkinative-mcp"],
"env": { "PKINATIVE_MCP_OUTPUT_DIR": "${workspaceFolder}/.mcp-pki" }
}
}
}PKINATIVE_MCP_PORT=3000 PKINATIVE_MCP_HTTP_TOKEN="$(openssl rand -hex 24)" PKINATIVE_MCP_OUTPUT_DIR=/srv/pki npx -y pkinative-mcp
# stderr: [pkinative-mcp] ready (HTTP transport, MCP 2026-07-28 + legacy) on http://127.0.0.1:3000/mcp — bearer token required
# every request: POST /mcp with Authorization: Bearer <token>For Claude Code the value must be absolute: Claude Code does not expand ${CLAUDE_PROJECT_DIR} here (it sets that variable only in the server's environment), and the server refuses a relative path.
Continue, Zed, Windsurf, Cline and Roo Code take the same command + args + env triple in their own files. Over HTTP the endpoint binds 127.0.0.1 only and answers POST /mcp; without PKINATIVE_MCP_HTTP_TOKEN it has no authentication, and other local processes can reach it. The server speaks MCP 2026-07-28 and falls back to every 2024–2025 revision a client opens with initialize. Its registry name is io.github.Nizoka/pkinative-mcp. More in Configuration by client.
Operator environment
Nine variables, declared in the server's server.json and read once at startup; an invalid value refuses to start, never a silent fallback. None of them can be set from a tool argument, and only the presence of a secret is ever logged.
| Variable | Default | Meaning |
|---|---|---|
| PKINATIVE_MCP_OUTPUT_DIR | unset | The one sandbox: every path input is read from it and outputMode: 'file' artefacts are written under it, never overwritten. A planted symlink or junction is SECURITY_VIOLATION; key-bearing files (.key .p8 .p12 .pfx) may be named by any path input — no tool returns their key bytes — but are never written, never listed and never served as resources. Unset: inline PEM and base64 only. |
| PKINATIVE_MCP_CACHE_DIR | unset | Opt-in content-addressed response cache (SHA-256 keyed, 1 h TTL, 256 MiB LRU, plaintext at rest). Never caches a path input, file output, a password or a signer, a random serial or nonce, an unpinned instant, describe_engine or draft_governance_issue. |
| PKINATIVE_MCP_PORT | unset → stdio | Serve Streamable HTTP on http://127.0.0.1:<port>/mcp instead of stdio. Unauthenticated unless the token below is set. |
| PKINATIVE_MCP_HTTP_TOKEN | unset | Secret. Bearer token for HTTP: at least 16 characters, no whitespace; compared in constant time, never logged. Without it on a request, 401. |
| PKINATIVE_MCP_PASSWORD | unset | Secret. The password of the encrypted PKCS#8 key or PKCS#12 the tools open, kept out of the model transcript. Exclusive with the per-call password input. |
| PKINATIVE_MCP_AT | unset → clock | Pinned instant (ISO 8601 or epoch milliseconds) every omitted at, notBefore and signingTime falls back to, for reproducible verdicts and artefacts. |
| PKINATIVE_MCP_MAX_INPUT_BYTES | 67108864 | Operator ceiling for limits.maxInputBytes and the decoded size of one PKI object; a per-call value above it is LIMIT_CEILING_EXCEEDED. |
| PKINATIVE_MCP_MAX_KDF_ITERATIONS | 10000000 | Operator ceiling for limits.maxKdfIterations and limits.maxPkcs12KdfIterations: the CPU bound of a hostile PBES2 key or PKCS#12. |
| PKINATIVE_MCP_MAX_PATHS_EXPLORED | 1000 | Operator ceiling for limits.maxPathsExplored: the RFC 5280 §6 path-building work bound. |
The environment variables section of the guide has the full rules.
Try the tools
Every card runs the engine call behind its tool on the arguments it shows. The certificate under test feeds the cards that read one certificate; the cards about paths use the Let's Encrypt samples in a fixed pairing, and the creation cards use the page sandbox described below. Files you drop feed the cards that need a CRL, an OCSP response, a CMS message, a time-stamp, a key or a PKCS#12.
Loading pkinative@1.0.0 from the CDN…
Your files
- None yet. Nothing you drop leaves this tab.
The page sandbox
On the server, a path argument names a file in the operator's PKINATIVE_MCP_OUTPUT_DIR. This page has no filesystem, so its path arguments resolve to the few objects it holds itself:
keys/page-ca.key.pemandkeys/page-leaf.key.pem— two ECDSA P-256 keys this page generated withcrypto.subtle.generateKey, non-extractable, gone when the tab closes. pkinative generates no key, and neither does the server: it signs with the key you give it.page-ca.crt.pem,page-leaf.csr.pem,page-leaf.crt.pem— what thecreate_certificateandcreate_csrcards made from them when the page loaded, and the SignedData thesign_cmscard made over one sentence.keys/your.keyandkeys/your.p12— the TEST key or PKCS#12 you dropped. The arguments name a path rather than carrying the bytes on purpose: key material belongs in the operator's sandbox, never in a model transcript.
Any other path answers BROWSER_LIMITATION — this page's own label, not one of the server's codes — with what the server does instead. The same label marks the rest a browser cannot reproduce: the response cache, the operator ceilings, the password from the environment, the governance drafter. Results are the tool's structuredContent shape with its key fields as the server names them; an artefact's bytes appear under _resource, where the server sends them once as an embedded resource block.
The prompts
The server advertises seven prompts, read-only and without arguments: two carry the governance contract, five are PKI recipes that name the tools in order. A client lists them with prompts/list.
| Prompt | What it walks through |
|---|---|
| governance_contract | The agent drafts, the human decides: zero runtime dependencies, no autonomous GitHub writes, no network, no secret in a draft. |
| draft_issue_workflow | Drafting an issue with draft_governance_issue and handing it to a human for review and submission. |
| verify_before_trust | inspect_certificate → verify_certificate_chain with a pinned instant → offline revocation evidence, and why a verified signature is not trust. |
| issue_certificate | How create_csr and create_certificate chain together, what is verified before the bytes return, and the key, scheme and instant rules. |
| sign_and_timestamp | sign_cms, the counter time-stamp over the signature value (create_timestamp_request → your TSA → amend_cms), and verify_cms as the one verdict. |
| offline_revocation | Where to fetch CRL and OCSP evidence yourself, and how check_crl_revocation, check_ocsp_status and verify_certificate_chain judge the bytes you bring. |
| open_keys_safely | inspect_private_key, inspect_pkcs12 and open_pkcs12: describe before opening, PBES2 and PBMAC1 only, the two password channels. |
Once the configuration is in place, ask in plain words:
- "Is this server certificate trustworthy for shop.example today, given the CRL I fetched?"
- "Make me a test CA and a leaf for svc.example.test from this CSR, valid 90 days, and prove the chain verifies."
- "Sign this file detached, then tell me what a verifier will see in the .p7s."
- "What is in this .p12 and how is it protected? Do not open it."
Resources
With PKINATIVE_MCP_OUTPUT_DIR set, every regular file in the sandbox is a resource under the template pkinative://output/{+path}, and an artefact written with outputMode: 'file' comes back as a resource_link to it — so create_csr → create_certificate → verify_certificate_chain never re-sends the bytes. Key-bearing files are never listed and never served, and key material is refused by content too, whatever the file name. This page has no sandbox, so it lists no resource.
Errors and verdicts
A negative verdict is not an error: a verdict tool answers valid: false with the engine's PKI_REASON_* codes in reasons[]. isError: true means the input was refused — with one of pkinative's 57 error codes passed through verbatim, or one of the server's 21 wrapper codes for the boundary the engine does not own. Branch on the code, never on the message; explain_code explains each one, and the error model lists the wrapper codes.
What this page does not do
- It runs no MCP server and speaks no JSON-RPC: each Run is the engine call behind a tool, made in this tab. Where the browser result differs from the server's — the cache, the sandbox, the ceilings, the server half of
describe_engine— the card says so. - It opens no connection but the one that loads pkinative@1.0.0 from esm.sh or jsDelivr, and the same-origin read of the code registries by
explain_code. No CRL, OCSP or TSA is ever contacted — the server has no network code path either. - Nothing you drop or type is uploaded, stored or logged; reload the page and it is gone.
- No key leaves the tab. The page generates its two keys as non-extractable, reads only their public halves, and describes the keys it unwraps from a PKCS#12 by algorithm and usages — never by a byte. Drop TEST material only all the same.
Further reading
- MCP guide — configuration, every tool's inputs and outputs, prompts, resources, the error and security models.
- MCP use cases — four workflows followed call by call.
- pkinative-mcp on GitHub · on npm
- The Model Context Protocol