MCP server for FIPSign — post-quantum signing via ML-DSA-44/65/87 (NIST FIPS 204)
FIPSign MCP server demonstrates solid tool definitions with complete schemas and descriptions for all 10 tools. Naming follows verb_noun convention (fipsign_sign, fipsign_verify, fipsign_revoke). Descriptions are detailed (100-300 chars) and explain WHAT, WHEN, and prerequisites. All tools have proper JSON Schema with typed parameters. However, several tools lack parameter descriptions (fipsign_health, fipsign_public_key, fipsign_usage, fipsign_ca_list, generate_key_pair have empty required arrays but no param docs). Output schemas are not explicitly documented in tool definitions. Error handling is present but generic (api_request returns tuple with error dict). No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications. Composition is clean, each tool has one responsibility. Security is well-handled: API key injected server-side via environment variable, never exposed as parameter.
Issue a CA certificate for a public key. Binds an ML-DSA public key to a subject name and optional metadata. Returns a PEM-encoded X.509 certificate signed by the FIPSign CA. The certificate can be used for independent verification of signatures without calling the FIPSign API. Costs 10 tokens. Requires API key.
List all CA certificates issued for the project. Returns an array of certificates with subject, algorithm, issuedAt, expiresAt, and metadata. Use this to audit certificate lifecycle and plan renewals.
Revoke a CA certificate. Once revoked, the certificate is no longer valid for independent verification. Idempotent: revoking an already-revoked certificate returns success. Costs 1 token.
Check the health of the FIPSign service. Returns the service status, algorithm (ML-DSA-44/65/87), NIST standard, and version. No API key required. Use this to verify the service is reachable before running other operations.
Get the ML-DSA public key for the project associated with the API key. The key size depends on the project's configured algorithm (ML-DSA-44: 1312 bytes, ML-DSA-65: 1952 bytes, ML-DSA-87: 2592 bytes). Use this when you need to verify token signatures independently without calling the /verify endpoint. Requires API key.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications in metadata. Tools like fipsign_revoke and fipsign_ca_revoke are marked IRREVERSIBLE but lack destructiveHint annotation.
Output schemas not documented in tool definitions. Callers cannot predict response structure (e.g., fipsign_sign returns {payload, signature, algorithm, issuedAt, usage} but this is not declared in inputSchema or a separate outputSchema field).
Tools with no parameters (fipsign_health, fipsign_public_key, fipsign_usage, fipsign_ca_list, generate_key_pair) have empty inputSchema but lack any documentation of what they return or when to call them relative to other tools.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
Permanently revoke a token. Once revoked, all future verify() calls will reject the token even if its signature is valid and it has not expired. Idempotent: revoking an already-revoked token returns success without consuming an extra token. Costs 1 token. Note: calling this on an already-expired token returns an error (400).
Sign any payload with ML-DSA (NIST FIPS 204) — algorithm is ML-DSA-44, ML-DSA-65, or ML-DSA-87 depending on the project configuration. The only required field is 'sub' — any string identifying the entity being signed: a user ID, order ID, document hash, device serial, AI agent action, or anything else. All other fields are stored in the payload and returned on verify. Costs 1 token. Returns the signed token object (payload, signature, algorithm, issuedAt) plus usage info.
Get current token usage for the project. Returns tokens_used (total consumed), tokens_remaining (budget left), reset_at (Unix timestamp when the budget resets), and period (billing period in days). Use this to monitor quota before running bulk signing operations.
Verify a FIPSign token. Checks the cryptographic signature (ML-DSA-44, ML-DSA-65, or ML-DSA-87 — read from token.algorithm), expiry, and revocation list. Returns valid:true with the decoded payload on success, or valid:false with an error message on failure. Never throws — always returns a result. Costs 1 token.
Generate an ML-DSA-65 key pair locally using pyca/cryptography >= 48.0.0. Returns publicKey (base64, 1952 bytes) and secretKey (base64, 32-byte seed). The secretKey must be stored securely on the device and never sent to any server. Pass publicKey to fipsign_ca_issue to bind it to a certificate. No API key required. No token cost.
Error handling is generic. api_request returns (ok, data) tuple with error dict, but error messages lack recovery guidance. E.g., 'FIPSIGN_API_KEY is not set' is clear, but API errors like 'HTTP 400' do not guide the LLM on what to retry or fix.
fipsign_sign accepts additionalProperties for custom fields but lacks validation constraints (max 10 fields, max 256 chars per value). LLMs may pass invalid payloads without clear feedback.