v2.8.1 release notes
Release Date: 2026-09-02
Upstream Base: CyberChef v11.4.0 (unchanged)
Licence: GPL-3.0-or-later
Node: >=24 <27
Highlights
Section titled “Highlights”A CI correctness release. No functional runtime code or dependency changed — every operation, the engine, the transports and the resolved dependency tree are what v2.8.0 shipped.
Not byte-for-byte, though, and the distinction is worth making precisely because it is the kind
of claim that is easy to overstate: package.json’s version is read at startup by
src/node/lib/config.mjs and surfaces in the MCP serverInfo, the startup log line and the
cyberchef_mcp_build_info metric. A running v2.8.1 server reports 2.8.1, as it should.
What changed is what CI measures, and two of those were wrong in ways a green pipeline hid.
We were testing Node 24 and shipping Node 26
Section titled “We were testing Node 24 and shipping Node 26”The published image runs Node 26.8.1. Every workflow that ran a test suite tested 24 — and the benchmark job, as below, was on 22.
So the runtime that actually ships was never exercised by a test, and nothing reported it — the pipeline was green throughout, because 24 is a perfectly valid version to test on. It just is not the one users get.
Bumping everything to 26 would have inverted the bug rather than fixed it. package.json
declares engines: >=24 <27, and 24 is a supported version for anyone installing from npm. Testing
only 26 would have left the declared floor untested, which is precisely the failure being fixed,
pointed the other way.
The test gates now run both boundaries:
| why | |
|---|---|
| Node 24 | the declared floor in engines |
| Node 26 | what Dockerfile.mcp actually runs |
with fail-fast: false, because when the Node version is the variable under test, “which ones
broke” is the entire result.
Everything that is not a test gate — benchmarks, release, docs, security scan, sync, rollback — moves to 26, matching the artefact it builds, publishes, measures or audits.
engines itself is unchanged. It matches upstream, and narrowing it would drop Node 24 consumers,
which is a breaking change and does not belong in a patch release.
The benchmarks were measured on an unsupported Node
Section titled “The benchmarks were measured on an unsupported Node”performance-benchmarks.yml still pinned node-version: '22', so every run printed:
npm warn EBADENGINE package: 'cyberchef-mcp@2.8.0'npm warn EBADENGINE required: { node: '>=24 <27' }, current: { node: 'v22.23.2' }That is worse than a warning. The performance numbers posted to every pull request were measured on a runtime this project does not support, against a V8 two majors behind the one it ships. A benchmark run on the wrong engine is a different measurement wearing the same label.
The v2.0.0 plan called for moving “all 7 workflows” to Node 24. This was the one that was missed, and it stayed missed for eight releases — because a warning is not a failure, and nobody reads a green job’s log.
Three Pages actions were force-run on deprecated Node 20
Section titled “Three Pages actions were force-run on deprecated Node 20”actions/configure-pages@v5 → v6, actions/upload-pages-artifact@v4 → v5,
actions/deploy-pages@v4 → v5. Each verified to declare using: node24.
One name in that deprecation warning appears nowhere in this repository:
actions/upload-artifact@ea165f8d... is pinned inside upload-pages-artifact@v4, and v5 pins
upload-artifact@v7 instead. Recorded because grepping for the warned-about action finds nothing,
and the obvious conclusion — that the warning is stale — is wrong.
What was left alone, and why
Section titled “What was left alone, and why”The sweep covered every warning in all seven workflows. What remains is benign, and saying which is the point of having swept.
EBADENGINE for @astronautlabs/amf@0.0.6 (a production dependency of AMF Encode and
AMF Decode). It declares engines: {node: "^14"} — stale author metadata. 0.0.6 is the
latest published version, so there is nothing to upgrade to, and upstream CyberChef declares it too.
Verified the operations work on 26.8.1 rather than assumed:
AMF Encode object -> OK (14 bytes) string -> OK (7 bytes) number -> OK (9 bytes)Noted in passing: the operations suite contains zero AMF test cases. That is upstream’s gap in an upstream-mirrored tree, so not this release’s to close — but it means the check above is currently the only coverage AMF has.
Four deprecated production packages. crypto-js and jsrsasign are genuine upstream operation
dependencies with no drop-in replacement. bootstrap-colorpicker and popper.js are two of the
five web-app leftovers measured in v2.8.0 — now known to be deprecated as well as unused, which
strengthens the case for removing them without changing the conclusion that the fork-boundary cost
is not worth 4.2% of the image.
Everything else matched the word rather than the condition and was deliberately not chased:
if-no-files-found: warn is an echoed input value; the git hint: lines are runner noise about
default branch naming; the WARNING: in the non-root container check is the script’s own message
text; and the level:"warn" lines in the test log are the audit trail and the session capacity
limiter being exercised on purpose by tests that assert those paths fire.
Upgrading
Section titled “Upgrading”Nothing to do. No functional runtime code or dependency changed from v2.8.0.
The image digest does change — it is a fresh build carrying the new version string — so a digest pin needs updating if you use one. What it does not carry is any behaviour difference: the only runtime-observable change is the version this server reports for itself.
Verification
Section titled “Verification”npm run lint cleannpm run test:mcp 1339 passed (51 files) on node v26.8.1 — the version the image runsnpm test 241 Node-API + 2289 operations passingactionlint clean on all modified workflowsCI matrix core and MCP suites green on node 24 AND node 26