@roadmapperai/mcp 0.9.0 → 0.9.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.
Files changed (3) hide show
  1. package/README.md +15 -0
  2. package/package.json +1 -1
  3. package/server.mjs +83 -1
package/README.md CHANGED
@@ -126,6 +126,21 @@ This package follows semver. Breaking changes to tool shapes get a
126
126
  major-version bump and a deprecation window. Add `--package=@roadmapperai/mcp@0.x.y`
127
127
  to your `npx` invocation if you want to pin.
128
128
 
129
+ Because the install is version-pinned (the dashboard hands you a config
130
+ pinned to an exact version), the server checks the npm registry at boot
131
+ and logs a one-line nudge to stderr if a newer version is published —
132
+ re-copy the install command from **Settings → MCP** to upgrade. Disable
133
+ the check with `ROADMAPPER_DISABLE_UPDATE_CHECK=1`.
134
+
135
+ ### Recent changes
136
+
137
+ - **0.9.1** — the server now self-reports its real version (was a stale
138
+ hardcoded string in `serverInfo` and audit logs) and warns at boot
139
+ when a newer package is published.
140
+ - **0.9.0** — entity reads on the customer path now route through the
141
+ broker, fixing an empty roadmap for every customer; new triage + gap
142
+ tools; light-by-default reads.
143
+
129
144
  ## Support
130
145
 
131
146
  - Bugs / feature requests: contact@roadmapperai.com
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roadmapperai/mcp",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Roadmapper AI MCP server — exposes a planning surface (themes, capabilities, tasks, sprints, PRs) to coding agents via stdio JSON-RPC. Pairs with the Roadmapper AI workspace at dashboard.roadmapperai.com.",
5
5
  "keywords": [
6
6
  "mcp",
package/server.mjs CHANGED
@@ -95,7 +95,22 @@ const REPO_AGENTS_PATH = join(REPO, "AGENTS.md");
95
95
 
96
96
  const PROTOCOL_VERSION = "2024-11-05";
97
97
  const SERVER_NAME = "roadmapper";
98
- const SERVER_VERSION = "0.6.0";
98
+ // Read the real version from the bundled package.json (it's in the npm
99
+ // `files` allow-list) so SERVER_VERSION never drifts from the published
100
+ // package. A hardcoded constant rotted to "0.6.0" while the package was
101
+ // at 0.9.0 — which silently mis-stamped every audit-log row's
102
+ // server_version. scripts/check-mcp-version.mjs guards the dashboard's
103
+ // LATEST_MCP_VERSION against package.json; this closes the same gap on
104
+ // the server side. Falls back to "0.0.0" only if the file is somehow
105
+ // unreadable (never expected in a real install).
106
+ const SERVER_VERSION = (() => {
107
+ try {
108
+ const pkg = JSON.parse(readFileSync(join(HERE, "package.json"), "utf-8"));
109
+ return typeof pkg.version === "string" ? pkg.version : "0.0.0";
110
+ } catch {
111
+ return "0.0.0";
112
+ }
113
+ })();
99
114
 
100
115
  // Must match src/types.ts EFFORT_DAYS — AI-era calibration.
101
116
  // Fractional values (XS=0.25, S=0.5) get rounded up when used to
@@ -110,6 +125,69 @@ function log(...args) {
110
125
  console.error("[roadmapper-mcp]", ...args);
111
126
  }
112
127
 
128
+ /**
129
+ * Compare two semver-ish strings ("1.2.3"). Returns 1 if a>b, -1 if
130
+ * a<b, 0 if equal. Compares the numeric major.minor.patch only — any
131
+ * prerelease/build suffix is ignored, which is fine for "is there a
132
+ * newer published release?" The probe below tolerates a 0 or negative
133
+ * result by staying silent, so an unexpected suffix never produces a
134
+ * false "upgrade available" nag.
135
+ */
136
+ function compareVersions(a, b) {
137
+ const pa = String(a).split(".").map((n) => parseInt(n, 10) || 0);
138
+ const pb = String(b).split(".").map((n) => parseInt(n, 10) || 0);
139
+ for (let i = 0; i < 3; i++) {
140
+ const da = pa[i] ?? 0;
141
+ const db = pb[i] ?? 0;
142
+ if (da > db) return 1;
143
+ if (da < db) return -1;
144
+ }
145
+ return 0;
146
+ }
147
+
148
+ /**
149
+ * Best-effort startup staleness check. Fetches the `latest` dist-tag
150
+ * for @roadmapperai/mcp from the npm registry and, if the running
151
+ * version is behind, logs a one-line nudge to stderr. Entirely
152
+ * advisory — the server is pinned to a specific version in the
153
+ * client's MCP config (see the dashboard install snippets), so there
154
+ * is no auto-update; the user upgrades by re-copying the install
155
+ * command from Settings → MCP. This is the only signal a stranded,
156
+ * outdated install ever gets, so failures must stay silent (a flaky
157
+ * network or offline install must never spam the log or delay boot).
158
+ * Disable entirely with ROADMAPPER_DISABLE_UPDATE_CHECK=1.
159
+ */
160
+ async function checkForUpdate() {
161
+ if (process.env.ROADMAPPER_DISABLE_UPDATE_CHECK === "1") return;
162
+ if (SERVER_VERSION === "0.0.0") return; // version unreadable; nothing to compare
163
+ try {
164
+ const ctrl = new AbortController();
165
+ const timer = setTimeout(() => ctrl.abort(), 2500);
166
+ let latest;
167
+ try {
168
+ const res = await fetch(
169
+ "https://registry.npmjs.org/@roadmapperai/mcp/latest",
170
+ { headers: { Accept: "application/json" }, signal: ctrl.signal }
171
+ );
172
+ if (!res.ok) return;
173
+ const body = await res.json();
174
+ latest = body && typeof body.version === "string" ? body.version : null;
175
+ } finally {
176
+ clearTimeout(timer);
177
+ }
178
+ if (!latest) return;
179
+ if (compareVersions(latest, SERVER_VERSION) > 0) {
180
+ log(
181
+ `update available: v${SERVER_VERSION} installed, v${latest} published. ` +
182
+ `This install is pinned — re-copy the install command from ` +
183
+ `Settings → MCP in the Roadmapper dashboard to upgrade.`
184
+ );
185
+ }
186
+ } catch {
187
+ // Offline, blocked, slow, or aborted — stay silent by design.
188
+ }
189
+ }
190
+
113
191
  function send(message) {
114
192
  process.stdout.write(JSON.stringify(message) + "\n");
115
193
  }
@@ -5976,4 +6054,8 @@ if (process.argv.includes("--selftest")) {
5976
6054
  const snapTail = snap ? `, snapshot-workspace=${snap}` : "";
5977
6055
  log(`ready (mode=${mode}${tail}${snapTail})`);
5978
6056
  })();
6057
+
6058
+ // Advisory: nudge the operator if a newer package is published. Runs
6059
+ // detached from boot — never blocks startup, never throws.
6060
+ checkForUpdate();
5979
6061
  }