You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cross-building standalone binaries via an oam carrier. NPMJS_MCP_BINARY_RUNTIME=oam builds through oam instead of Node SEA, and NPMJS_MCP_BINARY_TARGET=<platform>-<arch> cross-builds for another target from any host — SEA cannot, because it embeds the running node as its carrier. oam's embed format is a tail trailer ([JS][u64 LE len][OAMEXEC\0]), and appending to an executable's tail is tolerated identically by PE, ELF and Mach-O, so only the carrier is platform-specific. The carrier is fetched from the published oam release and verified against its SHA256SUMS entry; a mismatch or missing entry aborts. Verified: a linux-x64 cross build from windows-arm64 produces a genuine ELF 64-bit LSB pie executable, x86-64 whose trailer length matches the bundle byte for byte.
Runtime launcher at bin/npmjs-mcp.mjs: the published npmjs-mcp command now prefers the oam runtime and falls back to Node. NPMJS_MCP_RUNTIME selects (auto / oam / node) and OAM_BIN overrides discovery. Both paths were verified against the full MCP surface — handshake, 64 tools, live registry call, and the destructive-op confirm gate — and behave identically, because the server is a pre-bundled ESM file using only node: builtins oam implements.
dev:oam script: oam run --check=warn src/index.ts runs the TypeScript source with no build step, type-checking concurrently rather than blocking execution.
Changed
bin points at the launcher rather than dist/index.js directly. The fallback does not re-exec Node — npm has already started Node to run the launcher, so it is an in-process import() with no extra spawn or startup for users without oam.
.gitignore now excludes bin/* rather than bin/, so the launcher can be re-included with a negation. A directory-level exclusion cannot be undone by a negation for a file inside it, which would have left the launcher untracked and absent from any fresh clone while still appearing to work locally.
Notes
oam is faster than Node for this server; the launcher is not. Windows-arm64, n=12 medians, spawn to first MCP initialize: oam run dist/index.js 116 ms (0.67x), node dist/index.js 172 ms, launcher 243 ms (1.41x). npm bin entries are Node scripts, so reaching oam through one pays Node's startup plus oam's — more than oam saves. Point an MCP host directly at oam run <abs>/dist/index.js for the fast path; the launcher is for npx convenience.
Benchmarking caveat worth recording: an earlier revision of these notes claimed oam was a regression (~382 ms Node vs ~510 ms oam). That was measuring a virus scanner, not a runtime — the oam binary was being run out of a cargo target/ directory, which the active AV rescanned on every exec. The identical bytes copied elsewhere and run once to absorb the scan started 5.0x faster (306 ms → 61 ms, interleaved and reproducible). Never benchmark out of a build-output directory on Windows.
oam's --permission sandbox is deliberately unused. Its own divergence notes record that it denies filesystem, environment and network access, and the only grants implemented are --allow-fs-read/write, --allow-child-process, --allow-worker and --allow-addons. With no network grant, enabling it produces a server that completes the MCP handshake and then fails every tool call — confirmed empirically before ruling it out.