@mgsoftwarebv/mg-dashboard-mcp 6.0.0 → 6.0.1

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 CHANGED
@@ -1121,6 +1121,7 @@ async function handleVercelTool(name, args2, deps) {
1121
1121
  sinceExplicit ? Promise.resolve(null) : getDeploymentCreatedMs(token, deploymentId)
1122
1122
  ]);
1123
1123
  const maxWindowMin = 7 * 24 * 60;
1124
+ const autoCapMin = 30;
1124
1125
  let sinceMs;
1125
1126
  let windowNote = "";
1126
1127
  if (sinceExplicit) {
@@ -1129,17 +1130,18 @@ async function handleVercelTool(name, args2, deps) {
1129
1130
  windowNote = `window: last ${capped} min (caller-specified)`;
1130
1131
  } else if (deploymentCreatedMs) {
1131
1132
  const bufferMs = 5 * 6e4;
1132
- sinceMs = deploymentCreatedMs - bufferMs;
1133
- const ageMin = Math.max(1, Math.round((Date.now() - sinceMs) / 6e4));
1134
- if (ageMin > maxWindowMin) {
1135
- sinceMs = Date.now() - maxWindowMin * 6e4;
1136
- windowNote = `window: capped to ${maxWindowMin} min (deployment is older than 7 days)`;
1137
- } else {
1133
+ const sinceDeploymentMs = deploymentCreatedMs - bufferMs;
1134
+ const ageMin = Math.max(1, Math.round((Date.now() - sinceDeploymentMs) / 6e4));
1135
+ if (ageMin <= autoCapMin) {
1136
+ sinceMs = sinceDeploymentMs;
1138
1137
  windowNote = `window: auto ${ageMin} min from deployment createdAt - 5 min buffer`;
1138
+ } else {
1139
+ sinceMs = Date.now() - autoCapMin * 6e4;
1140
+ windowNote = `window: capped to last ${autoCapMin} min (deployment is ${ageMin} min old \u2014 pass sinceMinutes to widen up to ${maxWindowMin})`;
1139
1141
  }
1140
1142
  } else {
1141
- sinceMs = Date.now() - 60 * 6e4;
1142
- windowNote = "window: last 60 min (deployment metadata unavailable, used fallback)";
1143
+ sinceMs = Date.now() - autoCapMin * 6e4;
1144
+ windowNote = `window: last ${autoCapMin} min (deployment metadata unavailable, used fallback)`;
1143
1145
  }
1144
1146
  const { logs, error } = await getRuntimeLogs(
1145
1147
  token,
@@ -1152,10 +1154,15 @@ async function handleVercelTool(name, args2, deps) {
1152
1154
  const hint = error.includes("404") || error.includes("400") ? '\n\nThis endpoint requires both project ID and deployment ID and may not be available on every Vercel plan. Use kind="webhooks" or the supabase MCP (vercel_deployment_log table) for archived runtime logs.' : "";
1153
1155
  return { content: [{ type: "text", text: `Error: ${error}${hint}` }] };
1154
1156
  }
1155
- const text = `${formatRuntimeLogs(logs)}
1157
+ const body = formatRuntimeLogs(logs);
1158
+ const hitDurationLimit = /Exceeded query duration limit/i.test(body);
1159
+ const footer = hitDurationLimit ? `
1160
+
1161
+ [${windowNote}]
1162
+ [hint] Vercel hit its 5-min query budget for this window. Try a smaller sinceMinutes (e.g. 5-10), lower limit, or use kind="webhooks" / the supabase MCP vercel_deployment_log table for archived logs.` : `
1156
1163
 
1157
1164
  [${windowNote}]`;
1158
- return { content: [{ type: "text", text }] };
1165
+ return { content: [{ type: "text", text: body + footer }] };
1159
1166
  }
1160
1167
  if (kind === "webhooks") {
1161
1168
  const limit = Math.min(Math.max(Number(args2.limit) || 25, 1), 200);
@@ -3386,7 +3393,10 @@ function formatDbQueryFooter(output, appliedLimit, maxRows, explainMode) {
3386
3393
  return "\n\n[explain] Plan returned, no rows executed.";
3387
3394
  }
3388
3395
  if (!appliedLimit) return "";
3389
- const rows = output.split("\n").filter((l) => l.trim() && !/^\s*[-+|]/.test(l)).length;
3396
+ const rows = parseRowCountFromOutput(output);
3397
+ if (rows == null) return `
3398
+
3399
+ [ok] auto-LIMIT ${maxRows} applied (row count not detected).`;
3390
3400
  if (rows > maxRows) {
3391
3401
  return `
3392
3402
 
@@ -3396,6 +3406,21 @@ function formatDbQueryFooter(output, appliedLimit, maxRows, explainMode) {
3396
3406
 
3397
3407
  [ok] returned ${rows} row(s), under auto-LIMIT ${maxRows}.`;
3398
3408
  }
3409
+ function parseRowCountFromOutput(output) {
3410
+ const lines = output.split("\n");
3411
+ for (let i = lines.length - 1; i >= 0; i--) {
3412
+ const l = lines[i]?.trim();
3413
+ if (!l) continue;
3414
+ const m1 = /^\(\s*(\d+)\s+rows?\s*\)$/i.exec(l);
3415
+ if (m1?.[1]) return Number(m1[1]);
3416
+ const m2 = /^(\d+)\s+rows?\s+in\s+set\b/i.exec(l);
3417
+ if (m2?.[1]) return Number(m2[1]);
3418
+ const m3 = /^\(\s*(\d+)\s+rows?\s+affected\s*\)$/i.exec(l);
3419
+ if (m3?.[1]) return Number(m3[1]);
3420
+ if (/[a-zA-Z0-9]/.test(l) && i < lines.length - 3) return null;
3421
+ }
3422
+ return null;
3423
+ }
3399
3424
  function assertSafeSql(query) {
3400
3425
  const trimmed = query.trim();
3401
3426
  for (const pattern of BLOCKED_SQL_PATTERNS) {
@@ -3810,7 +3835,7 @@ var TOOLS = [
3810
3835
  // ----- Domains (mijn.host) -----
3811
3836
  {
3812
3837
  name: "domain-list",
3813
- description: "List all domains from the mijn.host account. Returns domain name, status, renewal date (= expiration), and tags. Requires MIJNHOST_API_KEY.\n\nPass `details: true` to also fetch DNS zone summary per domain in parallel: NS records, MX target, and presence of SPF/DMARC. Useful as a single-call overview instead of N follow-up dns-list calls. Skipped for inactive/expired domains.",
3838
+ description: "List all domains from the mijn.host account. Returns domain name, status, renewal date (= expiration), and tags. Requires MIJNHOST_API_KEY.\n\nPass `details: true` to also fetch DNS zone summary per domain in parallel: MX target(s) and presence of SPF/DMARC TXT records. Useful as a single-call overview instead of N follow-up dns-list calls. Skipped for inactive/expired domains.",
3814
3839
  inputSchema: {
3815
3840
  type: "object",
3816
3841
  properties: {
@@ -3855,7 +3880,7 @@ var TOOLS = [
3855
3880
  // ----- Vercel -----
3856
3881
  ...VERCEL_TOOLS
3857
3882
  ];
3858
- var MCP_VERSION = "6.0.0";
3883
+ var MCP_VERSION = "6.0.1";
3859
3884
  async function handleListTools() {
3860
3885
  if (!authContext) return { tools: TOOLS };
3861
3886
  const accessible = TOOLS.filter((tool) => {
@@ -5107,15 +5132,14 @@ ${lines2.join("\n")}` }] };
5107
5132
  `/domains/${encodeURIComponent(domain)}/dns`
5108
5133
  );
