@yawlabs/mcph 0.47.4 → 0.47.6
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/dist/index.js +129 -67
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -292,11 +292,11 @@ async function readConfigAt(path5, scope, warnings) {
|
|
|
292
292
|
`${path5}: schema version ${version} is newer than this mcph (${CURRENT_SCHEMA_VERSION}); upgrade with \`npm i -g @yawlabs/mcph@latest\`. Loading best-effort.`
|
|
293
293
|
);
|
|
294
294
|
}
|
|
295
|
-
const
|
|
295
|
+
const token6 = typeof obj.token === "string" && obj.token.length > 0 ? obj.token : void 0;
|
|
296
296
|
const apiBase = typeof obj.apiBase === "string" && obj.apiBase.length > 0 ? obj.apiBase : void 0;
|
|
297
297
|
const servers = Array.isArray(obj.servers) ? obj.servers.filter((v) => typeof v === "string") : void 0;
|
|
298
298
|
const blocked = Array.isArray(obj.blocked) ? obj.blocked.filter((v) => typeof v === "string") : void 0;
|
|
299
|
-
if (
|
|
299
|
+
if (token6) {
|
|
300
300
|
if (scope === "project") {
|
|
301
301
|
warnings.push(
|
|
302
302
|
`${path5}: 'token' should not appear in a project-shared file. Move it to ${CONFIG_DIRNAME}/${LOCAL_CONFIG_FILENAME} (gitignored) or ~/${CONFIG_DIRNAME}/${CONFIG_FILENAME}.`
|
|
@@ -304,7 +304,7 @@ async function readConfigAt(path5, scope, warnings) {
|
|
|
304
304
|
}
|
|
305
305
|
await checkPermissions(path5, warnings);
|
|
306
306
|
}
|
|
307
|
-
return { path: path5, scope, version, token:
|
|
307
|
+
return { path: path5, scope, version, token: token6, apiBase, servers, blocked };
|
|
308
308
|
}
|
|
309
309
|
async function checkPermissions(path5, warnings) {
|
|
310
310
|
if (process.platform === "win32") return;
|
|
@@ -361,16 +361,16 @@ async function loadMcphConfig(opts = {}) {
|
|
|
361
361
|
if (project) loadedFiles.push(project);
|
|
362
362
|
const global = await readConfigAt(globalPath, "global", warnings);
|
|
363
363
|
if (global) loadedFiles.push(global);
|
|
364
|
-
let
|
|
364
|
+
let token6 = null;
|
|
365
365
|
let tokenSource = "missing";
|
|
366
366
|
if (typeof env.MCPH_TOKEN === "string" && env.MCPH_TOKEN.length > 0) {
|
|
367
|
-
|
|
367
|
+
token6 = env.MCPH_TOKEN;
|
|
368
368
|
tokenSource = "env";
|
|
369
369
|
} else if (local?.token) {
|
|
370
|
-
|
|
370
|
+
token6 = local.token;
|
|
371
371
|
tokenSource = "local";
|
|
372
372
|
} else if (global?.token) {
|
|
373
|
-
|
|
373
|
+
token6 = global.token;
|
|
374
374
|
tokenSource = "global";
|
|
375
375
|
}
|
|
376
376
|
let apiBase = DEFAULT_API_BASE;
|
|
@@ -389,7 +389,7 @@ async function loadMcphConfig(opts = {}) {
|
|
|
389
389
|
apiBaseSource = "global";
|
|
390
390
|
}
|
|
391
391
|
return {
|
|
392
|
-
token:
|
|
392
|
+
token: token6,
|
|
393
393
|
tokenSource,
|
|
394
394
|
apiBase,
|
|
395
395
|
apiBaseSource,
|
|
@@ -400,10 +400,10 @@ async function loadMcphConfig(opts = {}) {
|
|
|
400
400
|
warnings
|
|
401
401
|
};
|
|
402
402
|
}
|
|
403
|
-
function tokenFingerprint(
|
|
404
|
-
if (!
|
|
405
|
-
if (
|
|
406
|
-
return `${
|
|
403
|
+
function tokenFingerprint(token6) {
|
|
404
|
+
if (!token6) return "(none)";
|
|
405
|
+
if (token6.length <= 8) return `***${token6.slice(-2)}`;
|
|
406
|
+
return `${token6.slice(0, 8)}\u2026${token6.slice(-4)}`;
|
|
407
407
|
}
|
|
408
408
|
function toProfile(config) {
|
|
409
409
|
if (config.servers === void 0 && config.blocked === void 0) return null;
|
|
@@ -442,10 +442,10 @@ function profileAllows(profile, namespace) {
|
|
|
442
442
|
|
|
443
443
|
// src/config.ts
|
|
444
444
|
import { request } from "undici";
|
|
445
|
-
async function fetchConfig(
|
|
446
|
-
const url = `${
|
|
445
|
+
async function fetchConfig(apiUrl6, token6, currentVersion) {
|
|
446
|
+
const url = `${apiUrl6.replace(/\/$/, "")}/api/connect/config`;
|
|
447
447
|
const headers = {
|
|
448
|
-
Authorization: `Bearer ${
|
|
448
|
+
Authorization: `Bearer ${token6}`,
|
|
449
449
|
Accept: "application/json"
|
|
450
450
|
};
|
|
451
451
|
if (currentVersion) {
|
|
@@ -466,7 +466,7 @@ async function fetchConfig(apiUrl5, token5, currentVersion) {
|
|
|
466
466
|
await res.body.text().catch(() => {
|
|
467
467
|
});
|
|
468
468
|
throw new ConfigError(
|
|
469
|
-
`Token rejected (HTTP 401) \u2014 the token ${tokenFingerprint(
|
|
469
|
+
`Token rejected (HTTP 401) \u2014 the token ${tokenFingerprint(token6)} is invalid or revoked.
|
|
470
470
|
Generate a new token at https://mcp.hosting/dashboard/settings/tokens,
|
|
471
471
|
then re-run \`mcph install <client> --token mcp_pat_...\` or set MCPH_TOKEN.`,
|
|
472
472
|
true
|
|
@@ -476,7 +476,7 @@ async function fetchConfig(apiUrl5, token5, currentVersion) {
|
|
|
476
476
|
await res.body.text().catch(() => {
|
|
477
477
|
});
|
|
478
478
|
throw new ConfigError(
|
|
479
|
-
`Access denied (HTTP 403) \u2014 the token ${tokenFingerprint(
|
|
479
|
+
`Access denied (HTTP 403) \u2014 the token ${tokenFingerprint(token6)} was accepted but lacks permission to read this account's servers.
|
|
480
480
|
The account may be suspended or the token scope reduced \u2014 check
|
|
481
481
|
https://mcp.hosting/dashboard/settings/tokens, or reach support@mcp.hosting.`,
|
|
482
482
|
true
|
|
@@ -900,12 +900,12 @@ async function runComplianceCommand(argv) {
|
|
|
900
900
|
);
|
|
901
901
|
return 1;
|
|
902
902
|
}
|
|
903
|
-
const
|
|
903
|
+
const apiUrl6 = process.env.MCPH_URL ?? "https://mcp.hosting";
|
|
904
904
|
const report = await runTest(args);
|
|
905
905
|
if (!report) return 1;
|
|
906
906
|
printSummary(report);
|
|
907
907
|
if (publish) {
|
|
908
|
-
const result = await publishReport(
|
|
908
|
+
const result = await publishReport(apiUrl6, report);
|
|
909
909
|
if (!result) return 1;
|
|
910
910
|
process.stdout.write(`
|
|
911
911
|
Published: ${result.reportUrl}
|
|
@@ -965,9 +965,9 @@ Target: ${url}
|
|
|
965
965
|
`
|
|
966
966
|
);
|
|
967
967
|
}
|
|
968
|
-
async function publishReport(
|
|
968
|
+
async function publishReport(apiUrl6, report) {
|
|
969
969
|
try {
|
|
970
|
-
const res = await request2(`${
|
|
970
|
+
const res = await request2(`${apiUrl6.replace(/\/$/, "")}/api/compliance/ext`, {
|
|
971
971
|
method: "POST",
|
|
972
972
|
headers: { "Content-Type": "application/json" },
|
|
973
973
|
body: JSON.stringify(report)
|
|
@@ -1650,7 +1650,7 @@ function selectFlakyNamespaces(entries, limit) {
|
|
|
1650
1650
|
}
|
|
1651
1651
|
|
|
1652
1652
|
// src/doctor-cmd.ts
|
|
1653
|
-
var VERSION = true ? "0.47.
|
|
1653
|
+
var VERSION = true ? "0.47.6" : "dev";
|
|
1654
1654
|
async function runDoctor(opts = {}) {
|
|
1655
1655
|
if (opts.json) return runDoctorJson(opts);
|
|
1656
1656
|
const lines = [];
|
|
@@ -2348,12 +2348,12 @@ ${USAGE}`);
|
|
|
2348
2348
|
}
|
|
2349
2349
|
log2(`Target: ${target.label} (${scope})`);
|
|
2350
2350
|
log2(`File: ${resolved.absolute}`);
|
|
2351
|
-
let
|
|
2352
|
-
if (!
|
|
2351
|
+
let token6 = opts.token ?? null;
|
|
2352
|
+
if (!token6) {
|
|
2353
2353
|
const cfg = await loadMcphConfig({ home: opts.home, cwd: process.cwd(), env: {} });
|
|
2354
|
-
|
|
2354
|
+
token6 = cfg.token;
|
|
2355
2355
|
}
|
|
2356
|
-
if (!
|
|
2356
|
+
if (!token6) {
|
|
2357
2357
|
err(
|
|
2358
2358
|
"\nmcph install: no token available.\n Pass one with --token mcp_pat_\u2026, or run `mcph install` with --token once to seed ~/.mcph/config.json,\n or create the token at https://mcp.hosting \u2192 Settings \u2192 API Tokens."
|
|
2359
2359
|
);
|
|
@@ -2423,7 +2423,7 @@ ${USAGE}`);
|
|
|
2423
2423
|
const writeMcphConfig = !opts.skipMcphConfig;
|
|
2424
2424
|
const home = opts.home ?? homedir5();
|
|
2425
2425
|
const mcphConfigPath = join5(home, CONFIG_DIRNAME, CONFIG_FILENAME);
|
|
2426
|
-
const mcphConfigComposed = await composeMcphConfig(mcphConfigPath,
|
|
2426
|
+
const mcphConfigComposed = await composeMcphConfig(mcphConfigPath, token6);
|
|
2427
2427
|
if (mcphConfigComposed.backupPath) {
|
|
2428
2428
|
log2(
|
|
2429
2429
|
`mcph install: existing ${mcphConfigPath} was malformed; original bytes backed up to ${mcphConfigComposed.backupPath} before overwriting.`
|
|
@@ -2579,7 +2579,7 @@ function mergeClientConfig(existing, containerPath, entry) {
|
|
|
2579
2579
|
parent[leafKey] = container;
|
|
2580
2580
|
return out;
|
|
2581
2581
|
}
|
|
2582
|
-
async function composeMcphConfig(path5,
|
|
2582
|
+
async function composeMcphConfig(path5, token6) {
|
|
2583
2583
|
let existing = {};
|
|
2584
2584
|
let backupPath;
|
|
2585
2585
|
if (existsSync2(path5)) {
|
|
@@ -2606,7 +2606,7 @@ async function composeMcphConfig(path5, token5) {
|
|
|
2606
2606
|
}
|
|
2607
2607
|
}
|
|
2608
2608
|
const next = { version: CURRENT_SCHEMA_VERSION, ...existing };
|
|
2609
|
-
next.token =
|
|
2609
|
+
next.token = token6;
|
|
2610
2610
|
if (typeof next.version !== "number") next.version = CURRENT_SCHEMA_VERSION;
|
|
2611
2611
|
return { json: `${JSON.stringify(next, null, 2)}
|
|
2612
2612
|
`, backupPath };
|
|
@@ -2903,7 +2903,7 @@ import {
|
|
|
2903
2903
|
ListToolsRequestSchema,
|
|
2904
2904
|
ReadResourceRequestSchema
|
|
2905
2905
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
2906
|
-
import { request as
|
|
2906
|
+
import { request as request9 } from "undici";
|
|
2907
2907
|
|
|
2908
2908
|
// src/compliance.ts
|
|
2909
2909
|
var GRADE_ORDER = {
|
|
@@ -3336,6 +3336,50 @@ function truncateForWarning(msg) {
|
|
|
3336
3336
|
return clean.length > 120 ? `${clean.slice(0, 117)}...` : clean;
|
|
3337
3337
|
}
|
|
3338
3338
|
|
|
3339
|
+
// src/heartbeat.ts
|
|
3340
|
+
import { request as request5 } from "undici";
|
|
3341
|
+
var HEARTBEAT_PATH = "/api/connect/heartbeat";
|
|
3342
|
+
var apiUrl3 = "";
|
|
3343
|
+
var token3 = "";
|
|
3344
|
+
function initHeartbeat(url, tok) {
|
|
3345
|
+
apiUrl3 = url;
|
|
3346
|
+
token3 = tok;
|
|
3347
|
+
}
|
|
3348
|
+
async function reportHeartbeat(clientName, clientVersion, isRefresh = false) {
|
|
3349
|
+
if (!apiUrl3 || !token3) return;
|
|
3350
|
+
try {
|
|
3351
|
+
const res = await request5(`${apiUrl3.replace(/\/$/, "")}${HEARTBEAT_PATH}`, {
|
|
3352
|
+
method: "POST",
|
|
3353
|
+
headers: {
|
|
3354
|
+
Authorization: `Bearer ${token3}`,
|
|
3355
|
+
"Content-Type": "application/json"
|
|
3356
|
+
},
|
|
3357
|
+
body: JSON.stringify({
|
|
3358
|
+
// Pass through whatever the AI client self-reported. Backend
|
|
3359
|
+
// normalizes (fallback to 'unknown', length caps) — keep this
|
|
3360
|
+
// side dumb so a backend tightening doesn't need a CLI roll.
|
|
3361
|
+
clientName: clientName ?? null,
|
|
3362
|
+
clientVersion: clientVersion ?? null,
|
|
3363
|
+
isRefresh
|
|
3364
|
+
}),
|
|
3365
|
+
headersTimeout: 1e4,
|
|
3366
|
+
bodyTimeout: 1e4
|
|
3367
|
+
});
|
|
3368
|
+
await res.body.text().catch(() => {
|
|
3369
|
+
});
|
|
3370
|
+
if (res.statusCode >= 400 && res.statusCode !== 404) {
|
|
3371
|
+
log("warn", "Heartbeat failed", { status: res.statusCode, isRefresh });
|
|
3372
|
+
} else if (!isRefresh) {
|
|
3373
|
+
log("info", "Reported AI client connect to mcp.hosting", {
|
|
3374
|
+
clientName: clientName ?? null,
|
|
3375
|
+
clientVersion: clientVersion ?? null
|
|
3376
|
+
});
|
|
3377
|
+
}
|
|
3378
|
+
} catch (err) {
|
|
3379
|
+
log("warn", "Heartbeat error", { error: err?.message, isRefresh });
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3339
3383
|
// src/idle-ttl.ts
|
|
3340
3384
|
var ADAPTIVE_WINDOW_MS = 5 * 60 * 1e3;
|
|
3341
3385
|
var ADAPTIVE_LOOKBACK = 20;
|
|
@@ -3944,9 +3988,9 @@ var PackDetector = class {
|
|
|
3944
3988
|
|
|
3945
3989
|
// src/progress.ts
|
|
3946
3990
|
function createProgressReporter(extra) {
|
|
3947
|
-
const
|
|
3991
|
+
const token6 = extra?._meta?.progressToken;
|
|
3948
3992
|
const send = extra?.sendNotification;
|
|
3949
|
-
if (
|
|
3993
|
+
if (token6 === void 0 || token6 === null || !send) {
|
|
3950
3994
|
return () => {
|
|
3951
3995
|
};
|
|
3952
3996
|
}
|
|
@@ -3954,7 +3998,7 @@ function createProgressReporter(extra) {
|
|
|
3954
3998
|
return (message, progress, total) => {
|
|
3955
3999
|
step += 1;
|
|
3956
4000
|
const params = {
|
|
3957
|
-
progressToken:
|
|
4001
|
+
progressToken: token6,
|
|
3958
4002
|
progress: progress ?? step,
|
|
3959
4003
|
message
|
|
3960
4004
|
};
|
|
@@ -4408,26 +4452,26 @@ function rankServers(context, servers) {
|
|
|
4408
4452
|
}
|
|
4409
4453
|
|
|
4410
4454
|
// src/rerank.ts
|
|
4411
|
-
import { request as
|
|
4412
|
-
var
|
|
4413
|
-
var
|
|
4455
|
+
import { request as request6 } from "undici";
|
|
4456
|
+
var apiUrl4 = "";
|
|
4457
|
+
var token4 = "";
|
|
4414
4458
|
var RERANK_TIMEOUT_MS = 2e3;
|
|
4415
4459
|
function initRerank(url, tok) {
|
|
4416
|
-
|
|
4417
|
-
|
|
4460
|
+
apiUrl4 = url;
|
|
4461
|
+
token4 = tok;
|
|
4418
4462
|
}
|
|
4419
4463
|
async function rerank(intent, candidateIds, limit) {
|
|
4420
|
-
if (!
|
|
4464
|
+
if (!apiUrl4 || !token4) return null;
|
|
4421
4465
|
if (!intent?.trim()) return null;
|
|
4422
4466
|
if (candidateIds !== void 0 && candidateIds.length === 0) return null;
|
|
4423
4467
|
const payload = { intent: intent.trim() };
|
|
4424
4468
|
if (candidateIds && candidateIds.length > 0) payload.candidateIds = candidateIds;
|
|
4425
4469
|
if (typeof limit === "number" && limit > 0) payload.limit = limit;
|
|
4426
4470
|
try {
|
|
4427
|
-
const res = await
|
|
4471
|
+
const res = await request6(`${apiUrl4.replace(/\/$/, "")}/api/connect/rerank`, {
|
|
4428
4472
|
method: "POST",
|
|
4429
4473
|
headers: {
|
|
4430
|
-
Authorization: `Bearer ${
|
|
4474
|
+
Authorization: `Bearer ${token4}`,
|
|
4431
4475
|
"Content-Type": "application/json"
|
|
4432
4476
|
},
|
|
4433
4477
|
body: JSON.stringify(payload),
|
|
@@ -4457,14 +4501,14 @@ async function rerank(intent, candidateIds, limit) {
|
|
|
4457
4501
|
|
|
4458
4502
|
// src/runtime-detect.ts
|
|
4459
4503
|
import { spawn as spawn2 } from "child_process";
|
|
4460
|
-
import { request as
|
|
4504
|
+
import { request as request7 } from "undici";
|
|
4461
4505
|
var PROBE_TIMEOUT_MS = 3e3;
|
|
4462
4506
|
var RUNTIME_REPORT_PATH = "/api/connect/runtimes";
|
|
4463
|
-
var
|
|
4464
|
-
var
|
|
4507
|
+
var apiUrl5 = "";
|
|
4508
|
+
var token5 = "";
|
|
4465
4509
|
function initRuntimeDetect(url, tok) {
|
|
4466
|
-
|
|
4467
|
-
|
|
4510
|
+
apiUrl5 = url;
|
|
4511
|
+
token5 = tok;
|
|
4468
4512
|
}
|
|
4469
4513
|
var PROBES = {
|
|
4470
4514
|
node: {
|
|
@@ -4576,7 +4620,7 @@ async function detectRuntimes() {
|
|
|
4576
4620
|
return out;
|
|
4577
4621
|
}
|
|
4578
4622
|
async function reportRuntimes() {
|
|
4579
|
-
if (!
|
|
4623
|
+
if (!apiUrl5 || !token5) return;
|
|
4580
4624
|
let runtimes;
|
|
4581
4625
|
try {
|
|
4582
4626
|
runtimes = await detectRuntimes();
|
|
@@ -4585,10 +4629,10 @@ async function reportRuntimes() {
|
|
|
4585
4629
|
return;
|
|
4586
4630
|
}
|
|
4587
4631
|
try {
|
|
4588
|
-
const res = await
|
|
4632
|
+
const res = await request7(`${apiUrl5.replace(/\/$/, "")}${RUNTIME_REPORT_PATH}`, {
|
|
4589
4633
|
method: "POST",
|
|
4590
4634
|
headers: {
|
|
4591
|
-
Authorization: `Bearer ${
|
|
4635
|
+
Authorization: `Bearer ${token5}`,
|
|
4592
4636
|
"Content-Type": "application/json"
|
|
4593
4637
|
},
|
|
4594
4638
|
body: JSON.stringify({ runtimes }),
|
|
@@ -4745,7 +4789,7 @@ import { createWriteStream } from "fs";
|
|
|
4745
4789
|
import fs from "fs/promises";
|
|
4746
4790
|
import path4 from "path";
|
|
4747
4791
|
import { pipeline } from "stream/promises";
|
|
4748
|
-
import { request as
|
|
4792
|
+
import { request as request8 } from "undici";
|
|
4749
4793
|
var UV_VERSION = "0.11.7";
|
|
4750
4794
|
var RELEASE_BASE = `https://github.com/astral-sh/uv/releases/download/${UV_VERSION}`;
|
|
4751
4795
|
function uvTarget() {
|
|
@@ -4822,7 +4866,7 @@ async function onPath(cmd) {
|
|
|
4822
4866
|
async function fetchWithRedirects(url, maxHops = 5) {
|
|
4823
4867
|
let current = url;
|
|
4824
4868
|
for (let i = 0; i < maxHops; i++) {
|
|
4825
|
-
const res = await
|
|
4869
|
+
const res = await request8(current, { method: "GET" });
|
|
4826
4870
|
if (res.statusCode >= 300 && res.statusCode < 400) {
|
|
4827
4871
|
const loc = res.headers.location;
|
|
4828
4872
|
if (!loc) throw new Error(`Redirect without Location header from ${current}`);
|
|
@@ -4971,7 +5015,7 @@ function categorizeSpawnError(err) {
|
|
|
4971
5015
|
}
|
|
4972
5016
|
async function connectToUpstream(config, onDisconnect, onListChanged) {
|
|
4973
5017
|
const client = new Client(
|
|
4974
|
-
{ name: "mcph", version: true ? "0.47.
|
|
5018
|
+
{ name: "mcph", version: true ? "0.47.6" : "dev" },
|
|
4975
5019
|
{ capabilities: {} }
|
|
4976
5020
|
);
|
|
4977
5021
|
let transport;
|
|
@@ -5275,11 +5319,11 @@ function computeToolOverlaps(connections) {
|
|
|
5275
5319
|
return overlaps;
|
|
5276
5320
|
}
|
|
5277
5321
|
var ConnectServer = class _ConnectServer {
|
|
5278
|
-
constructor(
|
|
5279
|
-
this.apiUrl =
|
|
5280
|
-
this.token =
|
|
5322
|
+
constructor(apiUrl6, token6) {
|
|
5323
|
+
this.apiUrl = apiUrl6;
|
|
5324
|
+
this.token = token6;
|
|
5281
5325
|
this.server = new Server(
|
|
5282
|
-
{ name: "mcph", version: true ? "0.47.
|
|
5326
|
+
{ name: "mcph", version: true ? "0.47.6" : "dev" },
|
|
5283
5327
|
{
|
|
5284
5328
|
capabilities: {
|
|
5285
5329
|
tools: { listChanged: true },
|
|
@@ -5297,6 +5341,10 @@ var ConnectServer = class _ConnectServer {
|
|
|
5297
5341
|
config = null;
|
|
5298
5342
|
configVersion = null;
|
|
5299
5343
|
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;
|
|
5300
5348
|
toolRoutes = /* @__PURE__ */ new Map();
|
|
5301
5349
|
resourceRoutes = /* @__PURE__ */ new Map();
|
|
5302
5350
|
promptRoutes = /* @__PURE__ */ new Map();
|
|
@@ -5420,23 +5468,23 @@ var ConnectServer = class _ConnectServer {
|
|
|
5420
5468
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
5421
5469
|
tools: buildToolList(this.connections, this.getDeferredServers(), this.toolFilters)
|
|
5422
5470
|
}));
|
|
5423
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (
|
|
5424
|
-
const { name, arguments: args } =
|
|
5471
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request10, extra) => {
|
|
5472
|
+
const { name, arguments: args } = request10.params;
|
|
5425
5473
|
return this.handleToolCall(name, args ?? {}, extra);
|
|
5426
5474
|
});
|
|
5427
5475
|
this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
5428
5476
|
resources: buildResourceList(this.connections, this.getBuiltinResources())
|
|
5429
5477
|
}));
|
|
5430
|
-
this.server.setRequestHandler(ReadResourceRequestSchema, async (
|
|
5431
|
-
return routeResourceRead(
|
|
5478
|
+
this.server.setRequestHandler(ReadResourceRequestSchema, async (request10) => {
|
|
5479
|
+
return routeResourceRead(request10.params.uri, this.resourceRoutes, this.connections, this.getBuiltinResourceMap());
|
|
5432
5480
|
});
|
|
5433
5481
|
this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
5434
5482
|
prompts: buildPromptList(this.connections)
|
|
5435
5483
|
}));
|
|
5436
|
-
this.server.setRequestHandler(GetPromptRequestSchema, async (
|
|
5484
|
+
this.server.setRequestHandler(GetPromptRequestSchema, async (request10) => {
|
|
5437
5485
|
return routePromptGet(
|
|
5438
|
-
|
|
5439
|
-
|
|
5486
|
+
request10.params.name,
|
|
5487
|
+
request10.params.arguments,
|
|
5440
5488
|
this.promptRoutes,
|
|
5441
5489
|
this.connections
|
|
5442
5490
|
);
|
|
@@ -5541,10 +5589,18 @@ var ConnectServer = class _ConnectServer {
|
|
|
5541
5589
|
initToolReport(this.apiUrl, this.token);
|
|
5542
5590
|
initRerank(this.apiUrl, this.token);
|
|
5543
5591
|
initRuntimeDetect(this.apiUrl, this.token);
|
|
5592
|
+
initHeartbeat(this.apiUrl, this.token);
|
|
5544
5593
|
reportRuntimes().catch((err) => log("warn", "reportRuntimes failed", { error: err?.message }));
|
|
5545
5594
|
if (this.config?.servers.some((s) => s.command === "uv" || s.command === "uvx")) {
|
|
5546
5595
|
ensureUv().catch((err) => log("warn", "uv prewarm failed", { error: err?.message }));
|
|
5547
5596
|
}
|
|
5597
|
+
this.server.oninitialized = () => {
|
|
5598
|
+
this.aiClientAttached = true;
|
|
5599
|
+
const info = this.server.getClientVersion();
|
|
5600
|
+
reportHeartbeat(info?.name, info?.version).catch(
|
|
5601
|
+
(err) => log("warn", "reportHeartbeat failed", { error: err?.message })
|
|
5602
|
+
);
|
|
5603
|
+
};
|
|
5548
5604
|
const transport = new StdioServerTransport();
|
|
5549
5605
|
await this.server.connect(transport);
|
|
5550
5606
|
this.startPolling();
|
|
@@ -6708,6 +6764,12 @@ ${activeCount} loaded in this session, ${totalTools} tools in context${tokenSumm
|
|
|
6708
6764
|
} catch (err) {
|
|
6709
6765
|
log("warn", "Config poll failed", { error: err.message });
|
|
6710
6766
|
}
|
|
6767
|
+
if (this.aiClientAttached) {
|
|
6768
|
+
const info = this.server.getClientVersion();
|
|
6769
|
+
reportHeartbeat(info?.name, info?.version, true).catch(
|
|
6770
|
+
(err) => log("warn", "reportHeartbeat refresh failed", { error: err?.message })
|
|
6771
|
+
);
|
|
6772
|
+
}
|
|
6711
6773
|
this.pollTimer = setTimeout(poll, intervalMs);
|
|
6712
6774
|
if (this.pollTimer.unref) this.pollTimer.unref();
|
|
6713
6775
|
};
|
|
@@ -6781,7 +6843,7 @@ ${activeCount} loaded in this session, ${totalTools} tools in context${tokenSumm
|
|
|
6781
6843
|
nsToKeys.set(s.namespace, existing);
|
|
6782
6844
|
}
|
|
6783
6845
|
const collisions = [...nsToKeys.entries()].filter(([, keys]) => keys.length > 1);
|
|
6784
|
-
const res = await
|
|
6846
|
+
const res = await request9(`${this.apiUrl.replace(/\/$/, "")}/api/connect/import`, {
|
|
6785
6847
|
method: "POST",
|
|
6786
6848
|
headers: {
|
|
6787
6849
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -6842,7 +6904,7 @@ Use mcp_connect_discover to see imported servers.`
|
|
|
6842
6904
|
}
|
|
6843
6905
|
const payload = built.payload;
|
|
6844
6906
|
try {
|
|
6845
|
-
const res = await
|
|
6907
|
+
const res = await request9(`${this.apiUrl.replace(/\/$/, "")}/api/connect/servers`, {
|
|
6846
6908
|
method: "POST",
|
|
6847
6909
|
headers: {
|
|
6848
6910
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -7640,7 +7702,7 @@ Or re-run with --run to upgrade in place.`);
|
|
|
7640
7702
|
return { exitCode: 3, lines };
|
|
7641
7703
|
}
|
|
7642
7704
|
function readCurrentVersion() {
|
|
7643
|
-
return true ? "0.47.
|
|
7705
|
+
return true ? "0.47.6" : "dev";
|
|
7644
7706
|
}
|
|
7645
7707
|
|
|
7646
7708
|
// src/index.ts
|
|
@@ -7808,7 +7870,7 @@ if (subcommand === "compliance") {
|
|
|
7808
7870
|
`);
|
|
7809
7871
|
process.exit(0);
|
|
7810
7872
|
} else if (subcommand === "--version" || subcommand === "-V") {
|
|
7811
|
-
process.stdout.write(`mcph ${true ? "0.47.
|
|
7873
|
+
process.stdout.write(`mcph ${true ? "0.47.6" : "dev"}
|
|
7812
7874
|
`);
|
|
7813
7875
|
process.exit(0);
|
|
7814
7876
|
} else if (subcommand && !subcommand.startsWith("-")) {
|
package/package.json
CHANGED