Added
- The publish workflow fails before
npm publishwhen the GitHub Release tag
andpackage.jsonversion disagree.check-versions.mjsproved that
package.jsonandserver.jsonagreed with each other — it does not read
package-lock.jsonin this repo — but nothing tied that version to the tag
the release was cut from — so tagging
v1.9.0on a commit reading2.0.0would have published 2.0.0 to npm and the
MCP Registry while the GitHub Release — the artifact humans read — claimed
otherwise, silently and on the irreversible side of the publish. Ported from
lexware-mcp-server 5.2.0 (lexware #103).
Changed
- The publish job runs on Node 24 (Active LTS) instead of Node 20. npm's Trusted
Publishing prerequisite is two-part — npm 11.5.1+ and Node 22.14+ — and
the job satisfied only the npm half, leaving the irreversiblenpm publish
step one npm patch away from breaking if that floor starts being enforced. The
CI test matrix stays on Node 20 + 22: it tracksengines.node, which is
unchanged. Ported from lexware-mcp-server 5.2.0 (lexware #102). - Raised the
@modelcontextprotocol/sdkfloor to^1.30.0, which declares
@hono/node-server: ^1.19.9 || ^2.0.5where 1.29.0 declared only^1.19.9.
A correctness alignment, not a security fix: the resolved tree already carried
a patched@hono/node-server, and the production audit gate was green before
and after. What it buys is that a resolver cannot fall back to an SDK whose
range predates the widening. Ported from lexware-mcp-server 5.2.0 (lexware
#81).
Security
-
Refreshed the
overridesfloors. Three had drifted inside live advisory
ranges and two packages that reach the production audit gate were not pinned
at all — verified against the GitHub advisory API on 2026-08-20:Package Was Now Advisory range fast-uri^3.1.2^3.1.5GHSA-7p8r-x3mc-p8w7, >=3.0.0 <3.1.5brace-expansion^5.0.6^5.0.9GHSA-rgw5-rvv9-x895, >=4.0.0 <5.0.9hono^4.12.25^4.12.34GHSA-8j4g-w8fx-2239 et al., <4.12.34ip-addressunpinned ^10.3.1GHSA-mwp4-54f8-5fhr, <=10.3.0body-parserunpinned ^2.3.0GHSA-v422-hmwv-36x6, >=2.0.0 <2.3.0package-lock.jsonis unchanged: every resolved version was already above the
new floors, so this closes a latent gap rather than a live one, and the audit
gate was green before and after. The unpinned entries are the dangerous ones —
anoverridesentry is the only thing that pulls a sticky lockfile forward on
install, so an unpinned transitive dep is the one that drifts into a range
while pinned ones re-resolve themselves. -
The override guard test now covers every pin. It asserted only
qs,hono
andform-data, leavingfast-uriandbrace-expansiondeclared but
unchecked — a pin nothing checks is indistinguishable from no pin once it
rots. The six hand-rolled assertions are replaced by aPINStable plus a
completeness assertion that fails when theoverridesblock and the table
disagree in either direction, so a pin cannot be added without a guard. Both
directions were vacuity-probed rather than assumed.