@yawlabs/mcph 0.29.0 → 0.30.0

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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to `@yawlabs/mcph` are documented here. This project uses [semantic versioning](https://semver.org) and a CI-gated release flow: pushing a `vX.Y.Z` tag triggers `.github/workflows/release.yml`, which publishes to npm.
4
4
 
5
+ ## 0.30.0 — 2026-04-18
6
+
7
+ - **Inline bundle completions in `discover()`** — When a curated bundle has some installed servers but is missing one or two, `mcp_connect_discover` surfaces a "Bundle completions" block with the partial bundle id, what's already installed, and what to add. Top 3 entries, ranked by fewest-missing first (cheapest to complete), tie-broken by most-momentum then id. Same data source as `mcp_connect_bundles action="match"`, but inline so the model can act on the nudge without the extra round-trip. Suppressed when no curated bundle has any overlap with the installed set.
8
+
5
9
  ## 0.29.0 — 2026-04-18
6
10
 
7
11
  - **Compliance-aware routing (`MCPH_MIN_COMPLIANCE`)** — Phase 3 item. Set the env var to `A`, `B`, `C`, `D`, or `F` and `mcp_connect_activate` refuses to load any installed server whose reported `complianceGrade` is below the floor, with an error that names the grade and the env var to unset. `mcp_connect_discover` annotates below-grade servers in place (so the model knows they exist and why they won't auto-activate) and emits a "Compliance filter active" header. Forward-compatible schema: the optional `complianceGrade` field on `UpstreamServerConfig` rides the existing `/api/connect/config` response — the feature kicks in automatically once the backend starts populating grades. Ungraded servers always pass (don't punish unknown).
package/dist/index.js CHANGED
@@ -946,7 +946,7 @@ function errorMessage(err) {
946
946
  }
947
947
 
948
948
  // src/doctor-cmd.ts
949
- var VERSION = true ? "0.29.0" : "dev";
949
+ var VERSION = true ? "0.30.0" : "dev";
950
950
  async function runDoctor(opts = {}) {
951
951
  const lines = [];
952
952
  const write = opts.out ?? ((s) => process.stdout.write(s));
@@ -1824,6 +1824,15 @@ function matchBundles(installedNamespaces) {
1824
1824
  function bundleActivateHint(bundle) {
1825
1825
  return `mcp_connect_activate({ namespaces: ${JSON.stringify(bundle.namespaces)} })`;
1826
1826
  }
1827
+ function topPartialBundles(installedNamespaces, limit) {
1828
+ if (limit <= 0) return [];
1829
+ const { partial } = matchBundles(installedNamespaces);
1830
+ return partial.slice().sort((a, b) => {
1831
+ if (a.missing.length !== b.missing.length) return a.missing.length - b.missing.length;
1832
+ if (a.have.length !== b.have.length) return b.have.length - a.have.length;
1833
+ return a.bundle.id.localeCompare(b.bundle.id);
1834
+ }).slice(0, limit);
1835
+ }
1827
1836
 
1828
1837
  // src/compliance.ts
1829
1838
  var GRADE_ORDER = {
@@ -3827,7 +3836,7 @@ function categorizeSpawnError(err) {
3827
3836
  }
3828
3837
  async function connectToUpstream(config, onDisconnect, onListChanged) {
3829
3838
  const client = new Client(
3830
- { name: "mcph", version: true ? "0.29.0" : "dev" },
3839
+ { name: "mcph", version: true ? "0.30.0" : "dev" },
3831
3840
  { capabilities: {} }
3832
3841
  );
3833
3842
  let transport;
@@ -4344,7 +4353,7 @@ var ConnectServer = class _ConnectServer {
4344
4353
  this.apiUrl = apiUrl6;
4345
4354
  this.token = token6;
4346
4355
  this.server = new Server(
4347
- { name: "mcph", version: true ? "0.29.0" : "dev" },
4356
+ { name: "mcph", version: true ? "0.30.0" : "dev" },
4348
4357
  {
4349
4358
  capabilities: {
4350
4359
  tools: { listChanged: true },
@@ -5239,6 +5248,14 @@ var ConnectServer = class _ConnectServer {
5239
5248
  lines.push(` ${o.bareName} \u2014 available in: ${o.namespaces.join(", ")}${suffix}`);
5240
5249
  }
5241
5250
  }
5251
+ const allInstalled = this.config.servers.map((s) => s.namespace);
5252
+ const bundleGaps = topPartialBundles(allInstalled, 3);
5253
+ if (bundleGaps.length > 0) {
5254
+ lines.push("\nBundle completions (install to unlock curated stacks):");
5255
+ for (const { bundle, have, missing } of bundleGaps) {
5256
+ lines.push(` ${bundle.id} \u2014 have: ${have.join(", ")}; add: ${missing.join(", ")}`);
5257
+ }
5258
+ }
5242
5259
  const inactive = this.config.servers.filter((s) => !s.isActive);
5243
5260
  if (inactive.length > 0) {
5244
5261
  lines.push("\nDisabled servers:");
@@ -6405,7 +6422,7 @@ ${installBlock}
6405
6422
  );
6406
6423
  process.exit(0);
6407
6424
  } else if (subcommand === "--version" || subcommand === "-V") {
6408
- process.stdout.write(`mcph ${true ? "0.29.0" : "dev"}
6425
+ process.stdout.write(`mcph ${true ? "0.30.0" : "dev"}
6409
6426
  `);
6410
6427
  process.exit(0);
6411
6428
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/mcph",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "mcp.hosting — one install, all your MCP servers, managed from the cloud",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Yaw Labs <contact@yaw.sh> (https://yaw.sh)",