mcp-pacemaker 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +142 -2
  2. package/CONTRIBUTING.md +11 -4
  3. package/README.md +116 -764
  4. package/SECURITY.md +7 -0
  5. package/THIRD_PARTY_NOTICES.txt +1 -1
  6. package/autostart/windows/legacy-access.ps1 +359 -0
  7. package/bin/account-upgrade-controller.mjs +1 -1
  8. package/bin/account-upgrade-worker.mjs +7 -0
  9. package/bin/cli-main.mjs +61 -5
  10. package/bin/dependency-lock.json +642 -0
  11. package/bin/legacy-access.mjs +73 -0
  12. package/bin/legacy-installation.mjs +75 -19
  13. package/bin/legacy-task.mjs +24 -0
  14. package/bin/legacy-upgrade.mjs +66 -10
  15. package/bin/managed-upgrade.mjs +102 -12
  16. package/bin/mcp-bridge.mjs +115 -20
  17. package/bin/prewarm.mjs +28 -6
  18. package/bin/service-control.mjs +10 -5
  19. package/bin/upgrade-capability.json +2 -1
  20. package/bin/upgrade-dependencies.mjs +67 -6
  21. package/bin/upgrade-package.mjs +2 -0
  22. package/bin/windows-legacy/LegacyProcessBroker.build.json +3 -3
  23. package/bin/windows-legacy/LegacyProcessBroker.exe +0 -0
  24. package/bin/windows-legacy/src/LegacyNative.cs +60 -11
  25. package/bin/windows-legacy/src/LegacyProcessBroker.cs +317 -197
  26. package/bin/windows-legacy-process.mjs +12 -5
  27. package/docs/account-upgrades.md +17 -4
  28. package/docs/comparison.md +167 -0
  29. package/docs/compatibility.md +39 -0
  30. package/docs/configuration.md +146 -0
  31. package/docs/dashboards.md +125 -0
  32. package/docs/execution-context.md +11 -5
  33. package/docs/http-api.md +47 -0
  34. package/docs/install.md +52 -0
  35. package/docs/operations.md +99 -0
  36. package/docs/upgrades.md +324 -0
  37. package/package.json +11 -3
  38. package/tools/windows-legacy/README.md +118 -92
  39. package/tools/windows-legacy/inventory.mjs +8 -6
  40. package/ui/dist/THIRD_PARTY_NOTICES.txt +1 -1
  41. package/ui/dist/third-party-manifest.json +6 -6