5109
5134
  const recs = r.data.records || [];
5110
- const ns = recs.filter((x) => x.type === "NS").map((x) => x.value).sort();
5111
5135
  const mx = recs.filter((x) => x.type === "MX").map((x) => x.value).sort();
5112
5136
  const hasSpf = recs.some((x) => x.type === "TXT" && x.value.toLowerCase().includes("v=spf1"));
5113
5137
  const hasDmarc = recs.some(
5114
5138
  (x) => x.type === "TXT" && (x.name.toLowerCase().startsWith("_dmarc") || x.value.toLowerCase().includes("v=dmarc1"))
5115
5139
  );
5116
- return { ns, mx, hasSpf, hasDmarc };
5140
+ return { mx, hasSpf, hasDmarc };
5117
5141
  } catch (err) {
5118
- return { ns: [], mx: [], hasSpf: false, hasDmarc: false, error: err instanceof Error ? err.message : String(err) };
5142
+ return { mx: [], hasSpf: false, hasDmarc: false, error: err instanceof Error ? err.message : String(err) };
5119
5143
  }
5120
5144
  }
5121
5145
  const queue = [...activeDomains];
@@ -5134,12 +5158,9 @@ ${lines2.join("\n")}` }] };
5134
5158
  if (!s) return head;
5135
5159
  if (s.error) return `${head}
5136
5160
  dns: error: ${s.error}`;
5137
- const ns = s.ns.length ? s.ns.join(", ") : "(none)";
5138
5161
  const mx = s.mx.length ? s.mx.join(", ") : "(none)";
5139
- const mail = `mx=${mx} spf=${s.hasSpf ? "yes" : "NO"} dmarc=${s.hasDmarc ? "yes" : "NO"}`;
5140
5162
  return `${head}
5141
- ns: ${ns}
5142
- ${mail}`;
5163
+ mx=${mx} spf=${s.hasSpf ? "yes" : "NO"} dmarc=${s.hasDmarc ? "yes" : "NO"}`;
5143
5164
  });
5144
5165
  return {
5145
5166
  content: [{