@mgsoftwarebv/mg-dashboard-mcp 2.2.1 → 2.2.3
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 +57 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,11 +16,14 @@ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
|
16
16
|
"INTERRUPTED",
|
|
17
17
|
"EXPIRED"
|
|
18
18
|
]);
|
|
19
|
-
var
|
|
19
|
+
var TRIGGER_SERVER_ID = "03659d55-e194-400d-b82a-bf6457371ded";
|
|
20
|
+
var COMPOSE_PROJECT = "mg-dashboard-supabase-trigger";
|
|
21
|
+
var PG_CONTAINER = `${COMPOSE_PROJECT}-postgres-1`;
|
|
22
|
+
var WA_CONTAINER = `${COMPOSE_PROJECT}-webapp-1`;
|
|
20
23
|
var TRIGGER_TOOLS = [
|
|
21
24
|
{
|
|
22
25
|
name: "trigger-list",
|
|
23
|
-
description:
|
|
26
|
+
description: 'List all Trigger.dev projects. Returns the project slug and name. Use the slug as the "project" parameter in other trigger-* tools.',
|
|
24
27
|
inputSchema: {
|
|
25
28
|
type: "object",
|
|
26
29
|
properties: {}
|
|
@@ -32,7 +35,7 @@ var TRIGGER_TOOLS = [
|
|
|
32
35
|
inputSchema: {
|
|
33
36
|
type: "object",
|
|
34
37
|
properties: {
|
|
35
|
-
project: { type: "string", description:
|
|
38
|
+
project: { type: "string", description: 'Project slug from trigger-list (e.g. "mg-dashboard-bHfS")' },
|
|
36
39
|
status: {
|
|
37
40
|
type: "string",
|
|
38
41
|
description: "Comma-separated status filter: QUEUED,EXECUTING,COMPLETED,FAILED,CRASHED,CANCELED,SYSTEM_FAILURE"
|
|
@@ -49,7 +52,7 @@ var TRIGGER_TOOLS = [
|
|
|
49
52
|
inputSchema: {
|
|
50
53
|
type: "object",
|
|
51
54
|
properties: {
|
|
52
|
-
project: { type: "string", description: "
|
|
55
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
53
56
|
runId: { type: "string", description: "Run ID (e.g. run_xxxxx)" }
|
|
54
57
|
},
|
|
55
58
|
required: ["project", "runId"]
|
|
@@ -61,7 +64,7 @@ var TRIGGER_TOOLS = [
|
|
|
61
64
|
inputSchema: {
|
|
62
65
|
type: "object",
|
|
63
66
|
properties: {
|
|
64
|
-
project: { type: "string", description: "
|
|
67
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
65
68
|
taskId: { type: "string", description: 'Task identifier (e.g. "hello-world", "execute-pipeline")' },
|
|
66
69
|
payload: { type: "string", description: "JSON payload string to pass to the task (optional)" },
|
|
67
70
|
waitSeconds: { type: "number", description: "Max seconds to wait for completion (default 60, max 300)" }
|
|
@@ -75,7 +78,7 @@ var TRIGGER_TOOLS = [
|
|
|
75
78
|
inputSchema: {
|
|
76
79
|
type: "object",
|
|
77
80
|
properties: {
|
|
78
|
-
project: { type: "string", description: "
|
|
81
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
79
82
|
runId: { type: "string", description: "Run ID to cancel (e.g. run_xxxxx)" }
|
|
80
83
|
},
|
|
81
84
|
required: ["project", "runId"]
|
|
@@ -87,7 +90,7 @@ var TRIGGER_TOOLS = [
|
|
|
87
90
|
inputSchema: {
|
|
88
91
|
type: "object",
|
|
89
92
|
properties: {
|
|
90
|
-
project: { type: "string", description: "
|
|
93
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
91
94
|
runId: { type: "string", description: "Run ID to replay (e.g. run_xxxxx)" }
|
|
92
95
|
},
|
|
93
96
|
required: ["project", "runId"]
|
|
@@ -103,12 +106,11 @@ var TRIGGER_TOOL_MODULE_MAP = {
|
|
|
103
106
|
"trigger-cancel-run": "ci_cd",
|
|
104
107
|
"trigger-replay-run": "ci_cd"
|
|
105
108
|
};
|
|
106
|
-
async function discoverInstance(
|
|
107
|
-
const
|
|
108
|
-
const wa = `${project}-webapp-1`;
|
|
109
|
+
async function discoverInstance(projectSlug, conn, proxy, sshExec2) {
|
|
110
|
+
const sql = `SELECT re.\\"apiKey\\" FROM \\"RuntimeEnvironment\\" re JOIN \\"Project\\" p ON re.\\"projectId\\" = p.id WHERE p.slug='${projectSlug}' AND re.slug='prod' LIMIT 1`;
|
|
109
111
|
const cmd = [
|
|
110
|
-
`PORT=$(docker port "${
|
|
111
|
-
`KEY=$(docker exec "${
|
|
112
|
+
`PORT=$(docker port "${WA_CONTAINER}" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,
|
|
113
|
+
`KEY=$(docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql}" 2>/dev/null | tr -d '[:space:]')`,
|
|
112
114
|
'echo "$PORT|$KEY"'
|
|
113
115
|
].join(" && ");
|
|
114
116
|
const result = await sshExec2(conn, cmd, proxy);
|
|
@@ -118,18 +120,35 @@ async function discoverInstance(project, conn, proxy, sshExec2) {
|
|
|
118
120
|
const apiKey2 = sepIdx > 0 ? output.substring(sepIdx + 1) : "";
|
|
119
121
|
if (!port) {
|
|
120
122
|
throw new Error(
|
|
121
|
-
`Could not find webapp port for ${
|
|
123
|
+
`Could not find webapp port for ${WA_CONTAINER}. Is the container running?`
|
|
122
124
|
);
|
|
123
125
|
}
|
|
124
126
|
if (!apiKey2) {
|
|
125
127
|
throw new Error(
|
|
126
|
-
`Could not get API key
|
|
128
|
+
`Could not get API key for project "${projectSlug}". Check if the project slug is correct (use trigger-list).`
|
|
127
129
|
);
|
|
128
130
|
}
|
|
129
131
|
return { port, apiKey: apiKey2 };
|
|
130
132
|
}
|
|
133
|
+
async function fetchRunLogs(runId, conn, proxy, sshExec2) {
|
|
134
|
+
const sql = `SELECT level, message, \\"isError\\", \\"createdAt\\" FROM \\"TaskEvent\\" WHERE \\"runId\\" = '${runId}' AND level IN ('INFO','WARN','ERROR','DEBUG','LOG','TRACE') ORDER BY \\"startTime\\" ASC LIMIT 200`;
|
|
135
|
+
const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql}" 2>/dev/null`;
|
|
136
|
+
const result = await sshExec2(conn, cmd, proxy);
|
|
137
|
+
const output = result.stdout.trim();
|
|
138
|
+
if (!output) return "";
|
|
139
|
+
return output.split("\n").map((line) => {
|
|
140
|
+
const parts = line.split("|");
|
|
141
|
+
const level = (parts[0] || "").padEnd(5);
|
|
142
|
+
const message = parts[1] || "";
|
|
143
|
+
const isError = parts[2] === "t";
|
|
144
|
+
const ts = parts[3] || "";
|
|
145
|
+
const time = ts ? ts.split(" ")[1]?.substring(0, 8) || "" : "";
|
|
146
|
+
const prefix = isError ? "!" : " ";
|
|
147
|
+
return `${prefix}${time} [${level}] ${message}`;
|
|
148
|
+
}).join("\n");
|
|
149
|
+
}
|
|
131
150
|
async function triggerApi(conn, proxy, sshExec2, instance, method, path, body) {
|
|
132
|
-
const parts = ["curl", "-s", "--max-time", "30"];
|
|
151
|
+
const parts = ["curl", "-s", "-g", "--max-time", "30"];
|
|
133
152
|
if (method !== "GET") parts.push("-X", method);
|
|
134
153
|
parts.push(`"http://localhost:${instance.port}${path}"`);
|
|
135
154
|
parts.push(`-H "Authorization: Bearer ${instance.apiKey}"`);
|
|
@@ -191,35 +210,22 @@ function formatRunDetail(run) {
|
|
|
191
210
|
}
|
|
192
211
|
async function handleTriggerTool(name, args2, deps) {
|
|
193
212
|
const { sshExec: sshExec2, getServerConnection: getServerConnection2 } = deps;
|
|
194
|
-
const
|
|
213
|
+
const { conn, proxy } = await getServerConnection2(TRIGGER_SERVER_ID);
|
|
195
214
|
switch (name) {
|
|
196
215
|
// -----------------------------------------------------------------
|
|
197
216
|
case "trigger-list": {
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
"for PG in $(docker ps --format '{{.Names}}' | grep -E 'trigger.*-postgres-[0-9]+$'); do",
|
|
202
|
-
` PROJECT=$(echo "$PG" | sed 's/-postgres-[0-9]*$//')`,
|
|
203
|
-
' WA="${PROJECT}-webapp-1"',
|
|
204
|
-
` PORT=$(docker port "$WA" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,
|
|
205
|
-
` STATUS=$(docker inspect -f '{{.State.Status}}' "$WA" 2>/dev/null || echo 'not_found')`,
|
|
206
|
-
` RUNNING=$(docker ps --filter "label=com.docker.compose.project=\${PROJECT}" --format '{{.Names}}' 2>/dev/null | wc -l)`,
|
|
207
|
-
` TOTAL=$(docker ps -a --filter "label=com.docker.compose.project=\${PROJECT}" --format '{{.Names}}' 2>/dev/null | wc -l)`,
|
|
208
|
-
' echo "${PROJECT}|${PORT:-?}|${STATUS}|${RUNNING}/${TOTAL}"',
|
|
209
|
-
" FOUND=1",
|
|
210
|
-
"done",
|
|
211
|
-
'[ "$FOUND" = "0" ] && echo "NO_INSTANCES"'
|
|
212
|
-
].join("\n");
|
|
213
|
-
const result = await sshExec2(conn, script, proxy);
|
|
217
|
+
const sql = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
|
|
218
|
+
const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql}" 2>/dev/null`;
|
|
219
|
+
const result = await sshExec2(conn, cmd, proxy);
|
|
214
220
|
const output = result.stdout.trim();
|
|
215
|
-
if (!output
|
|
216
|
-
return { content: [{ type: "text", text: "No Trigger.dev
|
|
221
|
+
if (!output) {
|
|
222
|
+
return { content: [{ type: "text", text: "No Trigger.dev projects found." }] };
|
|
217
223
|
}
|
|
218
|
-
const header = `${"
|
|
219
|
-
const sep = "-".repeat(
|
|
224
|
+
const header = `${"SLUG".padEnd(25)} NAME`;
|
|
225
|
+
const sep = "-".repeat(55);
|
|
220
226
|
const lines = output.split("\n").map((line) => {
|
|
221
|
-
const [
|
|
222
|
-
return `${(
|
|
227
|
+
const [slug, name2] = line.split("|");
|
|
228
|
+
return `${(slug || "").padEnd(25)} ${name2 || ""}`;
|
|
223
229
|
});
|
|
224
230
|
return { content: [{ type: "text", text: `${header}
|
|
225
231
|
${sep}
|
|
@@ -228,12 +234,11 @@ ${lines.join("\n")}` }] };
|
|
|
228
234
|
// -----------------------------------------------------------------
|
|
229
235
|
case "trigger-runs": {
|
|
230
236
|
const project = String(args2.project);
|
|
231
|
-
const { conn, proxy } = await getServerConnection2(serverId);
|
|
232
237
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
233
238
|
const limit = Math.min(Math.max(Number(args2.limit) || 20, 1), 100);
|
|
234
|
-
const queryParts = [`page
|
|
235
|
-
if (args2.status) queryParts.push(`filter
|
|
236
|
-
if (args2.taskIdentifier) queryParts.push(`filter
|
|
239
|
+
const queryParts = [`page%5Bsize%5D=${limit}`];
|
|
240
|
+
if (args2.status) queryParts.push(`filter%5Bstatus%5D=${String(args2.status)}`);
|
|
241
|
+
if (args2.taskIdentifier) queryParts.push(`filter%5BtaskIdentifier%5D=${String(args2.taskIdentifier)}`);
|
|
237
242
|
const rawJson = await triggerApi(
|
|
238
243
|
conn,
|
|
239
244
|
proxy,
|
|
@@ -256,7 +261,6 @@ ${rawJson.substring(0, 500)}` }] };
|
|
|
256
261
|
case "trigger-run-detail": {
|
|
257
262
|
const project = String(args2.project);
|
|
258
263
|
const runId = String(args2.runId);
|
|
259
|
-
const { conn, proxy } = await getServerConnection2(serverId);
|
|
260
264
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
261
265
|
const rawJson = await triggerApi(
|
|
262
266
|
conn,
|
|
@@ -273,14 +277,18 @@ ${rawJson.substring(0, 500)}` }] };
|
|
|
273
277
|
return { content: [{ type: "text", text: `Invalid API response:
|
|
274
278
|
${rawJson.substring(0, 500)}` }] };
|
|
275
279
|
}
|
|
276
|
-
|
|
280
|
+
const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
|
|
281
|
+
let text = formatRunDetail(run);
|
|
282
|
+
if (logs) {
|
|
283
|
+
text += "\n\n--- Logs ---\n" + logs;
|
|
284
|
+
}
|
|
285
|
+
return { content: [{ type: "text", text }] };
|
|
277
286
|
}
|
|
278
287
|
// -----------------------------------------------------------------
|
|
279
288
|
case "trigger-test-task": {
|
|
280
289
|
const project = String(args2.project);
|
|
281
290
|
const taskId = String(args2.taskId);
|
|
282
291
|
const waitSeconds = Math.min(Math.max(Number(args2.waitSeconds) || 60, 5), 300);
|
|
283
|
-
const { conn, proxy } = await getServerConnection2(serverId);
|
|
284
292
|
conn.timeout = (waitSeconds + 30) * 1e3;
|
|
285
293
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
286
294
|
let payload = "{}";
|
|
@@ -336,7 +344,10 @@ ${triggerJson.substring(0, 500)}` }] };
|
|
|
336
344
|
continue;
|
|
337
345
|
}
|
|
338
346
|
if (TERMINAL_STATUSES.has(run.status)) {
|
|
339
|
-
|
|
347
|
+
let text = formatRunDetail(run);
|
|
348
|
+
const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
|
|
349
|
+
if (logs) text += "\n\n--- Logs ---\n" + logs;
|
|
350
|
+
return { content: [{ type: "text", text }] };
|
|
340
351
|
}
|
|
341
352
|
}
|
|
342
353
|
return {
|
|
@@ -350,7 +361,6 @@ ${triggerJson.substring(0, 500)}` }] };
|
|
|
350
361
|
case "trigger-cancel-run": {
|
|
351
362
|
const project = String(args2.project);
|
|
352
363
|
const runId = String(args2.runId);
|
|
353
|
-
const { conn, proxy } = await getServerConnection2(serverId);
|
|
354
364
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
355
365
|
const rawJson = await triggerApi(
|
|
356
366
|
conn,
|
|
@@ -378,7 +388,6 @@ ${rawJson.substring(0, 500)}` }] };
|
|
|
378
388
|
case "trigger-replay-run": {
|
|
379
389
|
const project = String(args2.project);
|
|
380
390
|
const runId = String(args2.runId);
|
|
381
|
-
const { conn, proxy } = await getServerConnection2(serverId);
|
|
382
391
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
383
392
|
const rawJson = await triggerApi(
|
|
384
393
|
conn,
|