{
  "openapi": "3.1.1",
  "info": {
    "title": "Crypto Kitchen API",
    "version": "1.0.0",
    "summary": "CyberChef-style recipes: chain encodings, compression, hashes, AES, JWT and more, step by step.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://cryptokitchen.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "CyberChef-style recipes: chain encodings, compression, hashes, AES, JWT and more, step by step.",
        "description": "Write a recipe of operations, one per line, and run text or a file (up to 10 MB) through it: base64/32/58, hex, URL, HTML entities, Punycode and quoted-printable, gzip/deflate/brotli, hashes and HMAC, AES-GCM/CBC/CTR, XOR, ROT13/Caesar/Vigenère, JWT decode and verify, UUID/ULID parsing, timestamps, JSON, regex extraction, text case, byte swap, entropy and a Magic auto-decoder. Every intermediate result is shown; binary output can be downloaded.\n\nMethodology:\n- The input (pasted text, hex, base64 or an uploaded file) becomes a byte string; each recipe line is an operation that maps bytes to bytes. Text operations decode as UTF-8. The table shows every intermediate result; on an error the pipeline stops and reports the failing step.\n- Cryptography uses Node.js crypto (OpenSSL): AES-GCM appends/verifies the 16-byte tag, CBC uses PKCS#7 padding, CTR is a stream mode. You must supply key and IV, so results are reproducible; never reuse a GCM nonce with the same key.\n- JWT decode never checks signatures. jwt-verify supports HS256/384/512 (secret), RS*/PS* (RSA), ES256/384/512 (raw r||s signatures as in RFC 7518) and EdDSA with a PEM, certificate or JWK key, and refuses tokens whose header alg differs from the expected one.\n- Decompression stops at 50 MB of output to defuse decompression bombs; regex extraction runs in an isolated VM context with a 1-second limit.\n- Magic checks for gzip/zlib headers, JWTs, UUIDs/ULIDs, timestamps, JSON, percent-encoding, HTML entities, hex, base64/base64url, base32 and quoted-printable, and applies the most plausible decoder repeatedly while the output stays readable or reveals another known format.\n\nData and keys are processed on the server for this request only. Do not paste production secrets.",
        "tags": [
          "crypto"
        ],
        "x-mcp-tool": "crypto_kitchen",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CryptoKitchenInput"
              },
              "examples": {
                "example1": {
                  "summary": "Base64 → gunzip → pretty JSON",
                  "value": {
                    "input": "H4sIAAAAAAACA6tWKi1OLVKyUkpMSVTSUSrKz0ktVrKKVkpMyc3MU9JRSkktU4rVUUpMLsksS1WyKikqTa0FAJsiBuU0AAAA",
                    "recipe": "from-base64\ngunzip\njson-pretty"
                  }
                },
                "example2": {
                  "summary": "AES-256-GCM round trip with entropy check",
                  "value": {
                    "input": "Attack at dawn",
                    "recipe": "aes-encrypt mode=gcm key=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f iv=cafebabefacedbaddecaf888\nentropy\naes-decrypt mode=gcm key=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f iv=cafebabefacedbaddecaf888"
                  }
                },
                "example3": {
                  "summary": "Verify an HS256 JWT",
                  "value": {
                    "input": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
                    "recipe": "jwt-verify key=@key alg=HS256",
                    "key": "your-256-bit-secret"
                  }
                },
                "example4": {
                  "summary": "Magic: auto-detect and decode",
                  "value": {
                    "input": "H4sIAAAAAAACA6tWKi1OLVKyUkpMSVTSUSrKz0ktVrKKVkpMyc3MU9JRSkktU4rVUUpMLsksS1WyKikqTa0FAJsiBuU0AAAA",
                    "recipe": "magic"
                  }
                },
                "example5": {
                  "summary": "HMAC-SHA256 and hash of a file-like input",
                  "value": {
                    "input": "The quick brown fox jumps over the lazy dog",
                    "recipe": "hmac alg=sha256 key=key"
                  }
                },
                "example6": {
                  "summary": "Regex extract e-mail domains, then upper case",
                  "value": {
                    "input": "ada@example.org, bob@test.dev; eve@example.org",
                    "recipe": "regex-extract pattern=\"@([a-z0-9.-]+)\" group=1\ntext-case mode=upper"
                  }
                },
                "example7": {
                  "summary": "Gzip to binary (download)",
                  "value": {
                    "input": "hello hello hello hello",
                    "recipe": "gzip level=9"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CryptoKitchenResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "CryptoKitchenInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "input": {
            "title": "Input",
            "type": "string",
            "maxLength": 2000000
          },
          "inputFile": {
            "title": "Or upload a file",
            "description": "Any file up to 10 MB, processed as raw bytes. Upload as {filename, contentType?, contentBase64}. Max 10240 KiB. Accepts */*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "inputEncoding": {
            "title": "Pasted input is",
            "type": "string",
            "enum": [
              "text",
              "hex",
              "base64"
            ],
            "default": "text"
          },
          "recipe": {
            "title": "Recipe (one operation per line)",
            "description": "Syntax: op-id name=value name=\"value with spaces\". Operations: to-base64, from-base64, to-base64url, to-base32, from-base32, to-base58, from-base58, to-hex (separator?), from-hex, to-hexdump, url-encode (all?), url-decode (plus?), html-encode (nonAscii?), html-decode, punycode-encode, punycode-decode, qp-encode, qp-decode, gzip (level?), gunzip, deflate, inflate, deflate-raw, inflate-raw, brotli-compress (quality?), brotli-decompress, hash (alg?, format?), hmac (alg?, key, format?), crc32, aes-encrypt (mode?, key, iv, aad?, padding?), aes-decrypt (mode?, key, iv, tag?, aad?, padding?), xor (key), rot13, caesar (shift?), vigenere-encode (key), vigenere-decode (key), jwt-decode, jwt-verify (key, alg?), uuid-parse, ulid-parse, timestamp (unit?), json-pretty (indent?, sortKeys?), json-minify, regex-extract (pattern, flags?, group?), text-case (mode?), reverse (unit?), byte-swap (width?), entropy, magic (depth?). Byte arguments accept hex:, b64: or utf8: prefixes. Use @key to insert the secret field.",
            "type": "string",
            "maxLength": 20000,
            "default": "from-base64\ngunzip\njson-pretty"
          },
          "key": {
            "title": "Secret / key (referenced as @key)",
            "description": "Optional: HMAC/JWT secret or a PEM/JWK public key for jwt-verify. Hidden in the results.",
            "type": "string",
            "maxLength": 20000
          },
          "outputFormat": {
            "title": "Show output as",
            "type": "string",
            "enum": [
              "auto",
              "text",
              "hex",
              "base64"
            ],
            "default": "auto"
          }
        },
        "required": []
      },
      "CryptoKitchenResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "inputBytes",
              "recipe",
              "steps",
              "failed",
              "output",
              "artifact"
            ],
            "properties": {
              "inputBytes": {
                "type": "integer"
              },
              "recipe": {
                "type": "string"
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "index",
                    "op",
                    "label",
                    "args",
                    "bytes",
                    "kind",
                    "preview",
                    "notes",
                    "error"
                  ],
                  "properties": {
                    "index": {
                      "type": "integer"
                    },
                    "op": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "args": {
                      "type": "string",
                      "description": "Arguments as given; secret values are hidden."
                    },
                    "bytes": {
                      "type": "integer"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "text",
                        "binary"
                      ]
                    },
                    "preview": {
                      "type": "string"
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "failed": {
                "type": "boolean"
              },
              "output": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "bytes",
                  "kind",
                  "text",
                  "hex",
                  "base64",
                  "sha256",
                  "truncated"
                ],
                "properties": {
                  "bytes": {
                    "type": "integer"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "text",
                      "binary"
                    ]
                  },
                  "text": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "hex": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "base64": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "truncated": {
                    "type": "boolean",
                    "description": "true if text/hex/base64 were cut to 100,000 characters (download the artifact for everything)"
                  }
                }
              },
              "artifact": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}