package/CHANGELOG.md CHANGED
@@ -7,9 +7,147 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.1.2] - 2026-10-26
11
+
12
+ ### Fixed
13
+
14
+ - The bridge no longer crashes when a server exits while a request is being written to it, for
15
+ example when the server restarts mid-request. The write failed with `EPIPE` and nothing
16
+ handled the error, so the whole bridge restarted and calls in flight on every server failed.
17
+ A Streamable HTTP request now gets a "server exited before answering" error, and the bridge
18
+ keeps running.
19
+ - A crash after startup now leaves its error and stack in `bridge.log`. They went only to
20
+ stderr, which nothing captures when the bridge runs as a Windows task.
21
+ - The offline release verifier (`npm run publication:verify-local`) rejected every 2.1.x local
22
+ gate run with "Supporting command vector changed". The gate binds each Git command to its
23
+ checkout with `safe.directory`, and the verifier rebuilt the commands without it. Both now
24
+ build it with the same function.
25
+
26
+ ### Security
27
+
28
+ - Web pages from other sites can no longer use the bridge. Host and Origin were checked only on
29
+ the admin and pooling routes, so a page open in the user's browser could call tools through
30
+ the bridge, including on HTTP servers the bridge adds credentials to. Every route now answers
31
+ 403 when the Host is a DNS name other than `localhost` (DNS rebinding), when the Origin is
32
+ neither the bridge nor a `localhost` or loopback page, or when the browser marks the request
33
+ as cross-site, except opening the dashboard from a link. MCP clients, the CLI and the
34
+ dashboard work as before through `localhost` or an IP address; a client that reaches the
35
+ bridge by another host name, such as `host.docker.internal`, now gets 403 and should use an
36
+ IP address.
37
+ - The dashboard is built with Vite 7.3.7. Vite's development server has advisories up to 7.3.6
38
+ (GHSA-9jrq-w75r-8gcw, GHSA-rq7h-c2jc-7f22, GHSA-698v-4r3x-3vcv, GHSA-r825-w8mm-5pxw,
39
+ GHSA-587h-7wmj-h5pm). The published package ships the prebuilt dashboard and never runs that
40
+ server; the built dashboard is unchanged.
41
+
42
+ ### Changed
43
+
44
+ - The README again compares mcp-pacemaker with Supergateway, mcp-proxy, MCP Hub and ToolHive.
45
+ Each cell was checked against the projects' October 2026 releases and is sourced in
46
+ `docs/comparison.md`, which now ships in the package.
47
+ - The npm publishing tools accept 1.x release candidates. CI validation expects the 1.x Windows
48
+ job names, and the runtime file check asks only for the pooling modules a 1.x package has. The
49
+ 1.x maintenance line now carries these same tools.
50
+
51
+ ## [2.1.1] - 2026-10-15
52
+
53
+ Published to npm on 2026-10-17.
54
+
55
+ ### Added
56
+
57
+ - `upgrade --fix-legacy-access` is a one-time step for a Windows 1.3 install that was set up from
58
+ an administrator terminal. Run it from an administrator terminal. It gives the task's own
59
+ run-as user full control of that 1.3 task and makes that user the owner of the 1.3
60
+ `bin\cli.mjs`, and it records the previous permissions in
61
+ `legacy-upgrade\access-<time>.json` first. Nothing else changes: the task XML, triggers,
62
+ run-as account and run level, the other permission entries and the file contents stay the
63
+ same and are checked afterwards. `--plan` shows the change without making it.
64
+ - The Windows release qualification can resume after a failed or killed run with
65
+ `--resume RUN_DIRECTORY`. Each run records its inputs, controller, Docker engine, Windows
66
+ build and passed steps in `run-state.json`. A resume refuses any change to those or to the
67
+ kept evidence, sets the failed attempt aside next to the run and reruns only the steps that
68
+ did not pass. The offline verifier checks the recorded history; the published regression
69
+ statement is unchanged.
70
+
71
+ ### Fixed
72
+
73
+ - Upgrading a Windows 1.3 install that was set up from an administrator terminal no longer fails
74
+ part-way. Windows makes Administrators the owner of that task and lets your account only read
75
+ it, and makes Administrators the owner of the files, so the upgrade, which must run as an
76
+ ordinary user, was refused while copying the CLI file and would then have failed while holding
77
+ the task. Planning now checks these permissions first and stops before any process capture,
78
+ download or change. It names each item and the fix. Installs set up from a normal terminal
79
+ are unaffected.
80
+ - `upgrade --to` from an elevated terminal is now refused before planning and before any
81
+ confirmation prompt, with the normal-terminal next step. It used to ask for the restart
82
+ confirmation first and refuse afterwards.
83
+ - Managed upgrades no longer fail behind npm mirrors that publish only SHA-1 checksums, such as
84
+ some Azure Artifacts upstreams. Each release now carries the SHA-512 dependency lock it was
85
+ released and tested with (`bin/dependency-lock.json`, declared by `dependencyLock` in
86
+ `bin/upgrade-capability.json`), and staging installs exactly that lock with `npm ci` through
87
+ your configured registry, including when `replace-registry-host` is `never`.
88
+ Staged dependencies no longer move to newer in-range versions at upgrade time. Targets without
89
+ the lock keep the old resolution, and an entry without SHA-512 integrity now names the package.
90
+ - The Windows legacy process broker now waits up to eight seconds instead of two for each WMI
91
+ command-line query, and reports the first real failure instead of a generic
92
+ `Argument query cancelled`. A WMI timeout is reported as `Argument query timed out`. On a busy
93
+ host with about 1,000 processes the two-second limit made legacy planning fail.
94
+ - `reload` no longer reports a slow bridge as `bridge DOWN`. The bridge may spend its whole
95
+ pooling budget settling a pending batch before it answers, but the CLI gave up after five
96
+ seconds. It now waits past that budget and reports a late answer as a timeout. Status
97
+ checks wait ten seconds instead of two before treating a bridge as down. A refused
98
+ connection still fails at once.
99
+ - Upgrading a busy Windows 1.3 install no longer fails. The legacy process broker put every
100
+ process under the 1.3 bridge into the plan and refused when that list changed, but a busy
101
+ bridge starts and ends a session process every few seconds. It also refused any install
102
+ with more than 512 such processes (one had 533), and the upgrade refused whenever 1.3
103
+ rewrote `sessions.json`, which it does on every session start and end. The plan now holds
104
+ only the supervisor and the bridge. The stop ends the supervisor, holds a handle to every
105
+ process under the bridge, ends the bridge, and then stops everything it holds plus anything
106
+ those processes started, up to 2048 processes. Holding them first matters: Node ends a
107
+ process's direct children with it, and 1.3 runs each bare server command under `cmd.exe`,
108
+ so ending the bridge first would have left those servers running with no traceable parent.
109
+ A process it cannot stop is reported and left running instead of blocking the upgrade.
110
+ Capture and revalidation also get 120 seconds from the request instead of 14 to 15 seconds
111
+ from the broker's start, which a loaded host could use up before the capture began.
112
+ - A 1.3 upgrade started from inside the 1.3 tree, for example through an MCP server's shell,
113
+ is now refused before anything changes. It would have stopped itself part-way.
114
+ - A managed upgrade no longer refuses because a client is connected. The bridge counted every
115
+ open session as active work and refused after eight seconds, and once any client had dropped
116
+ a stream it refused every later upgrade until it restarted. Each refusal also left the bridge
117
+ answering 503 until `upgrade --recover`. Now calls in progress and config work get up to
118
+ eight seconds to finish, and open sessions and calls still running end with the restart.
119
+ Config work still unfinished then refuses the upgrade, and the upgrader resumes the current
120
+ version, trying for up to ten seconds while that work settles. A session that starts or ends
121
+ during the download no longer fails the upgrade either; only `servers.json` must be
122
+ unchanged. The installed version runs an upgrade, so this applies to upgrades from 2.1.1 on.
123
+ To upgrade from 2.1.0, close your MCP clients and restart Pacemaker first.
124
+ - `prewarm` no longer crashes on Windows with
125
+ `Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)` after the bridge refuses a change. It
126
+ prints the refusal and exits with status 1. Node 23, 24 before 24.20.0, 25, and 26 before
127
+ 26.7.0 can abort a process that exits soon after `fetch`
128
+ ([nodejs/node#56645](https://github.com/nodejs/node/issues/56645)), so `prewarm` now talks to
129
+ the bridge with `node:http` like the rest of the CLI. A bridge that does not answer within ten
130
+ seconds is now reported by port instead of as `The operation was aborted due to timeout`.
131
+
132
+ ### Changed
133
+
134
+ - Upgrades now follow one written rule: an upgrade may end open sessions and calls in progress,
135
+ and never retries a call; it never changes `servers.json` or your client setup. See
136
+ [upgrades and rollback](docs/upgrades.md#what-an-upgrade-keeps-and-what-it-ends).
137
+ - The Windows 1.3 upgrade accepts `--yes` to confirm the plan shown, like other upgrades, and
138
+ its confirmation now says what ends and what is kept. It used to require an interactive
139
+ terminal and ask you to pause callers first. Explicit-account (`--user`) upgrades still need
140
+ interactive confirmation, because they also create a task for that account.
141
+ - Split the Windows release qualification into a contained lane and a host session lane.
142
+ The qualification container has no interactive logon, so it now verifies the
143
+ `source-ordinary` contract and defers the four session-bound test files; those files run
144
+ on the publishing host under an ordinary, non-elevated interactive account and produce a
145
+ `session-lane.json` receipt that the offline verifier requires, bound to the same commit.
146
+ This closes a gap where those four files ran in no automated lane.
147
+
10
148
  ## [2.1.0] - 2026-10-12
11
149
 
12
- Target release: 2.1.0. This candidate has not yet been published.
150
+ Published to npm on 2026-10-14.
13
151
 
14
152
  ### Added
15
153
 
@@ -545,7 +683,9 @@ one is a trap for anyone building something similar.
545
683
  - Do not report a teardown the bridge initiated as a crash. `taskkill /F` exits non-zero, so
546
684
  every recycle, idle reap and session close was recorded as a failure, burying real ones.
547
685
 
548
- [Unreleased]: https://github.com/girishkvs/mcp-pacemaker/compare/v2.1.0...HEAD
686
+ [Unreleased]: https://github.com/girishkvs/mcp-pacemaker/compare/v2.1.2...HEAD
687
+ [2.1.2]: https://github.com/girishkvs/mcp-pacemaker/releases/tag/v2.1.2
688
+ [2.1.1]: https://github.com/girishkvs/mcp-pacemaker/releases/tag/v2.1.1
549
689
  [2.1.0]: https://github.com/girishkvs/mcp-pacemaker/releases/tag/v2.1.0
550
690
  [2.0.2]: https://github.com/girishkvs/mcp-pacemaker/releases/tag/v2.0.2
551
691
  [2.0.1]: https://github.com/girishkvs/mcp-pacemaker/releases/tag/v2.0.1
package/CONTRIBUTING.md CHANGED
@@ -128,6 +128,13 @@ instead of installing bundled Chromium. CI uses bundled Chromium, not that overr
128
128
  Both standalone test commands **fail** when preparation is missing or candidate bytes have
129
129
  changed. Clean and prepare again after changing package files, built assets, or Node major.
130
130
 
131
+ On Windows, run these gates on Node 20, 22, 24.20.0 or a later 24.x, or 26.7.0 and later.
132
+ Released CLIs up to 2.1.0 use `fetch` for `prewarm`, and Node 23, 24 before 24.20.0, 25, and 26
133
+ before 26.7.0 can abort a process that exits soon after `fetch`
134
+ ([nodejs/node#56645](https://github.com/nodejs/node/issues/56645)). There, any test that runs a
135
+ released CLI into a refused change (1.3.0, and 2.0.0 in the historical baseline) fails with exit
136
+ code 3221226505 and a libuv `UV_HANDLE_CLOSING` assertion.
137
+
131
138
  Historical compatibility baselines remain explicitly **1.3.0 and 2.0.0**.
132
139
  Candidate versions must be canonical stable **1.x legacy / 2.x current** versions.
133
140
  The owner selects the actual release and any exact opposite-major patch pair;
@@ -136,12 +143,12 @@ The same harness runs in both maintained branches:
136
143
 
137
144
  | Preparation | Selected legacy / current pair |
138
145
  |---|---|
139
- | Default in the selected 2.1.0 checkout | Immutable 1.3.0 / packed 2.1.0 |
140
- | Default in the 1.3.1 checkout | Packed 1.3.1 / immutable 2.0.0 |
146
+ | Default in the selected 2.1.2 checkout | Immutable 1.3.0 / packed 2.1.2 |
147
+ | Default in the 1.3.2 checkout | Packed 1.3.2 / immutable 2.0.0 |
141
148
  | `npm run compat:prepare:baseline` | Immutable 1.3.0 / immutable 2.0.0 |
142
- | `npm run compat:prepare -- --peer-root <opposite-patch-checkout>` | Packed explicit 1.x peer / packed 2.1.0 |
149
+ | `npm run compat:prepare -- --peer-root <opposite-patch-checkout>` | Packed explicit 1.x peer / packed 2.1.2 |
143
150
 
144
- These selections are not qualification evidence. The 2.1.0 candidate requires fresh
151
+ These selections are not qualification evidence. The 2.1.2 candidate requires fresh
145
152
  exact-byte gates; selecting it does not select an opposite-major patch pair.
146
153
  Earlier 1.3.1/2.0.2 and 1.3.1/2.0.1 results remain historical.
147
154