@yawlabs/mcph 0.34.0 → 0.36.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 +8 -0
- package/dist/index.js +34 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
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.36.0 — 2026-04-18
|
|
6
|
+
|
|
7
|
+
- **Negative signal in dispatch ranking (`boostFactor` penalty branch)** — The learning store's `boostFactor` now drops *below* 1.0 for namespaces with flaky history, mirroring the existing upward boost. Threshold is the same ≥3 dispatches / <80% success gate used by discover's inline reliability warning (v0.35.0) and health's cross-session block (v0.34.0) — so a server flagged flaky in those views also loses rank points at dispatch time rather than quietly continuing to win routing. Floor is `-10%` (`LEARNING_MIN_BOOST = 0.9`), symmetric with the existing `+10%` ceiling. Rate-based signal trumps count-based: a namespace with 10 successes but a 50% overall rate is flaky, not useful, and the penalty branch beats the positive branch in that case.
|
|
8
|
+
|
|
9
|
+
## 0.35.0 — 2026-04-18
|
|
10
|
+
|
|
11
|
+
- **Inline reliability warning in `mcp_connect_discover`** — Discover now annotates dormant (not currently loaded) servers with `reliability: P% success across N past calls` when persisted learning shows ≥3 dispatches and <80% success. Renders under the server card right after the live health warning, so the LLM sees the flaky history *before* it picks a server to activate — not only after `handleHealth` surfaces it post-hoc. Thresholds match the cross-session reliability block from v0.34.0 so the two views stay consistent. Suppressed for loaded servers (the live per-call warning already covers them with fresher data).
|
|
12
|
+
|
|
5
13
|
## 0.34.0 — 2026-04-18
|
|
6
14
|
|
|
7
15
|
- **Cross-session reliability block in `mcp_connect_health`** — New section at the bottom of health output surfaces flaky *dormant* namespaces pulled from persisted learning: `<namespace> — N calls, P% success, last used <age> ago`. Threshold is deliberately high (≥3 dispatches, <80% success) so a one-off failure doesn't light up the panel; loaded namespaces are skipped (in-session block already covers them). Sorted worst-rate first, ties broken by most calls then alpha; capped at 5. Also fixes a gap where `handleHealth` returned early on an empty-connections session and never showed dormant history — now it falls through so operators can see which past servers were unreliable even before loading anything.
|
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.
|
|
949
|
+
var VERSION = true ? "0.36.0" : "dev";
|
|
950
950
|
async function runDoctor(opts = {}) {
|
|
951
951
|
const lines = [];
|
|
952
952
|
const write = opts.out ?? ((s) => process.stdout.write(s));
|
|
@@ -2355,6 +2355,8 @@ function pushToolCall(history, record, limit = HISTORY_LIMIT) {
|
|
|
2355
2355
|
// src/learning.ts
|
|
2356
2356
|
var LEARNING_MIN_OBSERVATIONS = 3;
|
|
2357
2357
|
var LEARNING_MAX_BOOST = 1.1;
|
|
2358
|
+
var LEARNING_MIN_BOOST = 0.9;
|
|
2359
|
+
var PENALTY_RATE_THRESHOLD = 0.8;
|
|
2358
2360
|
var SATURATION_AT = 10;
|
|
2359
2361
|
var LearningStore = class {
|
|
2360
2362
|
usage = /* @__PURE__ */ new Map();
|
|
@@ -2377,13 +2379,23 @@ var LearningStore = class {
|
|
|
2377
2379
|
get(namespace) {
|
|
2378
2380
|
return this.usage.get(namespace);
|
|
2379
2381
|
}
|
|
2380
|
-
// Boost factor in [
|
|
2381
|
-
//
|
|
2382
|
-
//
|
|
2383
|
-
//
|
|
2382
|
+
// Boost factor in [LEARNING_MIN_BOOST, LEARNING_MAX_BOOST]. Penalty
|
|
2383
|
+
// branch wins when a namespace has been dispatched enough times and
|
|
2384
|
+
// its success rate has fallen below 80%; otherwise the positive
|
|
2385
|
+
// branch grows the factor with successful observation count, saturating
|
|
2386
|
+
// at SATURATION_AT successes so a heavily-used server can't runaway-win
|
|
2387
|
+
// against legitimately better matches.
|
|
2384
2388
|
boostFactor(namespace) {
|
|
2385
2389
|
const u = this.usage.get(namespace);
|
|
2386
|
-
if (!u
|
|
2390
|
+
if (!u) return 1;
|
|
2391
|
+
if (u.dispatched >= LEARNING_MIN_OBSERVATIONS) {
|
|
2392
|
+
const rate = u.succeeded / u.dispatched;
|
|
2393
|
+
if (rate < PENALTY_RATE_THRESHOLD) {
|
|
2394
|
+
const distance = Math.min(1, (PENALTY_RATE_THRESHOLD - rate) / PENALTY_RATE_THRESHOLD);
|
|
2395
|
+
return 1 - distance * (1 - LEARNING_MIN_BOOST);
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
if (u.succeeded < LEARNING_MIN_OBSERVATIONS) return 1;
|
|
2387
2399
|
const progress = Math.min(1, u.succeeded / SATURATION_AT);
|
|
2388
2400
|
return 1 + progress * (LEARNING_MAX_BOOST - 1);
|
|
2389
2401
|
}
|
|
@@ -3922,7 +3934,7 @@ function categorizeSpawnError(err) {
|
|
|
3922
3934
|
}
|
|
3923
3935
|
async function connectToUpstream(config, onDisconnect, onListChanged) {
|
|
3924
3936
|
const client = new Client(
|
|
3925
|
-
{ name: "mcph", version: true ? "0.
|
|
3937
|
+
{ name: "mcph", version: true ? "0.36.0" : "dev" },
|
|
3926
3938
|
{ capabilities: {} }
|
|
3927
3939
|
);
|
|
3928
3940
|
let transport;
|
|
@@ -4323,6 +4335,8 @@ async function reportTools(serverId, tools) {
|
|
|
4323
4335
|
// src/usage-hints.ts
|
|
4324
4336
|
var MAX_PEERS = 3;
|
|
4325
4337
|
var MIN_SUCCESS_TO_SHOW = 1;
|
|
4338
|
+
var RELIABILITY_MIN_OBSERVATIONS = 3;
|
|
4339
|
+
var RELIABILITY_THRESHOLD = 0.8;
|
|
4326
4340
|
function buildCoUsageMap(packs) {
|
|
4327
4341
|
const result = /* @__PURE__ */ new Map();
|
|
4328
4342
|
for (const pack of packs) {
|
|
@@ -4355,6 +4369,13 @@ function formatUsageHint(usage, coUsedWith) {
|
|
|
4355
4369
|
if (parts.length === 0) return null;
|
|
4356
4370
|
return `usage: ${parts.join("; ")}`;
|
|
4357
4371
|
}
|
|
4372
|
+
function formatReliabilityWarning(usage) {
|
|
4373
|
+
if (!usage || usage.dispatched < RELIABILITY_MIN_OBSERVATIONS) return null;
|
|
4374
|
+
const rate = usage.succeeded / usage.dispatched;
|
|
4375
|
+
if (rate >= RELIABILITY_THRESHOLD) return null;
|
|
4376
|
+
const pct = Math.round(rate * 100);
|
|
4377
|
+
return `reliability: ${pct}% success across ${usage.dispatched} past calls`;
|
|
4378
|
+
}
|
|
4358
4379
|
|
|
4359
4380
|
// src/server.ts
|
|
4360
4381
|
var DEFAULT_POLL_INTERVAL_MS = 6e4;
|
|
@@ -4439,7 +4460,7 @@ var ConnectServer = class _ConnectServer {
|
|
|
4439
4460
|
this.apiUrl = apiUrl6;
|
|
4440
4461
|
this.token = token6;
|
|
4441
4462
|
this.server = new Server(
|
|
4442
|
-
{ name: "mcph", version: true ? "0.
|
|
4463
|
+
{ name: "mcph", version: true ? "0.36.0" : "dev" },
|
|
4443
4464
|
{
|
|
4444
4465
|
capabilities: {
|
|
4445
4466
|
tools: { listChanged: true },
|
|
@@ -5314,6 +5335,10 @@ var ConnectServer = class _ConnectServer {
|
|
|
5314
5335
|
if (shadow) lines.push(` ${shadow}`);
|
|
5315
5336
|
const warning = formatHealthWarning(connection?.health, this.activationFailures.get(server.namespace));
|
|
5316
5337
|
if (warning) lines.push(` ${warning}`);
|
|
5338
|
+
if (!connection) {
|
|
5339
|
+
const reliability = formatReliabilityWarning(this.learning.get(server.namespace));
|
|
5340
|
+
if (reliability) lines.push(` ${reliability}`);
|
|
5341
|
+
}
|
|
5317
5342
|
const usageHint = formatUsageHint(this.learning.get(server.namespace), coUsageMap.get(server.namespace) ?? []);
|
|
5318
5343
|
if (usageHint) lines.push(` ${usageHint}`);
|
|
5319
5344
|
if (!connection) {
|
|
@@ -6540,7 +6565,7 @@ ${installBlock}
|
|
|
6540
6565
|
);
|
|
6541
6566
|
process.exit(0);
|
|
6542
6567
|
} else if (subcommand === "--version" || subcommand === "-V") {
|
|
6543
|
-
process.stdout.write(`mcph ${true ? "0.
|
|
6568
|
+
process.stdout.write(`mcph ${true ? "0.36.0" : "dev"}
|
|
6544
6569
|
`);
|
|
6545
6570
|
process.exit(0);
|
|
6546
6571
|
} else if (subcommand && !subcommand.startsWith("-")) {
|
package/package.json
CHANGED