@yawlabs/mcp 0.64.1 → 0.64.2
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 +155 -63
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1148,9 +1148,15 @@ async function runBundlesCommand(opts = {}) {
|
|
|
1148
1148
|
env: opts.env
|
|
1149
1149
|
});
|
|
1150
1150
|
if (!config.token) {
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1151
|
+
const msg = "no token resolved. Run `yaw-mcp install <client> --token mcp_pat_\u2026` or set YAW_MCP_TOKEN.";
|
|
1152
|
+
if (opts.json) {
|
|
1153
|
+
const jsonErr = JSON.stringify({ ok: false, error: msg });
|
|
1154
|
+
lines.push(jsonErr);
|
|
1155
|
+
writeErr(`${jsonErr}
|
|
1156
|
+
`);
|
|
1157
|
+
} else {
|
|
1158
|
+
printErr(`yaw-mcp bundles match: ${msg}`);
|
|
1159
|
+
}
|
|
1154
1160
|
return { exitCode: 1, lines };
|
|
1155
1161
|
}
|
|
1156
1162
|
const fetcher = opts.fetcher ?? fetchConfig;
|
|
@@ -1159,11 +1165,26 @@ async function runBundlesCommand(opts = {}) {
|
|
|
1159
1165
|
backend = await fetcher(config.apiBase, config.token);
|
|
1160
1166
|
} catch (err) {
|
|
1161
1167
|
const msg = err instanceof ConfigError || err instanceof Error ? err.message : String(err);
|
|
1162
|
-
|
|
1168
|
+
if (opts.json) {
|
|
1169
|
+
const jsonErr = JSON.stringify({ ok: false, error: msg });
|
|
1170
|
+
lines.push(jsonErr);
|
|
1171
|
+
writeErr(`${jsonErr}
|
|
1172
|
+
`);
|
|
1173
|
+
} else {
|
|
1174
|
+
printErr(`yaw-mcp bundles match: ${msg}`);
|
|
1175
|
+
}
|
|
1163
1176
|
return { exitCode: 2, lines };
|
|
1164
1177
|
}
|
|
1165
1178
|
if (!backend) {
|
|
1166
|
-
|
|
1179
|
+
const msg = "backend returned 304 without a conditional request.";
|
|
1180
|
+
if (opts.json) {
|
|
1181
|
+
const jsonErr = JSON.stringify({ ok: false, error: msg });
|
|
1182
|
+
lines.push(jsonErr);
|
|
1183
|
+
writeErr(`${jsonErr}
|
|
1184
|
+
`);
|
|
1185
|
+
} else {
|
|
1186
|
+
printErr(`yaw-mcp bundles match: ${msg}`);
|
|
1187
|
+
}
|
|
1167
1188
|
return { exitCode: 2, lines };
|
|
1168
1189
|
}
|
|
1169
1190
|
const installed = backend.servers.filter((s) => s.isActive).map((s) => s.namespace);
|
|
@@ -1380,18 +1401,27 @@ function renderScript(shell) {
|
|
|
1380
1401
|
return renderPowershell();
|
|
1381
1402
|
}
|
|
1382
1403
|
}
|
|
1404
|
+
function isPlaceholder(s) {
|
|
1405
|
+
return s.startsWith("<") && s.endsWith(">");
|
|
1406
|
+
}
|
|
1383
1407
|
function renderBash() {
|
|
1384
1408
|
const subcommandList = SUBCOMMAND_SPEC.map((s) => s.name).join(" ");
|
|
1385
1409
|
const topLevelFlags = "--help -h --version -V";
|
|
1386
1410
|
const cases = SUBCOMMAND_SPEC.map((spec) => {
|
|
1387
|
-
const
|
|
1388
|
-
|
|
1411
|
+
const indexedPositionals = (spec.positional ?? []).map((p, i) => ({ value: p, index: i })).filter(({ value }) => !isPlaceholder(value));
|
|
1412
|
+
const posClauses = indexedPositionals.map(
|
|
1413
|
+
({ value, index }) => ` if [[ $cword -eq $((${index} + 2)) ]]; then
|
|
1414
|
+
COMPREPLY=( $(compgen -W "${value}" -- "$cur") )
|
|
1389
1415
|
return 0
|
|
1390
|
-
fi`
|
|
1416
|
+
fi`
|
|
1417
|
+
);
|
|
1418
|
+
const parts = [
|
|
1419
|
+
...posClauses,
|
|
1420
|
+
` COMPREPLY=( $(compgen -W "${spec.flags.join(" ")}" -- "$cur") )`,
|
|
1421
|
+
" return 0"
|
|
1422
|
+
].filter((p) => p !== "");
|
|
1391
1423
|
return ` ${spec.name})
|
|
1392
|
-
${
|
|
1393
|
-
COMPREPLY=( $(compgen -W "${spec.flags.join(" ")}" -- "$cur") )
|
|
1394
|
-
return 0
|
|
1424
|
+
${parts.join("\n")}
|
|
1395
1425
|
;;`;
|
|
1396
1426
|
}).join("\n");
|
|
1397
1427
|
return `# bash completion for yaw-mcp \u2014 generated by \`yaw-mcp completion bash\`
|
|
@@ -1418,8 +1448,10 @@ function renderZsh() {
|
|
|
1418
1448
|
const subcommandList = SUBCOMMAND_SPEC.map((s) => ` '${s.name}:${s.description}'`).join("\n");
|
|
1419
1449
|
const argsCases = SUBCOMMAND_SPEC.map((spec) => {
|
|
1420
1450
|
const lines = [` ${spec.name})`];
|
|
1421
|
-
|
|
1422
|
-
|
|
1451
|
+
const indexedPositionals = (spec.positional ?? []).map((p, i) => ({ value: p, index: i })).filter(({ value }) => !isPlaceholder(value));
|
|
1452
|
+
if (indexedPositionals.length > 0) {
|
|
1453
|
+
const posArgs = indexedPositionals.map(({ value, index }) => `'${index + 1}: :(${value})'`).join(" ");
|
|
1454
|
+
lines.push(` _arguments ${posArgs} '*: :(${spec.flags.join(" ")})'`);
|
|
1423
1455
|
} else {
|
|
1424
1456
|
lines.push(` _arguments '*: :(${spec.flags.join(" ")})'`);
|
|
1425
1457
|
}
|
|
@@ -1463,9 +1495,13 @@ complete -c yaw-mcp -f`;
|
|
|
1463
1495
|
const flagLines = [];
|
|
1464
1496
|
for (const spec of SUBCOMMAND_SPEC) {
|
|
1465
1497
|
if (spec.positional) {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1498
|
+
spec.positional.forEach((p, i) => {
|
|
1499
|
+
if (isPlaceholder(p)) return;
|
|
1500
|
+
const expectedCount = i + 2;
|
|
1501
|
+
positionalLines.push(
|
|
1502
|
+
`complete -c yaw-mcp -n "__fish_seen_subcommand_from ${spec.name}; and test (count (commandline -opc)) -eq ${expectedCount}" -a ${p}`
|
|
1503
|
+
);
|
|
1504
|
+
});
|
|
1469
1505
|
}
|
|
1470
1506
|
for (const f of spec.flags) {
|
|
1471
1507
|
if (!f.startsWith("--")) continue;
|
|
@@ -1478,12 +1514,13 @@ complete -c yaw-mcp -f`;
|
|
|
1478
1514
|
function renderPowershell() {
|
|
1479
1515
|
const subcommandNames = SUBCOMMAND_SPEC.map((s) => `'${s.name}'`).join(", ");
|
|
1480
1516
|
const caseBranches = SUBCOMMAND_SPEC.map((spec) => {
|
|
1481
|
-
const
|
|
1517
|
+
const indexedPositionals = (spec.positional ?? []).map((p, i) => ({ value: p, index: i })).filter(({ value }) => !isPlaceholder(value));
|
|
1482
1518
|
const flags = spec.flags.map((f) => `'${f}'`).join(", ");
|
|
1483
|
-
const
|
|
1519
|
+
const positionalLines = indexedPositionals.map(({ value, index }) => ` if ($tokens.Count -eq ${index + 2}) { $completions += @('${value}') }`).join("\n");
|
|
1520
|
+
const positionalBlock = positionalLines ? `${positionalLines}
|
|
1484
1521
|
` : "";
|
|
1485
1522
|
return ` '${spec.name}' {
|
|
1486
|
-
${
|
|
1523
|
+
${positionalBlock} $completions += @(${flags})
|
|
1487
1524
|
}`;
|
|
1488
1525
|
}).join("\n");
|
|
1489
1526
|
return `# PowerShell completion for yaw-mcp \u2014 generated by \`yaw-mcp completion powershell\`
|
|
@@ -1694,6 +1731,19 @@ var token = "";
|
|
|
1694
1731
|
var lastFailure = null;
|
|
1695
1732
|
var lastLoggedConnectStatus = null;
|
|
1696
1733
|
var lastLoggedDispatchStatus = null;
|
|
1734
|
+
var warnedInsecureBearerSkipConnect = false;
|
|
1735
|
+
var warnedInsecureBearerSkipDispatch = false;
|
|
1736
|
+
function shouldSendBearer(targetUrl) {
|
|
1737
|
+
let parsed;
|
|
1738
|
+
try {
|
|
1739
|
+
parsed = new URL(targetUrl);
|
|
1740
|
+
} catch {
|
|
1741
|
+
return false;
|
|
1742
|
+
}
|
|
1743
|
+
if (parsed.protocol === "https:") return true;
|
|
1744
|
+
if (parsed.protocol === "http:" && isLoopbackHost(parsed.hostname)) return true;
|
|
1745
|
+
return false;
|
|
1746
|
+
}
|
|
1697
1747
|
function getLastAnalyticsFailure() {
|
|
1698
1748
|
return lastFailure;
|
|
1699
1749
|
}
|
|
@@ -1746,12 +1796,20 @@ async function flush() {
|
|
|
1746
1796
|
const events = buffer.splice(0, FLUSH_SIZE);
|
|
1747
1797
|
const url = `${apiUrl.replace(/\/$/, "")}/api/connect/analytics`;
|
|
1748
1798
|
try {
|
|
1799
|
+
const headers = { "Content-Type": "application/json" };
|
|
1800
|
+
if (shouldSendBearer(url)) {
|
|
1801
|
+
headers.Authorization = `Bearer ${token}`;
|
|
1802
|
+
} else if (!warnedInsecureBearerSkipConnect) {
|
|
1803
|
+
log(
|
|
1804
|
+
"warn",
|
|
1805
|
+
"Analytics URL is not https and not loopback; sending without Authorization header to avoid leaking the bearer token",
|
|
1806
|
+
{ url }
|
|
1807
|
+
);
|
|
1808
|
+
warnedInsecureBearerSkipConnect = true;
|
|
1809
|
+
}
|
|
1749
1810
|
const res = await request3(url, {
|
|
1750
1811
|
method: "POST",
|
|
1751
|
-
headers
|
|
1752
|
-
Authorization: `Bearer ${token}`,
|
|
1753
|
-
"Content-Type": "application/json"
|
|
1754
|
-
},
|
|
1812
|
+
headers,
|
|
1755
1813
|
body: JSON.stringify({ events }),
|
|
1756
1814
|
headersTimeout: 1e4,
|
|
1757
1815
|
bodyTimeout: 1e4
|
|
@@ -1788,17 +1846,25 @@ async function flushDispatch() {
|
|
|
1788
1846
|
const events = dispatchBuffer.splice(0, FLUSH_SIZE);
|
|
1789
1847
|
const url = `${apiUrl.replace(/\/$/, "")}/api/connect/dispatch-events`;
|
|
1790
1848
|
try {
|
|
1849
|
+
const headers = { "Content-Type": "application/json" };
|
|
1850
|
+
if (shouldSendBearer(url)) {
|
|
1851
|
+
headers.Authorization = `Bearer ${token}`;
|
|
1852
|
+
} else if (!warnedInsecureBearerSkipDispatch) {
|
|
1853
|
+
log(
|
|
1854
|
+
"warn",
|
|
1855
|
+
"Analytics URL is not https and not loopback; sending without Authorization header to avoid leaking the bearer token",
|
|
1856
|
+
{ url }
|
|
1857
|
+
);
|
|
1858
|
+
warnedInsecureBearerSkipDispatch = true;
|
|
1859
|
+
}
|
|
1791
1860
|
const res = await request3(url, {
|
|
1792
1861
|
method: "POST",
|
|
1793
|
-
headers
|
|
1794
|
-
Authorization: `Bearer ${token}`,
|
|
1795
|
-
"Content-Type": "application/json"
|
|
1796
|
-
},
|
|
1862
|
+
headers,
|
|
1797
1863
|
body: JSON.stringify({ events }),
|
|
1798
1864
|
headersTimeout: 1e4,
|
|
1799
1865
|
bodyTimeout: 1e4
|
|
1800
1866
|
});
|
|
1801
|
-
if (res.statusCode >= 400
|
|
1867
|
+
if (res.statusCode >= 400) {
|
|
1802
1868
|
const retryable = res.statusCode >= 500 || res.statusCode === 408 || res.statusCode === 429;
|
|
1803
1869
|
if (retryable) {
|
|
1804
1870
|
const room = MAX_BUFFER - dispatchBuffer.length;
|
|
@@ -1812,7 +1878,7 @@ async function flushDispatch() {
|
|
|
1812
1878
|
lastLoggedDispatchStatus = res.statusCode;
|
|
1813
1879
|
}
|
|
1814
1880
|
lastFailure = { statusCode: res.statusCode, url, at: Date.now() };
|
|
1815
|
-
} else
|
|
1881
|
+
} else {
|
|
1816
1882
|
lastFailure = null;
|
|
1817
1883
|
lastLoggedDispatchStatus = null;
|
|
1818
1884
|
}
|
|
@@ -1830,6 +1896,8 @@ function initAnalytics(url, tok) {
|
|
|
1830
1896
|
token = tok;
|
|
1831
1897
|
lastLoggedConnectStatus = null;
|
|
1832
1898
|
lastLoggedDispatchStatus = null;
|
|
1899
|
+
warnedInsecureBearerSkipConnect = false;
|
|
1900
|
+
warnedInsecureBearerSkipDispatch = false;
|
|
1833
1901
|
teamAnalyticsDisabled = false;
|
|
1834
1902
|
flushTimer = setInterval(() => {
|
|
1835
1903
|
flush().catch(() => {
|
|
@@ -2296,9 +2364,12 @@ function errorMessage(err) {
|
|
|
2296
2364
|
import { request as request4 } from "undici";
|
|
2297
2365
|
var apiUrl2 = "";
|
|
2298
2366
|
var token2 = "";
|
|
2299
|
-
var
|
|
2300
|
-
function getLastReportFailure() {
|
|
2301
|
-
return
|
|
2367
|
+
var lastFailureByServer = /* @__PURE__ */ new Map();
|
|
2368
|
+
function getLastReportFailure(serverId) {
|
|
2369
|
+
if (serverId !== void 0) return lastFailureByServer.get(serverId) ?? null;
|
|
2370
|
+
const entries = [...lastFailureByServer.values()];
|
|
2371
|
+
if (entries.length === 0) return null;
|
|
2372
|
+
return entries.reduce((a, b) => a.at >= b.at ? a : b);
|
|
2302
2373
|
}
|
|
2303
2374
|
function initToolReport(url, tok) {
|
|
2304
2375
|
apiUrl2 = url;
|
|
@@ -2306,7 +2377,7 @@ function initToolReport(url, tok) {
|
|
|
2306
2377
|
}
|
|
2307
2378
|
async function reportTools(serverId, tools) {
|
|
2308
2379
|
if (!apiUrl2 || !token2 || !serverId) return;
|
|
2309
|
-
const url = `${apiUrl2.replace(/\/$/, "")}/api/connect/servers/${serverId}/tools`;
|
|
2380
|
+
const url = `${apiUrl2.replace(/\/$/, "")}/api/connect/servers/${encodeURIComponent(serverId)}/tools`;
|
|
2310
2381
|
try {
|
|
2311
2382
|
const res = await request4(url, {
|
|
2312
2383
|
method: "POST",
|
|
@@ -2322,12 +2393,13 @@ async function reportTools(serverId, tools) {
|
|
|
2322
2393
|
});
|
|
2323
2394
|
if (res.statusCode >= 400 && res.statusCode !== 404) {
|
|
2324
2395
|
log("warn", "Tool report failed", { serverId, status: res.statusCode });
|
|
2325
|
-
|
|
2326
|
-
} else
|
|
2327
|
-
|
|
2396
|
+
lastFailureByServer.set(serverId, { statusCode: res.statusCode, url, at: Date.now() });
|
|
2397
|
+
} else {
|
|
2398
|
+
lastFailureByServer.delete(serverId);
|
|
2328
2399
|
}
|
|
2329
2400
|
} catch (err) {
|
|
2330
2401
|
log("warn", "Tool report error", { serverId, error: err?.message });
|
|
2402
|
+
lastFailureByServer.set(serverId, { statusCode: 0, url, at: Date.now() });
|
|
2331
2403
|
}
|
|
2332
2404
|
}
|
|
2333
2405
|
|
|
@@ -2367,6 +2439,9 @@ function tokenizeCommand(cmd) {
|
|
|
2367
2439
|
has = true;
|
|
2368
2440
|
}
|
|
2369
2441
|
}
|
|
2442
|
+
if (quote !== null) {
|
|
2443
|
+
throw new Error(`Unbalanced quote in command: ${cmd}`);
|
|
2444
|
+
}
|
|
2370
2445
|
if (has) out.push(cur);
|
|
2371
2446
|
return out;
|
|
2372
2447
|
}
|
|
@@ -3912,7 +3987,7 @@ async function runUpgrade(opts = {}) {
|
|
|
3912
3987
|
return { exitCode: 3, lines };
|
|
3913
3988
|
}
|
|
3914
3989
|
function readCurrentVersion() {
|
|
3915
|
-
return true ? "0.64.
|
|
3990
|
+
return true ? "0.64.2" : "dev";
|
|
3916
3991
|
}
|
|
3917
3992
|
|
|
3918
3993
|
// src/usage-hints.ts
|
|
@@ -3974,7 +4049,7 @@ function selectFlakyNamespaces(entries, limit) {
|
|
|
3974
4049
|
}
|
|
3975
4050
|
|
|
3976
4051
|
// src/doctor-cmd.ts
|
|
3977
|
-
var VERSION = true ? "0.64.
|
|
4052
|
+
var VERSION = true ? "0.64.2" : "dev";
|
|
3978
4053
|
function isPersistenceDisabled(env) {
|
|
3979
4054
|
const raw = env.YAW_MCP_DISABLE_PERSISTENCE;
|
|
3980
4055
|
return raw !== void 0 && raw !== "" && (raw === "1" || raw.toLowerCase() === "true");
|
|
@@ -6447,7 +6522,7 @@ function defaultSpawn2(cmd, args) {
|
|
|
6447
6522
|
async function maybeAutoUpgrade(deps = {}) {
|
|
6448
6523
|
const optOut = process.env.YAW_MCP_AUTO_UPGRADE;
|
|
6449
6524
|
if (optOut === "0" || optOut?.toLowerCase() === "false") return;
|
|
6450
|
-
const current = deps.currentVersion ?? (true ? "0.64.
|
|
6525
|
+
const current = deps.currentVersion ?? (true ? "0.64.2" : "dev");
|
|
6451
6526
|
if (current === "dev") return;
|
|
6452
6527
|
const method = (deps.isSeaImpl ? await deps.isSeaImpl() : await detectSea()) ? "binary" : detectInstallMethod(deps.argvPath ?? process.argv[1]);
|
|
6453
6528
|
const latest = await (deps.fetchLatestImpl ?? fetchLatestVersion2)();
|
|
@@ -6957,18 +7032,18 @@ import { readFile as readFile10 } from "fs/promises";
|
|
|
6957
7032
|
var GUIDE_READ_TIMEOUT_MS = 1e3;
|
|
6958
7033
|
async function readGuide(path5, scope) {
|
|
6959
7034
|
let raw;
|
|
7035
|
+
const ac = new AbortController();
|
|
7036
|
+
const timer = setTimeout(() => ac.abort(new Error("guide read timeout")), GUIDE_READ_TIMEOUT_MS);
|
|
6960
7037
|
try {
|
|
6961
|
-
raw = await
|
|
6962
|
-
readFile10(path5, "utf8"),
|
|
6963
|
-
new Promise(
|
|
6964
|
-
(_, reject) => setTimeout(() => reject(new Error("guide read timeout")), GUIDE_READ_TIMEOUT_MS)
|
|
6965
|
-
)
|
|
6966
|
-
]);
|
|
7038
|
+
raw = await readFile10(path5, { encoding: "utf8", signal: ac.signal });
|
|
6967
7039
|
} catch (err) {
|
|
6968
|
-
|
|
7040
|
+
const isTimeout = err instanceof Error && err.code === "ABORT_ERR";
|
|
7041
|
+
if (isTimeout) {
|
|
6969
7042
|
log("warn", "Guide read timed out", { path: path5 });
|
|
6970
7043
|
}
|
|
6971
7044
|
return null;
|
|
7045
|
+
} finally {
|
|
7046
|
+
clearTimeout(timer);
|
|
6972
7047
|
}
|
|
6973
7048
|
const content = raw.trim();
|
|
6974
7049
|
if (content.length === 0) {
|
|
@@ -7080,7 +7155,7 @@ function initHeartbeat(url, tok) {
|
|
|
7080
7155
|
lastLoggedErrorMessage = null;
|
|
7081
7156
|
warnedInsecureBearerSkip = false;
|
|
7082
7157
|
}
|
|
7083
|
-
function
|
|
7158
|
+
function shouldSendBearer2(targetUrl) {
|
|
7084
7159
|
let parsed;
|
|
7085
7160
|
try {
|
|
7086
7161
|
parsed = new URL(targetUrl);
|
|
@@ -7106,7 +7181,7 @@ async function reportHeartbeat(clientName, clientVersion, isRefresh = false) {
|
|
|
7106
7181
|
const headers = {
|
|
7107
7182
|
"Content-Type": "application/json"
|
|
7108
7183
|
};
|
|
7109
|
-
if (
|
|
7184
|
+
if (shouldSendBearer2(fullUrl)) {
|
|
7110
7185
|
headers.Authorization = `Bearer ${token3}`;
|
|
7111
7186
|
}
|
|
7112
7187
|
const res = await request6(fullUrl, {
|
|
@@ -8139,7 +8214,8 @@ function pruneJson(value) {
|
|
|
8139
8214
|
}
|
|
8140
8215
|
|
|
8141
8216
|
// src/read-tool.ts
|
|
8142
|
-
function normalizeToolName(namespace, raw) {
|
|
8217
|
+
function normalizeToolName(namespace, raw, tools) {
|
|
8218
|
+
if (tools?.some((t) => t.name === raw)) return raw;
|
|
8143
8219
|
const prefix = `${namespace}_`;
|
|
8144
8220
|
if (raw.startsWith(prefix) && raw.length > prefix.length) return raw.slice(prefix.length);
|
|
8145
8221
|
return raw;
|
|
@@ -9208,7 +9284,7 @@ function categorizeSpawnError(err) {
|
|
|
9208
9284
|
}
|
|
9209
9285
|
async function connectToUpstream(config, onDisconnect, onListChanged) {
|
|
9210
9286
|
const client = new Client(
|
|
9211
|
-
{ name: "yaw-mcp", version: true ? "0.64.
|
|
9287
|
+
{ name: "yaw-mcp", version: true ? "0.64.2" : "dev" },
|
|
9212
9288
|
{ capabilities: {} }
|
|
9213
9289
|
);
|
|
9214
9290
|
let transport;
|
|
@@ -9279,7 +9355,7 @@ async function connectToUpstream(config, onDisconnect, onListChanged) {
|
|
|
9279
9355
|
message = `Server "${config.namespace}" started but didn't complete the MCP handshake within ${connectTimeoutMs / 1e3}s.${trimmedStderr ? ` stderr tail: ${redactSecretsInOutput(trimmedStderr, resolvedServerEnv).slice(-500)}` : ""}`;
|
|
9280
9356
|
} else if (trimmedStderr.length > 0) {
|
|
9281
9357
|
category = "install_failure";
|
|
9282
|
-
const safe = redactSecretsInOutput(trimmedStderr,
|
|
9358
|
+
const safe = redactSecretsInOutput(trimmedStderr, resolvedServerEnv);
|
|
9283
9359
|
message = `Server "${config.namespace}" failed to start. stderr: ${safe.slice(-500)}`;
|
|
9284
9360
|
} else {
|
|
9285
9361
|
category = categorizeSpawnError(err);
|
|
@@ -9292,7 +9368,7 @@ async function connectToUpstream(config, onDisconnect, onListChanged) {
|
|
|
9292
9368
|
if (config.id) {
|
|
9293
9369
|
message = `${message} \u2192 Edit at https://yaw.sh/mcp/dashboard/connect#server-${config.id}`;
|
|
9294
9370
|
}
|
|
9295
|
-
const redactedTail = trimmedStderr ? redactSecretsInOutput(trimmedStderr,
|
|
9371
|
+
const redactedTail = trimmedStderr ? redactSecretsInOutput(trimmedStderr, resolvedServerEnv) : void 0;
|
|
9296
9372
|
throw new ActivationError(message, category, redactedTail, err);
|
|
9297
9373
|
}
|
|
9298
9374
|
log("info", "Connected to upstream", { name: config.name, namespace: config.namespace, type: config.type });
|
|
@@ -9540,7 +9616,7 @@ var ConnectServer = class _ConnectServer {
|
|
|
9540
9616
|
this.apiUrl = apiUrl5;
|
|
9541
9617
|
this.token = token5;
|
|
9542
9618
|
this.server = new Server(
|
|
9543
|
-
{ name: "yaw-mcp", version: true ? "0.64.
|
|
9619
|
+
{ name: "yaw-mcp", version: true ? "0.64.2" : "dev" },
|
|
9544
9620
|
{
|
|
9545
9621
|
capabilities: {
|
|
9546
9622
|
tools: { listChanged: true },
|
|
@@ -11471,9 +11547,9 @@ Use mcp_connect_discover to see imported servers.`
|
|
|
11471
11547
|
isError: true
|
|
11472
11548
|
};
|
|
11473
11549
|
}
|
|
11474
|
-
const toolName = normalizeToolName(serverArg, toolArg);
|
|
11475
11550
|
const existing = this.connections.get(serverArg);
|
|
11476
11551
|
if (existing && existing.status === "connected") {
|
|
11552
|
+
const toolName = normalizeToolName(serverArg, toolArg, existing.tools);
|
|
11477
11553
|
const tool = findTool(existing.tools, toolName);
|
|
11478
11554
|
if (!tool) {
|
|
11479
11555
|
return {
|
|
@@ -11509,6 +11585,7 @@ Use mcp_connect_discover to see imported servers.`
|
|
|
11509
11585
|
};
|
|
11510
11586
|
}
|
|
11511
11587
|
try {
|
|
11588
|
+
const toolName = normalizeToolName(serverArg, toolArg, transient.tools);
|
|
11512
11589
|
const tool = findTool(transient.tools, toolName);
|
|
11513
11590
|
if (!tool) {
|
|
11514
11591
|
return {
|
|
@@ -11974,9 +12051,10 @@ async function runServersCommand(opts = {}) {
|
|
|
11974
12051
|
printErr("yaw-mcp servers: backend returned no data (unexpected 304).");
|
|
11975
12052
|
return { exitCode: 2, lines };
|
|
11976
12053
|
}
|
|
11977
|
-
const
|
|
12054
|
+
const filterStr = opts.filter;
|
|
12055
|
+
const filtered = filterStr !== void 0 ? {
|
|
11978
12056
|
...backend,
|
|
11979
|
-
servers: backend.servers.filter((s) => s.namespace.toLowerCase().includes(
|
|
12057
|
+
servers: backend.servers.filter((s) => s.namespace.toLowerCase().includes(filterStr.toLowerCase()))
|
|
11980
12058
|
} : backend;
|
|
11981
12059
|
const gradesReader = opts.gradesReader ?? readGradesCache;
|
|
11982
12060
|
const grades = await gradesReader(opts.home).catch(() => ({}));
|
|
@@ -11991,12 +12069,12 @@ async function runServersCommand(opts = {}) {
|
|
|
11991
12069
|
const payload = {
|
|
11992
12070
|
...merged,
|
|
11993
12071
|
filter: opts.filter ?? null,
|
|
11994
|
-
filterMatched: opts.filter ? merged.servers.length > 0 : null
|
|
12072
|
+
filterMatched: opts.filter !== void 0 ? merged.servers.length > 0 : null
|
|
11995
12073
|
};
|
|
11996
12074
|
print(JSON.stringify(payload, null, 2));
|
|
11997
12075
|
return { exitCode: 0, lines };
|
|
11998
12076
|
}
|
|
11999
|
-
if (opts.filter && filtered.servers.length === 0) {
|
|
12077
|
+
if (opts.filter !== void 0 && filtered.servers.length === 0) {
|
|
12000
12078
|
print(`No servers match "${opts.filter}". Run \`yaw-mcp servers\` to see the full list.`);
|
|
12001
12079
|
return { exitCode: 0, lines };
|
|
12002
12080
|
}
|
|
@@ -12166,6 +12244,11 @@ async function runSetActive(opts, io = { out: (s) => process.stdout.write(s), er
|
|
|
12166
12244
|
mcp_bundles: { lastPulledVersion: putRes.version }
|
|
12167
12245
|
}).catch(() => {
|
|
12168
12246
|
});
|
|
12247
|
+
} else {
|
|
12248
|
+
io.err(
|
|
12249
|
+
`yaw-mcp set-active: putRes.version was not a number (got ${JSON.stringify(putRes.version)}); local sync-state not updated
|
|
12250
|
+
`
|
|
12251
|
+
);
|
|
12169
12252
|
}
|
|
12170
12253
|
return done(io, opts.json, namespace, active, true);
|
|
12171
12254
|
} catch (e) {
|
|
@@ -12416,7 +12499,15 @@ function suggestSubcommand(input, limit = 3) {
|
|
|
12416
12499
|
}
|
|
12417
12500
|
function suggestFlag(input, limit = 2) {
|
|
12418
12501
|
if (input.length <= 2) return [];
|
|
12419
|
-
|
|
12502
|
+
const q = input.toLowerCase();
|
|
12503
|
+
const hits = [];
|
|
12504
|
+
for (const alias of FLAG_ALIASES) {
|
|
12505
|
+
if (alias.toLowerCase() === q) continue;
|
|
12506
|
+
const d = levenshtein(q, alias.toLowerCase());
|
|
12507
|
+
if (d <= 2) hits.push({ name: alias, d });
|
|
12508
|
+
}
|
|
12509
|
+
hits.sort((a, b) => a.d - b.d || a.name.localeCompare(b.name));
|
|
12510
|
+
return hits.slice(0, limit).map((h) => h.name);
|
|
12420
12511
|
}
|
|
12421
12512
|
|
|
12422
12513
|
// src/sync-cmd.ts
|
|
@@ -12685,10 +12776,11 @@ function handleSyncError(err, opts, io) {
|
|
|
12685
12776
|
return { exitCode: 1 };
|
|
12686
12777
|
}
|
|
12687
12778
|
if (err instanceof TeamSyncAuthError) {
|
|
12688
|
-
|
|
12689
|
-
|
|
12779
|
+
const authMsg = "Session expired or revoked. Run `yaw-mcp login --key <license-key>` again.";
|
|
12780
|
+
if (opts.json) io.err(`${JSON.stringify({ ok: false, error: authMsg })}
|
|
12781
|
+
`);
|
|
12782
|
+
else io.err(`yaw-mcp sync: ${authMsg}
|
|
12690
12783
|
`);
|
|
12691
|
-
else io.err("yaw-mcp sync: session expired or revoked. Run `yaw-mcp login --key <license-key>` again.\n");
|
|
12692
12784
|
return { exitCode: 1 };
|
|
12693
12785
|
}
|
|
12694
12786
|
if (err instanceof TeamSyncForbiddenError) {
|
|
@@ -13100,7 +13192,7 @@ if (subcommand === "compliance") {
|
|
|
13100
13192
|
`);
|
|
13101
13193
|
process.exit(0);
|
|
13102
13194
|
} else if (subcommand === "--version" || subcommand === "-V") {
|
|
13103
|
-
process.stdout.write(`yaw-mcp ${true ? "0.64.
|
|
13195
|
+
process.stdout.write(`yaw-mcp ${true ? "0.64.2" : "dev"}
|
|
13104
13196
|
`);
|
|
13105
13197
|
process.exit(0);
|
|
13106
13198
|
} else if (subcommand && !subcommand.startsWith("-")) {
|
package/package.json
CHANGED