@mgsoftwarebv/mg-dashboard-mcp 2.2.0 → 2.2.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 +37 -59
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,26 +16,26 @@ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
|
16
16
|
"INTERRUPTED",
|
|
17
17
|
"EXPIRED"
|
|
18
18
|
]);
|
|
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`;
|
|
19
23
|
var TRIGGER_TOOLS = [
|
|
20
24
|
{
|
|
21
25
|
name: "trigger-list",
|
|
22
|
-
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.',
|
|
23
27
|
inputSchema: {
|
|
24
28
|
type: "object",
|
|
25
|
-
properties: {
|
|
26
|
-
serverId: { type: "string", description: "UUID of the SSH server running Trigger.dev" }
|
|
27
|
-
},
|
|
28
|
-
required: ["serverId"]
|
|
29
|
+
properties: {}
|
|
29
30
|
}
|
|
30
31
|
},
|
|
31
32
|
{
|
|
32
33
|
name: "trigger-runs",
|
|
33
|
-
description: "List recent task runs for a Trigger.dev
|
|
34
|
+
description: "List recent task runs for a Trigger.dev project. Returns run ID, task name, status, duration, and timestamps.",
|
|
34
35
|
inputSchema: {
|
|
35
36
|
type: "object",
|
|
36
37
|
properties: {
|
|
37
|
-
|
|
38
|
-
project: { type: "string", description: "Compose project name (from trigger-list)" },
|
|
38
|
+
project: { type: "string", description: 'Project slug from trigger-list (e.g. "mg-dashboard-bHfS")' },
|
|
39
39
|
status: {
|
|
40
40
|
type: "string",
|
|
41
41
|
description: "Comma-separated status filter: QUEUED,EXECUTING,COMPLETED,FAILED,CRASHED,CANCELED,SYSTEM_FAILURE"
|
|
@@ -43,7 +43,7 @@ var TRIGGER_TOOLS = [
|
|
|
43
43
|
taskIdentifier: { type: "string", description: 'Filter by task identifier (e.g. "hello-world")' },
|
|
44
44
|
limit: { type: "number", description: "Max runs to return (default 20, max 100)" }
|
|
45
45
|
},
|
|
46
|
-
required: ["
|
|
46
|
+
required: ["project"]
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
{
|
|
@@ -52,11 +52,10 @@ var TRIGGER_TOOLS = [
|
|
|
52
52
|
inputSchema: {
|
|
53
53
|
type: "object",
|
|
54
54
|
properties: {
|
|
55
|
-
|
|
56
|
-
project: { type: "string", description: "Compose project name" },
|
|
55
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
57
56
|
runId: { type: "string", description: "Run ID (e.g. run_xxxxx)" }
|
|
58
57
|
},
|
|
59
|
-
required: ["
|
|
58
|
+
required: ["project", "runId"]
|
|
60
59
|
}
|
|
61
60
|
},
|
|
62
61
|
{
|
|
@@ -65,13 +64,12 @@ var TRIGGER_TOOLS = [
|
|
|
65
64
|
inputSchema: {
|
|
66
65
|
type: "object",
|
|
67
66
|
properties: {
|
|
68
|
-
|
|
69
|
-
project: { type: "string", description: "Compose project name" },
|
|
67
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
70
68
|
taskId: { type: "string", description: 'Task identifier (e.g. "hello-world", "execute-pipeline")' },
|
|
71
69
|
payload: { type: "string", description: "JSON payload string to pass to the task (optional)" },
|
|
72
70
|
waitSeconds: { type: "number", description: "Max seconds to wait for completion (default 60, max 300)" }
|
|
73
71
|
},
|
|
74
|
-
required: ["
|
|
72
|
+
required: ["project", "taskId"]
|
|
75
73
|
}
|
|
76
74
|
},
|
|
77
75
|
{
|
|
@@ -80,11 +78,10 @@ var TRIGGER_TOOLS = [
|
|
|
80
78
|
inputSchema: {
|
|
81
79
|
type: "object",
|
|
82
80
|
properties: {
|
|
83
|
-
|
|
84
|
-
project: { type: "string", description: "Compose project name" },
|
|
81
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
85
82
|
runId: { type: "string", description: "Run ID to cancel (e.g. run_xxxxx)" }
|
|
86
83
|
},
|
|
87
|
-
required: ["
|
|
84
|
+
required: ["project", "runId"]
|
|
88
85
|
}
|
|
89
86
|
},
|
|
90
87
|
{
|
|
@@ -93,11 +90,10 @@ var TRIGGER_TOOLS = [
|
|
|
93
90
|
inputSchema: {
|
|
94
91
|
type: "object",
|
|
95
92
|
properties: {
|
|
96
|
-
|
|
97
|
-
project: { type: "string", description: "Compose project name" },
|
|
93
|
+
project: { type: "string", description: "Project slug from trigger-list" },
|
|
98
94
|
runId: { type: "string", description: "Run ID to replay (e.g. run_xxxxx)" }
|
|
99
95
|
},
|
|
100
|
-
required: ["
|
|
96
|
+
required: ["project", "runId"]
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
];
|
|
@@ -110,12 +106,11 @@ var TRIGGER_TOOL_MODULE_MAP = {
|
|
|
110
106
|
"trigger-cancel-run": "ci_cd",
|
|
111
107
|
"trigger-replay-run": "ci_cd"
|
|
112
108
|
};
|
|
113
|
-
async function discoverInstance(
|
|
114
|
-
const
|
|
115
|
-
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`;
|
|
116
111
|
const cmd = [
|
|
117
|
-
`PORT=$(docker port "${
|
|
118
|
-
`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:]')`,
|
|
119
114
|
'echo "$PORT|$KEY"'
|
|
120
115
|
].join(" && ");
|
|
121
116
|
const result = await sshExec2(conn, cmd, proxy);
|
|
@@ -125,18 +120,18 @@ async function discoverInstance(project, conn, proxy, sshExec2) {
|
|
|
125
120
|
const apiKey2 = sepIdx > 0 ? output.substring(sepIdx + 1) : "";
|
|
126
121
|
if (!port) {
|
|
127
122
|
throw new Error(
|
|
128
|
-
`Could not find webapp port for ${
|
|
123
|
+
`Could not find webapp port for ${WA_CONTAINER}. Is the container running?`
|
|
129
124
|
);
|
|
130
125
|
}
|
|
131
126
|
if (!apiKey2) {
|
|
132
127
|
throw new Error(
|
|
133
|
-
`Could not get API key
|
|
128
|
+
`Could not get API key for project "${projectSlug}". Check if the project slug is correct (use trigger-list).`
|
|
134
129
|
);
|
|
135
130
|
}
|
|
136
131
|
return { port, apiKey: apiKey2 };
|
|
137
132
|
}
|
|
138
133
|
async function triggerApi(conn, proxy, sshExec2, instance, method, path, body) {
|
|
139
|
-
const parts = ["curl", "-s", "--max-time", "30"];
|
|
134
|
+
const parts = ["curl", "-s", "-g", "--max-time", "30"];
|
|
140
135
|
if (method !== "GET") parts.push("-X", method);
|
|
141
136
|
parts.push(`"http://localhost:${instance.port}${path}"`);
|
|
142
137
|
parts.push(`-H "Authorization: Bearer ${instance.apiKey}"`);
|
|
@@ -198,34 +193,22 @@ function formatRunDetail(run) {
|
|
|
198
193
|
}
|
|
199
194
|
async function handleTriggerTool(name, args2, deps) {
|
|
200
195
|
const { sshExec: sshExec2, getServerConnection: getServerConnection2 } = deps;
|
|
196
|
+
const { conn, proxy } = await getServerConnection2(TRIGGER_SERVER_ID);
|
|
201
197
|
switch (name) {
|
|
202
198
|
// -----------------------------------------------------------------
|
|
203
199
|
case "trigger-list": {
|
|
204
|
-
const
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
"for PG in $(docker ps --format '{{.Names}}' | grep -E 'trigger.*-postgres-[0-9]+$'); do",
|
|
208
|
-
` PROJECT=$(echo "$PG" | sed 's/-postgres-[0-9]*$//')`,
|
|
209
|
-
' WA="${PROJECT}-webapp-1"',
|
|
210
|
-
` PORT=$(docker port "$WA" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,
|
|
211
|
-
` STATUS=$(docker inspect -f '{{.State.Status}}' "$WA" 2>/dev/null || echo 'not_found')`,
|
|
212
|
-
` RUNNING=$(docker ps --filter "label=com.docker.compose.project=\${PROJECT}" --format '{{.Names}}' 2>/dev/null | wc -l)`,
|
|
213
|
-
` TOTAL=$(docker ps -a --filter "label=com.docker.compose.project=\${PROJECT}" --format '{{.Names}}' 2>/dev/null | wc -l)`,
|
|
214
|
-
' echo "${PROJECT}|${PORT:-?}|${STATUS}|${RUNNING}/${TOTAL}"',
|
|
215
|
-
" FOUND=1",
|
|
216
|
-
"done",
|
|
217
|
-
'[ "$FOUND" = "0" ] && echo "NO_INSTANCES"'
|
|
218
|
-
].join("\n");
|
|
219
|
-
const result = await sshExec2(conn, script, proxy);
|
|
200
|
+
const sql = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
|
|
201
|
+
const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql}" 2>/dev/null`;
|
|
202
|
+
const result = await sshExec2(conn, cmd, proxy);
|
|
220
203
|
const output = result.stdout.trim();
|
|
221
|
-
if (!output
|
|
222
|
-
return { content: [{ type: "text", text: "No Trigger.dev
|
|
204
|
+
if (!output) {
|
|
205
|
+
return { content: [{ type: "text", text: "No Trigger.dev projects found." }] };
|
|
223
206
|
}
|
|
224
|
-
const header = `${"
|
|
225
|
-
const sep = "-".repeat(
|
|
207
|
+
const header = `${"SLUG".padEnd(25)} NAME`;
|
|
208
|
+
const sep = "-".repeat(55);
|
|
226
209
|
const lines = output.split("\n").map((line) => {
|
|
227
|
-
const [
|
|
228
|
-
return `${(
|
|
210
|
+
const [slug, name2] = line.split("|");
|
|
211
|
+
return `${(slug || "").padEnd(25)} ${name2 || ""}`;
|
|
229
212
|
});
|
|
230
213
|
return { content: [{ type: "text", text: `${header}
|
|
231
214
|
${sep}
|
|
@@ -234,12 +217,11 @@ ${lines.join("\n")}` }] };
|
|
|
234
217
|
// -----------------------------------------------------------------
|
|
235
218
|
case "trigger-runs": {
|
|
236
219
|
const project = String(args2.project);
|
|
237
|
-
const { conn, proxy } = await getServerConnection2(String(args2.serverId));
|
|
238
220
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
239
221
|
const limit = Math.min(Math.max(Number(args2.limit) || 20, 1), 100);
|
|
240
|
-
const queryParts = [`page
|
|
241
|
-
if (args2.status) queryParts.push(`filter
|
|
242
|
-
if (args2.taskIdentifier) queryParts.push(`filter
|
|
222
|
+
const queryParts = [`page%5Bsize%5D=${limit}`];
|
|
223
|
+
if (args2.status) queryParts.push(`filter%5Bstatus%5D=${String(args2.status)}`);
|
|
224
|
+
if (args2.taskIdentifier) queryParts.push(`filter%5BtaskIdentifier%5D=${String(args2.taskIdentifier)}`);
|
|
243
225
|
const rawJson = await triggerApi(
|
|
244
226
|
conn,
|
|
245
227
|
proxy,
|
|
@@ -262,7 +244,6 @@ ${rawJson.substring(0, 500)}` }] };
|
|
|
262
244
|
case "trigger-run-detail": {
|
|
263
245
|
const project = String(args2.project);
|
|
264
246
|
const runId = String(args2.runId);
|
|
265
|
-
const { conn, proxy } = await getServerConnection2(String(args2.serverId));
|
|
266
247
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
267
248
|
const rawJson = await triggerApi(
|
|
268
249
|
conn,
|
|
@@ -286,7 +267,6 @@ ${rawJson.substring(0, 500)}` }] };
|
|
|
286
267
|
const project = String(args2.project);
|
|
287
268
|
const taskId = String(args2.taskId);
|
|
288
269
|
const waitSeconds = Math.min(Math.max(Number(args2.waitSeconds) || 60, 5), 300);
|
|
289
|
-
const { conn, proxy } = await getServerConnection2(String(args2.serverId));
|
|
290
270
|
conn.timeout = (waitSeconds + 30) * 1e3;
|
|
291
271
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
292
272
|
let payload = "{}";
|
|
@@ -356,7 +336,6 @@ ${triggerJson.substring(0, 500)}` }] };
|
|
|
356
336
|
case "trigger-cancel-run": {
|
|
357
337
|
const project = String(args2.project);
|
|
358
338
|
const runId = String(args2.runId);
|
|
359
|
-
const { conn, proxy } = await getServerConnection2(String(args2.serverId));
|
|
360
339
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
361
340
|
const rawJson = await triggerApi(
|
|
362
341
|
conn,
|
|
@@ -384,7 +363,6 @@ ${rawJson.substring(0, 500)}` }] };
|
|
|
384
363
|
case "trigger-replay-run": {
|
|
385
364
|
const project = String(args2.project);
|
|
386
365
|
const runId = String(args2.runId);
|
|
387
|
-
const { conn, proxy } = await getServerConnection2(String(args2.serverId));
|
|
388
366
|
const instance = await discoverInstance(project, conn, proxy, sshExec2);
|
|
389
367
|
const rawJson = await triggerApi(
|
|
390
368
|
conn,
|