@yawlabs/mcph 0.47.6 → 0.47.8

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 (2) hide show
  1. package/dist/index.js +270 -205
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1435,7 +1435,7 @@ function pathFor(client, scope, os, base) {
1435
1435
  throw new Error(`Unhandled client: ${client}`);
1436
1436
  }
1437
1437
  function buildLaunchEntry(opts) {
1438
- const pkg = opts.pkg ?? "@yawlabs/mcph";
1438
+ const pkg = opts.pkg ?? "@yawlabs/mcph@latest";
1439
1439
  const entry = opts.os === "windows" ? { command: "cmd", args: ["/c", "npx", "-y", pkg] } : { command: "npx", args: ["-y", pkg] };
1440
1440
  if (opts.token) entry.env = { MCPH_TOKEN: opts.token };
1441
1441
  return entry;
@@ -1650,7 +1650,7 @@ function selectFlakyNamespaces(entries, limit) {
1650
1650
  }
1651
1651
 
1652
1652
  // src/doctor-cmd.ts
1653
- var VERSION = true ? "0.47.6" : "dev";
1653
+ var VERSION = true ? "0.47.8" : "dev";
1654
1654
  async function runDoctor(opts = {}) {
1655
1655
  if (opts.json) return runDoctorJson(opts);
1656
1656
  const lines = [];
@@ -2905,6 +2905,253 @@ import {
2905
2905
  } from "@modelcontextprotocol/sdk/types.js";
2906
2906
  import { request as request9 } from "undici";
2907
2907
 
2908
+ // src/auto-upgrade.ts
2909
+ import { spawn as spawn3 } from "child_process";
2910
+
2911
+ // src/upgrade-cmd.ts
2912
+ import { spawn as spawn2 } from "child_process";
2913
+ var UPGRADE_USAGE = `Usage: mcph upgrade [--run] [--json]
2914
+
2915
+ Show (or execute) the command to upgrade @yawlabs/mcph to the latest version.
2916
+
2917
+ --run If this install is global (npm install -g), spawn the upgrade
2918
+ command. No-op for npx installs \u2014 they always fetch the latest.
2919
+ --json Emit a machine-readable snapshot ({ current, latest, stale,
2920
+ method, command }) instead of prose.`;
2921
+ function parseUpgradeArgs(argv) {
2922
+ const opts = {};
2923
+ for (const a of argv) {
2924
+ if (a === "--run") opts.run = true;
2925
+ else if (a === "--json") opts.json = true;
2926
+ else if (a === "--help" || a === "-h") return { ok: false, error: UPGRADE_USAGE };
2927
+ else return { ok: false, error: `mcph upgrade: unknown argument "${a}"
2928
+
2929
+ ${UPGRADE_USAGE}` };
2930
+ }
2931
+ return { ok: true, options: opts };
2932
+ }
2933
+ function detectInstallMethod(argvPath) {
2934
+ if (!argvPath) return "unknown";
2935
+ const normalized = argvPath.replace(/\\/g, "/");
2936
+ if (/\/_npx\//.test(normalized)) return "npx";
2937
+ if (/\/npm\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "global-npm";
2938
+ if (/\/lib\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "global-npm";
2939
+ if (/\/AppData\/Roaming\/npm\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "global-npm";
2940
+ if (/\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "local-node-modules";
2941
+ if (/\/mcph\/(dist|src)\//.test(normalized)) return "dev-checkout";
2942
+ return "unknown";
2943
+ }
2944
+ function buildUpgradePlan(input) {
2945
+ const { current, latest, method } = input;
2946
+ const stale = latest !== null && current !== "dev" && compareSemverLocal(current, latest) < 0;
2947
+ let command;
2948
+ switch (method) {
2949
+ case "global-npm":
2950
+ command = "npm install -g @yawlabs/mcph@latest";
2951
+ break;
2952
+ case "npx":
2953
+ command = null;
2954
+ break;
2955
+ case "local-node-modules":
2956
+ command = "npm install @yawlabs/mcph@latest";
2957
+ break;
2958
+ case "dev-checkout":
2959
+ command = "git pull && npm run build";
2960
+ break;
2961
+ default:
2962
+ command = "npm install -g @yawlabs/mcph@latest";
2963
+ break;
2964
+ }
2965
+ return { current, latest, stale, method, command };
2966
+ }
2967
+ function compareSemverLocal(a, b) {
2968
+ const parse = (s) => {
2969
+ const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(s);
2970
+ if (!m) return null;
2971
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
2972
+ };
2973
+ const pa = parse(a);
2974
+ const pb = parse(b);
2975
+ if (!pa || !pb) return 0;
2976
+ for (let i = 0; i < 3; i++) {
2977
+ if (pa[i] < pb[i]) return -1;
2978
+ if (pa[i] > pb[i]) return 1;
2979
+ }
2980
+ return 0;
2981
+ }
2982
+ async function defaultFetchLatest() {
2983
+ const ac = new AbortController();
2984
+ const timer = setTimeout(() => ac.abort(), 3e3);
2985
+ try {
2986
+ const res = await fetch("https://registry.npmjs.org/@yawlabs/mcph/latest", {
2987
+ signal: ac.signal,
2988
+ headers: { accept: "application/json" }
2989
+ });
2990
+ if (!res.ok) return null;
2991
+ const body = await res.json();
2992
+ return typeof body.version === "string" ? body.version : null;
2993
+ } catch {
2994
+ return null;
2995
+ } finally {
2996
+ clearTimeout(timer);
2997
+ }
2998
+ }
2999
+ async function defaultSpawn(cmd, args) {
3000
+ return new Promise((resolve4) => {
3001
+ const child = spawn2(cmd, args, { stdio: "inherit", shell: process.platform === "win32" });
3002
+ child.on("close", (code) => resolve4(typeof code === "number" ? code : 1));
3003
+ child.on("error", () => resolve4(1));
3004
+ });
3005
+ }
3006
+ async function runUpgrade(opts = {}) {
3007
+ const write = opts.out ?? ((s) => process.stdout.write(s));
3008
+ const writeErr = opts.err ?? ((s) => process.stderr.write(s));
3009
+ const lines = [];
3010
+ const print = (s = "") => {
3011
+ lines.push(s);
3012
+ write(`${s}
3013
+ `);
3014
+ };
3015
+ const printErr = (s) => {
3016
+ lines.push(s);
3017
+ writeErr(`${s}
3018
+ `);
3019
+ };
3020
+ const fetcher = opts.fetchLatest ?? defaultFetchLatest;
3021
+ const current = opts.currentVersion ?? readCurrentVersion();
3022
+ const argvPath = opts.argvPath ?? process.argv[1];
3023
+ const method = detectInstallMethod(argvPath);
3024
+ let latest;
3025
+ try {
3026
+ latest = await fetcher();
3027
+ } catch {
3028
+ latest = null;
3029
+ }
3030
+ const plan = buildUpgradePlan({ current, latest, method });
3031
+ if (opts.json) {
3032
+ print(JSON.stringify(plan, null, 2));
3033
+ return { exitCode: plan.stale && !opts.run ? 1 : 0, lines };
3034
+ }
3035
+ if (latest === null) {
3036
+ print("mcph upgrade: couldn't reach the npm registry (offline? firewall?).");
3037
+ if (plan.command) {
3038
+ print(`When you're back online, run:
3039
+ ${plan.command}`);
3040
+ } else {
3041
+ print("Your install uses `npx -y` \u2014 just restart the MCP client when you're back online.");
3042
+ }
3043
+ return { exitCode: 0, lines };
3044
+ }
3045
+ print(`Current: ${current}`);
3046
+ print(`Latest: ${latest}`);
3047
+ print(`Install: ${method}`);
3048
+ if (!plan.stale) {
3049
+ print("");
3050
+ print("\u2713 You're on the latest version \u2014 nothing to do.");
3051
+ return { exitCode: 0, lines };
3052
+ }
3053
+ print("");
3054
+ if (method === "npx") {
3055
+ print("Your install uses `npx -y` \u2014 restart the MCP client and it will fetch the new version.");
3056
+ return { exitCode: 0, lines };
3057
+ }
3058
+ if (!plan.command) {
3059
+ print("No upgrade command available for this install method.");
3060
+ return { exitCode: 0, lines };
3061
+ }
3062
+ const autoRunnable = method === "global-npm";
3063
+ if (!opts.run) {
3064
+ if (autoRunnable) {
3065
+ print(`Run:
3066
+ ${plan.command}
3067
+
3068
+ Or re-run with --run to upgrade in place.`);
3069
+ } else {
3070
+ print(`Suggested command (run it yourself; --run only works for global-npm installs):
3071
+ ${plan.command}`);
3072
+ }
3073
+ return { exitCode: 1, lines };
3074
+ }
3075
+ if (!autoRunnable) {
3076
+ printErr(
3077
+ `mcph upgrade --run: install method "${method}" can't be upgraded automatically. Run manually:
3078
+ ${plan.command}`
3079
+ );
3080
+ return { exitCode: 2, lines };
3081
+ }
3082
+ const runner = opts.spawnImpl ?? defaultSpawn;
3083
+ print(`Running: ${plan.command}`);
3084
+ const code = await runner("npm", ["install", "-g", "@yawlabs/mcph@latest"]);
3085
+ if (code === 0) {
3086
+ print("");
3087
+ print(`\u2713 Upgraded @yawlabs/mcph to ${latest}.`);
3088
+ return { exitCode: 0, lines };
3089
+ }
3090
+ printErr(`mcph upgrade: npm exited ${code}. Try running the command manually.`);
3091
+ return { exitCode: 3, lines };
3092
+ }
3093
+ function readCurrentVersion() {
3094
+ return true ? "0.47.8" : "dev";
3095
+ }
3096
+
3097
+ // src/auto-upgrade.ts
3098
+ async function fetchLatestVersion2() {
3099
+ const ac = new AbortController();
3100
+ const timer = setTimeout(() => ac.abort(), 3e3);
3101
+ try {
3102
+ const res = await fetch("https://registry.npmjs.org/@yawlabs/mcph/latest", {
3103
+ signal: ac.signal,
3104
+ headers: { accept: "application/json" }
3105
+ });
3106
+ if (!res.ok) return null;
3107
+ const body = await res.json();
3108
+ return typeof body.version === "string" ? body.version : null;
3109
+ } catch {
3110
+ return null;
3111
+ } finally {
3112
+ clearTimeout(timer);
3113
+ }
3114
+ }
3115
+ function defaultSpawn2(cmd, args) {
3116
+ const child = spawn3(cmd, args, {
3117
+ stdio: "ignore",
3118
+ // Stay a child of this process (not detached) so it dies with mcph
3119
+ // if mcph exits mid-install -- a half-finished `npm i -g` is fine
3120
+ // (npm is atomic per package) and a re-run next startup completes it.
3121
+ detached: false,
3122
+ shell: process.platform === "win32"
3123
+ });
3124
+ child.on("close", (code) => {
3125
+ if (code === 0) {
3126
+ log("info", "mcph self-upgrade complete; the next client restart will run the new version");
3127
+ } else {
3128
+ log("warn", "mcph self-upgrade: npm exited non-zero", { code });
3129
+ }
3130
+ });
3131
+ child.on("error", (err) => {
3132
+ log("warn", "mcph self-upgrade: npm spawn failed", { error: err?.message });
3133
+ });
3134
+ }
3135
+ async function maybeAutoUpgrade(deps = {}) {
3136
+ const current = deps.currentVersion ?? (true ? "0.47.8" : "dev");
3137
+ if (current === "dev") return;
3138
+ const method = detectInstallMethod(deps.argvPath ?? process.argv[1]);
3139
+ const latest = await (deps.fetchLatestImpl ?? fetchLatestVersion2)();
3140
+ if (latest === null) return;
3141
+ const plan = buildUpgradePlan({ current, latest, method });
3142
+ if (!plan.stale) return;
3143
+ if (method === "global-npm") {
3144
+ log("info", "mcph is out of date; upgrading the global install in the background", { current, latest });
3145
+ (deps.spawnImpl ?? defaultSpawn2)("npm", ["install", "-g", "@yawlabs/mcph@latest"]);
3146
+ return;
3147
+ }
3148
+ log("info", "mcph is out of date; restart your MCP client to pick up the latest version", {
3149
+ current,
3150
+ latest,
3151
+ method
3152
+ });
3153
+ }
3154
+
2908
3155
  // src/compliance.ts
2909
3156
  var GRADE_ORDER = {
2910
3157
  A: 4,
@@ -4500,7 +4747,7 @@ async function rerank(intent, candidateIds, limit) {
4500
4747
  }
4501
4748
 
4502
4749
  // src/runtime-detect.ts
4503
- import { spawn as spawn2 } from "child_process";
4750
+ import { spawn as spawn4 } from "child_process";
4504
4751
  import { request as request7 } from "undici";
4505
4752
  var PROBE_TIMEOUT_MS = 3e3;
4506
4753
  var RUNTIME_REPORT_PATH = "/api/connect/runtimes";
@@ -4558,7 +4805,7 @@ async function probe(name, p) {
4558
4805
  let stderr = "";
4559
4806
  let child;
4560
4807
  try {
4561
- child = spawn2(p.bin, p.args, {
4808
+ child = spawn4(p.bin, p.args, {
4562
4809
  stdio: ["ignore", "pipe", "pipe"],
4563
4810
  // Windows needs a shell for PATH lookup of .cmd/.bat shims —
4564
4811
  // node/npx/uvx arrive as `npx.cmd` in PATH, and native spawn
@@ -4783,7 +5030,7 @@ import {
4783
5030
  } from "@modelcontextprotocol/sdk/types.js";
4784
5031
 
4785
5032
  // src/uv-bootstrap.ts
4786
- import { spawn as spawn3 } from "child_process";
5033
+ import { spawn as spawn5 } from "child_process";
4787
5034
  import { createHash } from "crypto";
4788
5035
  import { createWriteStream } from "fs";
4789
5036
  import fs from "fs/promises";
@@ -4836,7 +5083,7 @@ async function onPath(cmd) {
4836
5083
  };
4837
5084
  let child;
4838
5085
  try {
4839
- child = spawn3(cmd, ["--version"], {
5086
+ child = spawn5(cmd, ["--version"], {
4840
5087
  stdio: "ignore",
4841
5088
  shell: false,
4842
5089
  windowsHide: process.platform === "win32"
@@ -4897,7 +5144,7 @@ async function extractArchive(archivePath, destDir) {
4897
5144
  }
4898
5145
  function runCommand(cmd, args) {
4899
5146
  return new Promise((resolve4, reject) => {
4900
- const child = spawn3(cmd, args, {
5147
+ const child = spawn5(cmd, args, {
4901
5148
  stdio: ["ignore", "pipe", "pipe"],
4902
5149
  shell: false,
4903
5150
  windowsHide: process.platform === "win32"
@@ -5015,7 +5262,7 @@ function categorizeSpawnError(err) {
5015
5262
  }
5016
5263
  async function connectToUpstream(config, onDisconnect, onListChanged) {
5017
5264
  const client = new Client(
5018
- { name: "mcph", version: true ? "0.47.6" : "dev" },
5265
+ { name: "mcph", version: true ? "0.47.8" : "dev" },
5019
5266
  { capabilities: {} }
5020
5267
  );
5021
5268
  let transport;
@@ -5323,7 +5570,7 @@ var ConnectServer = class _ConnectServer {
5323
5570
  this.apiUrl = apiUrl6;
5324
5571
  this.token = token6;
5325
5572
  this.server = new Server(
5326
- { name: "mcph", version: true ? "0.47.6" : "dev" },
5573
+ { name: "mcph", version: true ? "0.47.8" : "dev" },
5327
5574
  {
5328
5575
  capabilities: {
5329
5576
  tools: { listChanged: true },
@@ -5341,10 +5588,14 @@ var ConnectServer = class _ConnectServer {
5341
5588
  config = null;
5342
5589
  configVersion = null;
5343
5590
  pollTimer = null;
5344
- // Flipped true once the first MCP `initialize` lands (see
5345
- // this.server.oninitialized). Gates the per-poll heartbeat refresh so
5346
- // we only ping liveness while a client is actually attached.
5347
- aiClientAttached = false;
5591
+ // Captures the AI client's Implementation block once the first MCP
5592
+ // `initialize` lands (see this.server.oninitialized). Non-null means a
5593
+ // client is attached. The per-poll heartbeat refresh reuses these
5594
+ // exact values so its upsert always targets the same
5595
+ // (accountId, clientName) key the attach beacon created; re-reading
5596
+ // getClientVersion() per poll risked a transient undefined becoming a
5597
+ // split-brain 'unknown' row on the backend.
5598
+ attachedClient = null;
5348
5599
  toolRoutes = /* @__PURE__ */ new Map();
5349
5600
  resourceRoutes = /* @__PURE__ */ new Map();
5350
5601
  promptRoutes = /* @__PURE__ */ new Map();
@@ -5595,8 +5846,8 @@ var ConnectServer = class _ConnectServer {
5595
5846
  ensureUv().catch((err) => log("warn", "uv prewarm failed", { error: err?.message }));
5596
5847
  }
5597
5848
  this.server.oninitialized = () => {
5598
- this.aiClientAttached = true;
5599
5849
  const info = this.server.getClientVersion();
5850
+ this.attachedClient = { name: info?.name, version: info?.version };
5600
5851
  reportHeartbeat(info?.name, info?.version).catch(
5601
5852
  (err) => log("warn", "reportHeartbeat failed", { error: err?.message })
5602
5853
  );
@@ -5605,6 +5856,7 @@ var ConnectServer = class _ConnectServer {
5605
5856
  await this.server.connect(transport);
5606
5857
  this.startPolling();
5607
5858
  this.prewarmDormantServers().catch((err) => log("warn", "Pre-warm failed", { error: err?.message }));
5859
+ maybeAutoUpgrade().catch((err) => log("warn", "Auto-upgrade check failed", { error: err?.message }));
5608
5860
  if (isAutoLoadEnabled() && this.persistenceReady) {
5609
5861
  this.autoLoadRecurringPack().catch((err) => log("warn", "Auto-load failed", { error: err?.message }));
5610
5862
  }
@@ -6764,9 +7016,8 @@ ${activeCount} loaded in this session, ${totalTools} tools in context${tokenSumm
6764
7016
  } catch (err) {
6765
7017
  log("warn", "Config poll failed", { error: err.message });
6766
7018
  }
6767
- if (this.aiClientAttached) {
6768
- const info = this.server.getClientVersion();
6769
- reportHeartbeat(info?.name, info?.version, true).catch(
7019
+ if (this.attachedClient) {
7020
+ reportHeartbeat(this.attachedClient.name, this.attachedClient.version, true).catch(
6770
7021
  (err) => log("warn", "reportHeartbeat refresh failed", { error: err?.message })
6771
7022
  );
6772
7023
  }
@@ -7519,192 +7770,6 @@ function truncateVersion(v) {
7519
7770
  return v.length > 8 ? v.slice(0, 8) : v;
7520
7771
  }
7521
7772
 
7522
- // src/upgrade-cmd.ts
7523
- import { spawn as spawn4 } from "child_process";
7524
- var UPGRADE_USAGE = `Usage: mcph upgrade [--run] [--json]
7525
-
7526
- Show (or execute) the command to upgrade @yawlabs/mcph to the latest version.
7527
-
7528
- --run If this install is global (npm install -g), spawn the upgrade
7529
- command. No-op for npx installs \u2014 they always fetch the latest.
7530
- --json Emit a machine-readable snapshot ({ current, latest, stale,
7531
- method, command }) instead of prose.`;
7532
- function parseUpgradeArgs(argv) {
7533
- const opts = {};
7534
- for (const a of argv) {
7535
- if (a === "--run") opts.run = true;
7536
- else if (a === "--json") opts.json = true;
7537
- else if (a === "--help" || a === "-h") return { ok: false, error: UPGRADE_USAGE };
7538
- else return { ok: false, error: `mcph upgrade: unknown argument "${a}"
7539
-
7540
- ${UPGRADE_USAGE}` };
7541
- }
7542
- return { ok: true, options: opts };
7543
- }
7544
- function detectInstallMethod(argvPath) {
7545
- if (!argvPath) return "unknown";
7546
- const normalized = argvPath.replace(/\\/g, "/");
7547
- if (/\/_npx\//.test(normalized)) return "npx";
7548
- if (/\/npm\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "global-npm";
7549
- if (/\/lib\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "global-npm";
7550
- if (/\/AppData\/Roaming\/npm\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "global-npm";
7551
- if (/\/node_modules\/@yawlabs\/mcph\//.test(normalized)) return "local-node-modules";
7552
- if (/\/mcph\/(dist|src)\//.test(normalized)) return "dev-checkout";
7553
- return "unknown";
7554
- }
7555
- function buildUpgradePlan(input) {
7556
- const { current, latest, method } = input;
7557
- const stale = latest !== null && current !== "dev" && compareSemverLocal(current, latest) < 0;
7558
- let command;
7559
- switch (method) {
7560
- case "global-npm":
7561
- command = "npm install -g @yawlabs/mcph@latest";
7562
- break;
7563
- case "npx":
7564
- command = null;
7565
- break;
7566
- case "local-node-modules":
7567
- command = "npm install @yawlabs/mcph@latest";
7568
- break;
7569
- case "dev-checkout":
7570
- command = "git pull && npm run build";
7571
- break;
7572
- default:
7573
- command = "npm install -g @yawlabs/mcph@latest";
7574
- break;
7575
- }
7576
- return { current, latest, stale, method, command };
7577
- }
7578
- function compareSemverLocal(a, b) {
7579
- const parse = (s) => {
7580
- const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(s);
7581
- if (!m) return null;
7582
- return [Number(m[1]), Number(m[2]), Number(m[3])];
7583
- };
7584
- const pa = parse(a);
7585
- const pb = parse(b);
7586
- if (!pa || !pb) return 0;
7587
- for (let i = 0; i < 3; i++) {
7588
- if (pa[i] < pb[i]) return -1;
7589
- if (pa[i] > pb[i]) return 1;
7590
- }
7591
- return 0;
7592
- }
7593
- async function defaultFetchLatest() {
7594
- const ac = new AbortController();
7595
- const timer = setTimeout(() => ac.abort(), 3e3);
7596
- try {
7597
- const res = await fetch("https://registry.npmjs.org/@yawlabs/mcph/latest", {
7598
- signal: ac.signal,
7599
- headers: { accept: "application/json" }
7600
- });
7601
- if (!res.ok) return null;
7602
- const body = await res.json();
7603
- return typeof body.version === "string" ? body.version : null;
7604
- } catch {
7605
- return null;
7606
- } finally {
7607
- clearTimeout(timer);
7608
- }
7609
- }
7610
- async function defaultSpawn(cmd, args) {
7611
- return new Promise((resolve4) => {
7612
- const child = spawn4(cmd, args, { stdio: "inherit", shell: process.platform === "win32" });
7613
- child.on("close", (code) => resolve4(typeof code === "number" ? code : 1));
7614
- child.on("error", () => resolve4(1));
7615
- });
7616
- }
7617
- async function runUpgrade(opts = {}) {
7618
- const write = opts.out ?? ((s) => process.stdout.write(s));
7619
- const writeErr = opts.err ?? ((s) => process.stderr.write(s));
7620
- const lines = [];
7621
- const print = (s = "") => {
7622
- lines.push(s);
7623
- write(`${s}
7624
- `);
7625
- };
7626
- const printErr = (s) => {
7627
- lines.push(s);
7628
- writeErr(`${s}
7629
- `);
7630
- };
7631
- const fetcher = opts.fetchLatest ?? defaultFetchLatest;
7632
- const current = opts.currentVersion ?? readCurrentVersion();
7633
- const argvPath = opts.argvPath ?? process.argv[1];
7634
- const method = detectInstallMethod(argvPath);
7635
- let latest;
7636
- try {
7637
- latest = await fetcher();
7638
- } catch {
7639
- latest = null;
7640
- }
7641
- const plan = buildUpgradePlan({ current, latest, method });
7642
- if (opts.json) {
7643
- print(JSON.stringify(plan, null, 2));
7644
- return { exitCode: plan.stale && !opts.run ? 1 : 0, lines };
7645
- }
7646
- if (latest === null) {
7647
- print("mcph upgrade: couldn't reach the npm registry (offline? firewall?).");
7648
- if (plan.command) {
7649
- print(`When you're back online, run:
7650
- ${plan.command}`);
7651
- } else {
7652
- print("Your install uses `npx -y` \u2014 just restart the MCP client when you're back online.");
7653
- }
7654
- return { exitCode: 0, lines };
7655
- }
7656
- print(`Current: ${current}`);
7657
- print(`Latest: ${latest}`);
7658
- print(`Install: ${method}`);
7659
- if (!plan.stale) {
7660
- print("");
7661
- print("\u2713 You're on the latest version \u2014 nothing to do.");
7662
- return { exitCode: 0, lines };
7663
- }
7664
- print("");
7665
- if (method === "npx") {
7666
- print("Your install uses `npx -y` \u2014 restart the MCP client and it will fetch the new version.");
7667
- return { exitCode: 0, lines };
7668
- }
7669
- if (!plan.command) {
7670
- print("No upgrade command available for this install method.");
7671
- return { exitCode: 0, lines };
7672
- }
7673
- const autoRunnable = method === "global-npm";
7674
- if (!opts.run) {
7675
- if (autoRunnable) {
7676
- print(`Run:
7677
- ${plan.command}
7678
-
7679
- Or re-run with --run to upgrade in place.`);
7680
- } else {
7681
- print(`Suggested command (run it yourself; --run only works for global-npm installs):
7682
- ${plan.command}`);
7683
- }
7684
- return { exitCode: 1, lines };
7685
- }
7686
- if (!autoRunnable) {
7687
- printErr(
7688
- `mcph upgrade --run: install method "${method}" can't be upgraded automatically. Run manually:
7689
- ${plan.command}`
7690
- );
7691
- return { exitCode: 2, lines };
7692
- }
7693
- const runner = opts.spawnImpl ?? defaultSpawn;
7694
- print(`Running: ${plan.command}`);
7695
- const code = await runner("npm", ["install", "-g", "@yawlabs/mcph@latest"]);
7696
- if (code === 0) {
7697
- print("");
7698
- print(`\u2713 Upgraded @yawlabs/mcph to ${latest}.`);
7699
- return { exitCode: 0, lines };
7700
- }
7701
- printErr(`mcph upgrade: npm exited ${code}. Try running the command manually.`);
7702
- return { exitCode: 3, lines };
7703
- }
7704
- function readCurrentVersion() {
7705
- return true ? "0.47.6" : "dev";
7706
- }
7707
-
7708
7773
  // src/index.ts
7709
7774
  var KNOWN_SUBCOMMANDS = [
7710
7775
  "compliance",
@@ -7870,7 +7935,7 @@ if (subcommand === "compliance") {
7870
7935
  `);
7871
7936
  process.exit(0);
7872
7937
  } else if (subcommand === "--version" || subcommand === "-V") {
7873
- process.stdout.write(`mcph ${true ? "0.47.6" : "dev"}
7938
+ process.stdout.write(`mcph ${true ? "0.47.8" : "dev"}
7874
7939
  `);
7875
7940
  process.exit(0);
7876
7941
  } else if (subcommand && !subcommand.startsWith("-")) {
@@ -7887,7 +7952,7 @@ async function runServer() {
7887
7952
  const config = await loadMcphConfig();
7888
7953
  if (!config.token) {
7889
7954
  process.stderr.write(
7890
- '\n mcph: no token resolved.\n\n Quick start (recommended):\n mcph install <claude-code|claude-desktop|cursor|vscode> --token mcp_pat_\u2026\n Creates ~/.mcph/config.json so every MCP client picks up the token automatically.\n\n Or set MCPH_TOKEN in your MCP client config:\n\n {\n "mcpServers": {\n "mcp.hosting": {\n "command": "npx",\n "args": ["-y", "@yawlabs/mcph"],\n "env": {\n "MCPH_TOKEN": "mcp_pat_your_token_here"\n }\n }\n }\n }\n\n Get a token at https://mcp.hosting \u2192 Settings \u2192 API Tokens, or run\n `mcph doctor` to see exactly where mcph looked.\n\n'
7955
+ '\n mcph: no token resolved.\n\n Quick start (recommended):\n mcph install <claude-code|claude-desktop|cursor|vscode> --token mcp_pat_\u2026\n Creates ~/.mcph/config.json so every MCP client picks up the token automatically.\n\n Or set MCPH_TOKEN in your MCP client config:\n\n {\n "mcpServers": {\n "mcp.hosting": {\n "command": "npx",\n "args": ["-y", "@yawlabs/mcph@latest"],\n "env": {\n "MCPH_TOKEN": "mcp_pat_your_token_here"\n }\n }\n }\n }\n\n Get a token at https://mcp.hosting \u2192 Settings \u2192 API Tokens, or run\n `mcph doctor` to see exactly where mcph looked.\n\n'
7891
7956
  );
7892
7957
  process.exit(1);
7893
7958
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/mcph",
3
- "version": "0.47.6",
3
+ "version": "0.47.8",
4
4
  "description": "mcp.hosting — one install, all your MCP servers, managed from the cloud",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Yaw Labs <support@mcp.hosting> (https://mcp.hosting)",