metheus-governance-mcp-cli 0.2.36 → 0.2.37

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/cli.mjs +95 -1
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -3491,6 +3491,83 @@ function ensureArray(value) {
3491
3491
  return Array.isArray(value) ? value : [];
3492
3492
  }
3493
3493
 
3494
+ function normalizeSafeToolAliasName(rawName) {
3495
+ const base = String(rawName || "")
3496
+ .trim()
3497
+ .replace(/[^a-zA-Z0-9_]/g, "_")
3498
+ .replace(/_+/g, "_")
3499
+ .replace(/^_+|_+$/g, "");
3500
+ if (!base) return "";
3501
+ if (/^[0-9]/.test(base)) return `tool_${base}`;
3502
+ return base;
3503
+ }
3504
+
3505
+ function buildToolAliasMaps(tools) {
3506
+ const canonicalNames = new Set(
3507
+ ensureArray(tools)
3508
+ .map((tool) => String(tool?.name || "").trim())
3509
+ .filter(Boolean),
3510
+ );
3511
+ const aliasToCanonical = new Map();
3512
+ const canonicalToAlias = new Map();
3513
+ const reserved = new Set(canonicalNames);
3514
+
3515
+ for (const canonicalName of canonicalNames) {
3516
+ const aliasBase = normalizeSafeToolAliasName(canonicalName);
3517
+ if (!aliasBase || aliasBase === canonicalName) continue;
3518
+ let alias = aliasBase;
3519
+ let counter = 2;
3520
+ while (reserved.has(alias) || aliasToCanonical.has(alias)) {
3521
+ alias = `${aliasBase}_${counter}`;
3522
+ counter += 1;
3523
+ }
3524
+ aliasToCanonical.set(alias, canonicalName);
3525
+ canonicalToAlias.set(canonicalName, alias);
3526
+ reserved.add(alias);
3527
+ }
3528
+ return { aliasToCanonical, canonicalToAlias };
3529
+ }
3530
+
3531
+ function applyToolAliasesToToolsListResponse(responseObj, canonicalToAlias) {
3532
+ const result = safeObject(responseObj.result);
3533
+ const tools = ensureArray(result.tools);
3534
+ result.tools = tools.map((tool) => {
3535
+ const safeTool = safeObject(tool);
3536
+ const currentName = String(safeTool.name || "").trim();
3537
+ const aliasName = canonicalToAlias.get(currentName);
3538
+ if (!aliasName) return safeTool;
3539
+ return { ...safeTool, name: aliasName };
3540
+ });
3541
+ responseObj.result = result;
3542
+ return responseObj;
3543
+ }
3544
+
3545
+ function rewriteAliasedToolCallToCanonical(requestObj, aliasToCanonical) {
3546
+ if (!isJsonRpcMethod(requestObj, "tools/call")) return requestObj;
3547
+ const params = safeObject(requestObj.params);
3548
+ const currentName = String(params.name ?? params.tool_name ?? params.toolName ?? "").trim();
3549
+ if (!currentName) return requestObj;
3550
+ const canonicalName = String(aliasToCanonical.get(currentName) || "").trim();
3551
+ if (!canonicalName) return requestObj;
3552
+
3553
+ const nextParams = { ...params, name: canonicalName };
3554
+ if (Object.prototype.hasOwnProperty.call(nextParams, "tool_name")) {
3555
+ nextParams.tool_name = canonicalName;
3556
+ }
3557
+ if (Object.prototype.hasOwnProperty.call(nextParams, "toolName")) {
3558
+ nextParams.toolName = canonicalName;
3559
+ }
3560
+ return { ...requestObj, params: nextParams };
3561
+ }
3562
+
3563
+ function shouldUseSafeToolAliasesForClient(initParamsRaw) {
3564
+ const initParams = safeObject(initParamsRaw);
3565
+ const clientInfo = safeObject(initParams.clientInfo);
3566
+ const name = String(clientInfo.name || "").trim().toLowerCase();
3567
+ if (!name) return false;
3568
+ return name.includes("cursor") || name.includes("antigravity");
3569
+ }
3570
+
3494
3571
  function injectWorkspaceDirIntoToolSchemas(tools) {
3495
3572
  const workspaceDirProp = {
3496
3573
  type: "string",
@@ -4044,6 +4121,9 @@ async function runProxy(flags) {
4044
4121
  let lastRefreshError = "";
4045
4122
  let sessionWorkspaceDir = "";
4046
4123
  let sessionWorkspaceTrusted = false;
4124
+ let sessionUseSafeToolAliases = false;
4125
+ let sessionToolAliasToCanonical = new Map();
4126
+ let sessionToolCanonicalToAlias = new Map();
4047
4127
 
4048
4128
  // Proxy-initiated requests (e.g., roots/list) pending client responses.
4049
4129
  const pendingProxyRequests = new Map(); // id → callback(responseObj)
@@ -4122,7 +4202,7 @@ async function runProxy(flags) {
4122
4202
  const line = String(lineRaw || "").trim();
4123
4203
  if (!line) return;
4124
4204
 
4125
- const requestObj = tryJsonParse(line);
4205
+ let requestObj = tryJsonParse(line);
4126
4206
  if (requestObj == null) {
4127
4207
  writeProxyJson(jsonRpcError(null, -32700, "parse error"));
4128
4208
  return;
@@ -4175,6 +4255,13 @@ async function runProxy(flags) {
4175
4255
  return;
4176
4256
  }
4177
4257
 
4258
+ if (isJsonRpcMethod(requestObj, "initialize") && shouldUseSafeToolAliasesForClient(requestObj?.params)) {
4259
+ sessionUseSafeToolAliases = true;
4260
+ }
4261
+ if (sessionUseSafeToolAliases) {
4262
+ requestObj = rewriteAliasedToolCallToCanonical(requestObj, sessionToolAliasToCanonical);
4263
+ }
4264
+
4178
4265
  const { name: toolName, args: toolArgs } = extractToolCall(requestObj);
4179
4266
  let strongRequestWorkspaceCandidate = "";
4180
4267
  let weakRequestWorkspaceCandidate = "";
@@ -4430,6 +4517,13 @@ async function runProxy(flags) {
4430
4517
  }
4431
4518
  if (isJsonRpcMethod(requestObj, "tools/list")) {
4432
4519
  patched = appendLocalToolToToolsList(patched);
4520
+ if (sessionUseSafeToolAliases) {
4521
+ const tools = ensureArray(safeObject(patched.result).tools);
4522
+ const aliasMaps = buildToolAliasMaps(tools);
4523
+ sessionToolAliasToCanonical = aliasMaps.aliasToCanonical;
4524
+ sessionToolCanonicalToAlias = aliasMaps.canonicalToAlias;
4525
+ patched = applyToolAliasesToToolsListResponse(patched, sessionToolCanonicalToAlias);
4526
+ }
4433
4527
  } else if (isJsonRpcMethod(requestObj, "initialize")) {
4434
4528
  patched = appendProjectHintToInitialize(patched, args);
4435
4529
  // Log initialize params for workspace debugging.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.36",
3
+ "version": "0.2.37",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [