@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 +41 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
1133
|
-
const ageMin = Math.max(1, Math.round((Date.now() -
|
|
1134
|
-
if (ageMin
|
|
1135
|
-
sinceMs =
|
|
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() -
|
|
1142
|
-
windowNote =
|
|
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
|
|
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
|
|
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:
|
|
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.
|
|
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 {
|
|
5140
|
+
return { mx, hasSpf, hasDmarc };
|
|
5117
5141
|
} catch (err) {
|
|
5118
|
-
return {
|
|
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
|
-
|
|
5142
|
-
${mail}`;
|
|
5163
|
+
mx=${mx} spf=${s.hasSpf ? "yes" : "NO"} dmarc=${s.hasDmarc ? "yes" : "NO"}`;
|
|
5143
5164
|
});
|
|
5144
5165
|
return {
|
|
5145
5166
|
content: [{
|