mcp-pacemaker 2.0.1
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.
- package/CHANGELOG.md +452 -0
- package/CONTRIBUTING.md +222 -0
- package/LICENSE +21 -0
- package/README.md +621 -0
- package/SECURITY.md +120 -0
- package/THIRD_PARTY_NOTICES.txt +366 -0
- package/autostart/windows/launcher.vbs +11 -0
- package/autostart/windows/register-task.ps1 +63 -0
- package/bin/cli.mjs +880 -0
- package/bin/config-checks.mjs +62 -0
- package/bin/logs.mjs +465 -0
- package/bin/mcp-bridge.mjs +2162 -0
- package/bin/pooling-batch-scheduler.mjs +129 -0
- package/bin/pooling-batches.mjs +270 -0
- package/bin/pooling-config.mjs +577 -0
- package/bin/pooling-editor.mjs +128 -0
- package/bin/pooling-errors.mjs +23 -0
- package/bin/pooling-execution.mjs +104 -0
- package/bin/pooling-files.mjs +541 -0
- package/bin/pooling-trace.mjs +218 -0
- package/bin/pooling-writer.mjs +242 -0
- package/bin/prewarm.mjs +233 -0
- package/bin/server-metrics.mjs +69 -0
- package/bin/service-control.mjs +124 -0
- package/bin/shared-sessions.mjs +1083 -0
- package/bin/top.mjs +115 -0
- package/bin/update-check.mjs +153 -0
- package/bin/windows/PoolingSecurityHelper.build.json +42 -0
- package/bin/windows/PoolingSecurityHelper.exe +0 -0
- package/bin/windows/src/AssemblyInfo.cs +11 -0
- package/bin/windows/src/PoolingNativeFiles.cs +678 -0
- package/bin/windows/src/PoolingSecurityHelper.cs +178 -0
- package/bin/windows/src/PoolingSecurityReader.cs +50 -0
- package/docs/shared-sessions.md +181 -0
- package/examples/servers.example.json +31 -0
- package/package.json +77 -0
- package/supervisor/bridge-child.mjs +14 -0
- package/supervisor/supervise.mjs +172 -0
- package/supervisor/supervise.ps1 +23 -0
- package/supervisor/supervise.sh +11 -0
- package/tools/windows-security-helper/README.md +238 -0
- package/tools/windows-security-helper/build.ps1 +262 -0
- package/ui/dist/THIRD_PARTY_NOTICES.txt +366 -0
- package/ui/dist/assets/index-CaLPg0c-.css +1 -0
- package/ui/dist/assets/index-CgPruWYi.js +9 -0
- package/ui/dist/index.html +14 -0
- package/ui/dist/third-party-manifest.json +597 -0
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for taking a look. This is a small, deliberately dependency-light project, so a few
|
|
4
|
+
constraints matter more than they might elsewhere.
|
|
5
|
+
|
|
6
|
+
## Getting set up
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/girishkvs/mcp-pacemaker
|
|
10
|
+
cd mcp-pacemaker
|
|
11
|
+
npm ci
|
|
12
|
+
npm test
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Node 20 or newer. The bridge itself (`bin/mcp-bridge.mjs`) has **zero npm runtime dependencies**
|
|
16
|
+
and must stay that way; it runs 24/7 on a developer's machine and its dependency surface is
|
|
17
|
+
part of its security posture. The setup CLI and the dashboard may use dependencies.
|
|
18
|
+
|
|
19
|
+
## Lockfiles must resolve to the public registry
|
|
20
|
+
|
|
21
|
+
CI fails any lockfile containing a `resolved` URL outside `registry.npmjs.org`. If you work
|
|
22
|
+
behind a private mirror, re-resolve before committing:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install --registry https://registry.npmjs.org
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Tests
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm test
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Tests are `node:test` only, no framework. Each test file that starts a bridge owns its own
|
|
35
|
+
ports, because files run in parallel; the current allocation is listed at the top of
|
|
36
|
+
`test/auth-token.test.mjs`. Pick unused ones for a new file.
|
|
37
|
+
|
|
38
|
+
Before submitting, run the complete `npm test` command with its normal file concurrency.
|
|
39
|
+
Focused or serialized runs help diagnose failures but do not replace that run. Record the
|
|
40
|
+
exact Node and npm versions, OS, architecture, and command; matching only the Node major is
|
|
41
|
+
not enough to reproduce a CI failure.
|
|
42
|
+
|
|
43
|
+
Filesystem coverage must include native POSIX absolute paths, macOS temporary-directory
|
|
44
|
+
aliases, and Windows 8.3 temporary paths as well as canonical paths. Preserve those inputs
|
|
45
|
+
when reproducing a failure instead of normalizing the whole test environment. Canonicalize
|
|
46
|
+
owned scratch roots and native watcher inputs at their boundaries; keep rejecting unexpected
|
|
47
|
+
links, replaced directories, and files outside the approved inventory. A Windows-only pass
|
|
48
|
+
does not establish Linux or macOS correctness; the hosted platform matrix remains required.
|
|
49
|
+
|
|
50
|
+
Windows configuration-write coverage must exercise the normal interactive startup token,
|
|
51
|
+
not only a test process inheriting an elevated runner. Validate both the actual token context
|
|
52
|
+
and successful staging/activation. Security-oracle fixtures may use already-authorized test
|
|
53
|
+
authority to establish and inspect their own files; production saves must not depend on it.
|
|
54
|
+
Directory-inherited auditing is the default. Test ordinary access restrictions, integrity,
|
|
55
|
+
custom-audit behavior, contender files and crash recovery separately.
|
|
56
|
+
|
|
57
|
+
Windows automatic edits use the packaged .NET Framework 4.6.2 helper. Changes to its source
|
|
58
|
+
must rebuild the executable and metadata with
|
|
59
|
+
`tools/windows-security-helper/build.ps1`, then pass `-Verify` with the recorded compiler
|
|
60
|
+
and reference assemblies. See the [helper build instructions](tools/windows-security-helper/README.md).
|
|
61
|
+
The portable Node suite checks normalized source/build-script and binary hashes on every CI
|
|
62
|
+
platform; Windows also exercises the real executable. Those checks do not replace the
|
|
63
|
+
byte-for-byte rebuild, and a rolling CI image may not contain the recorded compiler.
|
|
64
|
+
No compiler or PowerShell host runs in the production config-write path.
|
|
65
|
+
|
|
66
|
+
Batch tests must cover the full five-second trailing debounce, merging complete snapshots,
|
|
67
|
+
Reload now, requests during a flip, stale active revisions, whole-batch Cancel/Undo and late
|
|
68
|
+
commit outcomes. Use controlled clocks for scheduling boundaries and real file/HTTP cases for
|
|
69
|
+
integration. A skipped second move is not proof of recovery after actual process termination.
|
|
70
|
+
|
|
71
|
+
**A regression test must be shown to fail without its fix.** Revert the fix, watch the test
|
|
72
|
+
fail, restore it, watch it pass. Several bugs in this repo were originally "covered" by tests
|
|
73
|
+
that passed against the broken code — a test that cannot fail is worse than no test, because
|
|
74
|
+
it also stops anyone else from looking. If a bug involves process lifetime or timing, prefer
|
|
75
|
+
observing a real signal (a heartbeat file, a recorded request) over enumerating processes or
|
|
76
|
+
sleeping a fixed interval.
|
|
77
|
+
|
|
78
|
+
## Real-version compatibility gates
|
|
79
|
+
|
|
80
|
+
These are separate, mandatory CI gates, not substitutes for `npm test`. The root CI job runs
|
|
81
|
+
CLI/API pairs on Windows, Linux and macOS with Node 20, 22 and 24. The Linux/Node 22 UI
|
|
82
|
+
job runs one Chromium browser matrix after building the dashboard.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm ci
|
|
86
|
+
npm run compat:prepare
|
|
87
|
+
npm run test:compat
|
|
88
|
+
npm run compat:clean
|
|
89
|
+
|
|
90
|
+
# Browser gate: build before packing the candidate.
|
|
91
|
+
npm --prefix ui ci
|
|
92
|
+
npm --prefix ui run build
|
|
93
|
+
cd ui
|
|
94
|
+
npx --no-install playwright install --with-deps chromium
|
|
95
|
+
cd ..
|
|
96
|
+
npm run compat:prepare
|
|
97
|
+
npm run test:compat:browser
|
|
98
|
+
npm run compat:clean
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For an already installed local Chrome, set `MCP_COMPAT_BROWSER_CHANNEL=chrome` in your shell
|
|
102
|
+
instead of installing bundled Chromium. CI uses bundled Chromium, not that override.
|
|
103
|
+
Both standalone test commands **fail** when preparation is missing or candidate bytes have
|
|
104
|
+
changed. Clean and prepare again after changing package files, built assets, or Node major.
|
|
105
|
+
|
|
106
|
+
Scope is explicitly **1.3.0, 1.3.1, 2.0.0 and 2.0.1**, not arbitrary compatible-looking versions.
|
|
107
|
+
The same harness runs in both maintained branches:
|
|
108
|
+
|
|
109
|
+
| Preparation | Selected legacy / current pair |
|
|
110
|
+
|---|---|
|
|
111
|
+
| Default in the 2.0.1 checkout | Immutable 1.3.0 / packed 2.0.1 |
|
|
112
|
+
| Default in the 1.3.1 checkout | Packed 1.3.1 / immutable 2.0.0 |
|
|
113
|
+
| `npm run compat:prepare:baseline` | Immutable 1.3.0 / immutable 2.0.0 |
|
|
114
|
+
| `npm run compat:prepare -- --peer-root <opposite-patch-checkout>` | Packed 1.3.1 / packed 2.0.1 |
|
|
115
|
+
|
|
116
|
+
Run both API and browser gates for the explicit patch pair before publishing either complete
|
|
117
|
+
dual-major release set. The two default CI pairs alone do not establish that combined result.
|
|
118
|
+
Run `compat:clean` before selecting another pair.
|
|
119
|
+
|
|
120
|
+
Publication artifact gates add `--candidate-tarball <absolute.tgz> --candidate-sha256 <digest>`.
|
|
121
|
+
This supplies the checkout's own candidate role without repacking it, including the legacy
|
|
122
|
+
role when invoked from 1.3.1. The archive must match every package input and the supplied digest;
|
|
123
|
+
historical mode cannot substitute it. The manifest also records the exact npm CLI version.
|
|
124
|
+
|
|
125
|
+
Release sources are pinned to `2d525f4ced01b978a5aeb83aef69145e96cced05` (1.3.0) and
|
|
126
|
+
`db4812a1cbfb8546c814a656397b9a48ccf0f32c` (2.0.0). Missing commits are fetched read-only by
|
|
127
|
+
exact SHA into an owned temporary repository, never through a moving tag or into checkout refs.
|
|
128
|
+
Git archive uses canonical Git line endings and the committed attributes. Local candidates
|
|
129
|
+
are packed with lifecycle scripts disabled and compared against their actual source files.
|
|
130
|
+
|
|
131
|
+
Each selected package uses its own unchanged producer lock via `npm ci --omit=dev --ignore-scripts`.
|
|
132
|
+
This is producer-locked compatibility, not fresh consumer resolution. The manifest records the
|
|
133
|
+
selection mode, exact versions and release references, per-role archive/file hashes, source
|
|
134
|
+
inputs and Node major. Editing either candidate invalidates prepared fixtures. No patch is
|
|
135
|
+
relabeled as the original historical bytes. Git, tar, Node and npm must be available.
|
|
136
|
+
|
|
137
|
+
For local restores through an approved registry, preparation honors the caller's resolved
|
|
138
|
+
`npm_config_registry` and `npm_config_replace_registry_host` settings (and npm cache).
|
|
139
|
+
For example, in a POSIX shell:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npm_config_registry=https://approved-registry.example.test/npm/ \
|
|
143
|
+
npm_config_replace_registry_host=npmjs npm run compat:prepare
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Use your approved registry URL, not the example. These settings are forwarded to isolated
|
|
147
|
+
`npm ci` calls without changing npmrc files or recording registry settings in the manifest.
|
|
148
|
+
CI sets no override and uses the public registry. Both committed lockfiles and the fixture
|
|
149
|
+
lockfiles must retain public URLs; preparation verifies that restore leaves fixture locks
|
|
150
|
+
byte-identical. Registry policy or quarantine rejections fail preparation without a fallback.
|
|
151
|
+
|
|
152
|
+
Fixtures, private baseline code, configuration and fake HOME/state live in owned OS temporary
|
|
153
|
+
directories, never the user's active configuration. Only a manifest pointer is kept under
|
|
154
|
+
ignored `node_modules/.cache`. This manifest is also the prepared fixture's ownership marker:
|
|
155
|
+
it is created before restore, keeps its identity when preparation finishes, and is removed
|
|
156
|
+
only after its temporary tree is gone. A failed manifest unlink remains retryable. Other
|
|
157
|
+
temporary test directories use adjacent ownership markers. Ports are allocated dynamically.
|
|
158
|
+
Cleanup checks directory and marker identities and removes only owned files without following
|
|
159
|
+
links. Bridge/browser failures retain their original error and diagnostic logs in test output;
|
|
160
|
+
cleanup errors do not replace
|
|
161
|
+
the original failure. Run cleanup before another root `npm ci`, which removes the pointer.
|
|
162
|
+
|
|
163
|
+
| Pair/case | Required result |
|
|
164
|
+
|---|---|
|
|
165
|
+
| Selected 2.x CLI/API and built UI to selected 1.x backend | Legacy HTTP 200 enable and Undo; original config bytes restored |
|
|
166
|
+
| Selected 1.x CLI/API and built UI to selected 2.x backend, fresh nonce | Protocol HTTP 409, no queued write or config change |
|
|
167
|
+
| Already-open selected 1.x tab through an actual bridge restart | Old nonce gets HTTP 401; refresh loads the selected 2.x assets and can stage/cancel |
|
|
168
|
+
| Selected 2.x CLI and UI to selected 2.x backend | Queued save, Cancel, actual application and whole-batch Undo |
|
|
169
|
+
| Settled selected 1.x / 2.x / 1.x configuration | Edits/Undo and both restarts preserve the expected active bytes |
|
|
170
|
+
| Actual selected 1.x writes before and after that roundtrip, unchanged authority | Supported write/Undo must remain supported; known Windows audit-unavailable refusal must remain HTTP 403 with no change |
|
|
171
|
+
|
|
172
|
+
**Test-only UI asset serving:** the two mixed UI/backend cases serve exact old/new built
|
|
173
|
+
`ui/dist` files through Playwright, substituting only the current nonce in the HTML. All
|
|
174
|
+
API, admin mutation, SSE and MCP requests go to the real backend, without response mocks.
|
|
175
|
+
Nested JS assets are included. The old-tab upgrade case does not substitute assets: it stops
|
|
176
|
+
the actual selected 1.x process and starts the selected 2.x process on the same port before refresh.
|
|
177
|
+
|
|
178
|
+
No other version compatibility is claimed. Writable downgrade is checked on a fresh
|
|
179
|
+
synthetic config with default ownership and inherited security. The test does not change
|
|
180
|
+
tokens, elevate, or set ACLs. It checks unchanged caller authority and, on Windows, the actual
|
|
181
|
+
selected 1.x helper's full/partial audit visibility. Caller-context hashes are not direct measurements
|
|
182
|
+
of individual bridge tokens. Only the legacy HTTP 403 audit-unavailable
|
|
183
|
+
condition is accepted as unsupported; unexpected errors and any new HTTP 500 fail the gate.
|
|
184
|
+
The Windows 2.x writer retains a source owner matching the caller user or token default
|
|
185
|
+
owner; other owners still use checked transfer, and source write access remains required.
|
|
186
|
+
These gates do not test a downgrade with an unresolved transaction, installer/service
|
|
187
|
+
replacement, arbitrary Windows ACLs or authority changes, or all host integrations; their
|
|
188
|
+
separate tests and operational checks still apply.
|
|
189
|
+
|
|
190
|
+
## npm consumer validation
|
|
191
|
+
|
|
192
|
+
`npm run consumer:check -- --tarball <absolute-file> --sha256 <digest> --version <version> --name mcp-pacemaker`
|
|
193
|
+
installs the exact packed candidate into an owned disposable consumer project without a copied
|
|
194
|
+
producer lock, records the resolved graph, checks a separate global-prefix command shim, and
|
|
195
|
+
starts the real packaged bridge against synthetic servers and private state. It checks the
|
|
196
|
+
packaged UI assets and CLI status, then removes only its owned fixtures.
|
|
197
|
+
|
|
198
|
+
Run it with normal npm install-script policy and again with `--ignore-scripts`. It never uses
|
|
199
|
+
the user's global prefix, host configuration, live bridge, or npm credentials. It honors the
|
|
200
|
+
resolved caller registry/cache and offline setting without a mirror fallback. Registry
|
|
201
|
+
signatures and provenance are separate post-publication checks, not inferred from this smoke test.
|
|
202
|
+
|
|
203
|
+
## Changing how a host is wired
|
|
204
|
+
|
|
205
|
+
Host adapters live in `HOSTS` in `bin/cli.mjs`. Each one declares where that host's config
|
|
206
|
+
lives, the JSON key its servers sit under, and how a bridged entry is serialized. When you add
|
|
207
|
+
or change one:
|
|
208
|
+
|
|
209
|
+
- Add a case to `test/cli.test.mjs` asserting the exact entry shape.
|
|
210
|
+
- Never write a host config without backing it up first, and make sure `plan` reports the
|
|
211
|
+
change accurately — it is what people rely on before letting the tool touch their setup.
|
|
212
|
+
- Re-run `mcp-pacemaker plan` against a real config afterwards. It should report no changes
|
|
213
|
+
for a setup that is already correctly wired; anything else means the adapter and the
|
|
214
|
+
reconciliation logic disagree.
|
|
215
|
+
|
|
216
|
+
## Pull requests
|
|
217
|
+
|
|
218
|
+
- One concern per PR.
|
|
219
|
+
- Explain what broke and how you proved it fixed, not just what you changed.
|
|
220
|
+
- Comment only what needs clarifying — why something is done a particular way, not what the
|
|
221
|
+
line does.
|
|
222
|
+
- Update `CHANGELOG.md` under an `Unreleased` heading.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Girish Konda
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|