-
-
Notifications
You must be signed in to change notification settings - Fork 1
Contributing
git clone https://github.com/doublegate/CyberChef-MCP.git
cd CyberChef-MCP
npm install
npx grunt configTests # REQUIRED -- see InstallationNode >=24 <27. Package manager is npm — not pnpm, not bun.
Everything here must pass before a pull request is ready. CI runs the same commands.
npm run lint # ESLint via grunt -- zero errors
npm test # core: 241 Node-API + 2,289 operation tests
npm run test:mcp # MCP: 1,111 tests across 39 files (Vitest)
npm run test:coverage # thresholds: 95 statements / 96 lines / 88 branches / 96 functions
npm run testnodeconsumerTwo suites, not interchangeable: the core tests are custom Node runners, the MCP tests are Vitest.
- 4-space indentation. Upstream CyberChef style, not 2.
- No prettier. Formatting is enforced by ESLint.
-
Conventional Commits —
feat(scope):,fix(scope):, and so on. -
JSON imports use
with { type: "json" }, notassert. - Two lint rules interact awkwardly and are worth knowing before you fight them:
camelcasewithproperties: "always"anddot-notationtogether make a snake_case property unassignable after an object exists. Build such objects as literals with quoted keys, or useObject.assign.
Never hand-edit anything under src/core/ or the six upstream-owned files in src/node/. Add a
patch under patches/fork/ instead. See Fork & Upstream for the incident
that made this a rule.
Test through a real MCP client, not hand-rolled JSON-RPC. This is the project's most expensive
lesson. Every test before v2.1.0 spoke raw JSON-RPC or called handlers directly — and raw JSON-RPC
does no schema validation, so three releases shipped in which every one of 524 tools carried an
empty inputSchema while the suite stayed green. An official SDK client rejects that response
outright. tests/mcp/stdio-client-contract.test.mjs exists to close that gap.
Pin a known answer before implementing. For anything with a correct answer — a hash format, a factorisation, a pattern offset — write the vector first and verify the implementation against it. And generate the vector or cite where it came from; never recall it. A sha512crypt vector written from memory during v2.4.0 was 84 characters where the format has 86, and the reflex on a red test is to change the code rather than count the string.
Ask what makes it confidently wrong. Tests that cover what a tool is for miss the cases that matter most. Three correctness bugs in v2.4.0 — a square modulus, a digest colliding with a structural pattern, a fragment below the uniqueness window — all lived in inputs nobody had thought to construct.
Examples are executable. examples/ holds nine self-asserting scripts that CI runs.
Documentation that is not executed drifts.
Several bots review automatically — CodeQL, Trivy, CodeRabbit, Copilot, and a self-hosted Antigravity reviewer. Reply to every review thread, whether you adopt, reject or defer, and verify each claim against the code before answering. In v2.4.0 two suggestions would have introduced bugs if taken on trust, and several correct ones were nearly dismissed.
Edit docs/wiki/ in the repository, not the wiki itself. The wiki is published from that
directory by .github/workflows/wiki-sync.yml on every push to master that touches it, so an
edit made in the wiki UI is overwritten by the next sync. The footer on every page says so.
That indirection buys something: wiki content goes through review like code, and the pages cannot drift from a release without the diff being visible in the same pull request.
Two things about the mechanism are worth knowing before you debug it:
-
The wiki is a separate git repository (
<repo>.wiki.git), so the built-inGITHUB_TOKENcannot push to it. The workflow uses aWIKI_TOKENsecret — a classic PAT withreposcope, because a wiki is not covered by any fine-grained token permission. - The wiki repository does not exist until the first page is saved in the web UI. There is no API for creating it. Before that, a push fails with "Repository not found", which reads like a permissions problem and is not — the workflow's job summary names both causes rather than guessing between them.
Page filenames become URLs: Client-Setup.md is /wiki/Client-Setup. Link between pages with a
plain relative link — [Installation](Installation) — and keep _Sidebar.md in step, since a page
absent from it is reachable only by URL.
-
docs/adr/— architecture decisions, Nygard format -
docs/internal/*-findings-log.md— what was measured during each release, including what the plan got wrong. These are worth reading before changing anything they cover. -
docs/releases/— release notes -
docs/planning/ROADMAP.md— where things are going
v2.4.0 · upstream CyberChef v11.4.0 · GPL-3.0-or-later
Maintained in docs/wiki/ and published here automatically — edit the repository, not the wiki, or your change is overwritten on the next sync.
Getting started
Using it
Operating it
Help
The project