@mgsoftwarebv/mg-dashboard-mcp 2.3.1 → 2.3.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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/trigger-tools.ts","../src/script-tools.ts","../src/agent-tools.ts","../src/index.ts"],"names":["sshExec","apiKey","args","getServerConnection","name","supabase","error","SshClient","err","err2","stageIds","createHttpServer"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Trigger.dev MCP Tools\r\n *\r\n * SSH-based tools for managing Trigger.dev projects. All projects run on a\r\n * single Docker Compose instance. The compose project, server, postgres\r\n * container, and webapp port are auto-discovered — callers only need to\r\n * provide the Trigger.dev project slug (from trigger-list).\r\n *\r\n * @module trigger-tools\r\n */\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types (mirrored from index.ts to avoid circular imports)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface SshConnectionOptions {\r\n hostname: string;\r\n port: number;\r\n username: string;\r\n password?: string;\r\n privateKey?: string;\r\n passphrase?: string;\r\n timeout?: number;\r\n}\r\n\r\ninterface SshResult {\r\n stdout: string;\r\n stderr: string;\r\n exitCode: number;\r\n}\r\n\r\ntype SshExecFn = (\r\n conn: SshConnectionOptions,\r\n command: string,\r\n proxy?: SshConnectionOptions,\r\n) => Promise<SshResult>;\r\n\r\ntype GetServerConnectionFn = (\r\n serverId: string,\r\n) => Promise<{ conn: SshConnectionOptions; proxy?: SshConnectionOptions }>;\r\n\r\ninterface ToolResult {\r\n [key: string]: unknown;\r\n content: { type: string; text: string }[];\r\n}\r\n\r\ninterface TriggerToolDeps {\r\n sshExec: SshExecFn;\r\n getServerConnection: GetServerConnectionFn;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Trigger.dev API response shapes (partial, only fields we display)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface TriggerRunItem {\r\n id: string;\r\n status: string;\r\n taskIdentifier: string;\r\n version?: string;\r\n createdAt: string;\r\n updatedAt: string;\r\n startedAt?: string;\r\n finishedAt?: string;\r\n durationMs?: number;\r\n isTest?: boolean;\r\n}\r\n\r\ninterface TriggerRunDetail extends TriggerRunItem {\r\n payload?: unknown;\r\n output?: unknown;\r\n attempts?: {\r\n id: string;\r\n status: string;\r\n error?: { message: string; name?: string; stackTrace?: string };\r\n startedAt?: string;\r\n completedAt?: string;\r\n }[];\r\n}\r\n\r\nconst TERMINAL_STATUSES = new Set([\r\n 'COMPLETED', 'FAILED', 'CRASHED', 'CANCELED',\r\n 'SYSTEM_FAILURE', 'INTERRUPTED', 'EXPIRED',\r\n]);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Hardcoded infra constants — single Trigger.dev instance\r\n// ---------------------------------------------------------------------------\r\n\r\n/** SSH server that hosts the Trigger.dev Docker Compose stack. */\r\nconst TRIGGER_SERVER_ID = '03659d55-e194-400d-b82a-bf6457371ded';\r\n\r\n/** Docker Compose project name on the server. */\r\nconst COMPOSE_PROJECT = 'mg-dashboard-supabase-trigger';\r\n\r\nconst PG_CONTAINER = `${COMPOSE_PROJECT}-postgres-1`;\r\nconst WA_CONTAINER = `${COMPOSE_PROJECT}-webapp-1`;\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const TRIGGER_TOOLS = [\r\n {\r\n name: 'trigger-list',\r\n description:\r\n 'List all Trigger.dev projects. Returns the project slug and name. ' +\r\n 'Use the slug as the \"project\" parameter in other trigger-* tools.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {},\r\n },\r\n },\r\n {\r\n name: 'trigger-runs',\r\n description:\r\n 'List recent task runs for a Trigger.dev project. ' +\r\n 'Returns run ID, task name, status, duration, and timestamps.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list (e.g. \"mg-dashboard-bHfS\")' },\r\n status: {\r\n type: 'string',\r\n description: 'Comma-separated status filter: QUEUED,EXECUTING,COMPLETED,FAILED,CRASHED,CANCELED,SYSTEM_FAILURE',\r\n },\r\n taskIdentifier: { type: 'string', description: 'Filter by task identifier (e.g. \"hello-world\")' },\r\n limit: { type: 'number', description: 'Max runs to return (default 20, max 100)' },\r\n },\r\n required: ['project'],\r\n },\r\n },\r\n {\r\n name: 'trigger-run-detail',\r\n description:\r\n 'Get full details of a specific run: status, payload, output, and error stack traces. ' +\r\n 'Use after trigger-runs or trigger-test-task to inspect results.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list' },\r\n runId: { type: 'string', description: 'Run ID (e.g. run_xxxxx)' },\r\n },\r\n required: ['project', 'runId'],\r\n },\r\n },\r\n {\r\n name: 'trigger-test-task',\r\n description:\r\n 'Trigger a task run and wait for it to complete. Returns the final status, output, ' +\r\n 'or error with stack trace. The main tool for testing trigger tasks from Cursor.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list' },\r\n taskId: { type: 'string', description: 'Task identifier (e.g. \"hello-world\", \"execute-pipeline\")' },\r\n payload: { type: 'string', description: 'JSON payload string to pass to the task (optional)' },\r\n waitSeconds: { type: 'number', description: 'Max seconds to wait for completion (default 60, max 300)' },\r\n },\r\n required: ['project', 'taskId'],\r\n },\r\n },\r\n {\r\n name: 'trigger-replay-run',\r\n description: 'Replay a previously failed or completed run with the same payload. Returns the new run ID.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list' },\r\n runId: { type: 'string', description: 'Run ID to replay (e.g. run_xxxxx)' },\r\n },\r\n required: ['project', 'runId'],\r\n },\r\n },\r\n];\r\n\r\nexport const TRIGGER_TOOL_NAMES = new Set(TRIGGER_TOOLS.map((t) => t.name));\r\n\r\nexport const TRIGGER_TOOL_MODULE_MAP: Record<string, string> = {\r\n 'trigger-list': 'ci_cd',\r\n 'trigger-runs': 'ci_cd',\r\n 'trigger-run-detail': 'ci_cd',\r\n 'trigger-test-task': 'ci_cd',\r\n 'trigger-replay-run': 'ci_cd',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// SSH helpers\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface TriggerInstance {\r\n port: string;\r\n apiKey: string;\r\n}\r\n\r\n/**\r\n * Discover the webapp port and the production API key for a specific\r\n * Trigger.dev project by querying Docker and the Postgres container.\r\n * The API key is resolved via a JOIN on Project → RuntimeEnvironment.\r\n */\r\nasync function discoverInstance(\r\n projectSlug: string,\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n): Promise<TriggerInstance> {\r\n const sql = `SELECT re.\\\\\"apiKey\\\\\" FROM \\\\\"RuntimeEnvironment\\\\\" re `\r\n + `JOIN \\\\\"Project\\\\\" p ON re.\\\\\"projectId\\\\\" = p.id `\r\n + `WHERE p.slug='${projectSlug}' AND re.slug='prod' LIMIT 1`;\r\n\r\n const cmd = [\r\n `PORT=$(docker port \"${WA_CONTAINER}\" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,\r\n `KEY=$(docker exec \"${PG_CONTAINER}\" psql -U postgres -d main -t -A -c \"${sql}\" 2>/dev/null | tr -d '[:space:]')`,\r\n 'echo \"$PORT|$KEY\"',\r\n ].join(' && ');\r\n\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = result.stdout.trim();\r\n const sepIdx = output.indexOf('|');\r\n\r\n const port = sepIdx > 0 ? output.substring(0, sepIdx) : '';\r\n const apiKey = sepIdx > 0 ? output.substring(sepIdx + 1) : '';\r\n\r\n if (!port) {\r\n throw new Error(\r\n `Could not find webapp port for ${WA_CONTAINER}. Is the container running?`,\r\n );\r\n }\r\n if (!apiKey) {\r\n throw new Error(\r\n `Could not get API key for project \"${projectSlug}\". ` +\r\n 'Check if the project slug is correct (use trigger-list).',\r\n );\r\n }\r\n\r\n return { port, apiKey };\r\n}\r\n\r\n/**\r\n * Fetch console/logger output for a run from the TaskEvent table in Postgres.\r\n * Returns formatted log lines sorted by time, filtered to user-relevant levels.\r\n */\r\nasync function fetchRunLogs(\r\n runId: string,\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n): Promise<string> {\r\n const sql = `SELECT level, message, \\\\\"isError\\\\\", \\\\\"createdAt\\\\\" `\r\n + `FROM \\\\\"TaskEvent\\\\\" `\r\n + `WHERE \\\\\"runId\\\\\" = '${runId}' `\r\n + `AND level IN ('INFO','WARN','ERROR','DEBUG','LOG','TRACE') `\r\n + `ORDER BY \\\\\"startTime\\\\\" ASC LIMIT 200`;\r\n\r\n const cmd = `docker exec \"${PG_CONTAINER}\" psql -U postgres -d main -t -A -c \"${sql}\" 2>/dev/null`;\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = result.stdout.trim();\r\n\r\n if (!output) return '';\r\n\r\n return output.split('\\n').map((line) => {\r\n const parts = line.split('|');\r\n const level = (parts[0] || '').padEnd(5);\r\n const message = parts[1] || '';\r\n const isError = parts[2] === 't';\r\n const ts = parts[3] || '';\r\n const time = ts ? ts.split(' ')[1]?.substring(0, 8) || '' : '';\r\n const prefix = isError ? '!' : ' ';\r\n return `${prefix}${time} [${level}] ${message}`;\r\n }).join('\\n');\r\n}\r\n\r\n/**\r\n * Execute a curl request against the Trigger.dev REST API via SSH.\r\n * Uses -g (globoff) to prevent curl from interpreting brackets in URLs.\r\n */\r\nasync function triggerApi(\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n instance: TriggerInstance,\r\n method: string,\r\n path: string,\r\n body?: string,\r\n): Promise<string> {\r\n const parts = ['curl', '-s', '-g', '--max-time', '30'];\r\n if (method !== 'GET') parts.push('-X', method);\r\n parts.push(`\"http://localhost:${instance.port}${path}\"`);\r\n parts.push(`-H \"Authorization: Bearer ${instance.apiKey}\"`);\r\n if (body) {\r\n parts.push('-H \"Content-Type: application/json\"');\r\n parts.push(`-d '${body.replace(/'/g, \"'\\\\''\")}'`);\r\n }\r\n\r\n const result = await sshExec(conn, parts.join(' '), proxy);\r\n if (result.exitCode !== 0 && !result.stdout) {\r\n throw new Error(\r\n `Trigger.dev API call failed (${method} ${path}): ${result.stderr || `exit code ${result.exitCode}`}`,\r\n );\r\n }\r\n return result.stdout;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Output formatters\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction formatRunsTable(runs: TriggerRunItem[]): string {\r\n if (runs.length === 0) return 'No runs found';\r\n\r\n const lines = runs.map((r) => {\r\n const duration = r.durationMs != null ? `${(r.durationMs / 1000).toFixed(1)}s` : '-';\r\n const test = r.isTest ? ' [TEST]' : '';\r\n const created = r.createdAt ? new Date(r.createdAt).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' }) : '';\r\n return `${r.id} ${r.taskIdentifier.padEnd(35)} ${r.status.padEnd(16)} ${duration.padStart(8)} ${created}${test}`;\r\n });\r\n\r\n return `${'ID'.padEnd(20)} ${'TASK'.padEnd(35)} ${'STATUS'.padEnd(16)} ${'DURATION'.padStart(8)} CREATED\\n` +\r\n '-'.repeat(110) + '\\n' +\r\n lines.join('\\n');\r\n}\r\n\r\nfunction formatRunDetail(run: TriggerRunDetail): string {\r\n const sections: string[] = [];\r\n\r\n sections.push(`=== Run ${run.id} ===`);\r\n sections.push(`Task: ${run.taskIdentifier}`);\r\n sections.push(`Status: ${run.status}`);\r\n sections.push(`Version: ${run.version || '-'}`);\r\n\r\n if (run.startedAt) sections.push(`Started: ${new Date(run.startedAt).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' })}`);\r\n if (run.finishedAt) sections.push(`Finished: ${new Date(run.finishedAt).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' })}`);\r\n if (run.durationMs != null) sections.push(`Duration: ${(run.durationMs / 1000).toFixed(2)}s`);\r\n\r\n if (run.payload !== undefined) {\r\n const payloadStr = typeof run.payload === 'string'\r\n ? run.payload\r\n : JSON.stringify(run.payload, null, 2);\r\n sections.push('', '--- Payload ---', payloadStr);\r\n }\r\n\r\n if (run.output !== undefined) {\r\n const outputStr = typeof run.output === 'string'\r\n ? run.output\r\n : JSON.stringify(run.output, null, 2);\r\n sections.push('', '--- Output ---', outputStr);\r\n }\r\n\r\n if (run.attempts && run.attempts.length > 0) {\r\n for (const attempt of run.attempts) {\r\n if (attempt.error) {\r\n sections.push(\r\n '',\r\n `--- Error (${attempt.id}) ---`,\r\n `${attempt.error.name || 'Error'}: ${attempt.error.message}`,\r\n );\r\n if (attempt.error.stackTrace) {\r\n sections.push('', attempt.error.stackTrace);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return sections.join('\\n');\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main handler\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function handleTriggerTool(\r\n name: string,\r\n args: Record<string, unknown>,\r\n deps: TriggerToolDeps,\r\n): Promise<ToolResult> {\r\n const { sshExec, getServerConnection } = deps;\r\n const { conn, proxy } = await getServerConnection(TRIGGER_SERVER_ID);\r\n\r\n switch (name) {\r\n // -----------------------------------------------------------------\r\n case 'trigger-list': {\r\n const sql = 'SELECT slug, name FROM \\\\\"Project\\\\\" ORDER BY name';\r\n const cmd = `docker exec \"${PG_CONTAINER}\" psql -U postgres -d main -t -A -c \"${sql}\" 2>/dev/null`;\r\n\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = result.stdout.trim();\r\n\r\n if (!output) {\r\n return { content: [{ type: 'text', text: 'No Trigger.dev projects found.' }] };\r\n }\r\n\r\n const header = `${'SLUG'.padEnd(25)} NAME`;\r\n const sep = '-'.repeat(55);\r\n const lines = output.split('\\n').map((line) => {\r\n const [slug, name] = line.split('|');\r\n return `${(slug || '').padEnd(25)} ${name || ''}`;\r\n });\r\n\r\n return { content: [{ type: 'text', text: `${header}\\n${sep}\\n${lines.join('\\n')}` }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-runs': {\r\n const project = String(args.project);\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);\r\n const queryParts = [`page%5Bsize%5D=${limit}`];\r\n if (args.status) queryParts.push(`filter%5Bstatus%5D=${String(args.status)}`);\r\n if (args.taskIdentifier) queryParts.push(`filter%5BtaskIdentifier%5D=${String(args.taskIdentifier)}`);\r\n\r\n const rawJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'GET', `/api/v1/runs?${queryParts.join('&')}`,\r\n );\r\n\r\n let parsed: { data?: TriggerRunItem[] };\r\n try {\r\n parsed = JSON.parse(rawJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Invalid API response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n const runs = parsed.data || [];\r\n return { content: [{ type: 'text', text: formatRunsTable(runs) }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-run-detail': {\r\n const project = String(args.project);\r\n const runId = String(args.runId);\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n const [rawJson, logs] = await Promise.all([\r\n triggerApi(conn, proxy, sshExec, instance, 'GET', `/api/v3/runs/${encodeURIComponent(runId)}`),\r\n fetchRunLogs(runId, conn, proxy, sshExec),\r\n ]);\r\n\r\n let run: TriggerRunDetail;\r\n try {\r\n run = JSON.parse(rawJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Invalid API response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n let text = formatRunDetail(run);\r\n if (logs) {\r\n text += '\\n\\n--- Logs ---\\n' + logs;\r\n }\r\n\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-test-task': {\r\n const project = String(args.project);\r\n const taskId = String(args.taskId);\r\n const waitSeconds = Math.min(Math.max(Number(args.waitSeconds) || 60, 5), 300);\r\n\r\n conn.timeout = (waitSeconds + 30) * 1000;\r\n\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n let payload = '{}';\r\n if (args.payload) {\r\n try {\r\n JSON.parse(String(args.payload));\r\n payload = String(args.payload);\r\n } catch {\r\n throw new Error(`Invalid JSON payload: ${String(args.payload).substring(0, 200)}`);\r\n }\r\n }\r\n\r\n const triggerBody = JSON.stringify({\r\n payload: JSON.parse(payload),\r\n options: { tags: ['mcp-test'], test: true },\r\n });\r\n\r\n const triggerJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'POST', `/api/v1/tasks/${encodeURIComponent(taskId)}/trigger`,\r\n triggerBody,\r\n );\r\n\r\n let triggerResp: { id?: string };\r\n try {\r\n triggerResp = JSON.parse(triggerJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Failed to trigger task. API response:\\n${triggerJson.substring(0, 500)}` }] };\r\n }\r\n\r\n const runId = triggerResp.id;\r\n if (!runId) {\r\n return { content: [{ type: 'text', text: `Trigger API did not return a run ID:\\n${triggerJson.substring(0, 500)}` }] };\r\n }\r\n\r\n const pollInterval = 3000;\r\n const maxPolls = Math.ceil((waitSeconds * 1000) / pollInterval);\r\n\r\n for (let i = 0; i < maxPolls; i++) {\r\n await new Promise((r) => setTimeout(r, pollInterval));\r\n\r\n const pollJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'GET', `/api/v3/runs/${encodeURIComponent(runId)}`,\r\n );\r\n\r\n let run: TriggerRunDetail;\r\n try {\r\n run = JSON.parse(pollJson);\r\n } catch {\r\n continue;\r\n }\r\n\r\n if (TERMINAL_STATUSES.has(run.status)) {\r\n let text = formatRunDetail(run);\r\n const logs = await fetchRunLogs(runId, conn, proxy, sshExec);\r\n if (logs) text += '\\n\\n--- Logs ---\\n' + logs;\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Run ${runId} did not complete within ${waitSeconds}s (still running). Use trigger-run-detail to check later.`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-replay-run': {\r\n const project = String(args.project);\r\n const runId = String(args.runId);\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n const rawJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'POST', `/api/v1/runs/${encodeURIComponent(runId)}/replay`,\r\n );\r\n\r\n let result: { id?: string };\r\n try {\r\n result = JSON.parse(rawJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Replay response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: result.id\r\n ? `Run replayed. New run ID: ${result.id}`\r\n : `Replay response:\\n${rawJson.substring(0, 500)}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown trigger tool: ${name}` }] };\r\n }\r\n}\r\n","/**\r\n * Script Tools\r\n *\r\n * MCP tools that serve development workflow scripts (commit feedback,\r\n * PR creation, etc.) so they can be downloaded into any project that\r\n * has the mg-dashboard MCP enabled.\r\n *\r\n * @module script-tools\r\n */\r\n\r\n// ---------------------------------------------------------------------------\r\n// Embedded scripts\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ScriptDefinition {\r\n name: string;\r\n filename: string;\r\n description: string;\r\n content: string;\r\n}\r\n\r\nconst SCRIPTS: ScriptDefinition[] = [\r\n {\r\n name: 'commit-feedback',\r\n filename: 'commit-feedback.ps1',\r\n description:\r\n 'PowerShell script that provides colored terminal feedback for the Ctrl+Shift+K commit & push keybinding. ' +\r\n 'Polls for a new commit and shows branch, message, and file stats when done.',\r\n content: `param()\r\n\r\n$initial = git log --oneline -1 2>$null\r\n\r\nWrite-Host \"\\`n==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" Starting Commit & Push...\" -ForegroundColor Cyan\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" [1/5] Pulling latest...\" -ForegroundColor DarkGray\r\nWrite-Host \" [2/5] Staging changes...\" -ForegroundColor DarkGray\r\nWrite-Host \" [3/5] Generating AI commit message...\" -ForegroundColor DarkGray\r\nWrite-Host \" [4/5] Committing...\" -ForegroundColor DarkGray\r\nWrite-Host \" [5/5] Pushing to remote...\" -ForegroundColor DarkGray\r\nWrite-Host \"\"\r\nWrite-Host \" Waiting for commit\" -ForegroundColor DarkGray -NoNewline\r\n\r\n$timeout = 60\r\n$elapsed = 0\r\nwhile ($elapsed -lt $timeout) {\r\n $current = git log --oneline -1 2>$null\r\n if ($current -ne $initial) { break }\r\n Start-Sleep -Seconds 1\r\n $elapsed++\r\n Write-Host \".\" -ForegroundColor DarkGray -NoNewline\r\n}\r\nWrite-Host \"\"\r\n\r\nif ($current -eq $initial) {\r\n Write-Host \"\"\r\n Write-Host \" [!] No new commit detected (timed out after \\${timeout}s)\" -ForegroundColor Yellow\r\n Write-Host \"\"\r\n exit\r\n}\r\n\r\nStart-Sleep -Seconds 2\r\n\r\n$branch = git rev-parse --abbrev-ref HEAD 2>$null\r\n$commit = git log --format='%h %s' -1 2>$null\r\n\r\nWrite-Host \"\"\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" [OK] Commit & Push Complete\" -ForegroundColor Green\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" Branch: $branch\" -ForegroundColor Yellow\r\nWrite-Host \" Commit: $commit\" -ForegroundColor White\r\nWrite-Host \"\"\r\ngit --no-pager diff HEAD~1 --stat --color=always 2>$null\r\nWrite-Host \"\"\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \"\"\r\n`,\r\n },\r\n {\r\n name: 'create-pr',\r\n filename: 'create-pr.cmd',\r\n description:\r\n 'Windows batch script that auto-detects the target branch based on your release pipeline ' +\r\n '(v*-changes branches), merges the target into your branch, pushes, and creates a PR via gh CLI. ' +\r\n 'Bound to Ctrl+Shift+J.',\r\n content: `@echo off\r\nsetlocal enabledelayedexpansion\r\ntitle MG Dashboard - Create PR\r\n\r\nREM --- ANSI color setup ---\r\nfor /F %%a in ('echo prompt $E ^| cmd') do set \"ESC=%%a\"\r\nset \"GREEN=%ESC%[32m\"\r\nset \"RED=%ESC%[31m\"\r\nset \"YELLOW=%ESC%[33m\"\r\nset \"CYAN=%ESC%[36m\"\r\nset \"DIM=%ESC%[90m\"\r\nset \"BOLD=%ESC%[1m\"\r\nset \"RESET=%ESC%[0m\"\r\n\r\necho.\r\necho %CYAN%%BOLD%==========================================%RESET%\r\necho %CYAN%%BOLD% MG Dashboard - Create Pull Request%RESET%\r\necho %CYAN%%BOLD%==========================================%RESET%\r\necho.\r\n\r\nREM --- Merge origin/main first ---\r\necho %CYAN%[0/4]%RESET% Merging origin/main into current branch...\r\ngit fetch --prune >nul 2>&1\r\ngit merge origin/main --no-edit >nul 2>&1\r\nif errorlevel 1 (\r\n git merge --abort >nul 2>&1\r\n echo %RED%X Merge conflict with origin/main. Resolve manually.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %GREEN% OK%RESET%\r\necho.\r\n\r\nREM --- Prerequisite: gh CLI ---\r\nwhere gh >nul 2>&1\r\nif errorlevel 1 (\r\n echo %RED%X GitHub CLI ^(gh^) is not installed.%RESET%\r\n echo %DIM% Install it from: https://cli.github.com/%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Prerequisite: git repo ---\r\ngit rev-parse --is-inside-work-tree >nul 2>&1\r\nif errorlevel 1 (\r\n echo %RED%X Not inside a git repository.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Detect repo from git remote ---\r\nset \"REPO=\"\r\nfor /f \"tokens=*\" %%u in ('git remote get-url origin 2^>nul') do set \"REMOTE_URL=%%u\"\r\nif defined REMOTE_URL (\r\n echo !REMOTE_URL! | findstr /r \"git@github.com:\" >nul 2>&1\r\n if not errorlevel 1 (\r\n set \"REPO=!REMOTE_URL:git@github.com:=!\"\r\n set \"REPO=!REPO:.git=!\"\r\n )\r\n echo !REMOTE_URL! | findstr /r \"https://github.com/\" >nul 2>&1\r\n if not errorlevel 1 (\r\n set \"REPO=!REMOTE_URL:https://github.com/=!\"\r\n set \"REPO=!REPO:.git=!\"\r\n )\r\n)\r\nif not defined REPO (\r\n echo %RED%X Could not detect GitHub repo from git remote.%RESET%\r\n echo %DIM% Make sure origin points to a GitHub repository.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Get current branch ---\r\nfor /f \"tokens=*\" %%b in ('git rev-parse --abbrev-ref HEAD') do set \"CURRENT_BRANCH=%%b\"\r\n\r\necho %DIM% Repository: !REPO!%RESET%\r\necho %DIM% Branch: %CURRENT_BRANCH%%RESET%\r\necho.\r\n\r\nREM --- Guard: don't PR from main or a bare version branch ---\r\nif \"%CURRENT_BRANCH%\"==\"main\" (\r\n echo %RED%X You are on main. Switch to a feature or changes branch first.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %CURRENT_BRANCH% | findstr /r \"^v[0-9]*\\\\.[0-9]*\\\\.[0-9]*$\" >nul 2>&1\r\nif not errorlevel 1 (\r\n echo %RED%X You are on a version branch ^(%CURRENT_BRANCH%^). Switch to a feature or changes branch first.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Fetch latest remote refs ---\r\necho %CYAN%[1/4]%RESET% Fetching remote branches...\r\ngit fetch --prune >nul 2>&1\r\n\r\nREM --- Determine target branch ---\r\nset \"TARGET=\"\r\n\r\nREM Check if current branch is a -changes branch (last 8 chars)\r\nif \"!CURRENT_BRANCH:~-8!\"==\"-changes\" (\r\n set \"TARGET=!CURRENT_BRANCH:~0,-8!\"\r\n echo %GREEN% Detected -changes branch. Target: %BOLD%!TARGET!%RESET%\r\n goto :do_merge\r\n)\r\n\r\nREM Look for v*-changes branches on remote (highest version first)\r\nset \"TARGET=\"\r\nfor /f \"tokens=*\" %%r in ('git branch -r --sort=-version:refname --list \"origin/v*-changes\" 2^>nul') do (\r\n if not defined TARGET (\r\n set \"RAW=%%r\"\r\n set \"BRANCH=!RAW: origin/=!\"\r\n set \"BRANCH=!BRANCH:origin/=!\"\r\n set \"TARGET=!BRANCH!\"\r\n )\r\n)\r\n\r\nif defined TARGET (\r\n echo %GREEN% Release pipeline detected. Target: %BOLD%!TARGET!%RESET%\r\n) else (\r\n REM No -changes branch; try highest version branch\r\n set \"TARGET=\"\r\n for /f \"tokens=*\" %%r in ('git branch -r --sort=-version:refname --list \"origin/v*\" 2^>nul') do (\r\n if not defined TARGET (\r\n set \"RAW=%%r\"\r\n set \"BRANCH=!RAW: origin/=!\"\r\n set \"BRANCH=!BRANCH:origin/=!\"\r\n set \"TAIL=!BRANCH:~-8!\"\r\n if not \"!TAIL!\"==\"-changes\" set \"TARGET=!BRANCH!\"\r\n )\r\n )\r\n if defined TARGET (\r\n echo %GREEN% Version branch detected. Target: %BOLD%!TARGET!%RESET%\r\n ) else (\r\n set \"TARGET=main\"\r\n echo %YELLOW% No release pipeline or version branch found. Target: %BOLD%main%RESET%\r\n )\r\n)\r\n\r\n:do_merge\r\necho.\r\n\r\nREM --- Merge target into current branch ---\r\necho %CYAN%[2/4]%RESET% Merging %BOLD%!TARGET!%RESET% into %BOLD%%CURRENT_BRANCH%%RESET%...\r\ngit merge origin/!TARGET! --no-edit\r\nif errorlevel 1 (\r\n echo.\r\n echo %RED%X Merge conflict detected.%RESET%\r\n git merge --abort >nul 2>&1\r\n echo %DIM% Resolve conflicts manually, then retry.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %GREEN% OK%RESET%\r\necho.\r\n\r\nREM --- Push current branch to origin ---\r\necho %CYAN%[3/4]%RESET% Pushing %CURRENT_BRANCH% to origin...\r\ngit push -u origin HEAD\r\nif errorlevel 1 (\r\n echo.\r\n echo %RED%X Failed to push branch to origin.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %GREEN% OK%RESET%\r\necho.\r\n\r\nREM --- Guard: don't PR into the same branch ---\r\nif \"!TARGET!\"==\"!CURRENT_BRANCH!\" (\r\n echo %RED%X Target branch is the same as current branch ^(!TARGET!^). Cannot create PR.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\necho %CYAN%[4/4]%RESET% Creating PR: %BOLD%%CURRENT_BRANCH%%RESET% %DIM%->%RESET% %BOLD%%TARGET%%RESET%\r\necho.\r\n\r\nREM --- Create the PR ---\r\ngh pr create --repo \"!REPO!\" --base \"%TARGET%\" --fill\r\nif errorlevel 1 (\r\n echo.\r\n echo %RED%X Failed to create pull request.%RESET%\r\n echo %DIM% Check the error above. A PR may already exist for this branch.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\necho.\r\necho %GREEN%%BOLD% PR created successfully!%RESET%\r\necho.\r\n`,\r\n },\r\n {\r\n name: 'commit-and-pr',\r\n filename: 'commit-and-pr.ps1',\r\n description:\r\n 'PowerShell script that combines commit & push with PR creation. ' +\r\n 'Checks for pending changes first: if changes exist, waits for the commit (triggered by Cursor keybinding), ' +\r\n 'shows a summary, then runs create-pr.cmd. If no changes, skips straight to PR. ' +\r\n 'Requires create-pr.cmd in the same directory. Bound to Ctrl+Shift+M.',\r\n content: `param()\r\n\r\n$hasChanges = (git status --porcelain 2>$null)\r\n\r\nif ($hasChanges) {\r\n $initial = git log --oneline -1 2>$null\r\n\r\n Write-Host \"\\`n==========================================\" -ForegroundColor Cyan\r\n Write-Host \" Starting Commit, Push & PR...\" -ForegroundColor Cyan\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \" [1/5] Pulling latest...\" -ForegroundColor DarkGray\r\n Write-Host \" [2/5] Staging changes...\" -ForegroundColor DarkGray\r\n Write-Host \" [3/5] Generating AI commit message...\" -ForegroundColor DarkGray\r\n Write-Host \" [4/5] Committing...\" -ForegroundColor DarkGray\r\n Write-Host \" [5/5] Pushing to remote...\" -ForegroundColor DarkGray\r\n Write-Host \"\"\r\n Write-Host \" Waiting for commit\" -ForegroundColor DarkGray -NoNewline\r\n\r\n $timeout = 60\r\n $elapsed = 0\r\n while ($elapsed -lt $timeout) {\r\n $current = git log --oneline -1 2>$null\r\n if ($current -ne $initial) { break }\r\n Start-Sleep -Seconds 1\r\n $elapsed++\r\n Write-Host \".\" -ForegroundColor DarkGray -NoNewline\r\n }\r\n Write-Host \"\"\r\n\r\n if ($current -eq $initial) {\r\n Write-Host \"\"\r\n Write-Host \" [!] No new commit detected (timed out after \\${timeout}s)\" -ForegroundColor Yellow\r\n Write-Host \" Skipping PR creation.\" -ForegroundColor Yellow\r\n Write-Host \"\"\r\n exit\r\n }\r\n\r\n Start-Sleep -Seconds 2\r\n\r\n $branch = git rev-parse --abbrev-ref HEAD 2>$null\r\n $commit = git log --format='%h %s' -1 2>$null\r\n\r\n Write-Host \"\"\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \" [OK] Commit & Push Complete\" -ForegroundColor Green\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \" Branch: $branch\" -ForegroundColor Yellow\r\n Write-Host \" Commit: $commit\" -ForegroundColor White\r\n Write-Host \"\"\r\n git --no-pager diff HEAD~1 --stat --color=always 2>$null\r\n Write-Host \"\"\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \"\"\r\n} else {\r\n Write-Host \"\\`n==========================================\" -ForegroundColor Cyan\r\n Write-Host \" No changes to commit\" -ForegroundColor DarkGray\r\n Write-Host \" Proceeding to PR creation...\" -ForegroundColor Cyan\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \"\"\r\n}\r\n\r\n& .\\\\create-pr.cmd\r\n`,\r\n },\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const SCRIPT_TOOLS = [\r\n {\r\n name: 'scripts-list',\r\n description:\r\n 'List available MG Dashboard workflow scripts that can be downloaded into your project. ' +\r\n 'Returns script names, filenames, and descriptions.',\r\n inputSchema: { type: 'object' as const, properties: {}, required: [] },\r\n },\r\n {\r\n name: 'script-get',\r\n description:\r\n 'Get the content of an MG Dashboard workflow script by name. ' +\r\n 'Save the returned content to the filename indicated in the response. ' +\r\n 'Place scripts in the repository root.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n name: {\r\n type: 'string',\r\n description: `Script name. Available: ${SCRIPTS.map((s) => s.name).join(', ')}`,\r\n },\r\n },\r\n required: ['name'],\r\n },\r\n },\r\n];\r\n\r\nexport const SCRIPT_TOOL_NAMES = new Set(SCRIPT_TOOLS.map((t) => t.name));\r\n\r\n// ---------------------------------------------------------------------------\r\n// Handler\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ToolResult {\r\n [key: string]: unknown;\r\n content: { type: string; text: string }[];\r\n}\r\n\r\nexport function handleScriptTool(\r\n toolName: string,\r\n args: Record<string, unknown>,\r\n): ToolResult {\r\n switch (toolName) {\r\n case 'scripts-list': {\r\n const list = SCRIPTS.map((s) => ({\r\n name: s.name,\r\n filename: s.filename,\r\n description: s.description,\r\n }));\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(list, null, 2),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'script-get': {\r\n const scriptName = String(args.name);\r\n const script = SCRIPTS.find((s) => s.name === scriptName);\r\n if (!script) {\r\n const available = SCRIPTS.map((s) => s.name).join(', ');\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Unknown script: \"${scriptName}\". Available scripts: ${available}`,\r\n },\r\n ],\r\n };\r\n }\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: [\r\n `Filename: ${script.filename}`,\r\n `Description: ${script.description}`,\r\n `Place this file in the repository root.`,\r\n '',\r\n '--- CONTENT START ---',\r\n script.content,\r\n '--- CONTENT END ---',\r\n ].join('\\n'),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown script tool: ${toolName}` }] };\r\n }\r\n}\r\n","/**\r\n * Agent Reporting MCP Tools\r\n *\r\n * Tools used by automated Cursor agents (doc scanners, perf auditors, etc.)\r\n * to report findings directly to the dashboard database. Replaces the old\r\n * marker-based output parsing pipeline.\r\n *\r\n * @module agent-tools\r\n */\r\n\r\nimport type { SupabaseClient } from '@supabase/supabase-js';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ToolResult {\r\n [key: string]: unknown;\r\n content: { type: string; text: string }[];\r\n}\r\n\r\ninterface AgentToolDeps {\r\n supabase: SupabaseClient;\r\n workspaceId: string | null;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Valid enum values (shared with the old parse-* modules — canonical source)\r\n// ---------------------------------------------------------------------------\r\n\r\nconst VALID_FINDING_TYPES = new Set([\r\n 'missing_docs', 'inaccurate', 'incomplete', 'outdated', 'improvement',\r\n 'n_plus_1_query', 'bundle_size', 'unnecessary_rerender',\r\n 'slow_endpoint', 'memory_leak', 'missing_memoization', 'large_dependency',\r\n]);\r\n\r\nconst VALID_SEVERITIES = new Set(['info', 'warning', 'critical']);\r\n\r\nconst VALID_SCOPES = new Set([\r\n 'architecture', 'module', 'component', 'api', 'package',\r\n]);\r\n\r\nconst VALID_REVIEW_STATUSES = new Set([\r\n 'pending', 'approved', 'rejected', 'outdated',\r\n]);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const AGENT_TOOLS = [\r\n {\r\n name: 'agent-report-coverage',\r\n description:\r\n 'Report documentation coverage data for a repository. Upserts records ' +\r\n 'into doc_coverage. Call once per logical unit (package, module, theme, plugin directory). ' +\r\n 'Provide all entries in a single call for efficiency.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: {\r\n type: 'string',\r\n description: 'Repository slug (e.g. \"mg-dashboard\", \"bna-wordpress\")',\r\n },\r\n refront_project_id: {\r\n type: 'string',\r\n description: 'Refront project UUID linked to this repository',\r\n },\r\n entries: {\r\n type: 'array',\r\n description: 'Array of coverage entries, one per logical unit',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n path: { type: 'string', description: 'Logical unit path (e.g. \"packages/ui\", \"wp-content/themes/bna\")' },\r\n total_functions: { type: 'number', description: 'Total public functions/methods' },\r\n documented_functions: { type: 'number', description: 'Functions with doc comments' },\r\n total_types: { type: 'number', description: 'Total classes/interfaces/types' },\r\n documented_types: { type: 'number', description: 'Types with doc comments' },\r\n total_endpoints: { type: 'number', description: 'Total API/REST/hook endpoints' },\r\n documented_endpoints: { type: 'number', description: 'Endpoints with documentation' },\r\n },\r\n required: ['path', 'total_functions', 'documented_functions'],\r\n },\r\n },\r\n },\r\n required: ['repo_slug', 'refront_project_id', 'entries'],\r\n },\r\n },\r\n {\r\n name: 'agent-report-finding',\r\n description:\r\n 'Report documentation or performance findings for a repository. ' +\r\n 'Inserts records into doc_suggestion. Auto-creates a parent documentation ' +\r\n 'record if one does not exist yet. Batch multiple findings in one call.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: {\r\n type: 'string',\r\n description: 'Repository slug',\r\n },\r\n refront_project_id: {\r\n type: 'string',\r\n description: 'Refront project UUID linked to this repository',\r\n },\r\n category: {\r\n type: 'string',\r\n enum: ['scan_findings', 'perf_audit'],\r\n description: 'Finding category: \"scan_findings\" for doc issues, \"perf_audit\" for performance issues',\r\n },\r\n findings: {\r\n type: 'array',\r\n description: 'Array of findings to report',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n type: {\r\n type: 'string',\r\n enum: [...VALID_FINDING_TYPES],\r\n description: 'Finding type',\r\n },\r\n severity: {\r\n type: 'string',\r\n enum: ['info', 'warning', 'critical'],\r\n description: 'Severity level',\r\n },\r\n description: {\r\n type: 'string',\r\n description: 'Clear description of the issue (max 2000 chars)',\r\n },\r\n file_path: {\r\n type: 'string',\r\n description: 'Relative file path where the issue was found',\r\n },\r\n suggested_fix: {\r\n type: 'string',\r\n description: 'Suggested fix with code example (max 5000 chars)',\r\n },\r\n },\r\n required: ['type', 'severity', 'description'],\r\n },\r\n },\r\n },\r\n required: ['repo_slug', 'refront_project_id', 'category', 'findings'],\r\n },\r\n },\r\n {\r\n name: 'agent-save-documentation',\r\n description:\r\n 'Save or update a documentation record for a repository. ' +\r\n 'Upserts by repo_slug + scope + path combination.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: { type: 'string', description: 'Repository slug' },\r\n refront_project_id: { type: 'string', description: 'Refront project UUID' },\r\n scope: {\r\n type: 'string',\r\n enum: [...VALID_SCOPES],\r\n description: 'Documentation scope',\r\n },\r\n path: {\r\n type: 'string',\r\n description: 'Path within the repo (e.g. \"packages/ui\", \"__perf_audit__\")',\r\n },\r\n title: { type: 'string', description: 'Document title' },\r\n content: { type: 'string', description: 'Documentation content (markdown)' },\r\n review_status: {\r\n type: 'string',\r\n enum: [...VALID_REVIEW_STATUSES],\r\n description: 'Review status (default: \"pending\")',\r\n },\r\n },\r\n required: ['repo_slug', 'refront_project_id', 'scope', 'path', 'title', 'content'],\r\n },\r\n },\r\n {\r\n name: 'agent-list-findings',\r\n description:\r\n 'List existing findings (doc_suggestion records) for a repository. ' +\r\n 'Use this to check what has already been reported before submitting new findings.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: { type: 'string', description: 'Repository slug' },\r\n type: {\r\n type: 'string',\r\n enum: [...VALID_FINDING_TYPES],\r\n description: 'Filter by finding type',\r\n },\r\n severity: {\r\n type: 'string',\r\n enum: ['info', 'warning', 'critical'],\r\n description: 'Filter by severity',\r\n },\r\n status: {\r\n type: 'string',\r\n enum: ['open', 'accepted', 'rejected', 'fixed'],\r\n description: 'Filter by status (default: all)',\r\n },\r\n limit: {\r\n type: 'number',\r\n description: 'Max results to return (default: 50, max: 200)',\r\n },\r\n },\r\n required: ['repo_slug'],\r\n },\r\n },\r\n {\r\n name: 'agent-get-documentation',\r\n description:\r\n 'Retrieve existing documentation records for a repository. ' +\r\n 'Use this to read current docs before generating or reviewing.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: { type: 'string', description: 'Repository slug' },\r\n scope: {\r\n type: 'string',\r\n enum: [...VALID_SCOPES],\r\n description: 'Filter by scope',\r\n },\r\n path: { type: 'string', description: 'Filter by exact path' },\r\n limit: {\r\n type: 'number',\r\n description: 'Max results to return (default: 20, max: 100)',\r\n },\r\n },\r\n required: ['repo_slug'],\r\n },\r\n },\r\n];\r\n\r\nexport const AGENT_TOOL_NAMES = new Set(AGENT_TOOLS.map((t) => t.name));\r\n\r\nexport const AGENT_TOOL_MODULE_MAP: Record<string, string> = {\r\n 'agent-report-coverage': 'agent_reporting',\r\n 'agent-report-finding': 'agent_reporting',\r\n 'agent-save-documentation': 'agent_reporting',\r\n 'agent-list-findings': 'agent_reporting',\r\n 'agent-get-documentation': 'agent_reporting',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction clamp(val: number, min: number, max: number): number {\r\n return Math.max(min, Math.min(max, val));\r\n}\r\n\r\nfunction sanitizeString(val: unknown, maxLen: number): string {\r\n return String(val ?? '').slice(0, maxLen);\r\n}\r\n\r\n/**\r\n * Find or create a parent project_documentation record for grouping findings.\r\n * Uses a well-known path convention per category.\r\n */\r\nasync function getOrCreateParentDoc(\r\n supabase: SupabaseClient,\r\n repoSlug: string,\r\n refrontProjectId: string,\r\n category: 'scan_findings' | 'perf_audit',\r\n): Promise<string> {\r\n const path = category === 'perf_audit' ? '__perf_audit__' : '__scan_findings__';\r\n const title = category === 'perf_audit'\r\n ? `Performance Audit: ${repoSlug}`\r\n : `Scan Findings: ${repoSlug}`;\r\n\r\n const { data: existing } = await supabase\r\n .from('project_documentation')\r\n .select('id')\r\n .eq('repo_slug', repoSlug)\r\n .eq('path', path)\r\n .maybeSingle();\r\n\r\n if (existing) return existing.id;\r\n\r\n const { data: inserted, error } = await supabase\r\n .from('project_documentation')\r\n .insert({\r\n refront_project_id: refrontProjectId,\r\n repo_slug: repoSlug,\r\n scope: 'architecture',\r\n path,\r\n title,\r\n content: `Auto-generated parent record for ${category.replace('_', ' ')} suggestions.`,\r\n generated_by: `${category}-agent-v1`,\r\n review_status: 'pending',\r\n })\r\n .select('id')\r\n .single();\r\n\r\n if (error || !inserted) {\r\n throw new Error(`Failed to create parent doc record: ${error?.message}`);\r\n }\r\n\r\n return inserted.id;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main handler\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function handleAgentTool(\r\n name: string,\r\n args: Record<string, unknown>,\r\n deps: AgentToolDeps,\r\n): Promise<ToolResult> {\r\n const { supabase } = deps;\r\n\r\n switch (name) {\r\n // -----------------------------------------------------------------\r\n case 'agent-report-coverage': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n const refrontProjectId = sanitizeString(args.refront_project_id, 100);\r\n const entries = Array.isArray(args.entries) ? args.entries : [];\r\n\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n if (!refrontProjectId) throw new Error('refront_project_id is required');\r\n if (entries.length === 0) throw new Error('entries array must not be empty');\r\n\r\n const wsId = deps.workspaceId;\r\n const scanCommit = wsId ? `agent-scan-${wsId.slice(0, 8)}` : `agent-scan-${Date.now().toString(36)}`;\r\n\r\n let upserted = 0;\r\n let errors = 0;\r\n\r\n for (const entry of entries) {\r\n const { error } = await supabase\r\n .from('doc_coverage')\r\n .upsert(\r\n {\r\n refront_project_id: refrontProjectId,\r\n repo_slug: repoSlug,\r\n path: sanitizeString(entry.path, 500),\r\n total_functions: clamp(Number(entry.total_functions) || 0, 0, 99999),\r\n documented_functions: clamp(Number(entry.documented_functions) || 0, 0, 99999),\r\n total_types: clamp(Number(entry.total_types) || 0, 0, 99999),\r\n documented_types: clamp(Number(entry.documented_types) || 0, 0, 99999),\r\n total_endpoints: clamp(Number(entry.total_endpoints) || 0, 0, 99999),\r\n documented_endpoints: clamp(Number(entry.documented_endpoints) || 0, 0, 99999),\r\n scan_commit: scanCommit,\r\n scanned_at: new Date().toISOString(),\r\n },\r\n { onConflict: 'repo_slug,path' },\r\n );\r\n\r\n if (error) errors++;\r\n else upserted++;\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Coverage reported: ${upserted} entries upserted${errors > 0 ? `, ${errors} errors` : ''}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-report-finding': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n const refrontProjectId = sanitizeString(args.refront_project_id, 100);\r\n const category = args.category as 'scan_findings' | 'perf_audit';\r\n const findings = Array.isArray(args.findings) ? args.findings : [];\r\n\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n if (!refrontProjectId) throw new Error('refront_project_id is required');\r\n if (!category || !['scan_findings', 'perf_audit'].includes(category)) {\r\n throw new Error('category must be \"scan_findings\" or \"perf_audit\"');\r\n }\r\n if (findings.length === 0) throw new Error('findings array must not be empty');\r\n\r\n const parentDocId = await getOrCreateParentDoc(supabase, repoSlug, refrontProjectId, category);\r\n\r\n let inserted = 0;\r\n let errors = 0;\r\n\r\n for (const f of findings) {\r\n const findingType = VALID_FINDING_TYPES.has(f.type) ? f.type : 'improvement';\r\n const severity = VALID_SEVERITIES.has(f.severity) ? f.severity : 'info';\r\n const description = sanitizeString(f.description, 2000);\r\n\r\n if (!description) continue;\r\n\r\n const { error } = await supabase.from('doc_suggestion').insert({\r\n documentation_id: parentDocId,\r\n type: findingType,\r\n severity,\r\n description,\r\n file_path: f.file_path ? sanitizeString(f.file_path, 500) : null,\r\n suggested_fix: f.suggested_fix ? sanitizeString(f.suggested_fix, 5000) : null,\r\n status: 'open',\r\n });\r\n\r\n if (error) errors++;\r\n else inserted++;\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Findings reported: ${inserted} inserted under ${category}${errors > 0 ? `, ${errors} errors` : ''}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-save-documentation': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n const refrontProjectId = sanitizeString(args.refront_project_id, 100);\r\n const scope = VALID_SCOPES.has(args.scope as string) ? (args.scope as string) : 'module';\r\n const path = sanitizeString(args.path, 500);\r\n const title = sanitizeString(args.title, 500);\r\n const content = sanitizeString(args.content, 100_000);\r\n const reviewStatus = VALID_REVIEW_STATUSES.has(args.review_status as string)\r\n ? (args.review_status as string)\r\n : 'pending';\r\n\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n if (!refrontProjectId) throw new Error('refront_project_id is required');\r\n if (!path) throw new Error('path is required');\r\n if (!title) throw new Error('title is required');\r\n if (!content) throw new Error('content is required');\r\n\r\n const { data: existing } = await supabase\r\n .from('project_documentation')\r\n .select('id')\r\n .eq('repo_slug', repoSlug)\r\n .eq('scope', scope)\r\n .eq('path', path)\r\n .maybeSingle();\r\n\r\n if (existing) {\r\n const { error } = await supabase\r\n .from('project_documentation')\r\n .update({\r\n title,\r\n content,\r\n review_status: reviewStatus,\r\n updated_at: new Date().toISOString(),\r\n })\r\n .eq('id', existing.id);\r\n\r\n if (error) throw new Error(`Failed to update documentation: ${error.message}`);\r\n return { content: [{ type: 'text', text: `Documentation updated: ${title} (${scope}/${path})` }] };\r\n }\r\n\r\n const generatedBy = deps.workspaceId\r\n ? `agent-${deps.workspaceId.slice(0, 8)}`\r\n : 'agent-mcp';\r\n\r\n const { error } = await supabase\r\n .from('project_documentation')\r\n .insert({\r\n refront_project_id: refrontProjectId,\r\n repo_slug: repoSlug,\r\n scope,\r\n path,\r\n title,\r\n content,\r\n generated_by: generatedBy,\r\n review_status: reviewStatus,\r\n });\r\n\r\n if (error) throw new Error(`Failed to save documentation: ${error.message}`);\r\n return { content: [{ type: 'text', text: `Documentation saved: ${title} (${scope}/${path})` }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-list-findings': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n\r\n const limit = clamp(Number(args.limit) || 50, 1, 200);\r\n\r\n // Findings are linked via project_documentation → doc_suggestion\r\n let docQuery = supabase\r\n .from('project_documentation')\r\n .select('id')\r\n .eq('repo_slug', repoSlug);\r\n\r\n const docIds = await docQuery;\r\n if (!docIds.data || docIds.data.length === 0) {\r\n return { content: [{ type: 'text', text: `No documentation records found for repo \"${repoSlug}\"` }] };\r\n }\r\n\r\n let query = supabase\r\n .from('doc_suggestion')\r\n .select('id, type, severity, description, file_path, status, created_at')\r\n .in('documentation_id', docIds.data.map((d: { id: string }) => d.id))\r\n .order('created_at', { ascending: false })\r\n .limit(limit);\r\n\r\n if (args.type && VALID_FINDING_TYPES.has(args.type as string)) {\r\n query = query.eq('type', args.type as string);\r\n }\r\n if (args.severity && VALID_SEVERITIES.has(args.severity as string)) {\r\n query = query.eq('severity', args.severity as string);\r\n }\r\n if (args.status) {\r\n query = query.eq('status', args.status as string);\r\n }\r\n\r\n const { data: findings, error } = await query;\r\n if (error) throw new Error(`Failed to query findings: ${error.message}`);\r\n\r\n if (!findings || findings.length === 0) {\r\n return { content: [{ type: 'text', text: `No findings found for repo \"${repoSlug}\"` }] };\r\n }\r\n\r\n const summary = findings.map((f: Record<string, unknown>) =>\r\n `[${f.severity}] ${f.type}: ${String(f.description).slice(0, 120)}${f.file_path ? ` (${f.file_path})` : ''} — ${f.status}`\r\n ).join('\\n');\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `${findings.length} findings for \"${repoSlug}\":\\n\\n${summary}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-get-documentation': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n\r\n const limit = clamp(Number(args.limit) || 20, 1, 100);\r\n\r\n let query = supabase\r\n .from('project_documentation')\r\n .select('id, repo_slug, scope, path, title, content, review_status, generated_by, created_at, updated_at')\r\n .eq('repo_slug', repoSlug)\r\n .order('updated_at', { ascending: false })\r\n .limit(limit);\r\n\r\n if (args.scope && VALID_SCOPES.has(args.scope as string)) {\r\n query = query.eq('scope', args.scope as string);\r\n }\r\n if (args.path) {\r\n query = query.eq('path', sanitizeString(args.path, 500));\r\n }\r\n\r\n const { data: docs, error } = await query;\r\n if (error) throw new Error(`Failed to query documentation: ${error.message}`);\r\n\r\n if (!docs || docs.length === 0) {\r\n return { content: [{ type: 'text', text: `No documentation found for repo \"${repoSlug}\"` }] };\r\n }\r\n\r\n const output = docs.map((d: Record<string, unknown>) => {\r\n const contentPreview = String(d.content || '').slice(0, 500);\r\n return [\r\n `## ${d.title} (${d.scope}/${d.path})`,\r\n `Status: ${d.review_status} | By: ${d.generated_by || 'unknown'}`,\r\n `Updated: ${d.updated_at || d.created_at}`,\r\n '',\r\n contentPreview + (String(d.content || '').length > 500 ? '\\n...(truncated)' : ''),\r\n '',\r\n ].join('\\n');\r\n }).join('\\n---\\n\\n');\r\n\r\n return {\r\n content: [{ type: 'text', text: `${docs.length} docs for \"${repoSlug}\":\\n\\n${output}` }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown agent tool: ${name}` }] };\r\n }\r\n}\r\n","#!/usr/bin/env node\r\n\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\r\nimport { CallToolRequestSchema, ListToolsRequestSchema, isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';\r\nimport { createServer as createHttpServer } from 'node:http';\r\nimport { randomUUID } from 'node:crypto';\r\nimport { createClient } from '@supabase/supabase-js';\r\nimport { createHash, randomBytes, createCipheriv, createDecipheriv } from 'crypto';\r\nimport { Client as SshClient } from 'ssh2';\r\nimport {\r\n TRIGGER_TOOLS,\r\n TRIGGER_TOOL_NAMES,\r\n TRIGGER_TOOL_MODULE_MAP,\r\n handleTriggerTool,\r\n} from './trigger-tools.js';\r\nimport {\r\n SCRIPT_TOOLS,\r\n SCRIPT_TOOL_NAMES,\r\n handleScriptTool,\r\n} from './script-tools.js';\r\nimport {\r\n AGENT_TOOLS,\r\n AGENT_TOOL_NAMES,\r\n AGENT_TOOL_MODULE_MAP,\r\n handleAgentTool,\r\n} from './agent-tools.js';\r\n\r\n// ---------------------------------------------------------------------------\r\n// CLI argument parsing\r\n// ---------------------------------------------------------------------------\r\n\r\nconst args = process.argv.slice(2);\r\n\r\nfunction getArg(name: string): string | undefined {\r\n return args.find(a => a.startsWith(`--${name}=`))?.split('=').slice(1).join('=');\r\n}\r\n\r\nconst apiKey = getArg('api-key') || process.env.MG_DASHBOARD_API_KEY;\r\nconst supabaseUrl = getArg('supabase-url') || process.env.SUPABASE_URL;\r\nconst supabaseKey = getArg('supabase-key') || process.env.SUPABASE_SERVICE_ROLE_KEY;\r\nconst encryptionKey = getArg('encryption-key') || process.env.ENCRYPTION_KEY;\r\nconst mijnhostApiKey = getArg('mijnhost-api-key') || process.env.MIJNHOST_API_KEY;\r\nconst agentWorkspaceId = getArg('workspace-id') || process.env.AGENT_WORKSPACE_ID || null;\r\nconst httpMode = args.includes('--http');\r\nconst httpPort = Number(getArg('port')) || 3100;\r\n\r\nif (!apiKey) {\r\n console.error('API key is required. Use --api-key=dk_xxx or set MG_DASHBOARD_API_KEY');\r\n process.exit(1);\r\n}\r\n\r\nif (!supabaseUrl || !supabaseKey) {\r\n console.error('Supabase credentials required. Use --supabase-url and --supabase-key or set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY');\r\n process.exit(1);\r\n}\r\n\r\nconst supabase = createClient(supabaseUrl, supabaseKey);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Rate limiting\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface RateLimitEntry {\r\n count: number;\r\n resetAt: number;\r\n}\r\n\r\nclass RateLimiter {\r\n private buckets = new Map<string, RateLimitEntry>();\r\n private readonly maxAttempts: number;\r\n private readonly windowMs: number;\r\n\r\n constructor(maxAttempts: number, windowMs: number) {\r\n this.maxAttempts = maxAttempts;\r\n this.windowMs = windowMs;\r\n }\r\n\r\n /**\r\n * Check if an action is allowed for the given key.\r\n * Increments the counter and returns whether the action should proceed.\r\n */\r\n check(key: string): { allowed: boolean; remaining: number; retryAfterMs: number } {\r\n const now = Date.now();\r\n const entry = this.buckets.get(key);\r\n\r\n if (!entry || now >= entry.resetAt) {\r\n this.buckets.set(key, { count: 1, resetAt: now + this.windowMs });\r\n return { allowed: true, remaining: this.maxAttempts - 1, retryAfterMs: 0 };\r\n }\r\n\r\n entry.count++;\r\n\r\n if (entry.count > this.maxAttempts) {\r\n return {\r\n allowed: false,\r\n remaining: 0,\r\n retryAfterMs: entry.resetAt - now,\r\n };\r\n }\r\n\r\n return {\r\n allowed: true,\r\n remaining: this.maxAttempts - entry.count,\r\n retryAfterMs: 0,\r\n };\r\n }\r\n\r\n /** Periodically remove expired entries to prevent unbounded growth. */\r\n cleanup(): void {\r\n const now = Date.now();\r\n for (const [key, entry] of this.buckets) {\r\n if (now >= entry.resetAt) this.buckets.delete(key);\r\n }\r\n }\r\n}\r\n\r\nconst authRateLimiter = new RateLimiter(5, 15 * 60 * 1000);\r\n\r\n// Cleanup expired rate limit entries every 5 minutes\r\nsetInterval(() => {\r\n authRateLimiter.cleanup();\r\n}, 5 * 60 * 1000).unref();\r\n\r\n// ---------------------------------------------------------------------------\r\n// Permission model (mirrors packages/supabase/src/utils/permissions.ts)\r\n// ---------------------------------------------------------------------------\r\n\r\nconst MODULE_KEYS = [\r\n 'users', 'ssh_servers', 'supabase',\r\n 'wiki', 'ci_cd', 'source_control', 'domains',\r\n 'settings', 'agent_reporting',\r\n] as const;\r\n\r\ntype ModuleKey = (typeof MODULE_KEYS)[number];\r\n\r\ninterface ModulePermissions {\r\n users?: boolean;\r\n ssh_servers?: boolean;\r\n supabase?: boolean;\r\n wiki?: boolean;\r\n ci_cd?: boolean;\r\n source_control?: boolean;\r\n domains?: boolean;\r\n settings?: boolean;\r\n agent_reporting?: boolean;\r\n}\r\n\r\ninterface ResourcePermissions {\r\n ssh_servers: string[];\r\n supabase_instances: string[];\r\n}\r\n\r\ninterface UserPermissions {\r\n modules: ModulePermissions;\r\n resources: ResourcePermissions;\r\n}\r\n\r\nconst FULL_PERMISSIONS: UserPermissions = {\r\n modules: Object.fromEntries(MODULE_KEYS.map((k) => [k, true])) as ModulePermissions,\r\n resources: { ssh_servers: ['*'], supabase_instances: ['*'] },\r\n};\r\n\r\nfunction parsePermissions(raw: unknown): Partial<UserPermissions> | null {\r\n if (!raw || typeof raw !== 'object') return null;\r\n return raw as Partial<UserPermissions>;\r\n}\r\n\r\nfunction resolvePermissions(\r\n roleName: string,\r\n roleDefaults: unknown,\r\n userOverrides: unknown,\r\n): UserPermissions {\r\n if (roleName === 'superadmin') return FULL_PERMISSIONS;\r\n\r\n const base = parsePermissions(roleDefaults);\r\n const overrides = parsePermissions(userOverrides);\r\n\r\n const modules: ModulePermissions = {} as ModulePermissions;\r\n for (const key of MODULE_KEYS) {\r\n const userVal = overrides?.modules?.[key];\r\n const roleVal = base?.modules?.[key];\r\n (modules as Record<string, boolean>)[key] =\r\n userVal !== undefined ? userVal : roleVal !== undefined ? roleVal : false;\r\n }\r\n\r\n const resources: ResourcePermissions = {\r\n ssh_servers: overrides?.resources?.ssh_servers ?? base?.resources?.ssh_servers ?? [],\r\n supabase_instances: overrides?.resources?.supabase_instances ?? base?.resources?.supabase_instances ?? [],\r\n };\r\n\r\n return { modules, resources };\r\n}\r\n\r\n/**\r\n * Intersect key-level server restrictions with user permission resources.\r\n * Most restrictive wins: if both specify lists, return the overlap.\r\n */\r\nfunction intersectServerAccess(\r\n keyServerIds: string[] | null,\r\n permissionServerIds: string[],\r\n): string[] | null {\r\n const keyHasRestriction = keyServerIds !== null;\r\n const permWildcard = permissionServerIds.includes('*');\r\n const permEmpty = permissionServerIds.length === 0;\r\n\r\n if (!keyHasRestriction && permWildcard) return null; // unrestricted\r\n if (!keyHasRestriction && permEmpty) return [];\r\n if (!keyHasRestriction) return permissionServerIds;\r\n if (permWildcard) return keyServerIds;\r\n if (permEmpty) return [];\r\n return keyServerIds.filter((id) => permissionServerIds.includes(id));\r\n}\r\n\r\n/** Maps each MCP tool to the module permission it requires. */\r\nconst TOOL_MODULE_MAP: Partial<Record<string, ModuleKey>> = {\r\n 'list-servers': 'ssh_servers',\r\n 'ssh-execute': 'ssh_servers',\r\n 'sftp-list': 'ssh_servers',\r\n 'sftp-read': 'ssh_servers',\r\n 'sftp-write': 'ssh_servers',\r\n 'sftp-delete': 'ssh_servers',\r\n 'docker-list': 'ssh_servers',\r\n 'docker-logs': 'ssh_servers',\r\n 'db-discover': 'ssh_servers',\r\n 'db-tables': 'ssh_servers',\r\n 'db-describe': 'ssh_servers',\r\n 'db-query': 'ssh_servers',\r\n 'cache-purge': 'ssh_servers',\r\n 'env-list': 'ci_cd',\r\n 'env-get': 'ci_cd',\r\n 'env-store': 'ci_cd',\r\n 'domain-list': 'domains',\r\n 'domain-get': 'domains',\r\n 'dns-list': 'domains',\r\n 'dns-create': 'domains',\r\n 'dns-update': 'domains',\r\n 'dns-delete': 'domains',\r\n ...TRIGGER_TOOL_MODULE_MAP,\r\n ...AGENT_TOOL_MODULE_MAP,\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Auth context\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface AuthContext {\r\n userId: string;\r\n allowedServerIds: string[] | null;\r\n permissions: UserPermissions;\r\n roleName: string;\r\n}\r\n\r\nlet authContext: AuthContext | null = null;\r\n\r\nasync function validateApiKey(key: string): Promise<AuthContext | null> {\r\n if (!key.startsWith('dk_') || key.length !== 67) {\r\n console.error('Invalid API key format (expected dk_ + 64 hex chars)');\r\n return null;\r\n }\r\n\r\n const keyHash = createHash('sha256').update(key).digest('hex');\r\n\r\n const rateCheck = authRateLimiter.check(keyHash);\r\n if (!rateCheck.allowed) {\r\n const retryMin = Math.ceil(rateCheck.retryAfterMs / 60_000);\r\n console.error(`Rate limited: too many failed auth attempts. Retry in ${retryMin} minute(s).`);\r\n return null;\r\n }\r\n\r\n const { data, error } = await supabase\r\n .from('dashboard_mcp_api_key')\r\n .select('id, created_by, allowed_server_ids, is_active, expires_at')\r\n .eq('api_key_hash', keyHash)\r\n .eq('is_active', true)\r\n .single();\r\n\r\n if (error || !data) {\r\n console.error(`API key not found or inactive (${rateCheck.remaining} attempts remaining)`);\r\n return null;\r\n }\r\n\r\n if (data.expires_at && new Date(data.expires_at) < new Date()) {\r\n console.error(`API key has expired (${rateCheck.remaining} attempts remaining)`);\r\n return null;\r\n }\r\n\r\n // Load user + role permissions\r\n const { data: userData, error: userError } = await supabase\r\n .from('user')\r\n .select('permissions, role:role!role_id(name, default_permissions)')\r\n .eq('id', data.created_by)\r\n .single();\r\n\r\n if (userError || !userData) {\r\n console.error(`User not found for API key creator: ${data.created_by}`);\r\n return null;\r\n }\r\n\r\n const roleName = (userData.role as { name?: string })?.name || 'user';\r\n const roleDefaults = (userData.role as { default_permissions?: unknown })?.default_permissions ?? {};\r\n const userOverrides = userData.permissions ?? null;\r\n const permissions = resolvePermissions(roleName, roleDefaults, userOverrides);\r\n\r\n const allowedServerIds = intersectServerAccess(\r\n data.allowed_server_ids,\r\n permissions.resources.ssh_servers,\r\n );\r\n\r\n await supabase\r\n .from('dashboard_mcp_api_key')\r\n .update({ last_used_at: new Date().toISOString() })\r\n .eq('id', data.id);\r\n\r\n const moduleCount = MODULE_KEYS.filter((k) => permissions.modules[k]).length;\r\n console.error(`Authenticated as user ${data.created_by} (role: ${roleName}, modules: ${moduleCount}/${MODULE_KEYS.length})`);\r\n\r\n return {\r\n userId: data.created_by,\r\n allowedServerIds,\r\n permissions,\r\n roleName,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Server access helper\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction assertServerAccess(serverId: string): void {\r\n if (!authContext) throw new Error('Not authenticated');\r\n if (authContext.allowedServerIds === null) return;\r\n if (!authContext.allowedServerIds.includes(serverId)) {\r\n throw new Error(`Access denied: you do not have permission for server ${serverId}`);\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Release profile resolution helper\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Resolve a release profile name to its stage IDs.\r\n * Returns { stageIds, profileId } or throws with available profile names.\r\n */\r\nasync function resolveReleaseProfileStageIds(\r\n profileName: string,\r\n): Promise<{ stageIds: string[]; profileId: string }> {\r\n const { data: profile, error } = await supabase\r\n .from('release_profile')\r\n .select('id, name')\r\n .ilike('name', profileName)\r\n .maybeSingle();\r\n\r\n if (error) throw new Error(`Failed to look up release profile: ${error.message}`);\r\n\r\n if (!profile) {\r\n const { data: all } = await supabase\r\n .from('release_profile')\r\n .select('name')\r\n .order('name');\r\n const names = (all || []).map((p) => p.name).join(', ');\r\n throw new Error(\r\n `Release profile \"${profileName}\" not found. Available profiles: ${names || '(none)'}`,\r\n );\r\n }\r\n\r\n const { data: stages, error: stageErr } = await supabase\r\n .from('release_profile_stage')\r\n .select('id')\r\n .eq('release_profile_id', profile.id);\r\n\r\n if (stageErr) throw new Error(`Failed to look up stages: ${stageErr.message}`);\r\n if (!stages || stages.length === 0) {\r\n throw new Error(`Release profile \"${profile.name}\" has no stages configured`);\r\n }\r\n\r\n return { stageIds: stages.map((s) => s.id), profileId: profile.id };\r\n}\r\n\r\n/**\r\n * Look up release profile names for a set of stage IDs.\r\n * Returns a map of stageId -> profileName.\r\n */\r\nasync function getProfileNamesForStageIds(\r\n stageIds: string[],\r\n): Promise<Record<string, string>> {\r\n if (stageIds.length === 0) return {};\r\n\r\n const { data: stages } = await supabase\r\n .from('release_profile_stage')\r\n .select('id, release_profile_id')\r\n .in('id', stageIds);\r\n\r\n if (!stages || stages.length === 0) return {};\r\n\r\n const profileIds = [...new Set(stages.map((s) => s.release_profile_id))];\r\n const { data: profiles } = await supabase\r\n .from('release_profile')\r\n .select('id, name')\r\n .in('id', profileIds);\r\n\r\n if (!profiles) return {};\r\n\r\n const profileMap: Record<string, string> = {};\r\n for (const p of profiles) profileMap[p.id] = p.name;\r\n\r\n const result: Record<string, string> = {};\r\n for (const s of stages) {\r\n result[s.id] = profileMap[s.release_profile_id] || 'unknown';\r\n }\r\n return result;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Encryption helpers (AES-256-GCM, compatible with dashboard encryption.ts)\r\n// ---------------------------------------------------------------------------\r\n\r\nconst ENC_ALGORITHM = 'aes-256-gcm';\r\nconst ENC_IV_LENGTH = 16;\r\nconst ENC_TAG_LENGTH = 16;\r\n\r\nfunction getEncryptionKey(): Buffer {\r\n if (!encryptionKey) throw new Error('ENCRYPTION_KEY is required for env operations');\r\n const buf = Buffer.from(encryptionKey, 'hex');\r\n if (buf.length !== 32) throw new Error('ENCRYPTION_KEY must be a 64-character hex string');\r\n return buf;\r\n}\r\n\r\nfunction encrypt(text: string): string {\r\n const key = getEncryptionKey();\r\n const iv = randomBytes(ENC_IV_LENGTH);\r\n const cipher = createCipheriv(ENC_ALGORITHM, new Uint8Array(key), new Uint8Array(iv));\r\n let encrypted = cipher.update(text, 'utf8', 'hex');\r\n encrypted += cipher.final('hex');\r\n const authTag = cipher.getAuthTag();\r\n return Buffer.concat([\r\n new Uint8Array(iv),\r\n new Uint8Array(authTag),\r\n new Uint8Array(Buffer.from(encrypted, 'hex')),\r\n ]).toString('base64');\r\n}\r\n\r\nfunction decrypt(payload: string): string {\r\n const key = getEncryptionKey();\r\n const buf = Buffer.from(payload, 'base64');\r\n const iv = buf.subarray(0, ENC_IV_LENGTH);\r\n const authTag = buf.subarray(ENC_IV_LENGTH, ENC_IV_LENGTH + ENC_TAG_LENGTH);\r\n const encrypted = buf.subarray(ENC_IV_LENGTH + ENC_TAG_LENGTH);\r\n const decipher = createDecipheriv(ENC_ALGORITHM, new Uint8Array(key), new Uint8Array(iv));\r\n decipher.setAuthTag(new Uint8Array(authTag));\r\n let decrypted = decipher.update(encrypted.toString('hex'), 'hex', 'utf8');\r\n decrypted += decipher.final('utf8');\r\n return decrypted;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Vercel env sync helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nconst VERCEL_API = 'https://api.vercel.com';\r\n\r\n/**\r\n * Parse a .env content string into key-value pairs.\r\n * Lines starting with # and empty lines are skipped.\r\n */\r\nfunction parseEnvContent(content: string): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n for (const line of content.split('\\n')) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('#')) continue;\r\n const eqIdx = trimmed.indexOf('=');\r\n if (eqIdx === -1) continue;\r\n const key = trimmed.slice(0, eqIdx).trim();\r\n let value = trimmed.slice(eqIdx + 1).trim();\r\n if (\r\n (value.startsWith('\"') && value.endsWith('\"')) ||\r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\r\n ) {\r\n value = value.slice(1, -1);\r\n }\r\n if (key) result[key] = value;\r\n }\r\n return result;\r\n}\r\n\r\ninterface VercelEnvVar {\r\n key: string;\r\n value: string;\r\n type: 'plain';\r\n target?: ('production' | 'preview' | 'development')[];\r\n customEnvironmentIds?: string[];\r\n}\r\n\r\ninterface StageApp {\r\n path: string;\r\n label: string;\r\n deployMethod: string;\r\n enabled: boolean;\r\n vercelProjectId?: string | null;\r\n vercelCustomEnvId?: string | null;\r\n}\r\n\r\n/**\r\n * Map stage type to Vercel target environments or custom environment ID.\r\n */\r\nfunction stageToVercelTargets(\r\n stageType: 'dev' | 'staging' | 'prod',\r\n customEnvId?: string | null,\r\n): { target?: ('production' | 'preview' | 'development')[]; customEnvironmentIds?: string[] } {\r\n if (stageType === 'prod') return { target: ['production'] };\r\n if (customEnvId) return { customEnvironmentIds: [customEnvId] };\r\n return { target: ['preview'] };\r\n}\r\n\r\n/** Dev stages also sync to built-in `development` for `vercel dev` (matches dashboard). */\r\nfunction getVercelEnvSyncTargetings(\r\n stageType: 'dev' | 'staging' | 'prod',\r\n customEnvId?: string | null,\r\n): Array<{ target?: ('production' | 'preview' | 'development')[]; customEnvironmentIds?: string[] }> {\r\n const primary = stageToVercelTargets(stageType, customEnvId);\r\n if (stageType !== 'dev') return [primary];\r\n return [primary, { target: ['development'] }];\r\n}\r\n\r\n/**\r\n * Push env vars to a Vercel project using upsert.\r\n */\r\nasync function syncEnvVarsToVercel(\r\n token: string,\r\n projectId: string,\r\n envVars: VercelEnvVar[],\r\n): Promise<{ created: number; error: string | null }> {\r\n if (envVars.length === 0) return { created: 0, error: null };\r\n\r\n const res = await fetch(\r\n `${VERCEL_API}/v10/projects/${encodeURIComponent(projectId)}/env?upsert=true`,\r\n {\r\n method: 'POST',\r\n headers: {\r\n Authorization: `Bearer ${token}`,\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify(envVars),\r\n },\r\n );\r\n\r\n if (!res.ok) {\r\n const body = await res.text().catch(() => '');\r\n return { created: 0, error: `Vercel API ${res.status}: ${body}` };\r\n }\r\n\r\n const data = await res.json().catch(() => ({}));\r\n return { created: (data as any)?.created?.length ?? envVars.length, error: null };\r\n}\r\n\r\n/**\r\n * After an env_config upsert, attempt to sync env vars to Vercel for the\r\n * linked stage. Resolves the stage via `release_profile_stage_id` on the\r\n * record or by looking up siblings with the same `app_name`.\r\n *\r\n * Returns a status string for inclusion in the MCP response.\r\n */\r\nasync function attemptVercelSync(appName: string, environment: string, knownStageId?: string): Promise<string> {\r\n try {\r\n // 1. Find the stage linked to this app_name\r\n let stageId = knownStageId;\r\n if (!stageId) {\r\n const { data: direct } = await supabase\r\n .from('env_config')\r\n .select('release_profile_stage_id')\r\n .eq('app_name', appName)\r\n .not('release_profile_stage_id', 'is', null)\r\n .limit(1)\r\n .single();\r\n\r\n stageId = direct?.release_profile_stage_id;\r\n }\r\n if (!stageId) return 'Vercel sync skipped: no stage link found';\r\n\r\n // 2. Get Vercel token\r\n const { data: settings } = await supabase\r\n .from('app_setting')\r\n .select('vercel_token_encrypted')\r\n .maybeSingle();\r\n\r\n if (!settings?.vercel_token_encrypted) return 'Vercel sync skipped: no Vercel token configured';\r\n\r\n let token: string;\r\n try {\r\n token = decrypt(settings.vercel_token_encrypted);\r\n } catch {\r\n return 'Vercel sync failed: could not decrypt Vercel token';\r\n }\r\n\r\n // 3. Fetch stage + stage_apps\r\n const { data: stage } = await supabase\r\n .from('release_profile_stage')\r\n .select('id, stage, stage_apps')\r\n .eq('id', stageId)\r\n .single();\r\n\r\n if (!stage) return 'Vercel sync skipped: stage not found';\r\n\r\n const stageType = stage.stage as 'dev' | 'staging' | 'prod';\r\n const stageApps: StageApp[] = (stage.stage_apps as StageApp[]) || [];\r\n const vercelApps = stageApps.filter(\r\n (a) => a.deployMethod === 'vercel' && a.enabled && a.vercelProjectId,\r\n );\r\n\r\n if (vercelApps.length === 0) return 'Vercel sync skipped: no Vercel apps in stage';\r\n\r\n // 4. Fetch all env_configs for the stage\r\n const { data: envConfigs } = await supabase\r\n .from('env_config')\r\n .select('*')\r\n .eq('release_profile_stage_id', stageId);\r\n\r\n if (!envConfigs || envConfigs.length === 0) return 'Vercel sync skipped: no env configs for stage';\r\n\r\n const variantMap: Record<string, string> = {\r\n dev: 'development',\r\n staging: 'staging',\r\n prod: 'production',\r\n };\r\n const deployedVariant = variantMap[stageType] ?? stageType;\r\n\r\n // 5. Sync each Vercel app\r\n const syncResults: string[] = [];\r\n for (const app of vercelApps) {\r\n const name = app.path.replace('apps/', '');\r\n const config = envConfigs.find(\r\n (c: any) => c.app_name === name && c.variant === deployedVariant,\r\n );\r\n\r\n if (!config) {\r\n syncResults.push(`${app.label}: skipped (no config for variant \"${deployedVariant}\")`);\r\n continue;\r\n }\r\n\r\n let envContent: string;\r\n try {\r\n envContent = decrypt((config as any).env_data_encrypted);\r\n } catch {\r\n syncResults.push(`${app.label}: decrypt failed`);\r\n continue;\r\n }\r\n\r\n const pairs = parseEnvContent(envContent);\r\n const keys = Object.keys(pairs);\r\n if (keys.length === 0) {\r\n syncResults.push(`${app.label}: empty config`);\r\n continue;\r\n }\r\n\r\n const targetings = getVercelEnvSyncTargetings(stageType, app.vercelCustomEnvId);\r\n let createdTotal = 0;\r\n let lastErr: string | null = null;\r\n\r\n for (const targeting of targetings) {\r\n const envVars: VercelEnvVar[] = keys.map((key) => ({\r\n key,\r\n value: pairs[key]!,\r\n type: 'plain' as const,\r\n ...targeting,\r\n }));\r\n\r\n const { created, error } = await syncEnvVarsToVercel(token, app.vercelProjectId!, envVars);\r\n if (error) lastErr = error;\r\n else createdTotal += created;\r\n }\r\n\r\n if (lastErr) {\r\n syncResults.push(`${app.label}: FAILED - ${lastErr}`);\r\n } else {\r\n syncResults.push(`${app.label}: ${createdTotal} var upsert(s) synced`);\r\n }\r\n }\r\n\r\n return `Vercel sync: ${syncResults.join('; ')}`;\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return `Vercel sync error: ${msg}`;\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// SSH helpers\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface SshConnectionOptions {\r\n hostname: string;\r\n port: number;\r\n username: string;\r\n password?: string;\r\n privateKey?: string;\r\n passphrase?: string;\r\n timeout?: number;\r\n}\r\n\r\ninterface SshResult {\r\n stdout: string;\r\n stderr: string;\r\n exitCode: number;\r\n}\r\n\r\nconst SSH_PROXY_SERVER_ID = '03659d55-e194-400d-b82a-bf6457371ded';\r\nlet _proxyConnCache: SshConnectionOptions | null = null;\r\n\r\nasync function getProxyConnection(): Promise<SshConnectionOptions> {\r\n if (_proxyConnCache) return _proxyConnCache;\r\n\r\n const { data, error } = await supabase\r\n .from('ssh_server')\r\n .select('hostname, port, username, password_encrypted, ssh_key_encrypted, ssh_key_passphrase_encrypted')\r\n .eq('id', SSH_PROXY_SERVER_ID)\r\n .single();\r\n\r\n if (error || !data) throw new Error('SSH Proxy server not found in database');\r\n if (!encryptionKey) throw new Error('ENCRYPTION_KEY required to decrypt server credentials');\r\n\r\n _proxyConnCache = {\r\n hostname: data.hostname,\r\n port: data.port || 22,\r\n username: data.username,\r\n password: data.password_encrypted ? decrypt(data.password_encrypted) : undefined,\r\n privateKey: data.ssh_key_encrypted ? decrypt(data.ssh_key_encrypted) : undefined,\r\n passphrase: data.ssh_key_passphrase_encrypted ? decrypt(data.ssh_key_passphrase_encrypted) : undefined,\r\n };\r\n return _proxyConnCache;\r\n}\r\n\r\n/**\r\n * Get connection options for a server. When `allowed_ssh_ips` is configured,\r\n * also returns proxy options so callers can route through the SSH Proxy.\r\n */\r\nasync function getServerConnection(serverId: string): Promise<{ conn: SshConnectionOptions; proxy?: SshConnectionOptions }> {\r\n assertServerAccess(serverId);\r\n\r\n const { data, error } = await supabase\r\n .from('ssh_server')\r\n .select('hostname, port, username, password_encrypted, ssh_key_encrypted, ssh_key_passphrase_encrypted, allowed_ssh_ips')\r\n .eq('id', serverId)\r\n .single();\r\n\r\n if (error || !data) throw new Error(`Server not found: ${serverId}`);\r\n if (!encryptionKey) throw new Error('ENCRYPTION_KEY required to decrypt server credentials');\r\n\r\n const conn: SshConnectionOptions = {\r\n hostname: data.hostname,\r\n port: data.port || 22,\r\n username: data.username,\r\n password: data.password_encrypted ? decrypt(data.password_encrypted) : undefined,\r\n privateKey: data.ssh_key_encrypted ? decrypt(data.ssh_key_encrypted) : undefined,\r\n passphrase: data.ssh_key_passphrase_encrypted ? decrypt(data.ssh_key_passphrase_encrypted) : undefined,\r\n };\r\n\r\n const needsProxy = data.allowed_ssh_ips !== null && serverId !== SSH_PROXY_SERVER_ID;\r\n const proxy = needsProxy ? await getProxyConnection() : undefined;\r\n\r\n return { conn, proxy };\r\n}\r\n\r\n/**\r\n * Execute an SSH command, optionally tunnelling through a proxy (ProxyJump).\r\n * When proxy is provided, the target server only sees the proxy's IP.\r\n */\r\nasync function sshExec(opts: SshConnectionOptions, command: string, proxy?: SshConnectionOptions): Promise<SshResult> {\r\n if (proxy) return sshExecViaProxy(proxy, opts, command);\r\n\r\n return new Promise((resolve) => {\r\n const ssh = new SshClient();\r\n let stdout = '';\r\n let stderr = '';\r\n let done = false;\r\n const timeout = opts.timeout || 60_000;\r\n\r\n const timer = setTimeout(() => {\r\n if (!done) { done = true; ssh.end(); resolve({ stdout, stderr, exitCode: -1 }); }\r\n }, timeout);\r\n\r\n ssh.on('ready', () => {\r\n ssh.exec(command, (err, stream) => {\r\n if (err) {\r\n if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve({ stdout, stderr, exitCode: -1 }); }\r\n return;\r\n }\r\n stream.on('data', (d: Buffer) => { stdout += d.toString(); });\r\n stream.stderr.on('data', (d: Buffer) => { stderr += d.toString(); });\r\n stream.on('close', (code: number | null) => {\r\n if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve({ stdout, stderr, exitCode: code ?? 0 }); }\r\n });\r\n });\r\n });\r\n\r\n ssh.on('error', (err) => {\r\n if (!done) { done = true; clearTimeout(timer); resolve({ stdout, stderr: err.message, exitCode: -1 }); }\r\n });\r\n\r\n ssh.connect({\r\n host: opts.hostname, port: opts.port, username: opts.username,\r\n password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase,\r\n readyTimeout: timeout,\r\n });\r\n });\r\n}\r\n\r\nfunction sshExecViaProxy(proxyOpts: SshConnectionOptions, targetOpts: SshConnectionOptions, command: string): Promise<SshResult> {\r\n return new Promise((resolve) => {\r\n const proxyClient = new SshClient();\r\n let done = false;\r\n const timeout = targetOpts.timeout || 60_000;\r\n\r\n const timer = setTimeout(() => {\r\n if (!done) { done = true; proxyClient.end(); resolve({ stdout: '', stderr: 'SSH proxy command timeout', exitCode: -1 }); }\r\n }, timeout);\r\n\r\n const cleanup = () => { clearTimeout(timer); proxyClient.end(); };\r\n\r\n proxyClient.on('ready', () => {\r\n proxyClient.forwardOut('127.0.0.1', 0, targetOpts.hostname, targetOpts.port, (err, tunnel) => {\r\n if (err) {\r\n if (!done) { done = true; cleanup(); resolve({ stdout: '', stderr: err.message, exitCode: -1 }); }\r\n return;\r\n }\r\n\r\n const targetClient = new SshClient();\r\n let stdout = '';\r\n let stderr = '';\r\n\r\n targetClient.on('ready', () => {\r\n targetClient.exec(command, (execErr, stream) => {\r\n if (execErr) {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout, stderr, exitCode: -1 }); }\r\n return;\r\n }\r\n stream.on('data', (d: Buffer) => { stdout += d.toString(); });\r\n stream.stderr.on('data', (d: Buffer) => { stderr += d.toString(); });\r\n stream.on('close', (code: number | null) => {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout, stderr, exitCode: code ?? 0 }); }\r\n });\r\n });\r\n });\r\n\r\n targetClient.on('error', (targetErr) => {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout, stderr: targetErr.message, exitCode: -1 }); }\r\n });\r\n\r\n targetClient.connect({\r\n sock: tunnel,\r\n username: targetOpts.username, password: targetOpts.password,\r\n privateKey: targetOpts.privateKey, passphrase: targetOpts.passphrase,\r\n readyTimeout: timeout,\r\n });\r\n });\r\n });\r\n\r\n proxyClient.on('error', (err) => {\r\n if (!done) { done = true; cleanup(); resolve({ stdout: '', stderr: err.message, exitCode: -1 }); }\r\n });\r\n\r\n proxyClient.connect({\r\n host: proxyOpts.hostname, port: proxyOpts.port, username: proxyOpts.username,\r\n password: proxyOpts.password, privateKey: proxyOpts.privateKey, passphrase: proxyOpts.passphrase,\r\n readyTimeout: proxyOpts.timeout || 30_000,\r\n });\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// SFTP helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction sanitizePath(path: string): string {\r\n let normalized = path.replace(/\\\\/g, '/').replace(/\\0/g, '');\r\n const parts = normalized.split('/');\r\n const resolved: string[] = [];\r\n for (const part of parts) {\r\n if (part === '..') { if (resolved.length > 0 && resolved[resolved.length - 1] !== '') resolved.pop(); }\r\n else if (part !== '.' && part !== '') resolved.push(part);\r\n }\r\n return '/' + resolved.join('/');\r\n}\r\n\r\nconst PROTECTED_PATHS = ['/etc/', '/boot/', '/usr/', '/bin/', '/sbin/', '/lib/', '/lib64/'];\r\n\r\nfunction assertWritablePath(path: string): void {\r\n const safe = sanitizePath(path);\r\n for (const p of PROTECTED_PATHS) {\r\n if (safe === p.slice(0, -1) || safe.startsWith(p)) {\r\n throw new Error(`Write access denied to protected path: ${safe}`);\r\n }\r\n }\r\n}\r\n\r\nasync function sftpReaddir(opts: SshConnectionOptions, dirPath: string): Promise<string> {\r\n const safe = sanitizePath(dirPath);\r\n return new Promise((resolve) => {\r\n const ssh = new SshClient();\r\n let done = false;\r\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 30_000);\r\n\r\n ssh.on('ready', () => {\r\n ssh.sftp((err, sftp) => {\r\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\r\n sftp.readdir(safe, (err, list) => {\r\n done = true; clearTimeout(timer);\r\n if (err) { ssh.end(); resolve(`Error: ${err.message}`); return; }\r\n const entries = list.map(item => {\r\n const mode = item.attrs.mode || 0;\r\n const isDir = (mode & 0o170000) === 0o040000;\r\n const size = item.attrs.size || 0;\r\n const mtime = item.attrs.mtime ? new Date(item.attrs.mtime * 1000).toISOString() : '';\r\n return `${isDir ? 'd' : '-'} ${String(size).padStart(10)} ${mtime} ${item.filename}`;\r\n });\r\n ssh.end();\r\n resolve(entries.join('\\n'));\r\n });\r\n });\r\n });\r\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\r\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 30_000 });\r\n });\r\n}\r\n\r\nasync function sftpRead(opts: SshConnectionOptions, filePath: string): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n return new Promise((resolve) => {\r\n const ssh = new SshClient();\r\n let done = false;\r\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 60_000);\r\n\r\n ssh.on('ready', () => {\r\n ssh.sftp((err, sftp) => {\r\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\r\n sftp.stat(safe, (err, stats) => {\r\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\r\n if ((stats.size || 0) > 1_048_576) {\r\n if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: file too large (${stats.size} bytes, max 1MB)`); }\r\n return;\r\n }\r\n const chunks: Buffer[] = [];\r\n const rs = sftp.createReadStream(safe);\r\n rs.on('data', (c: Buffer) => chunks.push(c));\r\n rs.on('end', () => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(Buffer.concat(chunks.map(c => new Uint8Array(c))).toString('utf-8')); } });\r\n rs.on('error', (e: Error) => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${e.message}`); } });\r\n });\r\n });\r\n });\r\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\r\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 60_000 });\r\n });\r\n}\r\n\r\nasync function sftpWrite(opts: SshConnectionOptions, filePath: string, content: string): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n assertWritablePath(safe);\r\n return new Promise((resolve) => {\r\n const ssh = new SshClient();\r\n let done = false;\r\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 60_000);\r\n\r\n ssh.on('ready', () => {\r\n ssh.sftp((err, sftp) => {\r\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\r\n const ws = sftp.createWriteStream(safe, { mode: 0o644 });\r\n ws.on('close', () => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Written ${content.length} bytes to ${safe}`); } });\r\n ws.on('error', (e: Error) => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${e.message}`); } });\r\n ws.end(Buffer.from(content, 'utf-8'));\r\n });\r\n });\r\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\r\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 60_000 });\r\n });\r\n}\r\n\r\nasync function sftpDelete(opts: SshConnectionOptions, filePath: string): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n assertWritablePath(safe);\r\n return new Promise((resolve) => {\r\n const ssh = new SshClient();\r\n let done = false;\r\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 30_000);\r\n\r\n ssh.on('ready', () => {\r\n ssh.sftp((err, sftp) => {\r\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\r\n sftp.unlink(safe, (err) => {\r\n if (err) {\r\n sftp.rmdir(safe, (err2) => {\r\n done = true; clearTimeout(timer); ssh.end();\r\n resolve(err2 ? `Error: ${err.message}` : `Deleted directory ${safe}`);\r\n });\r\n } else {\r\n done = true; clearTimeout(timer); ssh.end();\r\n resolve(`Deleted file ${safe}`);\r\n }\r\n });\r\n });\r\n });\r\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\r\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 30_000 });\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Safety: dangerous command blocklist\r\n// ---------------------------------------------------------------------------\r\n\r\nconst BLOCKED_COMMANDS = [\r\n 'rm -rf /', 'rm -fr /', 'mkfs', 'dd if=', ':(){ :|:& };:',\r\n 'shutdown', 'halt', 'init 0', 'init 6',\r\n '> /dev/sda', 'mv /* /dev/null', 'chmod -R 000 /',\r\n];\r\n\r\nfunction assertSafeCommand(command: string): void {\r\n const lower = command.toLowerCase().trim();\r\n for (const blocked of BLOCKED_COMMANDS) {\r\n if (lower.includes(blocked)) {\r\n throw new Error(`Blocked dangerous command pattern: \"${blocked}\"`);\r\n }\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// MySQL / Database helpers\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface DbCredentials {\r\n host: string;\r\n user: string;\r\n password: string;\r\n database: string;\r\n port: number;\r\n sitePath: string;\r\n appType: string;\r\n}\r\n\r\n/**\r\n * Discovers web applications under /var/www and extracts DB credentials\r\n * from their config files (WordPress, PrestaShop, Laravel, custom .env).\r\n */\r\nasync function discoverSiteDatabases(conn: SshConnectionOptions, proxy?: SshConnectionOptions): Promise<DbCredentials[]> {\r\n const script = `\r\ncheck_dir() {\r\n local base=\"$1\" root=\"$2\"\r\n # WordPress\r\n if [ -f \"$root/wp-config.php\" ]; then\r\n echo \"WP|$base|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_NAME'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_USER'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_PASSWORD'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_HOST'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\"\r\n return\r\n fi\r\n # PrestaShop 1.7+\r\n if [ -f \"$root/app/config/parameters.php\" ]; then\r\n echo \"PS|$base|$(grep -oP \"'database_name'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)|$(grep -oP \"'database_user'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)|$(grep -oP \"'database_password'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)|$(grep -oP \"'database_host'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\"\r\n return\r\n fi\r\n # PrestaShop 1.6\r\n if [ -f \"$root/config/settings.inc.php\" ]; then\r\n echo \"PS|$base|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_NAME_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_USER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_PASSWD_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_SERVER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\"\r\n return\r\n fi\r\n # Laravel / generic .env\r\n if [ -f \"$root/.env\" ]; then\r\n DB_CONN=$(grep -oP '^DB_CONNECTION=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n if [ -n \"$DB_CONN\" ] && [ \"$DB_CONN\" != \"sqlite\" ]; then\r\n echo \"ENV|$base|$(grep -oP '^DB_DATABASE=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_USERNAME=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_PASSWORD=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_HOST=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_PORT=\\\\K.*' \"$root/.env\" 2>/dev/null)\"\r\n return\r\n fi\r\n fi\r\n}\r\nfor dir in /var/www/*/; do\r\n [ -d \"$dir\" ] || continue\r\n check_dir \"$dir\" \"$dir\"\r\n # Also check common subdirectories: html, public_html, public, httpdocs\r\n for sub in html public_html public httpdocs; do\r\n [ -d \"$dir$sub\" ] && check_dir \"$dir\" \"$dir$sub\"\r\n done\r\ndone\r\n`.trim();\r\n\r\n const result = await sshExec(conn, script, proxy);\r\n const sites: DbCredentials[] = [];\r\n\r\n for (const line of result.stdout.split('\\n')) {\r\n if (!line.trim()) continue;\r\n const parts = line.split('|');\r\n if (parts.length < 6) continue;\r\n\r\n const [type, sitePath, database, user, password, host, port] = parts;\r\n if (!database || !user || !type || !sitePath) continue;\r\n\r\n const appTypes: Record<string, string> = { WP: 'WordPress', PS: 'PrestaShop', ENV: 'Laravel/.env' };\r\n\r\n sites.push({\r\n appType: appTypes[type] || type,\r\n sitePath: sitePath.replace(/\\/$/, ''),\r\n database,\r\n user,\r\n password: password || '',\r\n host: host || 'localhost',\r\n port: parseInt(port || '3306', 10),\r\n });\r\n }\r\n\r\n return sites;\r\n}\r\n\r\nfunction escapeMysqlShell(value: string): string {\r\n return value.replace(/'/g, \"'\\\\''\");\r\n}\r\n\r\nconst BLOCKED_SQL_PATTERNS = [\r\n /\\bDROP\\s+DATABASE\\b/i,\r\n /\\bDROP\\s+TABLE\\b/i,\r\n /\\bDROP\\s+INDEX\\b/i,\r\n /\\bTRUNCATE\\b/i,\r\n /\\bALTER\\s+TABLE\\s+\\w+\\s+DROP\\b/i,\r\n /\\bDELETE\\s+FROM\\s+\\w+\\s*$/i,\r\n];\r\n\r\nfunction assertSafeSql(query: string): void {\r\n const trimmed = query.trim();\r\n for (const pattern of BLOCKED_SQL_PATTERNS) {\r\n if (pattern.test(trimmed)) {\r\n throw new Error(`Blocked destructive SQL pattern: ${pattern.source}`);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Builds a shell snippet that discovers DB credentials for a site path\r\n * and then executes a MySQL query, all in a single SSH session.\r\n */\r\nfunction buildSiteMysqlCommand(sitePath: string, query: string): string {\r\n const safePath = escapeMysqlShell(sitePath.replace(/\\/$/, ''));\r\n const safeQuery = escapeMysqlShell(query);\r\n\r\n return `\r\nSITE='${safePath}'\r\nDB_USER=\"\" DB_PASS=\"\" DB_NAME=\"\" DB_HOST=\"localhost\" DB_PORT=\"3306\"\r\nfor root in \"$SITE\" \"$SITE/html\" \"$SITE/public_html\" \"$SITE/public\" \"$SITE/httpdocs\"; do\r\n [ -d \"$root\" ] || continue\r\n if [ -f \"$root/wp-config.php\" ]; then\r\n DB_NAME=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_NAME'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\r\n DB_USER=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_USER'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\r\n DB_PASS=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_PASSWORD'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\r\n DB_HOST=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_HOST'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\r\n break\r\n elif [ -f \"$root/app/config/parameters.php\" ]; then\r\n DB_NAME=$(grep -oP \"'database_name'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\r\n DB_USER=$(grep -oP \"'database_user'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\r\n DB_PASS=$(grep -oP \"'database_password'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\r\n DB_HOST=$(grep -oP \"'database_host'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\r\n break\r\n elif [ -f \"$root/config/settings.inc.php\" ]; then\r\n DB_NAME=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_NAME_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\r\n DB_USER=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_USER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\r\n DB_PASS=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_PASSWD_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\r\n DB_HOST=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_SERVER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\r\n break\r\n elif [ -f \"$root/.env\" ]; then\r\n DB_CONN=$(grep -oP '^DB_CONNECTION=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n if [ -n \"$DB_CONN\" ] && [ \"$DB_CONN\" != \"sqlite\" ]; then\r\n DB_NAME=$(grep -oP '^DB_DATABASE=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n DB_USER=$(grep -oP '^DB_USERNAME=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n DB_PASS=$(grep -oP '^DB_PASSWORD=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n DB_HOST=$(grep -oP '^DB_HOST=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n DB_PORT=$(grep -oP '^DB_PORT=\\\\K.*' \"$root/.env\" 2>/dev/null)\r\n break\r\n fi\r\n fi\r\ndone\r\n[ -z \"$DB_NAME\" ] || [ -z \"$DB_USER\" ] && echo \"ERROR: No database config found at $SITE\" && exit 1\r\nDB_HOST=\\${DB_HOST:-localhost}\r\nDB_PORT=\\${DB_PORT:-3306}\r\nmysql --user=\"$DB_USER\" --password=\"$DB_PASS\" --host=\"$DB_HOST\" --port=\"$DB_PORT\" -t -e '${safeQuery}' \"$DB_NAME\" 2>&1 | grep -v \"\\\\[Warning\\\\].*password\"\r\n`.trim();\r\n}\r\n\r\n/**\r\n * Execute a MySQL query for a site in a single SSH session.\r\n * Discovers credentials and runs the query in one command.\r\n */\r\nasync function execSiteMysql(conn: SshConnectionOptions, sitePath: string, query: string, proxy?: SshConnectionOptions): Promise<string> {\r\n const cmd = buildSiteMysqlCommand(sitePath, query);\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = (result.stdout || '').trim();\r\n if (output.startsWith('ERROR: No database config found')) {\r\n throw new Error(output);\r\n }\r\n if (result.exitCode !== 0 && !output) {\r\n throw new Error(result.stderr || 'MySQL command failed');\r\n }\r\n return output;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// mijn.host API helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nconst MIJNHOST_BASE_URL = 'https://mijn.host/api/v2';\r\n\r\ninterface MijnHostApiResponse<T = unknown> {\r\n status: number;\r\n status_description: string;\r\n data: T;\r\n}\r\n\r\nfunction requireMijnhostApiKey(): string {\r\n if (!mijnhostApiKey) {\r\n throw new Error('mijn.host API key not configured. Use --mijnhost-api-key=xxx or set MIJNHOST_API_KEY');\r\n }\r\n return mijnhostApiKey;\r\n}\r\n\r\nasync function mijnhostFetch<T>(path: string, options: RequestInit = {}): Promise<MijnHostApiResponse<T>> {\r\n const key = requireMijnhostApiKey();\r\n\r\n const res = await fetch(`${MIJNHOST_BASE_URL}${path}`, {\r\n ...options,\r\n headers: {\r\n 'API-Key': key,\r\n 'Accept': 'application/json',\r\n 'Content-Type': 'application/json',\r\n 'User-Agent': 'mg-dashboard-mcp/2.2.0',\r\n ...((options.headers as Record<string, string>) || {}),\r\n },\r\n });\r\n\r\n const json: unknown = await res.json();\r\n const body = json as MijnHostApiResponse<T>;\r\n\r\n if (!res.ok) {\r\n throw new Error(body?.status_description || `mijn.host API error: ${res.status}`);\r\n }\r\n\r\n return body;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nconst TOOLS = [\r\n {\r\n name: 'list-servers',\r\n description: 'List all SSH servers you have access to. Returns id, name, hostname, and tags for each server.',\r\n inputSchema: { type: 'object' as const, properties: {}, required: [] },\r\n },\r\n {\r\n name: 'ssh-execute',\r\n description: 'Execute a shell command on a remote server via SSH. Some dangerous commands are blocked for safety.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n command: { type: 'string', description: 'Shell command to execute' },\r\n timeout: { type: 'number', description: 'Timeout in milliseconds (default: 60000)' },\r\n },\r\n required: ['serverId', 'command'],\r\n },\r\n },\r\n {\r\n name: 'sftp-list',\r\n description: 'List files and directories at a given path on a remote server via SFTP.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n path: { type: 'string', description: 'Directory path to list (default: /)' },\r\n },\r\n required: ['serverId'],\r\n },\r\n },\r\n {\r\n name: 'sftp-read',\r\n description: 'Read the contents of a text file on a remote server via SFTP (max 1MB).',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n path: { type: 'string', description: 'File path to read' },\r\n },\r\n required: ['serverId', 'path'],\r\n },\r\n },\r\n {\r\n name: 'sftp-write',\r\n description: 'Write content to a file on a remote server via SFTP. Protected system paths are blocked.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n path: { type: 'string', description: 'File path to write' },\r\n content: { type: 'string', description: 'File content to write' },\r\n },\r\n required: ['serverId', 'path', 'content'],\r\n },\r\n },\r\n {\r\n name: 'sftp-delete',\r\n description: 'Delete a file or empty directory on a remote server via SFTP. Protected system paths are blocked.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n path: { type: 'string', description: 'File or directory path to delete' },\r\n },\r\n required: ['serverId', 'path'],\r\n },\r\n },\r\n {\r\n name: 'docker-list',\r\n description: 'List all Docker containers on a remote server (running and stopped).',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n },\r\n required: ['serverId'],\r\n },\r\n },\r\n {\r\n name: 'docker-logs',\r\n description: 'Get recent logs from a Docker container.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n containerName: { type: 'string', description: 'Container name or ID' },\r\n lines: { type: 'number', description: 'Number of log lines to retrieve (default: 100)' },\r\n },\r\n required: ['serverId', 'containerName'],\r\n },\r\n },\r\n {\r\n name: 'db-discover',\r\n description: 'Scan /var/www on a server for web applications (WordPress, PrestaShop, Laravel, .env) and list their database credentials. Use this first to find available sites before running other db-* tools.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n },\r\n required: ['serverId'],\r\n },\r\n },\r\n {\r\n name: 'db-tables',\r\n description: 'List all tables in a site database with row counts and sizes. Credentials are auto-discovered from the site config files (wp-config.php, parameters.php, .env).',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com)' },\r\n },\r\n required: ['serverId', 'sitePath'],\r\n },\r\n },\r\n {\r\n name: 'db-describe',\r\n description: 'Show the structure of a database table (columns, types, keys, defaults). Credentials are auto-discovered from site config files.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com)' },\r\n table: { type: 'string', description: 'Table name' },\r\n },\r\n required: ['serverId', 'sitePath', 'table'],\r\n },\r\n },\r\n {\r\n name: 'db-query',\r\n description: 'Execute a SQL query on a site database. Credentials are auto-discovered from site config files. Destructive operations (DROP, TRUNCATE) are blocked.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com)' },\r\n query: { type: 'string', description: 'SQL query to execute' },\r\n },\r\n required: ['serverId', 'sitePath', 'query'],\r\n },\r\n },\r\n {\r\n name: 'env-list',\r\n description: 'List all stored environment configurations with their release profile names.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n releaseProfile: { type: 'string', description: 'Release profile name to filter by (usually matches the project folder name or git repo name, e.g. prefabaanbouw). Omit to list all.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'env-get',\r\n description: 'Retrieve the decrypted .env content for a specific app and environment.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n appName: { type: 'string', description: 'Application name (e.g. backoffice, api, web)' },\r\n environment: { type: 'string', description: 'Environment name (e.g. production, staging, development, local)' },\r\n releaseProfile: { type: 'string', description: 'Release profile name (usually matches the project folder name or git repo name, e.g. prefabaanbouw). Required when multiple profiles exist. Use env-list to discover available profiles.' },\r\n },\r\n required: ['appName', 'environment'],\r\n },\r\n },\r\n {\r\n name: 'env-store',\r\n description: 'Store or update an encrypted .env configuration for an app and environment.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n appName: { type: 'string', description: 'Application name (e.g. backoffice, api, web)' },\r\n environment: { type: 'string', description: 'Environment name (e.g. production, staging, development, local)' },\r\n content: { type: 'string', description: 'The .env file content to store' },\r\n description: { type: 'string', description: 'Optional description' },\r\n releaseProfile: { type: 'string', description: 'Release profile name (usually matches the project folder name or git repo name, e.g. prefabaanbouw). Required when multiple profiles exist. Use env-list to discover available profiles.' },\r\n },\r\n required: ['appName', 'environment', 'content'],\r\n },\r\n },\r\n {\r\n name: 'cache-purge',\r\n description: 'Purge ALL caches on a server in one operation: OPcache (kills lsphp), LiteSpeed cache, WordPress object cache (wp-cli or file-based), PrestaShop Smarty/app cache, Redis FLUSHALL, and Memcached flush. Returns a per-cache status report.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server' },\r\n },\r\n required: ['serverId'],\r\n },\r\n },\r\n // ----- Domains (mijn.host) -----\r\n {\r\n name: 'domain-list',\r\n description: 'List all domains from the mijn.host account. Returns domain name, status, renewal date, and tags. Requires MIJNHOST_API_KEY.',\r\n inputSchema: { type: 'object' as const, properties: {}, required: [] },\r\n },\r\n {\r\n name: 'domain-get',\r\n description: 'Get detailed information about a specific domain: status, renewal date, lock state, managed DNS, DNSSEC, nameservers, contact handles, and messages.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\r\n },\r\n required: ['domain'],\r\n },\r\n },\r\n {\r\n name: 'dns-list',\r\n description: 'List all DNS records for a domain. Returns type (A, AAAA, CNAME, MX, TXT, etc.), name, value, and TTL for each record.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\r\n },\r\n required: ['domain'],\r\n },\r\n },\r\n {\r\n name: 'dns-create',\r\n description: 'Add a new DNS record to a domain. Uses PATCH to add without replacing existing records.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\r\n type: { type: 'string', description: 'Record type: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, or TLSA' },\r\n name: { type: 'string', description: 'Record name (e.g. @ or subdomain)' },\r\n value: { type: 'string', description: 'Record value (e.g. IP address, hostname)' },\r\n ttl: { type: 'number', description: 'TTL in seconds (min 60, default 3600)' },\r\n },\r\n required: ['domain', 'type', 'name', 'value'],\r\n },\r\n },\r\n {\r\n name: 'dns-update',\r\n description: 'Update an existing DNS record. Identifies the record by type+name+oldValue, then replaces it with new values via PATCH.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\r\n type: { type: 'string', description: 'Record type: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, or TLSA' },\r\n name: { type: 'string', description: 'Record name' },\r\n oldValue: { type: 'string', description: 'Current value of the record to update' },\r\n newValue: { type: 'string', description: 'New value for the record' },\r\n ttl: { type: 'number', description: 'New TTL in seconds (min 60)' },\r\n },\r\n required: ['domain', 'type', 'name', 'oldValue', 'newValue'],\r\n },\r\n },\r\n {\r\n name: 'dns-delete',\r\n description: 'Delete a DNS record by type, name, and value. Fetches all records, removes the matching one, then replaces the full set.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\r\n type: { type: 'string', description: 'Record type to delete' },\r\n name: { type: 'string', description: 'Record name to delete' },\r\n value: { type: 'string', description: 'Record value to delete (must match exactly)' },\r\n },\r\n required: ['domain', 'type', 'name', 'value'],\r\n },\r\n },\r\n // ----- Trigger.dev -----\r\n ...TRIGGER_TOOLS,\r\n // ----- Scripts -----\r\n ...SCRIPT_TOOLS,\r\n // ----- Agent Reporting -----\r\n ...AGENT_TOOLS,\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// MCP Server\r\n// ---------------------------------------------------------------------------\r\n\r\nconst MCP_VERSION = '2.3.1';\r\n\r\nasync function handleListTools() {\r\n if (!authContext) return { tools: TOOLS };\r\n\r\n const accessible = TOOLS.filter((tool) => {\r\n const requiredModule = TOOL_MODULE_MAP[tool.name];\r\n if (!requiredModule) return true;\r\n return authContext!.permissions.modules[requiredModule] === true;\r\n });\r\n\r\n return { tools: accessible };\r\n}\r\n\r\nasync function handleCallTool(request: { params: { name: string; arguments?: Record<string, unknown> } }) {\r\n if (!authContext) {\r\n return { content: [{ type: 'text', text: 'Error: not authenticated' }] };\r\n }\r\n\r\n const { name, arguments: toolArgs } = request.params;\r\n const a = (toolArgs || {}) as Record<string, unknown>;\r\n\r\n // Module-level permission check\r\n const requiredModule = TOOL_MODULE_MAP[name];\r\n if (requiredModule && authContext.permissions.modules[requiredModule] !== true) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Access denied: you do not have permission for the \"${requiredModule}\" module (tool: ${name})`,\r\n }],\r\n };\r\n }\r\n\r\n try {\r\n switch (name) {\r\n // ----- Servers -----\r\n case 'list-servers': {\r\n let query = supabase\r\n .from('ssh_server')\r\n .select('id, name, hostname, port, username, tags, hosted_by, created_at')\r\n .order('name');\r\n\r\n if (authContext.allowedServerIds !== null) {\r\n query = query.in('id', authContext.allowedServerIds);\r\n }\r\n\r\n const { data, error } = await query;\r\n if (error) throw new Error(error.message);\r\n\r\n const lines = (data || []).map(s => {\r\n const tags = Array.isArray(s.tags) ? (s.tags as string[]).join(', ') : '';\r\n return `${s.id} ${s.name} ${s.hostname}:${s.port} ${s.username} [${tags}] ${s.hosted_by || ''}`;\r\n });\r\n\r\n return { content: [{ type: 'text', text: lines.length ? lines.join('\\n') : 'No servers found' }] };\r\n }\r\n\r\n // ----- SSH -----\r\n case 'ssh-execute': {\r\n const command = String(a.command);\r\n assertSafeCommand(command);\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n if (a.timeout) conn.timeout = Number(a.timeout);\r\n const result = await sshExec(conn, command, proxy);\r\n const output = [`Exit code: ${result.exitCode}`];\r\n if (result.stdout) output.push(`--- stdout ---\\n${result.stdout}`);\r\n if (result.stderr) output.push(`--- stderr ---\\n${result.stderr}`);\r\n return { content: [{ type: 'text', text: output.join('\\n') }] };\r\n }\r\n\r\n // ----- SFTP (no proxy support yet — direct connection only) -----\r\n case 'sftp-list': {\r\n const { conn } = await getServerConnection(String(a.serverId));\r\n const listing = await sftpReaddir(conn, String(a.path || '/'));\r\n return { content: [{ type: 'text', text: listing }] };\r\n }\r\n\r\n case 'sftp-read': {\r\n const { conn } = await getServerConnection(String(a.serverId));\r\n const content = await sftpRead(conn, String(a.path));\r\n return { content: [{ type: 'text', text: content }] };\r\n }\r\n\r\n case 'sftp-write': {\r\n const { conn } = await getServerConnection(String(a.serverId));\r\n const result = await sftpWrite(conn, String(a.path), String(a.content));\r\n return { content: [{ type: 'text', text: result }] };\r\n }\r\n\r\n case 'sftp-delete': {\r\n const { conn } = await getServerConnection(String(a.serverId));\r\n const result = await sftpDelete(conn, String(a.path));\r\n return { content: [{ type: 'text', text: result }] };\r\n }\r\n\r\n // ----- Docker -----\r\n case 'docker-list': {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const result = await sshExec(conn, 'docker ps -a --format \"table {{.Names}}\\t{{.Image}}\\t{{.Status}}\\t{{.Ports}}\"', proxy);\r\n return { content: [{ type: 'text', text: result.exitCode === 0 ? result.stdout : `Error: ${result.stderr}` }] };\r\n }\r\n\r\n case 'docker-logs': {\r\n const container = String(a.containerName).replace(/[^a-zA-Z0-9._-]/g, '');\r\n const lines = Number(a.lines) || 100;\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const result = await sshExec(conn, `docker logs --tail ${lines} ${container} 2>&1`, proxy);\r\n return { content: [{ type: 'text', text: result.exitCode === 0 ? result.stdout : `Error: ${result.stderr}` }] };\r\n }\r\n\r\n // ----- Database -----\r\n case 'db-discover': {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const sites = await discoverSiteDatabases(conn, proxy);\r\n if (!sites.length) {\r\n return { content: [{ type: 'text', text: 'No web applications with database configs found in /var/www/' }] };\r\n }\r\n const lines = sites.map(s =>\r\n `${s.sitePath} [${s.appType}] db=${s.database} user=${s.user} host=${s.host}:${s.port}`\r\n );\r\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\r\n }\r\n\r\n case 'db-tables': {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const sql = \"SELECT TABLE_NAME, ENGINE, TABLE_ROWS, ROUND(DATA_LENGTH/1024/1024, 2) AS `Size (MB)`, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME\";\r\n const output = await execSiteMysql(conn, String(a.sitePath), sql, proxy);\r\n return { content: [{ type: 'text', text: output || 'No tables found' }] };\r\n }\r\n\r\n case 'db-describe': {\r\n const table = String(a.table).replace(/[^a-zA-Z0-9_]/g, '');\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const output = await execSiteMysql(conn, String(a.sitePath),\r\n `DESCRIBE \\`${table}\\`; SHOW INDEX FROM \\`${table}\\``, proxy);\r\n return { content: [{ type: 'text', text: output }] };\r\n }\r\n\r\n case 'db-query': {\r\n const query = String(a.query).trim();\r\n assertSafeSql(query);\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const output = await execSiteMysql(conn, String(a.sitePath), query, proxy);\r\n return { content: [{ type: 'text', text: output || 'Query executed successfully (no output)' }] };\r\n }\r\n\r\n // ----- Env Config -----\r\n case 'env-list': {\r\n let query = supabase\r\n .from('env_config')\r\n .select('id, app_name, environment, description, updated_at, release_profile_stage_id')\r\n .order('app_name')\r\n .order('environment');\r\n\r\n if (a.releaseProfile) {\r\n const { stageIds } = await resolveReleaseProfileStageIds(String(a.releaseProfile));\r\n query = query.in('release_profile_stage_id', stageIds);\r\n }\r\n\r\n const { data, error } = await query;\r\n if (error) throw new Error(error.message);\r\n\r\n const stageIds = (data || [])\r\n .map((e) => e.release_profile_stage_id)\r\n .filter(Boolean) as string[];\r\n const profileNames = await getProfileNamesForStageIds(stageIds);\r\n\r\n const lines = (data || []).map((e) => {\r\n const profile = e.release_profile_stage_id\r\n ? profileNames[e.release_profile_stage_id] || 'unknown'\r\n : 'unlinked';\r\n return `${e.app_name}/${e.environment} [${profile}] (updated: ${e.updated_at})`;\r\n });\r\n return { content: [{ type: 'text', text: lines.length ? lines.join('\\n') : 'No environment configs stored' }] };\r\n }\r\n\r\n case 'env-get': {\r\n let query = supabase\r\n .from('env_config')\r\n .select('env_data_encrypted, release_profile_stage_id')\r\n .eq('app_name', String(a.appName))\r\n .eq('environment', String(a.environment));\r\n\r\n if (a.releaseProfile) {\r\n const { stageIds } = await resolveReleaseProfileStageIds(String(a.releaseProfile));\r\n query = query.in('release_profile_stage_id', stageIds);\r\n }\r\n\r\n const { data, error } = await query;\r\n\r\n if (error) throw new Error(`Env config query failed: ${error.message}`);\r\n if (!data || data.length === 0) {\r\n throw new Error(`Env config not found: ${a.appName}/${a.environment}${a.releaseProfile ? ` (profile: ${a.releaseProfile})` : ''}`);\r\n }\r\n if (data.length > 1) {\r\n const stageIds = data\r\n .map((r) => r.release_profile_stage_id)\r\n .filter(Boolean) as string[];\r\n const profileNames = await getProfileNamesForStageIds(stageIds);\r\n const names = [...new Set(Object.values(profileNames))].join(', ');\r\n throw new Error(\r\n `Multiple env configs found for ${a.appName}/${a.environment} across profiles: ${names}. ` +\r\n `Pass releaseProfile parameter to select one (e.g. releaseProfile: \"${Object.values(profileNames)[0] || '...'}\")`,\r\n );\r\n }\r\n\r\n const decrypted = decrypt(data[0]!.env_data_encrypted);\r\n return { content: [{ type: 'text', text: decrypted }] };\r\n }\r\n\r\n case 'env-store': {\r\n const appName = String(a.appName);\r\n const environment = String(a.environment);\r\n const encrypted = encrypt(String(a.content));\r\n\r\n let resolvedStageIds: string[] | null = null;\r\n if (a.releaseProfile) {\r\n const { stageIds } = await resolveReleaseProfileStageIds(String(a.releaseProfile));\r\n resolvedStageIds = stageIds;\r\n }\r\n\r\n let existQuery = supabase\r\n .from('env_config')\r\n .select('id, release_profile_stage_id')\r\n .eq('app_name', appName)\r\n .eq('environment', environment);\r\n\r\n if (resolvedStageIds) {\r\n existQuery = existQuery.in('release_profile_stage_id', resolvedStageIds);\r\n }\r\n\r\n const { data: existingRows, error: existErr } = await existQuery;\r\n if (existErr) throw new Error(`Lookup failed: ${existErr.message}`);\r\n\r\n if (existingRows && existingRows.length > 1 && !resolvedStageIds) {\r\n const stageIds = existingRows\r\n .map((r) => r.release_profile_stage_id)\r\n .filter(Boolean) as string[];\r\n const profileNames = await getProfileNamesForStageIds(stageIds);\r\n const names = [...new Set(Object.values(profileNames))].join(', ');\r\n throw new Error(\r\n `Multiple env configs found for ${appName}/${environment} across profiles: ${names}. ` +\r\n `Pass releaseProfile parameter to select one.`,\r\n );\r\n }\r\n\r\n const existing = existingRows?.[0] ?? null;\r\n let saveMsg: string;\r\n if (existing) {\r\n const { error } = await supabase\r\n .from('env_config')\r\n .update({\r\n env_data_encrypted: encrypted,\r\n description: a.description ? String(a.description) : undefined,\r\n updated_by: authContext!.userId,\r\n updated_at: new Date().toISOString(),\r\n })\r\n .eq('id', existing.id);\r\n if (error) throw new Error(error.message);\r\n saveMsg = `Updated env config: ${appName}/${environment}`;\r\n } else {\r\n const insertData: Record<string, unknown> = {\r\n app_name: appName,\r\n environment,\r\n env_data_encrypted: encrypted,\r\n description: a.description ? String(a.description) : null,\r\n created_by: authContext!.userId,\r\n updated_by: authContext!.userId,\r\n };\r\n if (resolvedStageIds?.[0]) {\r\n insertData.release_profile_stage_id = resolvedStageIds[0];\r\n }\r\n const { error } = await supabase.from('env_config').insert(insertData);\r\n if (error) throw new Error(error.message);\r\n saveMsg = `Stored env config: ${appName}/${environment}`;\r\n }\r\n\r\n const syncStageId = existing?.release_profile_stage_id ?? resolvedStageIds?.[0];\r\n const vercelStatus = await attemptVercelSync(appName, environment, syncStageId);\r\n return { content: [{ type: 'text', text: `${saveMsg}. ${vercelStatus}` }] };\r\n }\r\n\r\n // ----- Cache Purge -----\r\n case 'cache-purge': {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n conn.timeout = 120_000;\r\n const script = `\r\nR=\"\"\r\n# 1. OPcache – kill lsphp so it respawns with a fresh OPcache\r\nif pgrep -x lsphp >/dev/null 2>&1; then\r\n sudo killall lsphp 2>/dev/null && R=\"\\${R}[OK] OPcache: killed lsphp processes\\\\n\" || R=\"\\${R}[FAIL] OPcache: could not kill lsphp\\\\n\"\r\nelse\r\n R=\"\\${R}[SKIP] OPcache: no lsphp processes running\\\\n\"\r\nfi\r\n# 2. LiteSpeed cache directories\r\nLS=0\r\nfor cdir in /tmp/lshttpd/swap /usr/local/lsws/cachedata; do\r\n if [ -d \"\\$cdir\" ] && [ \"\\$(ls -A \"\\$cdir\" 2>/dev/null)\" ]; then\r\n sudo rm -rf \"\\$cdir\"/* 2>/dev/null && R=\"\\${R}[OK] LS cache: cleared \\$cdir\\\\n\" && LS=1 || R=\"\\${R}[FAIL] LS cache: \\$cdir\\\\n\"\r\n fi\r\ndone\r\n[ \"\\$LS\" -eq 0 ] && R=\"\\${R}[SKIP] LS cache: no cache dirs with content\\\\n\"\r\n# 3. LiteSpeed graceful restart\r\nif [ -x /usr/local/lsws/bin/lswsctrl ]; then\r\n sudo /usr/local/lsws/bin/lswsctrl restart 2>/dev/null && R=\"\\${R}[OK] LiteSpeed: graceful restart\\\\n\" || R=\"\\${R}[FAIL] LiteSpeed: restart failed\\\\n\"\r\nelif systemctl is-active lsws >/dev/null 2>&1 || systemctl is-active lshttpd >/dev/null 2>&1; then\r\n sudo systemctl restart lsws 2>/dev/null || sudo systemctl restart lshttpd 2>/dev/null\r\n R=\"\\${R}[OK] LiteSpeed: restarted via systemctl\\\\n\"\r\nelse\r\n R=\"\\${R}[SKIP] LiteSpeed: not detected\\\\n\"\r\nfi\r\n# 4. WordPress caches\r\nWP=0\r\nfor dir in /var/www/*/; do\r\n [ -d \"\\$dir\" ] || continue\r\n for root in \"\\$dir\" \"\\${dir}html\" \"\\${dir}public_html\" \"\\${dir}public\" \"\\${dir}httpdocs\"; do\r\n [ -f \"\\$root/wp-config.php\" ] || continue\r\n WP=1; SITE=\\$(basename \"\\$dir\")\r\n if command -v wp >/dev/null 2>&1; then\r\n wp cache flush --allow-root --path=\"\\$root\" 2>/dev/null && R=\"\\${R}[OK] WP (\\$SITE): wp cache flush\\\\n\" || R=\"\\${R}[FAIL] WP (\\$SITE): wp cache flush\\\\n\"\r\n elif [ -d \"\\$root/wp-content/cache\" ]; then\r\n rm -rf \"\\$root/wp-content/cache\"/* 2>/dev/null && R=\"\\${R}[OK] WP (\\$SITE): cleared wp-content/cache\\\\n\"\r\n else\r\n R=\"\\${R}[SKIP] WP (\\$SITE): no cache dir, no wp-cli\\\\n\"\r\n fi\r\n break\r\n done\r\ndone\r\n[ \"\\$WP\" -eq 0 ] && R=\"\\${R}[SKIP] WordPress: no sites found\\\\n\"\r\n# 5. PrestaShop caches\r\nPS=0\r\nfor dir in /var/www/*/; do\r\n [ -d \"\\$dir\" ] || continue\r\n for root in \"\\$dir\" \"\\${dir}html\" \"\\${dir}public_html\" \"\\${dir}public\" \"\\${dir}httpdocs\"; do\r\n IS=0\r\n [ -f \"\\$root/app/config/parameters.php\" ] && IS=1\r\n [ -f \"\\$root/config/settings.inc.php\" ] && IS=1\r\n [ \"\\$IS\" -eq 0 ] && continue\r\n PS=1; SITE=\\$(basename \"\\$dir\"); C=\"\"\r\n [ -d \"\\$root/var/cache\" ] && rm -rf \"\\$root/var/cache\"/* 2>/dev/null && C=\"\\${C}var/cache \"\r\n [ -d \"\\$root/cache/smarty/compile\" ] && rm -rf \"\\$root/cache/smarty/compile\"/* 2>/dev/null && C=\"\\${C}smarty/compile \"\r\n [ -d \"\\$root/cache/smarty/cache\" ] && rm -rf \"\\$root/cache/smarty/cache\"/* 2>/dev/null && C=\"\\${C}smarty/cache \"\r\n [ -n \"\\$C\" ] && R=\"\\${R}[OK] PS (\\$SITE): cleared \\${C}\\\\n\" || R=\"\\${R}[SKIP] PS (\\$SITE): no cache dirs\\\\n\"\r\n break\r\n done\r\ndone\r\n[ \"\\$PS\" -eq 0 ] && R=\"\\${R}[SKIP] PrestaShop: no sites found\\\\n\"\r\n# 6. Redis\r\nif command -v redis-cli >/dev/null 2>&1 && redis-cli ping >/dev/null 2>&1; then\r\n redis-cli FLUSHALL 2>/dev/null && R=\"\\${R}[OK] Redis: FLUSHALL\\\\n\" || R=\"\\${R}[FAIL] Redis: FLUSHALL failed\\\\n\"\r\nelse\r\n R=\"\\${R}[SKIP] Redis: not available\\\\n\"\r\nfi\r\n# 7. Memcached\r\nif systemctl is-active memcached >/dev/null 2>&1; then\r\n if command -v memcflush >/dev/null 2>&1; then\r\n memcflush --servers=localhost 2>/dev/null && R=\"\\${R}[OK] Memcached: flushed\\\\n\" || R=\"\\${R}[FAIL] Memcached: flush failed\\\\n\"\r\n else\r\n echo \"flush_all\" | nc -q1 localhost 11211 2>/dev/null && R=\"\\${R}[OK] Memcached: flushed via nc\\\\n\" || R=\"\\${R}[FAIL] Memcached: flush failed\\\\n\"\r\n fi\r\nelse\r\n R=\"\\${R}[SKIP] Memcached: not active\\\\n\"\r\nfi\r\necho -e \"\\$R\"\r\n`.trim();\r\n const result = await sshExec(conn, script, proxy);\r\n const output = (result.stdout || '').trim();\r\n return { content: [{ type: 'text', text: output || 'Cache purge completed (no output)' }] };\r\n }\r\n\r\n // ----- Domains (mijn.host) -----\r\n case 'domain-list': {\r\n interface DomainListItem {\r\n id: number;\r\n domain: string;\r\n renewal_date: string;\r\n status: string;\r\n status_id: number;\r\n tags: string[];\r\n }\r\n\r\n const res = await mijnhostFetch<{ domains: DomainListItem[] }>('/domains');\r\n const domains = res.data.domains;\r\n\r\n if (!domains.length) {\r\n return { content: [{ type: 'text', text: 'No domains found' }] };\r\n }\r\n\r\n const lines = domains.map(d => {\r\n const tags = d.tags?.length ? ` [${d.tags.join(', ')}]` : '';\r\n return `${d.domain} status=${d.status} renewal=${d.renewal_date}${tags}`;\r\n });\r\n\r\n return { content: [{ type: 'text', text: `${domains.length} domain(s):\\n\\n${lines.join('\\n')}` }] };\r\n }\r\n\r\n case 'domain-get': {\r\n const domain = String(a.domain);\r\n if (!domain) throw new Error('domain is required');\r\n\r\n interface DomainDetail {\r\n domain: string;\r\n renewal_date: string;\r\n is_lockable: boolean;\r\n is_locked: boolean;\r\n dnssec_enabled: number;\r\n nameservers: string[];\r\n managed_dns: boolean;\r\n whitelabel_ns: boolean;\r\n handles: {\r\n owner: { type: string; name: string; handle_id: number };\r\n tech: { type: string; name: string; handle_id: number };\r\n admin: { type: string; name: string; handle_id: number };\r\n reseller: { type: string; name: string; handle_id: number };\r\n };\r\n status: string;\r\n messages: string[];\r\n }\r\n\r\n const res = await mijnhostFetch<DomainDetail>(`/domains/${encodeURIComponent(domain)}`);\r\n const d = res.data;\r\n\r\n const sections = [\r\n `=== ${d.domain} ===`,\r\n `Status: ${d.status}`,\r\n `Renewal: ${d.renewal_date}`,\r\n `Locked: ${d.is_locked ? 'Yes' : 'No'} (lockable: ${d.is_lockable ? 'Yes' : 'No'})`,\r\n `Managed DNS: ${d.managed_dns ? 'Yes' : 'No'}`,\r\n `DNSSEC: ${d.dnssec_enabled ? 'Enabled' : 'Disabled'}`,\r\n `Nameservers: ${d.nameservers.join(', ')}`,\r\n '',\r\n '--- Contact Handles ---',\r\n `Owner: ${d.handles?.owner?.name ?? '-'}`,\r\n `Admin: ${d.handles?.admin?.name ?? '-'}`,\r\n `Tech: ${d.handles?.tech?.name ?? '-'}`,\r\n `Reseller: ${d.handles?.reseller?.name ?? '-'}`,\r\n ];\r\n\r\n if (d.messages?.length) {\r\n sections.push('', '--- Messages ---', ...d.messages);\r\n }\r\n\r\n return { content: [{ type: 'text', text: sections.join('\\n') }] };\r\n }\r\n\r\n case 'dns-list': {\r\n const domain = String(a.domain);\r\n if (!domain) throw new Error('domain is required');\r\n\r\n interface DnsRecord { type: string; name: string; value: string; ttl: number; }\r\n\r\n const res = await mijnhostFetch<{ domain: string; records: DnsRecord[] }>(\r\n `/domains/${encodeURIComponent(domain)}/dns`\r\n );\r\n const records = res.data.records;\r\n\r\n if (!records.length) {\r\n return { content: [{ type: 'text', text: `No DNS records found for ${domain}` }] };\r\n }\r\n\r\n const header = 'TYPE NAME VALUE TTL';\r\n const sep = '-'.repeat(90);\r\n const lines = records.map(r =>\r\n `${r.type.padEnd(10)}${r.name.padEnd(31)}${r.value.substring(0, 40).padEnd(41)}${r.ttl}`\r\n );\r\n\r\n return { content: [{ type: 'text', text: `DNS records for ${domain} (${records.length}):\\n\\n${header}\\n${sep}\\n${lines.join('\\n')}` }] };\r\n }\r\n\r\n case 'dns-create': {\r\n const domain = String(a.domain);\r\n const type = String(a.type).toUpperCase();\r\n const dnsName = String(a.name);\r\n const value = String(a.value);\r\n const ttl = Number(a.ttl) || 3600;\r\n\r\n if (!domain || !type || !dnsName || !value) {\r\n throw new Error('domain, type, name, and value are required');\r\n }\r\n\r\n interface DnsRecordCreate { type: string; name: string; value: string; ttl: number; }\r\n\r\n const current = await mijnhostFetch<{ domain: string; records: DnsRecordCreate[] }>(\r\n `/domains/${encodeURIComponent(domain)}/dns`\r\n );\r\n\r\n const records = [...current.data.records, { type, name: dnsName, value, ttl }];\r\n\r\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\r\n method: 'PUT',\r\n body: JSON.stringify({ records }),\r\n });\r\n\r\n return { content: [{ type: 'text', text: `DNS record created: ${type} ${dnsName} → ${value} (TTL: ${ttl})` }] };\r\n }\r\n\r\n case 'dns-update': {\r\n const domain = String(a.domain);\r\n const type = String(a.type).toUpperCase();\r\n const dnsName = String(a.name);\r\n const oldValue = String(a.oldValue);\r\n const newValue = String(a.newValue);\r\n const ttl = Number(a.ttl) || undefined;\r\n\r\n if (!domain || !type || !dnsName || !oldValue || !newValue) {\r\n throw new Error('domain, type, name, oldValue, and newValue are required');\r\n }\r\n\r\n interface DnsRecord { type: string; name: string; value: string; ttl: number; }\r\n\r\n const current = await mijnhostFetch<{ domain: string; records: DnsRecord[] }>(\r\n `/domains/${encodeURIComponent(domain)}/dns`\r\n );\r\n\r\n const idx = current.data.records.findIndex(\r\n r => r.type === type && r.name === dnsName && r.value === oldValue\r\n );\r\n\r\n if (idx === -1) {\r\n throw new Error(`No matching DNS record found: ${type} ${dnsName} = ${oldValue}`);\r\n }\r\n\r\n const updated = [...current.data.records];\r\n const existingTtl = updated[idx]!.ttl;\r\n updated[idx] = {\r\n type,\r\n name: dnsName,\r\n value: newValue,\r\n ttl: ttl ?? existingTtl,\r\n };\r\n\r\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\r\n method: 'PUT',\r\n body: JSON.stringify({ records: updated }),\r\n });\r\n\r\n return { content: [{ type: 'text', text: `DNS record updated: ${type} ${dnsName} → ${newValue}${ttl ? ` (TTL: ${ttl})` : ''}` }] };\r\n }\r\n\r\n case 'dns-delete': {\r\n const domain = String(a.domain);\r\n const type = String(a.type).toUpperCase();\r\n const dnsName = String(a.name);\r\n const value = String(a.value);\r\n\r\n if (!domain || !type || !dnsName || !value) {\r\n throw new Error('domain, type, name, and value are required');\r\n }\r\n\r\n interface DnsRecord { type: string; name: string; value: string; ttl: number; }\r\n\r\n const current = await mijnhostFetch<{ domain: string; records: DnsRecord[] }>(\r\n `/domains/${encodeURIComponent(domain)}/dns`\r\n );\r\n\r\n const before = current.data.records.length;\r\n const remaining = current.data.records.filter(\r\n r => !(r.type === type && r.name === dnsName && r.value === value)\r\n );\r\n\r\n if (remaining.length === before) {\r\n throw new Error(`No matching DNS record found: ${type} ${dnsName} = ${value}`);\r\n }\r\n\r\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\r\n method: 'PUT',\r\n body: JSON.stringify({ records: remaining }),\r\n });\r\n\r\n return { content: [{ type: 'text', text: `DNS record deleted: ${type} ${dnsName} = ${value} (${remaining.length} records remaining)` }] };\r\n }\r\n\r\n default:\r\n if (TRIGGER_TOOL_NAMES.has(name)) {\r\n return handleTriggerTool(name, a, { sshExec, getServerConnection });\r\n }\r\n if (SCRIPT_TOOL_NAMES.has(name)) {\r\n return handleScriptTool(name, a);\r\n }\r\n if (AGENT_TOOL_NAMES.has(name)) {\r\n return handleAgentTool(name, a, { supabase, workspaceId: agentWorkspaceId });\r\n }\r\n return { content: [{ type: 'text', text: `Unknown tool: ${name}` }] };\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n return { content: [{ type: 'text', text: `Error: ${message}` }] };\r\n }\r\n}\r\n\r\n/** Create a configured MCP Server instance with handlers attached. */\r\nfunction createMcpServer(): Server {\r\n const s = new Server(\r\n { name: 'mg-dashboard-mcp', version: MCP_VERSION },\r\n { capabilities: { tools: {} } },\r\n );\r\n s.setRequestHandler(ListToolsRequestSchema, handleListTools);\r\n s.setRequestHandler(CallToolRequestSchema, handleCallTool as Parameters<typeof s.setRequestHandler>[1]);\r\n return s;\r\n}\r\n\r\nconst server = createMcpServer();\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main\r\n// ---------------------------------------------------------------------------\r\n\r\nasync function main() {\r\n console.error('Starting MG Dashboard MCP Server...');\r\n\r\n authContext = await validateApiKey(apiKey!);\r\n if (!authContext) {\r\n console.error('API key validation failed');\r\n process.exit(1);\r\n }\r\n\r\n const toolNames = TOOLS.map(t => t.name).join(', ');\r\n\r\n if (httpMode) {\r\n console.error(`API key validated. Starting Streamable HTTP transport on port ${httpPort}...`);\r\n\r\n const transports = new Map<string, StreamableHTTPServerTransport>();\r\n\r\n const httpServer = createHttpServer(async (req, res) => {\r\n const url = new URL(req.url ?? '/', `http://localhost:${httpPort}`);\r\n if (url.pathname !== '/mcp') {\r\n res.writeHead(404, { 'Content-Type': 'text/plain' });\r\n res.end('Not found');\r\n return;\r\n }\r\n\r\n if (req.method === 'OPTIONS') {\r\n res.writeHead(204, {\r\n 'Access-Control-Allow-Origin': '*',\r\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\r\n 'Access-Control-Allow-Headers': 'Content-Type, mcp-session-id',\r\n 'Access-Control-Expose-Headers': 'mcp-session-id',\r\n });\r\n res.end();\r\n return;\r\n }\r\n\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Expose-Headers', 'mcp-session-id');\r\n\r\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\r\n\r\n let body: Record<string, unknown> | undefined;\r\n if (req.method === 'POST') {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of req) chunks.push(chunk as Buffer);\r\n try {\r\n body = JSON.parse(Buffer.concat(chunks).toString());\r\n } catch {\r\n res.writeHead(400, { 'Content-Type': 'text/plain' });\r\n res.end('Invalid JSON');\r\n return;\r\n }\r\n }\r\n\r\n if (sessionId && transports.has(sessionId)) {\r\n await transports.get(sessionId)!.handleRequest(req, res, body);\r\n return;\r\n }\r\n\r\n if (req.method === 'POST' && body && (Array.isArray(body) ? body.some(isInitializeRequest) : isInitializeRequest(body))) {\r\n const transport = new StreamableHTTPServerTransport({\r\n sessionIdGenerator: () => randomUUID(),\r\n });\r\n transport.onclose = () => {\r\n if (transport.sessionId) transports.delete(transport.sessionId);\r\n };\r\n const sessionServer = createMcpServer();\r\n await sessionServer.connect(transport);\r\n if (transport.sessionId) transports.set(transport.sessionId, transport);\r\n await transport.handleRequest(req, res, body);\r\n return;\r\n }\r\n\r\n res.writeHead(400, { 'Content-Type': 'text/plain' });\r\n res.end('Bad request — missing or invalid session');\r\n });\r\n\r\n httpServer.listen(httpPort, () => {\r\n console.error(`MCP HTTP server ready on port ${httpPort}. Tools: ${toolNames}`);\r\n });\r\n } else {\r\n console.error('API key validated. Starting stdio transport...');\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n console.error(`MCP Server ready. Tools: ${toolNames}`);\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error('Fatal error:', err);\r\n process.exit(1);\r\n});\r\n"]}
1
+ {"version":3,"sources":["../src/trigger-tools.ts","../src/script-tools.ts","../src/agent-tools.ts","../src/index.ts"],"names":["sshExec","apiKey","args","getServerConnection","name","supabase","error","SshClient","err","err2","stageIds","createHttpServer"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Trigger.dev MCP Tools\r\n *\r\n * SSH-based tools for managing Trigger.dev projects. All projects run on a\r\n * single Docker Compose instance. The compose project, server, postgres\r\n * container, and webapp port are auto-discovered — callers only need to\r\n * provide the Trigger.dev project slug (from trigger-list).\r\n *\r\n * @module trigger-tools\r\n */\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types (mirrored from index.ts to avoid circular imports)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface SshConnectionOptions {\r\n hostname: string;\r\n port: number;\r\n username: string;\r\n password?: string;\r\n privateKey?: string;\r\n passphrase?: string;\r\n timeout?: number;\r\n}\r\n\r\ninterface SshResult {\r\n stdout: string;\r\n stderr: string;\r\n exitCode: number;\r\n}\r\n\r\ntype SshExecFn = (\r\n conn: SshConnectionOptions,\r\n command: string,\r\n proxy?: SshConnectionOptions,\r\n) => Promise<SshResult>;\r\n\r\ntype GetServerConnectionFn = (\r\n serverId: string,\r\n) => Promise<{ conn: SshConnectionOptions; proxy?: SshConnectionOptions }>;\r\n\r\ninterface ToolResult {\r\n [key: string]: unknown;\r\n content: { type: string; text: string }[];\r\n}\r\n\r\ninterface TriggerToolDeps {\r\n sshExec: SshExecFn;\r\n getServerConnection: GetServerConnectionFn;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Trigger.dev API response shapes (partial, only fields we display)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface TriggerRunItem {\r\n id: string;\r\n status: string;\r\n taskIdentifier: string;\r\n version?: string;\r\n createdAt: string;\r\n updatedAt: string;\r\n startedAt?: string;\r\n finishedAt?: string;\r\n durationMs?: number;\r\n isTest?: boolean;\r\n}\r\n\r\ninterface TriggerRunDetail extends TriggerRunItem {\r\n payload?: unknown;\r\n output?: unknown;\r\n attempts?: {\r\n id: string;\r\n status: string;\r\n error?: { message: string; name?: string; stackTrace?: string };\r\n startedAt?: string;\r\n completedAt?: string;\r\n }[];\r\n}\r\n\r\nconst TERMINAL_STATUSES = new Set([\r\n 'COMPLETED', 'FAILED', 'CRASHED', 'CANCELED',\r\n 'SYSTEM_FAILURE', 'INTERRUPTED', 'EXPIRED',\r\n]);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Hardcoded infra constants — single Trigger.dev instance\r\n// ---------------------------------------------------------------------------\r\n\r\n/** SSH server that hosts the Trigger.dev Docker Compose stack. */\r\nconst TRIGGER_SERVER_ID = '03659d55-e194-400d-b82a-bf6457371ded';\r\n\r\n/** Docker Compose project name on the server. */\r\nconst COMPOSE_PROJECT = 'mg-dashboard-supabase-trigger';\r\n\r\nconst PG_CONTAINER = `${COMPOSE_PROJECT}-postgres-1`;\r\nconst WA_CONTAINER = `${COMPOSE_PROJECT}-webapp-1`;\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const TRIGGER_TOOLS = [\r\n {\r\n name: 'trigger-list',\r\n description:\r\n 'List all Trigger.dev projects. Returns the project slug and name. ' +\r\n 'Use the slug as the \"project\" parameter in other trigger-* tools.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {},\r\n },\r\n },\r\n {\r\n name: 'trigger-runs',\r\n description:\r\n 'List recent task runs for a Trigger.dev project. ' +\r\n 'Returns run ID, task name, status, duration, and timestamps.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list (e.g. \"mg-dashboard-bHfS\")' },\r\n status: {\r\n type: 'string',\r\n description: 'Comma-separated status filter: QUEUED,EXECUTING,COMPLETED,FAILED,CRASHED,CANCELED,SYSTEM_FAILURE',\r\n },\r\n taskIdentifier: { type: 'string', description: 'Filter by task identifier (e.g. \"hello-world\")' },\r\n limit: { type: 'number', description: 'Max runs to return (default 20, max 100)' },\r\n },\r\n required: ['project'],\r\n },\r\n },\r\n {\r\n name: 'trigger-run-detail',\r\n description:\r\n 'Get full details of a specific run: status, payload, output, and error stack traces. ' +\r\n 'Use after trigger-runs or trigger-test-task to inspect results.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list' },\r\n runId: { type: 'string', description: 'Run ID (e.g. run_xxxxx)' },\r\n },\r\n required: ['project', 'runId'],\r\n },\r\n },\r\n {\r\n name: 'trigger-test-task',\r\n description:\r\n 'Trigger a task run and wait for it to complete. Returns the final status, output, ' +\r\n 'or error with stack trace. The main tool for testing trigger tasks from Cursor.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list' },\r\n taskId: { type: 'string', description: 'Task identifier (e.g. \"hello-world\", \"execute-pipeline\")' },\r\n payload: { type: 'string', description: 'JSON payload string to pass to the task (optional)' },\r\n waitSeconds: { type: 'number', description: 'Max seconds to wait for completion (default 60, max 300)' },\r\n },\r\n required: ['project', 'taskId'],\r\n },\r\n },\r\n {\r\n name: 'trigger-replay-run',\r\n description: 'Replay a previously failed or completed run with the same payload. Returns the new run ID.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Project slug from trigger-list' },\r\n runId: { type: 'string', description: 'Run ID to replay (e.g. run_xxxxx)' },\r\n },\r\n required: ['project', 'runId'],\r\n },\r\n },\r\n];\r\n\r\nexport const TRIGGER_TOOL_NAMES = new Set(TRIGGER_TOOLS.map((t) => t.name));\r\n\r\nexport const TRIGGER_TOOL_MODULE_MAP: Record<string, string> = {\r\n 'trigger-list': 'ci_cd',\r\n 'trigger-runs': 'ci_cd',\r\n 'trigger-run-detail': 'ci_cd',\r\n 'trigger-test-task': 'ci_cd',\r\n 'trigger-replay-run': 'ci_cd',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// SSH helpers\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface TriggerInstance {\r\n port: string;\r\n apiKey: string;\r\n}\r\n\r\n/**\r\n * Discover the webapp port and the production API key for a specific\r\n * Trigger.dev project by querying Docker and the Postgres container.\r\n * The API key is resolved via a JOIN on Project → RuntimeEnvironment.\r\n */\r\nasync function discoverInstance(\r\n projectSlug: string,\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n): Promise<TriggerInstance> {\r\n const sql = `SELECT re.\\\\\"apiKey\\\\\" FROM \\\\\"RuntimeEnvironment\\\\\" re `\r\n + `JOIN \\\\\"Project\\\\\" p ON re.\\\\\"projectId\\\\\" = p.id `\r\n + `WHERE p.slug='${projectSlug}' AND re.slug='prod' LIMIT 1`;\r\n\r\n const cmd = [\r\n `PORT=$(docker port \"${WA_CONTAINER}\" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,\r\n `KEY=$(docker exec \"${PG_CONTAINER}\" psql -U postgres -d main -t -A -c \"${sql}\" 2>/dev/null | tr -d '[:space:]')`,\r\n 'echo \"$PORT|$KEY\"',\r\n ].join(' && ');\r\n\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = result.stdout.trim();\r\n const sepIdx = output.indexOf('|');\r\n\r\n const port = sepIdx > 0 ? output.substring(0, sepIdx) : '';\r\n const apiKey = sepIdx > 0 ? output.substring(sepIdx + 1) : '';\r\n\r\n if (!port) {\r\n throw new Error(\r\n `Could not find webapp port for ${WA_CONTAINER}. Is the container running?`,\r\n );\r\n }\r\n if (!apiKey) {\r\n throw new Error(\r\n `Could not get API key for project \"${projectSlug}\". ` +\r\n 'Check if the project slug is correct (use trigger-list).',\r\n );\r\n }\r\n\r\n return { port, apiKey };\r\n}\r\n\r\n/**\r\n * Fetch console/logger output for a run from the TaskEvent table in Postgres.\r\n * Returns formatted log lines sorted by time, filtered to user-relevant levels.\r\n */\r\nasync function fetchRunLogs(\r\n runId: string,\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n): Promise<string> {\r\n const sql = `SELECT level, message, \\\\\"isError\\\\\", \\\\\"createdAt\\\\\" `\r\n + `FROM \\\\\"TaskEvent\\\\\" `\r\n + `WHERE \\\\\"runId\\\\\" = '${runId}' `\r\n + `AND level IN ('INFO','WARN','ERROR','DEBUG','LOG','TRACE') `\r\n + `ORDER BY \\\\\"startTime\\\\\" ASC LIMIT 200`;\r\n\r\n const cmd = `docker exec \"${PG_CONTAINER}\" psql -U postgres -d main -t -A -c \"${sql}\" 2>/dev/null`;\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = result.stdout.trim();\r\n\r\n if (!output) return '';\r\n\r\n return output.split('\\n').map((line) => {\r\n const parts = line.split('|');\r\n const level = (parts[0] || '').padEnd(5);\r\n const message = parts[1] || '';\r\n const isError = parts[2] === 't';\r\n const ts = parts[3] || '';\r\n const time = ts ? ts.split(' ')[1]?.substring(0, 8) || '' : '';\r\n const prefix = isError ? '!' : ' ';\r\n return `${prefix}${time} [${level}] ${message}`;\r\n }).join('\\n');\r\n}\r\n\r\n/**\r\n * Execute a curl request against the Trigger.dev REST API via SSH.\r\n * Uses -g (globoff) to prevent curl from interpreting brackets in URLs.\r\n */\r\nasync function triggerApi(\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n instance: TriggerInstance,\r\n method: string,\r\n path: string,\r\n body?: string,\r\n): Promise<string> {\r\n const parts = ['curl', '-s', '-g', '--max-time', '30'];\r\n if (method !== 'GET') parts.push('-X', method);\r\n parts.push(`\"http://localhost:${instance.port}${path}\"`);\r\n parts.push(`-H \"Authorization: Bearer ${instance.apiKey}\"`);\r\n if (body) {\r\n parts.push('-H \"Content-Type: application/json\"');\r\n parts.push(`-d '${body.replace(/'/g, \"'\\\\''\")}'`);\r\n }\r\n\r\n const result = await sshExec(conn, parts.join(' '), proxy);\r\n if (result.exitCode !== 0 && !result.stdout) {\r\n throw new Error(\r\n `Trigger.dev API call failed (${method} ${path}): ${result.stderr || `exit code ${result.exitCode}`}`,\r\n );\r\n }\r\n return result.stdout;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Output formatters\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction formatRunsTable(runs: TriggerRunItem[]): string {\r\n if (runs.length === 0) return 'No runs found';\r\n\r\n const lines = runs.map((r) => {\r\n const duration = r.durationMs != null ? `${(r.durationMs / 1000).toFixed(1)}s` : '-';\r\n const test = r.isTest ? ' [TEST]' : '';\r\n const created = r.createdAt ? new Date(r.createdAt).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' }) : '';\r\n return `${r.id} ${r.taskIdentifier.padEnd(35)} ${r.status.padEnd(16)} ${duration.padStart(8)} ${created}${test}`;\r\n });\r\n\r\n return `${'ID'.padEnd(20)} ${'TASK'.padEnd(35)} ${'STATUS'.padEnd(16)} ${'DURATION'.padStart(8)} CREATED\\n` +\r\n '-'.repeat(110) + '\\n' +\r\n lines.join('\\n');\r\n}\r\n\r\nfunction formatRunDetail(run: TriggerRunDetail): string {\r\n const sections: string[] = [];\r\n\r\n sections.push(`=== Run ${run.id} ===`);\r\n sections.push(`Task: ${run.taskIdentifier}`);\r\n sections.push(`Status: ${run.status}`);\r\n sections.push(`Version: ${run.version || '-'}`);\r\n\r\n if (run.startedAt) sections.push(`Started: ${new Date(run.startedAt).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' })}`);\r\n if (run.finishedAt) sections.push(`Finished: ${new Date(run.finishedAt).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' })}`);\r\n if (run.durationMs != null) sections.push(`Duration: ${(run.durationMs / 1000).toFixed(2)}s`);\r\n\r\n if (run.payload !== undefined) {\r\n const payloadStr = typeof run.payload === 'string'\r\n ? run.payload\r\n : JSON.stringify(run.payload, null, 2);\r\n sections.push('', '--- Payload ---', payloadStr);\r\n }\r\n\r\n if (run.output !== undefined) {\r\n const outputStr = typeof run.output === 'string'\r\n ? run.output\r\n : JSON.stringify(run.output, null, 2);\r\n sections.push('', '--- Output ---', outputStr);\r\n }\r\n\r\n if (run.attempts && run.attempts.length > 0) {\r\n for (const attempt of run.attempts) {\r\n if (attempt.error) {\r\n sections.push(\r\n '',\r\n `--- Error (${attempt.id}) ---`,\r\n `${attempt.error.name || 'Error'}: ${attempt.error.message}`,\r\n );\r\n if (attempt.error.stackTrace) {\r\n sections.push('', attempt.error.stackTrace);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return sections.join('\\n');\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main handler\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function handleTriggerTool(\r\n name: string,\r\n args: Record<string, unknown>,\r\n deps: TriggerToolDeps,\r\n): Promise<ToolResult> {\r\n const { sshExec, getServerConnection } = deps;\r\n const { conn, proxy } = await getServerConnection(TRIGGER_SERVER_ID);\r\n\r\n switch (name) {\r\n // -----------------------------------------------------------------\r\n case 'trigger-list': {\r\n const sql = 'SELECT slug, name FROM \\\\\"Project\\\\\" ORDER BY name';\r\n const cmd = `docker exec \"${PG_CONTAINER}\" psql -U postgres -d main -t -A -c \"${sql}\" 2>/dev/null`;\r\n\r\n const result = await sshExec(conn, cmd, proxy);\r\n const output = result.stdout.trim();\r\n\r\n if (!output) {\r\n return { content: [{ type: 'text', text: 'No Trigger.dev projects found.' }] };\r\n }\r\n\r\n const header = `${'SLUG'.padEnd(25)} NAME`;\r\n const sep = '-'.repeat(55);\r\n const lines = output.split('\\n').map((line) => {\r\n const [slug, name] = line.split('|');\r\n return `${(slug || '').padEnd(25)} ${name || ''}`;\r\n });\r\n\r\n return { content: [{ type: 'text', text: `${header}\\n${sep}\\n${lines.join('\\n')}` }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-runs': {\r\n const project = String(args.project);\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);\r\n const queryParts = [`page%5Bsize%5D=${limit}`];\r\n if (args.status) queryParts.push(`filter%5Bstatus%5D=${String(args.status)}`);\r\n if (args.taskIdentifier) queryParts.push(`filter%5BtaskIdentifier%5D=${String(args.taskIdentifier)}`);\r\n\r\n const rawJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'GET', `/api/v1/runs?${queryParts.join('&')}`,\r\n );\r\n\r\n let parsed: { data?: TriggerRunItem[] };\r\n try {\r\n parsed = JSON.parse(rawJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Invalid API response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n const runs = parsed.data || [];\r\n return { content: [{ type: 'text', text: formatRunsTable(runs) }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-run-detail': {\r\n const project = String(args.project);\r\n const runId = String(args.runId);\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n const [rawJson, logs] = await Promise.all([\r\n triggerApi(conn, proxy, sshExec, instance, 'GET', `/api/v3/runs/${encodeURIComponent(runId)}`),\r\n fetchRunLogs(runId, conn, proxy, sshExec),\r\n ]);\r\n\r\n let run: TriggerRunDetail;\r\n try {\r\n run = JSON.parse(rawJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Invalid API response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n let text = formatRunDetail(run);\r\n if (logs) {\r\n text += '\\n\\n--- Logs ---\\n' + logs;\r\n }\r\n\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-test-task': {\r\n const project = String(args.project);\r\n const taskId = String(args.taskId);\r\n const waitSeconds = Math.min(Math.max(Number(args.waitSeconds) || 60, 5), 300);\r\n\r\n conn.timeout = (waitSeconds + 30) * 1000;\r\n\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n let payload = '{}';\r\n if (args.payload) {\r\n try {\r\n JSON.parse(String(args.payload));\r\n payload = String(args.payload);\r\n } catch {\r\n throw new Error(`Invalid JSON payload: ${String(args.payload).substring(0, 200)}`);\r\n }\r\n }\r\n\r\n const triggerBody = JSON.stringify({\r\n payload: JSON.parse(payload),\r\n options: { tags: ['mcp-test'], test: true },\r\n });\r\n\r\n const triggerJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'POST', `/api/v1/tasks/${encodeURIComponent(taskId)}/trigger`,\r\n triggerBody,\r\n );\r\n\r\n let triggerResp: { id?: string };\r\n try {\r\n triggerResp = JSON.parse(triggerJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Failed to trigger task. API response:\\n${triggerJson.substring(0, 500)}` }] };\r\n }\r\n\r\n const runId = triggerResp.id;\r\n if (!runId) {\r\n return { content: [{ type: 'text', text: `Trigger API did not return a run ID:\\n${triggerJson.substring(0, 500)}` }] };\r\n }\r\n\r\n const pollInterval = 3000;\r\n const maxPolls = Math.ceil((waitSeconds * 1000) / pollInterval);\r\n\r\n for (let i = 0; i < maxPolls; i++) {\r\n await new Promise((r) => setTimeout(r, pollInterval));\r\n\r\n const pollJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'GET', `/api/v3/runs/${encodeURIComponent(runId)}`,\r\n );\r\n\r\n let run: TriggerRunDetail;\r\n try {\r\n run = JSON.parse(pollJson);\r\n } catch {\r\n continue;\r\n }\r\n\r\n if (TERMINAL_STATUSES.has(run.status)) {\r\n let text = formatRunDetail(run);\r\n const logs = await fetchRunLogs(runId, conn, proxy, sshExec);\r\n if (logs) text += '\\n\\n--- Logs ---\\n' + logs;\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Run ${runId} did not complete within ${waitSeconds}s (still running). Use trigger-run-detail to check later.`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'trigger-replay-run': {\r\n const project = String(args.project);\r\n const runId = String(args.runId);\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n\r\n const rawJson = await triggerApi(\r\n conn, proxy, sshExec, instance,\r\n 'POST', `/api/v1/runs/${encodeURIComponent(runId)}/replay`,\r\n );\r\n\r\n let result: { id?: string };\r\n try {\r\n result = JSON.parse(rawJson);\r\n } catch {\r\n return { content: [{ type: 'text', text: `Replay response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: result.id\r\n ? `Run replayed. New run ID: ${result.id}`\r\n : `Replay response:\\n${rawJson.substring(0, 500)}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown trigger tool: ${name}` }] };\r\n }\r\n}\r\n","/**\r\n * Script Tools\r\n *\r\n * MCP tools that serve development workflow scripts (commit feedback,\r\n * PR creation, etc.) so they can be downloaded into any project that\r\n * has the mg-dashboard MCP enabled.\r\n *\r\n * @module script-tools\r\n */\r\n\r\n// ---------------------------------------------------------------------------\r\n// Embedded scripts\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ScriptDefinition {\r\n name: string;\r\n filename: string;\r\n description: string;\r\n content: string;\r\n}\r\n\r\nconst SCRIPTS: ScriptDefinition[] = [\r\n {\r\n name: 'commit-feedback',\r\n filename: 'commit-feedback.ps1',\r\n description:\r\n 'PowerShell script that provides colored terminal feedback for the Ctrl+Shift+K commit & push keybinding. ' +\r\n 'Polls for a new commit and shows branch, message, and file stats when done.',\r\n content: `param()\r\n\r\n$initial = git log --oneline -1 2>$null\r\n\r\nWrite-Host \"\\`n==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" Starting Commit & Push...\" -ForegroundColor Cyan\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" [1/5] Pulling latest...\" -ForegroundColor DarkGray\r\nWrite-Host \" [2/5] Staging changes...\" -ForegroundColor DarkGray\r\nWrite-Host \" [3/5] Generating AI commit message...\" -ForegroundColor DarkGray\r\nWrite-Host \" [4/5] Committing...\" -ForegroundColor DarkGray\r\nWrite-Host \" [5/5] Pushing to remote...\" -ForegroundColor DarkGray\r\nWrite-Host \"\"\r\nWrite-Host \" Waiting for commit\" -ForegroundColor DarkGray -NoNewline\r\n\r\n$timeout = 60\r\n$elapsed = 0\r\nwhile ($elapsed -lt $timeout) {\r\n $current = git log --oneline -1 2>$null\r\n if ($current -ne $initial) { break }\r\n Start-Sleep -Seconds 1\r\n $elapsed++\r\n Write-Host \".\" -ForegroundColor DarkGray -NoNewline\r\n}\r\nWrite-Host \"\"\r\n\r\nif ($current -eq $initial) {\r\n Write-Host \"\"\r\n Write-Host \" [!] No new commit detected (timed out after \\${timeout}s)\" -ForegroundColor Yellow\r\n Write-Host \"\"\r\n exit\r\n}\r\n\r\nStart-Sleep -Seconds 2\r\n\r\n$branch = git rev-parse --abbrev-ref HEAD 2>$null\r\n$commit = git log --format='%h %s' -1 2>$null\r\n\r\nWrite-Host \"\"\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" [OK] Commit & Push Complete\" -ForegroundColor Green\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \" Branch: $branch\" -ForegroundColor Yellow\r\nWrite-Host \" Commit: $commit\" -ForegroundColor White\r\nWrite-Host \"\"\r\ngit --no-pager diff HEAD~1 --stat --color=always 2>$null\r\nWrite-Host \"\"\r\nWrite-Host \"==========================================\" -ForegroundColor Cyan\r\nWrite-Host \"\"\r\n`,\r\n },\r\n {\r\n name: 'create-pr',\r\n filename: 'create-pr.cmd',\r\n description:\r\n 'Windows batch script that auto-detects the target branch based on your release pipeline ' +\r\n '(v*-changes branches), merges the target into your branch, pushes, and creates a PR via gh CLI. ' +\r\n 'Bound to Ctrl+Shift+J.',\r\n content: `@echo off\r\nsetlocal enabledelayedexpansion\r\ntitle MG Dashboard - Create PR\r\n\r\nREM --- ANSI color setup ---\r\nfor /F %%a in ('echo prompt $E ^| cmd') do set \"ESC=%%a\"\r\nset \"GREEN=%ESC%[32m\"\r\nset \"RED=%ESC%[31m\"\r\nset \"YELLOW=%ESC%[33m\"\r\nset \"CYAN=%ESC%[36m\"\r\nset \"DIM=%ESC%[90m\"\r\nset \"BOLD=%ESC%[1m\"\r\nset \"RESET=%ESC%[0m\"\r\n\r\necho.\r\necho %CYAN%%BOLD%==========================================%RESET%\r\necho %CYAN%%BOLD% MG Dashboard - Create Pull Request%RESET%\r\necho %CYAN%%BOLD%==========================================%RESET%\r\necho.\r\n\r\nREM --- Merge origin/main first ---\r\necho %CYAN%[0/4]%RESET% Merging origin/main into current branch...\r\ngit fetch --prune >nul 2>&1\r\ngit merge origin/main --no-edit >nul 2>&1\r\nif errorlevel 1 (\r\n git merge --abort >nul 2>&1\r\n echo %RED%X Merge conflict with origin/main. Resolve manually.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %GREEN% OK%RESET%\r\necho.\r\n\r\nREM --- Prerequisite: gh CLI ---\r\nwhere gh >nul 2>&1\r\nif errorlevel 1 (\r\n echo %RED%X GitHub CLI ^(gh^) is not installed.%RESET%\r\n echo %DIM% Install it from: https://cli.github.com/%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Prerequisite: git repo ---\r\ngit rev-parse --is-inside-work-tree >nul 2>&1\r\nif errorlevel 1 (\r\n echo %RED%X Not inside a git repository.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Detect repo from git remote ---\r\nset \"REPO=\"\r\nfor /f \"tokens=*\" %%u in ('git remote get-url origin 2^>nul') do set \"REMOTE_URL=%%u\"\r\nif defined REMOTE_URL (\r\n echo !REMOTE_URL! | findstr /r \"git@github.com:\" >nul 2>&1\r\n if not errorlevel 1 (\r\n set \"REPO=!REMOTE_URL:git@github.com:=!\"\r\n set \"REPO=!REPO:.git=!\"\r\n )\r\n echo !REMOTE_URL! | findstr /r \"https://github.com/\" >nul 2>&1\r\n if not errorlevel 1 (\r\n set \"REPO=!REMOTE_URL:https://github.com/=!\"\r\n set \"REPO=!REPO:.git=!\"\r\n )\r\n)\r\nif not defined REPO (\r\n echo %RED%X Could not detect GitHub repo from git remote.%RESET%\r\n echo %DIM% Make sure origin points to a GitHub repository.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Get current branch ---\r\nfor /f \"tokens=*\" %%b in ('git rev-parse --abbrev-ref HEAD') do set \"CURRENT_BRANCH=%%b\"\r\n\r\necho %DIM% Repository: !REPO!%RESET%\r\necho %DIM% Branch: %CURRENT_BRANCH%%RESET%\r\necho.\r\n\r\nREM --- Guard: don't PR from main or a bare version branch ---\r\nif \"%CURRENT_BRANCH%\"==\"main\" (\r\n echo %RED%X You are on main. Switch to a feature or changes branch first.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %CURRENT_BRANCH% | findstr /r \"^v[0-9]*\\\\.[0-9]*\\\\.[0-9]*$\" >nul 2>&1\r\nif not errorlevel 1 (\r\n echo %RED%X You are on a version branch ^(%CURRENT_BRANCH%^). Switch to a feature or changes branch first.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\nREM --- Fetch latest remote refs ---\r\necho %CYAN%[1/4]%RESET% Fetching remote branches...\r\ngit fetch --prune >nul 2>&1\r\n\r\nREM --- Determine target branch ---\r\nset \"TARGET=\"\r\n\r\nREM Check if current branch is a -changes branch (last 8 chars)\r\nif \"!CURRENT_BRANCH:~-8!\"==\"-changes\" (\r\n set \"TARGET=!CURRENT_BRANCH:~0,-8!\"\r\n echo %GREEN% Detected -changes branch. Target: %BOLD%!TARGET!%RESET%\r\n goto :do_merge\r\n)\r\n\r\nREM Look for v*-changes branches on remote (highest version first)\r\nset \"TARGET=\"\r\nfor /f \"tokens=*\" %%r in ('git branch -r --sort=-version:refname --list \"origin/v*-changes\" 2^>nul') do (\r\n if not defined TARGET (\r\n set \"RAW=%%r\"\r\n set \"BRANCH=!RAW: origin/=!\"\r\n set \"BRANCH=!BRANCH:origin/=!\"\r\n set \"TARGET=!BRANCH!\"\r\n )\r\n)\r\n\r\nif defined TARGET (\r\n echo %GREEN% Release pipeline detected. Target: %BOLD%!TARGET!%RESET%\r\n) else (\r\n REM No -changes branch; try highest version branch\r\n set \"TARGET=\"\r\n for /f \"tokens=*\" %%r in ('git branch -r --sort=-version:refname --list \"origin/v*\" 2^>nul') do (\r\n if not defined TARGET (\r\n set \"RAW=%%r\"\r\n set \"BRANCH=!RAW: origin/=!\"\r\n set \"BRANCH=!BRANCH:origin/=!\"\r\n set \"TAIL=!BRANCH:~-8!\"\r\n if not \"!TAIL!\"==\"-changes\" set \"TARGET=!BRANCH!\"\r\n )\r\n )\r\n if defined TARGET (\r\n echo %GREEN% Version branch detected. Target: %BOLD%!TARGET!%RESET%\r\n ) else (\r\n set \"TARGET=main\"\r\n echo %YELLOW% No release pipeline or version branch found. Target: %BOLD%main%RESET%\r\n )\r\n)\r\n\r\n:do_merge\r\necho.\r\n\r\nREM --- Merge target into current branch ---\r\necho %CYAN%[2/4]%RESET% Merging %BOLD%!TARGET!%RESET% into %BOLD%%CURRENT_BRANCH%%RESET%...\r\ngit merge origin/!TARGET! --no-edit\r\nif errorlevel 1 (\r\n echo.\r\n echo %RED%X Merge conflict detected.%RESET%\r\n git merge --abort >nul 2>&1\r\n echo %DIM% Resolve conflicts manually, then retry.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %GREEN% OK%RESET%\r\necho.\r\n\r\nREM --- Push current branch to origin ---\r\necho %CYAN%[3/4]%RESET% Pushing %CURRENT_BRANCH% to origin...\r\ngit push -u origin HEAD\r\nif errorlevel 1 (\r\n echo.\r\n echo %RED%X Failed to push branch to origin.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\necho %GREEN% OK%RESET%\r\necho.\r\n\r\nREM --- Guard: don't PR into the same branch ---\r\nif \"!TARGET!\"==\"!CURRENT_BRANCH!\" (\r\n echo %RED%X Target branch is the same as current branch ^(!TARGET!^). Cannot create PR.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\necho %CYAN%[4/4]%RESET% Creating PR: %BOLD%%CURRENT_BRANCH%%RESET% %DIM%->%RESET% %BOLD%%TARGET%%RESET%\r\necho.\r\n\r\nREM --- Create the PR ---\r\ngh pr create --repo \"!REPO!\" --base \"%TARGET%\" --fill\r\nif errorlevel 1 (\r\n echo.\r\n echo %RED%X Failed to create pull request.%RESET%\r\n echo %DIM% Check the error above. A PR may already exist for this branch.%RESET%\r\n echo.\r\n exit /b 1\r\n)\r\n\r\necho.\r\necho %GREEN%%BOLD% PR created successfully!%RESET%\r\necho.\r\n`,\r\n },\r\n {\r\n name: 'commit-and-pr',\r\n filename: 'commit-and-pr.ps1',\r\n description:\r\n 'PowerShell script that combines commit & push with PR creation. ' +\r\n 'Checks for pending changes first: if changes exist, waits for the commit (triggered by Cursor keybinding), ' +\r\n 'shows a summary, then runs create-pr.cmd. If no changes, skips straight to PR. ' +\r\n 'Requires create-pr.cmd in the same directory. Bound to Ctrl+Shift+M.',\r\n content: `param()\r\n\r\n$hasChanges = (git status --porcelain 2>$null)\r\n\r\nif ($hasChanges) {\r\n $initial = git log --oneline -1 2>$null\r\n\r\n Write-Host \"\\`n==========================================\" -ForegroundColor Cyan\r\n Write-Host \" Starting Commit, Push & PR...\" -ForegroundColor Cyan\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \" [1/5] Pulling latest...\" -ForegroundColor DarkGray\r\n Write-Host \" [2/5] Staging changes...\" -ForegroundColor DarkGray\r\n Write-Host \" [3/5] Generating AI commit message...\" -ForegroundColor DarkGray\r\n Write-Host \" [4/5] Committing...\" -ForegroundColor DarkGray\r\n Write-Host \" [5/5] Pushing to remote...\" -ForegroundColor DarkGray\r\n Write-Host \"\"\r\n Write-Host \" Waiting for commit\" -ForegroundColor DarkGray -NoNewline\r\n\r\n $timeout = 60\r\n $elapsed = 0\r\n while ($elapsed -lt $timeout) {\r\n $current = git log --oneline -1 2>$null\r\n if ($current -ne $initial) { break }\r\n Start-Sleep -Seconds 1\r\n $elapsed++\r\n Write-Host \".\" -ForegroundColor DarkGray -NoNewline\r\n }\r\n Write-Host \"\"\r\n\r\n if ($current -eq $initial) {\r\n Write-Host \"\"\r\n Write-Host \" [!] No new commit detected (timed out after \\${timeout}s)\" -ForegroundColor Yellow\r\n Write-Host \" Skipping PR creation.\" -ForegroundColor Yellow\r\n Write-Host \"\"\r\n exit\r\n }\r\n\r\n Start-Sleep -Seconds 2\r\n\r\n $branch = git rev-parse --abbrev-ref HEAD 2>$null\r\n $commit = git log --format='%h %s' -1 2>$null\r\n\r\n Write-Host \"\"\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \" [OK] Commit & Push Complete\" -ForegroundColor Green\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \" Branch: $branch\" -ForegroundColor Yellow\r\n Write-Host \" Commit: $commit\" -ForegroundColor White\r\n Write-Host \"\"\r\n git --no-pager diff HEAD~1 --stat --color=always 2>$null\r\n Write-Host \"\"\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \"\"\r\n} else {\r\n Write-Host \"\\`n==========================================\" -ForegroundColor Cyan\r\n Write-Host \" No changes to commit\" -ForegroundColor DarkGray\r\n Write-Host \" Proceeding to PR creation...\" -ForegroundColor Cyan\r\n Write-Host \"==========================================\" -ForegroundColor Cyan\r\n Write-Host \"\"\r\n}\r\n\r\n& .\\\\create-pr.cmd\r\n`,\r\n },\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const SCRIPT_TOOLS = [\r\n {\r\n name: 'scripts-list',\r\n description:\r\n 'List available MG Dashboard workflow scripts that can be downloaded into your project. ' +\r\n 'Returns script names, filenames, and descriptions.',\r\n inputSchema: { type: 'object' as const, properties: {}, required: [] },\r\n },\r\n {\r\n name: 'script-get',\r\n description:\r\n 'Get the content of an MG Dashboard workflow script by name. ' +\r\n 'Save the returned content to the filename indicated in the response. ' +\r\n 'Place scripts in the repository root.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n name: {\r\n type: 'string',\r\n description: `Script name. Available: ${SCRIPTS.map((s) => s.name).join(', ')}`,\r\n },\r\n },\r\n required: ['name'],\r\n },\r\n },\r\n];\r\n\r\nexport const SCRIPT_TOOL_NAMES = new Set(SCRIPT_TOOLS.map((t) => t.name));\r\n\r\n// ---------------------------------------------------------------------------\r\n// Handler\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ToolResult {\r\n [key: string]: unknown;\r\n content: { type: string; text: string }[];\r\n}\r\n\r\nexport function handleScriptTool(\r\n toolName: string,\r\n args: Record<string, unknown>,\r\n): ToolResult {\r\n switch (toolName) {\r\n case 'scripts-list': {\r\n const list = SCRIPTS.map((s) => ({\r\n name: s.name,\r\n filename: s.filename,\r\n description: s.description,\r\n }));\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: JSON.stringify(list, null, 2),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n case 'script-get': {\r\n const scriptName = String(args.name);\r\n const script = SCRIPTS.find((s) => s.name === scriptName);\r\n if (!script) {\r\n const available = SCRIPTS.map((s) => s.name).join(', ');\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Unknown script: \"${scriptName}\". Available scripts: ${available}`,\r\n },\r\n ],\r\n };\r\n }\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: [\r\n `Filename: ${script.filename}`,\r\n `Description: ${script.description}`,\r\n `Place this file in the repository root.`,\r\n '',\r\n '--- CONTENT START ---',\r\n script.content,\r\n '--- CONTENT END ---',\r\n ].join('\\n'),\r\n },\r\n ],\r\n };\r\n }\r\n\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown script tool: ${toolName}` }] };\r\n }\r\n}\r\n","/**\r\n * Agent Reporting MCP Tools\r\n *\r\n * Tools used by automated Cursor agents (doc scanners, perf auditors, etc.)\r\n * to report findings directly to the dashboard database. Replaces the old\r\n * marker-based output parsing pipeline.\r\n *\r\n * @module agent-tools\r\n */\r\n\r\nimport type { SupabaseClient } from '@supabase/supabase-js';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface ToolResult {\r\n [key: string]: unknown;\r\n content: { type: string; text: string }[];\r\n}\r\n\r\ninterface AgentToolDeps {\r\n supabase: SupabaseClient;\r\n workspaceId: string | null;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Valid enum values (shared with the old parse-* modules — canonical source)\r\n// ---------------------------------------------------------------------------\r\n\r\nconst VALID_FINDING_TYPES = new Set([\r\n 'missing_docs', 'inaccurate', 'incomplete', 'outdated', 'improvement',\r\n 'n_plus_1_query', 'bundle_size', 'unnecessary_rerender',\r\n 'slow_endpoint', 'memory_leak', 'missing_memoization', 'large_dependency',\r\n]);\r\n\r\nconst VALID_SEVERITIES = new Set(['info', 'warning', 'critical']);\r\n\r\nconst VALID_SCOPES = new Set([\r\n 'architecture', 'module', 'component', 'api', 'package',\r\n]);\r\n\r\nconst VALID_REVIEW_STATUSES = new Set([\r\n 'pending', 'approved', 'rejected', 'outdated',\r\n]);\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const AGENT_TOOLS = [\r\n {\r\n name: 'agent-report-coverage',\r\n description:\r\n 'Report documentation coverage data for a repository. Upserts records ' +\r\n 'into doc_coverage. Call once per logical unit (package, module, theme, plugin directory). ' +\r\n 'Provide all entries in a single call for efficiency.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: {\r\n type: 'string',\r\n description: 'Repository slug (e.g. \"mg-dashboard\", \"bna-wordpress\")',\r\n },\r\n refront_project_id: {\r\n type: 'string',\r\n description: 'Refront project UUID linked to this repository',\r\n },\r\n entries: {\r\n type: 'array',\r\n description: 'Array of coverage entries, one per logical unit',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n path: { type: 'string', description: 'Logical unit path (e.g. \"packages/ui\", \"wp-content/themes/bna\")' },\r\n total_functions: { type: 'number', description: 'Total public functions/methods' },\r\n documented_functions: { type: 'number', description: 'Functions with doc comments' },\r\n total_types: { type: 'number', description: 'Total classes/interfaces/types' },\r\n documented_types: { type: 'number', description: 'Types with doc comments' },\r\n total_endpoints: { type: 'number', description: 'Total API/REST/hook endpoints' },\r\n documented_endpoints: { type: 'number', description: 'Endpoints with documentation' },\r\n },\r\n required: ['path', 'total_functions', 'documented_functions'],\r\n },\r\n },\r\n },\r\n required: ['repo_slug', 'refront_project_id', 'entries'],\r\n },\r\n },\r\n {\r\n name: 'agent-report-finding',\r\n description:\r\n 'Report documentation or performance findings for a repository. ' +\r\n 'Inserts records into doc_suggestion. Auto-creates a parent documentation ' +\r\n 'record if one does not exist yet. Batch multiple findings in one call.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: {\r\n type: 'string',\r\n description: 'Repository slug',\r\n },\r\n refront_project_id: {\r\n type: 'string',\r\n description: 'Refront project UUID linked to this repository',\r\n },\r\n category: {\r\n type: 'string',\r\n enum: ['scan_findings', 'perf_audit'],\r\n description: 'Finding category: \"scan_findings\" for doc issues, \"perf_audit\" for performance issues',\r\n },\r\n findings: {\r\n type: 'array',\r\n description: 'Array of findings to report',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n type: {\r\n type: 'string',\r\n enum: [...VALID_FINDING_TYPES],\r\n description: 'Finding type',\r\n },\r\n severity: {\r\n type: 'string',\r\n enum: ['info', 'warning', 'critical'],\r\n description: 'Severity level',\r\n },\r\n description: {\r\n type: 'string',\r\n description: 'Clear description of the issue (max 2000 chars)',\r\n },\r\n file_path: {\r\n type: 'string',\r\n description: 'Relative file path where the issue was found',\r\n },\r\n suggested_fix: {\r\n type: 'string',\r\n description: 'Suggested fix with code example (max 5000 chars)',\r\n },\r\n },\r\n required: ['type', 'severity', 'description'],\r\n },\r\n },\r\n },\r\n required: ['repo_slug', 'refront_project_id', 'category', 'findings'],\r\n },\r\n },\r\n {\r\n name: 'agent-save-documentation',\r\n description:\r\n 'Save or update a documentation record for a repository. ' +\r\n 'Upserts by repo_slug + scope + path combination.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: { type: 'string', description: 'Repository slug' },\r\n refront_project_id: { type: 'string', description: 'Refront project UUID' },\r\n scope: {\r\n type: 'string',\r\n enum: [...VALID_SCOPES],\r\n description: 'Documentation scope',\r\n },\r\n path: {\r\n type: 'string',\r\n description: 'Path within the repo (e.g. \"packages/ui\", \"__perf_audit__\")',\r\n },\r\n title: { type: 'string', description: 'Document title' },\r\n content: { type: 'string', description: 'Documentation content (markdown)' },\r\n review_status: {\r\n type: 'string',\r\n enum: [...VALID_REVIEW_STATUSES],\r\n description: 'Review status (default: \"pending\")',\r\n },\r\n },\r\n required: ['repo_slug', 'refront_project_id', 'scope', 'path', 'title', 'content'],\r\n },\r\n },\r\n {\r\n name: 'agent-list-findings',\r\n description:\r\n 'List existing findings (doc_suggestion records) for a repository. ' +\r\n 'Use this to check what has already been reported before submitting new findings.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: { type: 'string', description: 'Repository slug' },\r\n type: {\r\n type: 'string',\r\n enum: [...VALID_FINDING_TYPES],\r\n description: 'Filter by finding type',\r\n },\r\n severity: {\r\n type: 'string',\r\n enum: ['info', 'warning', 'critical'],\r\n description: 'Filter by severity',\r\n },\r\n status: {\r\n type: 'string',\r\n enum: ['open', 'accepted', 'rejected', 'fixed'],\r\n description: 'Filter by status (default: all)',\r\n },\r\n limit: {\r\n type: 'number',\r\n description: 'Max results to return (default: 50, max: 200)',\r\n },\r\n },\r\n required: ['repo_slug'],\r\n },\r\n },\r\n {\r\n name: 'agent-get-documentation',\r\n description:\r\n 'Retrieve existing documentation records for a repository. ' +\r\n 'Use this to read current docs before generating or reviewing.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n repo_slug: { type: 'string', description: 'Repository slug' },\r\n scope: {\r\n type: 'string',\r\n enum: [...VALID_SCOPES],\r\n description: 'Filter by scope',\r\n },\r\n path: { type: 'string', description: 'Filter by exact path' },\r\n limit: {\r\n type: 'number',\r\n description: 'Max results to return (default: 20, max: 100)',\r\n },\r\n },\r\n required: ['repo_slug'],\r\n },\r\n },\r\n];\r\n\r\nexport const AGENT_TOOL_NAMES = new Set(AGENT_TOOLS.map((t) => t.name));\r\n\r\nexport const AGENT_TOOL_MODULE_MAP: Record<string, string> = {\r\n 'agent-report-coverage': 'agent_reporting',\r\n 'agent-report-finding': 'agent_reporting',\r\n 'agent-save-documentation': 'agent_reporting',\r\n 'agent-list-findings': 'agent_reporting',\r\n 'agent-get-documentation': 'agent_reporting',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction clamp(val: number, min: number, max: number): number {\r\n return Math.max(min, Math.min(max, val));\r\n}\r\n\r\nfunction sanitizeString(val: unknown, maxLen: number): string {\r\n return String(val ?? '').slice(0, maxLen);\r\n}\r\n\r\n/**\r\n * Find or create a parent project_documentation record for grouping findings.\r\n * Uses a well-known path convention per category.\r\n */\r\nasync function getOrCreateParentDoc(\r\n supabase: SupabaseClient,\r\n repoSlug: string,\r\n refrontProjectId: string,\r\n category: 'scan_findings' | 'perf_audit',\r\n): Promise<string> {\r\n const path = category === 'perf_audit' ? '__perf_audit__' : '__scan_findings__';\r\n const title = category === 'perf_audit'\r\n ? `Performance Audit: ${repoSlug}`\r\n : `Scan Findings: ${repoSlug}`;\r\n\r\n const { data: existing } = await supabase\r\n .from('project_documentation')\r\n .select('id')\r\n .eq('repo_slug', repoSlug)\r\n .eq('path', path)\r\n .maybeSingle();\r\n\r\n if (existing) return existing.id;\r\n\r\n const { data: inserted, error } = await supabase\r\n .from('project_documentation')\r\n .insert({\r\n refront_project_id: refrontProjectId,\r\n repo_slug: repoSlug,\r\n scope: 'architecture',\r\n path,\r\n title,\r\n content: `Auto-generated parent record for ${category.replace('_', ' ')} suggestions.`,\r\n generated_by: `${category}-agent-v1`,\r\n review_status: 'pending',\r\n })\r\n .select('id')\r\n .single();\r\n\r\n if (error || !inserted) {\r\n throw new Error(`Failed to create parent doc record: ${error?.message}`);\r\n }\r\n\r\n return inserted.id;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main handler\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function handleAgentTool(\r\n name: string,\r\n args: Record<string, unknown>,\r\n deps: AgentToolDeps,\r\n): Promise<ToolResult> {\r\n const { supabase } = deps;\r\n\r\n switch (name) {\r\n // -----------------------------------------------------------------\r\n case 'agent-report-coverage': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n const refrontProjectId = sanitizeString(args.refront_project_id, 100);\r\n const entries = Array.isArray(args.entries) ? args.entries : [];\r\n\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n if (!refrontProjectId) throw new Error('refront_project_id is required');\r\n if (entries.length === 0) throw new Error('entries array must not be empty');\r\n\r\n const wsId = deps.workspaceId;\r\n const scanCommit = wsId ? `agent-scan-${wsId.slice(0, 8)}` : `agent-scan-${Date.now().toString(36)}`;\r\n\r\n let upserted = 0;\r\n let errors = 0;\r\n\r\n for (const entry of entries) {\r\n const { error } = await supabase\r\n .from('doc_coverage')\r\n .upsert(\r\n {\r\n refront_project_id: refrontProjectId,\r\n repo_slug: repoSlug,\r\n path: sanitizeString(entry.path, 500),\r\n total_functions: clamp(Number(entry.total_functions) || 0, 0, 99999),\r\n documented_functions: clamp(Number(entry.documented_functions) || 0, 0, 99999),\r\n total_types: clamp(Number(entry.total_types) || 0, 0, 99999),\r\n documented_types: clamp(Number(entry.documented_types) || 0, 0, 99999),\r\n total_endpoints: clamp(Number(entry.total_endpoints) || 0, 0, 99999),\r\n documented_endpoints: clamp(Number(entry.documented_endpoints) || 0, 0, 99999),\r\n scan_commit: scanCommit,\r\n scanned_at: new Date().toISOString(),\r\n },\r\n { onConflict: 'repo_slug,path' },\r\n );\r\n\r\n if (error) errors++;\r\n else upserted++;\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Coverage reported: ${upserted} entries upserted${errors > 0 ? `, ${errors} errors` : ''}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-report-finding': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n const refrontProjectId = sanitizeString(args.refront_project_id, 100);\r\n const category = args.category as 'scan_findings' | 'perf_audit';\r\n const findings = Array.isArray(args.findings) ? args.findings : [];\r\n\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n if (!refrontProjectId) throw new Error('refront_project_id is required');\r\n if (!category || !['scan_findings', 'perf_audit'].includes(category)) {\r\n throw new Error('category must be \"scan_findings\" or \"perf_audit\"');\r\n }\r\n if (findings.length === 0) throw new Error('findings array must not be empty');\r\n\r\n const parentDocId = await getOrCreateParentDoc(supabase, repoSlug, refrontProjectId, category);\r\n\r\n let inserted = 0;\r\n let errors = 0;\r\n\r\n for (const f of findings) {\r\n const findingType = VALID_FINDING_TYPES.has(f.type) ? f.type : 'improvement';\r\n const severity = VALID_SEVERITIES.has(f.severity) ? f.severity : 'info';\r\n const description = sanitizeString(f.description, 2000);\r\n\r\n if (!description) continue;\r\n\r\n const { error } = await supabase.from('doc_suggestion').insert({\r\n documentation_id: parentDocId,\r\n type: findingType,\r\n severity,\r\n description,\r\n file_path: f.file_path ? sanitizeString(f.file_path, 500) : null,\r\n suggested_fix: f.suggested_fix ? sanitizeString(f.suggested_fix, 5000) : null,\r\n status: 'open',\r\n });\r\n\r\n if (error) errors++;\r\n else inserted++;\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Findings reported: ${inserted} inserted under ${category}${errors > 0 ? `, ${errors} errors` : ''}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-save-documentation': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n const refrontProjectId = sanitizeString(args.refront_project_id, 100);\r\n const scope = VALID_SCOPES.has(args.scope as string) ? (args.scope as string) : 'module';\r\n const path = sanitizeString(args.path, 500);\r\n const title = sanitizeString(args.title, 500);\r\n const content = sanitizeString(args.content, 100_000);\r\n const reviewStatus = VALID_REVIEW_STATUSES.has(args.review_status as string)\r\n ? (args.review_status as string)\r\n : 'pending';\r\n\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n if (!refrontProjectId) throw new Error('refront_project_id is required');\r\n if (!path) throw new Error('path is required');\r\n if (!title) throw new Error('title is required');\r\n if (!content) throw new Error('content is required');\r\n\r\n const { data: existing } = await supabase\r\n .from('project_documentation')\r\n .select('id')\r\n .eq('repo_slug', repoSlug)\r\n .eq('scope', scope)\r\n .eq('path', path)\r\n .maybeSingle();\r\n\r\n if (existing) {\r\n const { error } = await supabase\r\n .from('project_documentation')\r\n .update({\r\n title,\r\n content,\r\n review_status: reviewStatus,\r\n updated_at: new Date().toISOString(),\r\n })\r\n .eq('id', existing.id);\r\n\r\n if (error) throw new Error(`Failed to update documentation: ${error.message}`);\r\n return { content: [{ type: 'text', text: `Documentation updated: ${title} (${scope}/${path})` }] };\r\n }\r\n\r\n const generatedBy = deps.workspaceId\r\n ? `agent-${deps.workspaceId.slice(0, 8)}`\r\n : 'agent-mcp';\r\n\r\n const { error } = await supabase\r\n .from('project_documentation')\r\n .insert({\r\n refront_project_id: refrontProjectId,\r\n repo_slug: repoSlug,\r\n scope,\r\n path,\r\n title,\r\n content,\r\n generated_by: generatedBy,\r\n review_status: reviewStatus,\r\n });\r\n\r\n if (error) throw new Error(`Failed to save documentation: ${error.message}`);\r\n return { content: [{ type: 'text', text: `Documentation saved: ${title} (${scope}/${path})` }] };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-list-findings': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n\r\n const limit = clamp(Number(args.limit) || 50, 1, 200);\r\n\r\n // Findings are linked via project_documentation → doc_suggestion\r\n let docQuery = supabase\r\n .from('project_documentation')\r\n .select('id')\r\n .eq('repo_slug', repoSlug);\r\n\r\n const docIds = await docQuery;\r\n if (!docIds.data || docIds.data.length === 0) {\r\n return { content: [{ type: 'text', text: `No documentation records found for repo \"${repoSlug}\"` }] };\r\n }\r\n\r\n let query = supabase\r\n .from('doc_suggestion')\r\n .select('id, type, severity, description, file_path, status, created_at')\r\n .in('documentation_id', docIds.data.map((d: { id: string }) => d.id))\r\n .order('created_at', { ascending: false })\r\n .limit(limit);\r\n\r\n if (args.type && VALID_FINDING_TYPES.has(args.type as string)) {\r\n query = query.eq('type', args.type as string);\r\n }\r\n if (args.severity && VALID_SEVERITIES.has(args.severity as string)) {\r\n query = query.eq('severity', args.severity as string);\r\n }\r\n if (args.status) {\r\n query = query.eq('status', args.status as string);\r\n }\r\n\r\n const { data: findings, error } = await query;\r\n if (error) throw new Error(`Failed to query findings: ${error.message}`);\r\n\r\n if (!findings || findings.length === 0) {\r\n return { content: [{ type: 'text', text: `No findings found for repo \"${repoSlug}\"` }] };\r\n }\r\n\r\n const summary = findings.map((f: Record<string, unknown>) =>\r\n `[${f.severity}] ${f.type}: ${String(f.description).slice(0, 120)}${f.file_path ? ` (${f.file_path})` : ''} — ${f.status}`\r\n ).join('\\n');\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `${findings.length} findings for \"${repoSlug}\":\\n\\n${summary}`,\r\n }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n case 'agent-get-documentation': {\r\n const repoSlug = sanitizeString(args.repo_slug, 200);\r\n if (!repoSlug) throw new Error('repo_slug is required');\r\n\r\n const limit = clamp(Number(args.limit) || 20, 1, 100);\r\n\r\n let query = supabase\r\n .from('project_documentation')\r\n .select('id, repo_slug, scope, path, title, content, review_status, generated_by, created_at, updated_at')\r\n .eq('repo_slug', repoSlug)\r\n .order('updated_at', { ascending: false })\r\n .limit(limit);\r\n\r\n if (args.scope && VALID_SCOPES.has(args.scope as string)) {\r\n query = query.eq('scope', args.scope as string);\r\n }\r\n if (args.path) {\r\n query = query.eq('path', sanitizeString(args.path, 500));\r\n }\r\n\r\n const { data: docs, error } = await query;\r\n if (error) throw new Error(`Failed to query documentation: ${error.message}`);\r\n\r\n if (!docs || docs.length === 0) {\r\n return { content: [{ type: 'text', text: `No documentation found for repo \"${repoSlug}\"` }] };\r\n }\r\n\r\n const output = docs.map((d: Record<string, unknown>) => {\r\n const contentPreview = String(d.content || '').slice(0, 500);\r\n return [\r\n `## ${d.title} (${d.scope}/${d.path})`,\r\n `Status: ${d.review_status} | By: ${d.generated_by || 'unknown'}`,\r\n `Updated: ${d.updated_at || d.created_at}`,\r\n '',\r\n contentPreview + (String(d.content || '').length > 500 ? '\\n...(truncated)' : ''),\r\n '',\r\n ].join('\\n');\r\n }).join('\\n---\\n\\n');\r\n\r\n return {\r\n content: [{ type: 'text', text: `${docs.length} docs for \"${repoSlug}\":\\n\\n${output}` }],\r\n };\r\n }\r\n\r\n // -----------------------------------------------------------------\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown agent tool: ${name}` }] };\r\n }\r\n}\r\n","#!/usr/bin/env node\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { CallToolRequestSchema, ListToolsRequestSchema, isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { createServer as createHttpServer } from 'node:http';\nimport { randomUUID } from 'node:crypto';\nimport { createClient } from '@supabase/supabase-js';\nimport { createHash, randomBytes, createCipheriv, createDecipheriv } from 'crypto';\nimport { Client as SshClient } from 'ssh2';\nimport {\n TRIGGER_TOOLS,\n TRIGGER_TOOL_NAMES,\n TRIGGER_TOOL_MODULE_MAP,\n handleTriggerTool,\n} from './trigger-tools.js';\nimport {\n SCRIPT_TOOLS,\n SCRIPT_TOOL_NAMES,\n handleScriptTool,\n} from './script-tools.js';\nimport {\n AGENT_TOOLS,\n AGENT_TOOL_NAMES,\n AGENT_TOOL_MODULE_MAP,\n handleAgentTool,\n} from './agent-tools.js';\n\n// ---------------------------------------------------------------------------\n// CLI argument parsing\n// ---------------------------------------------------------------------------\n\nconst args = process.argv.slice(2);\n\nfunction getArg(name: string): string | undefined {\n return args.find(a => a.startsWith(`--${name}=`))?.split('=').slice(1).join('=');\n}\n\nconst apiKey = getArg('api-key') || process.env.MG_DASHBOARD_API_KEY;\nconst supabaseUrl = getArg('supabase-url') || process.env.SUPABASE_URL;\nconst supabaseKey = getArg('supabase-key') || process.env.SUPABASE_SERVICE_ROLE_KEY;\nconst encryptionKey = getArg('encryption-key') || process.env.ENCRYPTION_KEY;\nconst mijnhostApiKey = getArg('mijnhost-api-key') || process.env.MIJNHOST_API_KEY;\nconst agentWorkspaceId = getArg('workspace-id') || process.env.AGENT_WORKSPACE_ID || null;\nconst httpMode = args.includes('--http');\nconst httpPort = Number(getArg('port')) || 3100;\n\nif (!apiKey) {\n console.error('API key is required. Use --api-key=dk_xxx or set MG_DASHBOARD_API_KEY');\n process.exit(1);\n}\n\nif (!supabaseUrl || !supabaseKey) {\n console.error('Supabase credentials required. Use --supabase-url and --supabase-key or set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY');\n process.exit(1);\n}\n\nconst supabase = createClient(supabaseUrl, supabaseKey);\n\n// ---------------------------------------------------------------------------\n// Rate limiting\n// ---------------------------------------------------------------------------\n\ninterface RateLimitEntry {\n count: number;\n resetAt: number;\n}\n\nclass RateLimiter {\n private buckets = new Map<string, RateLimitEntry>();\n private readonly maxAttempts: number;\n private readonly windowMs: number;\n\n constructor(maxAttempts: number, windowMs: number) {\n this.maxAttempts = maxAttempts;\n this.windowMs = windowMs;\n }\n\n /**\n * Check if an action is allowed for the given key.\n * Increments the counter and returns whether the action should proceed.\n */\n check(key: string): { allowed: boolean; remaining: number; retryAfterMs: number } {\n const now = Date.now();\n const entry = this.buckets.get(key);\n\n if (!entry || now >= entry.resetAt) {\n this.buckets.set(key, { count: 1, resetAt: now + this.windowMs });\n return { allowed: true, remaining: this.maxAttempts - 1, retryAfterMs: 0 };\n }\n\n entry.count++;\n\n if (entry.count > this.maxAttempts) {\n return {\n allowed: false,\n remaining: 0,\n retryAfterMs: entry.resetAt - now,\n };\n }\n\n return {\n allowed: true,\n remaining: this.maxAttempts - entry.count,\n retryAfterMs: 0,\n };\n }\n\n /** Periodically remove expired entries to prevent unbounded growth. */\n cleanup(): void {\n const now = Date.now();\n for (const [key, entry] of this.buckets) {\n if (now >= entry.resetAt) this.buckets.delete(key);\n }\n }\n}\n\nconst authRateLimiter = new RateLimiter(5, 15 * 60 * 1000);\n\n// Cleanup expired rate limit entries every 5 minutes\nsetInterval(() => {\n authRateLimiter.cleanup();\n}, 5 * 60 * 1000).unref();\n\n// ---------------------------------------------------------------------------\n// Permission model (mirrors packages/supabase/src/utils/permissions.ts)\n// ---------------------------------------------------------------------------\n\nconst MODULE_KEYS = [\n 'users', 'ssh_servers', 'supabase',\n 'wiki', 'ci_cd', 'source_control', 'domains',\n 'settings', 'agent_reporting',\n] as const;\n\ntype ModuleKey = (typeof MODULE_KEYS)[number];\n\ninterface ModulePermissions {\n users?: boolean;\n ssh_servers?: boolean;\n supabase?: boolean;\n wiki?: boolean;\n ci_cd?: boolean;\n source_control?: boolean;\n domains?: boolean;\n settings?: boolean;\n agent_reporting?: boolean;\n}\n\ninterface ResourcePermissions {\n ssh_servers: string[];\n supabase_instances: string[];\n}\n\ninterface UserPermissions {\n modules: ModulePermissions;\n resources: ResourcePermissions;\n}\n\nconst FULL_PERMISSIONS: UserPermissions = {\n modules: Object.fromEntries(MODULE_KEYS.map((k) => [k, true])) as ModulePermissions,\n resources: { ssh_servers: ['*'], supabase_instances: ['*'] },\n};\n\nfunction parsePermissions(raw: unknown): Partial<UserPermissions> | null {\n if (!raw || typeof raw !== 'object') return null;\n return raw as Partial<UserPermissions>;\n}\n\nfunction resolvePermissions(\n roleName: string,\n roleDefaults: unknown,\n userOverrides: unknown,\n): UserPermissions {\n if (roleName === 'superadmin') return FULL_PERMISSIONS;\n\n const base = parsePermissions(roleDefaults);\n const overrides = parsePermissions(userOverrides);\n\n const modules: ModulePermissions = {} as ModulePermissions;\n for (const key of MODULE_KEYS) {\n const userVal = overrides?.modules?.[key];\n const roleVal = base?.modules?.[key];\n (modules as Record<string, boolean>)[key] =\n userVal !== undefined ? userVal : roleVal !== undefined ? roleVal : false;\n }\n\n const resources: ResourcePermissions = {\n ssh_servers: overrides?.resources?.ssh_servers ?? base?.resources?.ssh_servers ?? [],\n supabase_instances: overrides?.resources?.supabase_instances ?? base?.resources?.supabase_instances ?? [],\n };\n\n return { modules, resources };\n}\n\n/**\n * Intersect key-level server restrictions with user permission resources.\n * Most restrictive wins: if both specify lists, return the overlap.\n */\nfunction intersectServerAccess(\n keyServerIds: string[] | null,\n permissionServerIds: string[],\n): string[] | null {\n const keyHasRestriction = keyServerIds !== null;\n const permWildcard = permissionServerIds.includes('*');\n const permEmpty = permissionServerIds.length === 0;\n\n if (!keyHasRestriction && permWildcard) return null; // unrestricted\n if (!keyHasRestriction && permEmpty) return [];\n if (!keyHasRestriction) return permissionServerIds;\n if (permWildcard) return keyServerIds;\n if (permEmpty) return [];\n return keyServerIds.filter((id) => permissionServerIds.includes(id));\n}\n\n/** Maps each MCP tool to the module permission it requires. */\nconst TOOL_MODULE_MAP: Partial<Record<string, ModuleKey>> = {\n 'list-servers': 'ssh_servers',\n 'ssh-execute': 'ssh_servers',\n 'sftp-list': 'ssh_servers',\n 'sftp-read': 'ssh_servers',\n 'sftp-write': 'ssh_servers',\n 'sftp-delete': 'ssh_servers',\n 'docker-list': 'ssh_servers',\n 'docker-logs': 'ssh_servers',\n 'db-discover': 'ssh_servers',\n 'db-tables': 'ssh_servers',\n 'db-describe': 'ssh_servers',\n 'db-query': 'ssh_servers',\n 'cache-purge': 'ssh_servers',\n 'env-list': 'ci_cd',\n 'env-get': 'ci_cd',\n 'env-store': 'ci_cd',\n 'domain-list': 'domains',\n 'domain-get': 'domains',\n 'dns-list': 'domains',\n 'dns-create': 'domains',\n 'dns-update': 'domains',\n 'dns-delete': 'domains',\n ...TRIGGER_TOOL_MODULE_MAP,\n ...AGENT_TOOL_MODULE_MAP,\n};\n\n// ---------------------------------------------------------------------------\n// Auth context\n// ---------------------------------------------------------------------------\n\ninterface AuthContext {\n userId: string;\n allowedServerIds: string[] | null;\n permissions: UserPermissions;\n roleName: string;\n}\n\nlet authContext: AuthContext | null = null;\n\nasync function validateApiKey(key: string): Promise<AuthContext | null> {\n if (!key.startsWith('dk_') || key.length !== 67) {\n console.error('Invalid API key format (expected dk_ + 64 hex chars)');\n return null;\n }\n\n const keyHash = createHash('sha256').update(key).digest('hex');\n\n const rateCheck = authRateLimiter.check(keyHash);\n if (!rateCheck.allowed) {\n const retryMin = Math.ceil(rateCheck.retryAfterMs / 60_000);\n console.error(`Rate limited: too many failed auth attempts. Retry in ${retryMin} minute(s).`);\n return null;\n }\n\n const { data, error } = await supabase\n .from('dashboard_mcp_api_key')\n .select('id, created_by, allowed_server_ids, is_active, expires_at')\n .eq('api_key_hash', keyHash)\n .eq('is_active', true)\n .single();\n\n if (error || !data) {\n console.error(`API key not found or inactive (${rateCheck.remaining} attempts remaining)`);\n return null;\n }\n\n if (data.expires_at && new Date(data.expires_at) < new Date()) {\n console.error(`API key has expired (${rateCheck.remaining} attempts remaining)`);\n return null;\n }\n\n // Load user + role permissions\n const { data: userData, error: userError } = await supabase\n .from('user')\n .select('permissions, role:role!role_id(name, default_permissions)')\n .eq('id', data.created_by)\n .single();\n\n if (userError || !userData) {\n console.error(`User not found for API key creator: ${data.created_by}`);\n return null;\n }\n\n const roleName = (userData.role as { name?: string })?.name || 'user';\n const roleDefaults = (userData.role as { default_permissions?: unknown })?.default_permissions ?? {};\n const userOverrides = userData.permissions ?? null;\n const permissions = resolvePermissions(roleName, roleDefaults, userOverrides);\n\n const allowedServerIds = intersectServerAccess(\n data.allowed_server_ids,\n permissions.resources.ssh_servers,\n );\n\n await supabase\n .from('dashboard_mcp_api_key')\n .update({ last_used_at: new Date().toISOString() })\n .eq('id', data.id);\n\n const moduleCount = MODULE_KEYS.filter((k) => permissions.modules[k]).length;\n console.error(`Authenticated as user ${data.created_by} (role: ${roleName}, modules: ${moduleCount}/${MODULE_KEYS.length})`);\n\n return {\n userId: data.created_by,\n allowedServerIds,\n permissions,\n roleName,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Server access helper\n// ---------------------------------------------------------------------------\n\nfunction assertServerAccess(serverId: string): void {\n if (!authContext) throw new Error('Not authenticated');\n if (authContext.allowedServerIds === null) return;\n if (!authContext.allowedServerIds.includes(serverId)) {\n throw new Error(`Access denied: you do not have permission for server ${serverId}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Release profile resolution helper\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a release profile name to its stage IDs.\n * Returns { stageIds, profileId } or throws with available profile names.\n */\nasync function resolveReleaseProfileStageIds(\n profileName: string,\n): Promise<{ stageIds: string[]; profileId: string }> {\n const { data: profile, error } = await supabase\n .from('release_profile')\n .select('id, name')\n .ilike('name', profileName)\n .maybeSingle();\n\n if (error) throw new Error(`Failed to look up release profile: ${error.message}`);\n\n if (!profile) {\n const { data: all } = await supabase\n .from('release_profile')\n .select('name')\n .order('name');\n const names = (all || []).map((p) => p.name).join(', ');\n throw new Error(\n `Release profile \"${profileName}\" not found. Available profiles: ${names || '(none)'}`,\n );\n }\n\n const { data: stages, error: stageErr } = await supabase\n .from('release_profile_stage')\n .select('id')\n .eq('release_profile_id', profile.id);\n\n if (stageErr) throw new Error(`Failed to look up stages: ${stageErr.message}`);\n if (!stages || stages.length === 0) {\n throw new Error(`Release profile \"${profile.name}\" has no stages configured`);\n }\n\n return { stageIds: stages.map((s) => s.id), profileId: profile.id };\n}\n\n/**\n * Look up release profile names for a set of stage IDs.\n * Returns a map of stageId -> profileName.\n */\nasync function getProfileNamesForStageIds(\n stageIds: string[],\n): Promise<Record<string, string>> {\n if (stageIds.length === 0) return {};\n\n const { data: stages } = await supabase\n .from('release_profile_stage')\n .select('id, release_profile_id')\n .in('id', stageIds);\n\n if (!stages || stages.length === 0) return {};\n\n const profileIds = [...new Set(stages.map((s) => s.release_profile_id))];\n const { data: profiles } = await supabase\n .from('release_profile')\n .select('id, name')\n .in('id', profileIds);\n\n if (!profiles) return {};\n\n const profileMap: Record<string, string> = {};\n for (const p of profiles) profileMap[p.id] = p.name;\n\n const result: Record<string, string> = {};\n for (const s of stages) {\n result[s.id] = profileMap[s.release_profile_id] || 'unknown';\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Encryption helpers (AES-256-GCM, compatible with dashboard encryption.ts)\n// ---------------------------------------------------------------------------\n\nconst ENC_ALGORITHM = 'aes-256-gcm';\nconst ENC_IV_LENGTH = 16;\nconst ENC_TAG_LENGTH = 16;\n\nfunction getEncryptionKey(): Buffer {\n if (!encryptionKey) throw new Error('ENCRYPTION_KEY is required for env operations');\n const buf = Buffer.from(encryptionKey, 'hex');\n if (buf.length !== 32) throw new Error('ENCRYPTION_KEY must be a 64-character hex string');\n return buf;\n}\n\nfunction encrypt(text: string): string {\n const key = getEncryptionKey();\n const iv = randomBytes(ENC_IV_LENGTH);\n const cipher = createCipheriv(ENC_ALGORITHM, new Uint8Array(key), new Uint8Array(iv));\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n const authTag = cipher.getAuthTag();\n return Buffer.concat([\n new Uint8Array(iv),\n new Uint8Array(authTag),\n new Uint8Array(Buffer.from(encrypted, 'hex')),\n ]).toString('base64');\n}\n\nfunction decrypt(payload: string): string {\n const key = getEncryptionKey();\n const buf = Buffer.from(payload, 'base64');\n const iv = buf.subarray(0, ENC_IV_LENGTH);\n const authTag = buf.subarray(ENC_IV_LENGTH, ENC_IV_LENGTH + ENC_TAG_LENGTH);\n const encrypted = buf.subarray(ENC_IV_LENGTH + ENC_TAG_LENGTH);\n const decipher = createDecipheriv(ENC_ALGORITHM, new Uint8Array(key), new Uint8Array(iv));\n decipher.setAuthTag(new Uint8Array(authTag));\n let decrypted = decipher.update(encrypted.toString('hex'), 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n}\n\n// ---------------------------------------------------------------------------\n// Vercel env sync helpers\n// ---------------------------------------------------------------------------\n\nconst VERCEL_API = 'https://api.vercel.com';\n\n/**\n * Parse a .env content string into key-value pairs.\n * Lines starting with # and empty lines are skipped.\n */\nfunction parseEnvContent(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx === -1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n let value = trimmed.slice(eqIdx + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (key) result[key] = value;\n }\n return result;\n}\n\ninterface VercelEnvVar {\n key: string;\n value: string;\n type: 'plain';\n target?: ('production' | 'preview' | 'development')[];\n customEnvironmentIds?: string[];\n}\n\ninterface StageApp {\n path: string;\n label: string;\n deployMethod: string;\n enabled: boolean;\n vercelProjectId?: string | null;\n vercelCustomEnvId?: string | null;\n}\n\n/**\n * Map stage type to Vercel target environments or custom environment ID.\n */\nfunction stageToVercelTargets(\n stageType: 'dev' | 'staging' | 'prod',\n customEnvId?: string | null,\n): { target?: ('production' | 'preview' | 'development')[]; customEnvironmentIds?: string[] } {\n if (stageType === 'prod') return { target: ['production'] };\n if (customEnvId) return { customEnvironmentIds: [customEnvId] };\n return { target: ['preview'] };\n}\n\n/** Dev stages also sync to built-in `development` for `vercel dev` (matches dashboard). */\nfunction getVercelEnvSyncTargetings(\n stageType: 'dev' | 'staging' | 'prod',\n customEnvId?: string | null,\n): Array<{ target?: ('production' | 'preview' | 'development')[]; customEnvironmentIds?: string[] }> {\n const primary = stageToVercelTargets(stageType, customEnvId);\n if (stageType !== 'dev') return [primary];\n return [primary, { target: ['development'] }];\n}\n\n/**\n * Push env vars to a Vercel project using upsert.\n */\nasync function syncEnvVarsToVercel(\n token: string,\n projectId: string,\n envVars: VercelEnvVar[],\n): Promise<{ created: number; error: string | null }> {\n if (envVars.length === 0) return { created: 0, error: null };\n\n const res = await fetch(\n `${VERCEL_API}/v10/projects/${encodeURIComponent(projectId)}/env?upsert=true`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(envVars),\n },\n );\n\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n return { created: 0, error: `Vercel API ${res.status}: ${body}` };\n }\n\n const data = await res.json().catch(() => ({}));\n return { created: (data as any)?.created?.length ?? envVars.length, error: null };\n}\n\n/**\n * After an env_config upsert, attempt to sync env vars to Vercel for the\n * linked stage. Resolves the stage via `release_profile_stage_id` on the\n * record or by looking up siblings with the same `app_name`.\n *\n * Returns a status string for inclusion in the MCP response.\n */\nasync function attemptVercelSync(appName: string, environment: string, knownStageId?: string): Promise<string> {\n try {\n // 1. Find the stage linked to this app_name\n let stageId = knownStageId;\n if (!stageId) {\n const { data: direct } = await supabase\n .from('env_config')\n .select('release_profile_stage_id')\n .eq('app_name', appName)\n .not('release_profile_stage_id', 'is', null)\n .limit(1)\n .single();\n\n stageId = direct?.release_profile_stage_id;\n }\n if (!stageId) return 'Vercel sync skipped: no stage link found';\n\n // 2. Get Vercel token\n const { data: settings } = await supabase\n .from('app_setting')\n .select('vercel_token_encrypted')\n .maybeSingle();\n\n if (!settings?.vercel_token_encrypted) return 'Vercel sync skipped: no Vercel token configured';\n\n let token: string;\n try {\n token = decrypt(settings.vercel_token_encrypted);\n } catch {\n return 'Vercel sync failed: could not decrypt Vercel token';\n }\n\n // 3. Fetch stage + stage_apps\n const { data: stage } = await supabase\n .from('release_profile_stage')\n .select('id, stage, stage_apps')\n .eq('id', stageId)\n .single();\n\n if (!stage) return 'Vercel sync skipped: stage not found';\n\n const stageType = stage.stage as 'dev' | 'staging' | 'prod';\n const stageApps: StageApp[] = (stage.stage_apps as StageApp[]) || [];\n const vercelApps = stageApps.filter(\n (a) => a.deployMethod === 'vercel' && a.enabled && a.vercelProjectId,\n );\n\n if (vercelApps.length === 0) return 'Vercel sync skipped: no Vercel apps in stage';\n\n // 4. Fetch all env_configs for the stage\n const { data: envConfigs } = await supabase\n .from('env_config')\n .select('*')\n .eq('release_profile_stage_id', stageId);\n\n if (!envConfigs || envConfigs.length === 0) return 'Vercel sync skipped: no env configs for stage';\n\n const variantMap: Record<string, string> = {\n dev: 'development',\n staging: 'staging',\n prod: 'production',\n };\n const deployedVariant = variantMap[stageType] ?? stageType;\n\n // 5. Sync each Vercel app\n const syncResults: string[] = [];\n for (const app of vercelApps) {\n const name = app.path.replace('apps/', '');\n const config = envConfigs.find(\n (c: any) => c.app_name === name && c.variant === deployedVariant,\n );\n\n if (!config) {\n syncResults.push(`${app.label}: skipped (no config for variant \"${deployedVariant}\")`);\n continue;\n }\n\n let envContent: string;\n try {\n envContent = decrypt((config as any).env_data_encrypted);\n } catch {\n syncResults.push(`${app.label}: decrypt failed`);\n continue;\n }\n\n const pairs = parseEnvContent(envContent);\n const keys = Object.keys(pairs);\n if (keys.length === 0) {\n syncResults.push(`${app.label}: empty config`);\n continue;\n }\n\n const targetings = getVercelEnvSyncTargetings(stageType, app.vercelCustomEnvId);\n let createdTotal = 0;\n let lastErr: string | null = null;\n\n for (const targeting of targetings) {\n const envVars: VercelEnvVar[] = keys.map((key) => ({\n key,\n value: pairs[key]!,\n type: 'plain' as const,\n ...targeting,\n }));\n\n const { created, error } = await syncEnvVarsToVercel(token, app.vercelProjectId!, envVars);\n if (error) lastErr = error;\n else createdTotal += created;\n }\n\n if (lastErr) {\n syncResults.push(`${app.label}: FAILED - ${lastErr}`);\n } else {\n syncResults.push(`${app.label}: ${createdTotal} var upsert(s) synced`);\n }\n }\n\n return `Vercel sync: ${syncResults.join('; ')}`;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Vercel sync error: ${msg}`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// SSH helpers\n// ---------------------------------------------------------------------------\n\ninterface SshConnectionOptions {\n hostname: string;\n port: number;\n username: string;\n password?: string;\n privateKey?: string;\n passphrase?: string;\n timeout?: number;\n}\n\ninterface SshResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nconst SSH_PROXY_SERVER_ID = '03659d55-e194-400d-b82a-bf6457371ded';\nlet _proxyConnCache: SshConnectionOptions | null = null;\n\nasync function getProxyConnection(): Promise<SshConnectionOptions> {\n if (_proxyConnCache) return _proxyConnCache;\n\n const { data, error } = await supabase\n .from('ssh_server')\n .select('hostname, port, username, password_encrypted, ssh_key_encrypted, ssh_key_passphrase_encrypted')\n .eq('id', SSH_PROXY_SERVER_ID)\n .single();\n\n if (error || !data) throw new Error('SSH Proxy server not found in database');\n if (!encryptionKey) throw new Error('ENCRYPTION_KEY required to decrypt server credentials');\n\n _proxyConnCache = {\n hostname: data.hostname,\n port: data.port || 22,\n username: data.username,\n password: data.password_encrypted ? decrypt(data.password_encrypted) : undefined,\n privateKey: data.ssh_key_encrypted ? decrypt(data.ssh_key_encrypted) : undefined,\n passphrase: data.ssh_key_passphrase_encrypted ? decrypt(data.ssh_key_passphrase_encrypted) : undefined,\n };\n return _proxyConnCache;\n}\n\n/**\n * Get connection options for a server. When `allowed_ssh_ips` is configured,\n * also returns proxy options so callers can route through the SSH Proxy.\n */\nasync function getServerConnection(serverId: string): Promise<{ conn: SshConnectionOptions; proxy?: SshConnectionOptions }> {\n assertServerAccess(serverId);\n\n const { data, error } = await supabase\n .from('ssh_server')\n .select('hostname, port, username, password_encrypted, ssh_key_encrypted, ssh_key_passphrase_encrypted, allowed_ssh_ips')\n .eq('id', serverId)\n .single();\n\n if (error || !data) throw new Error(`Server not found: ${serverId}`);\n if (!encryptionKey) throw new Error('ENCRYPTION_KEY required to decrypt server credentials');\n\n const conn: SshConnectionOptions = {\n hostname: data.hostname,\n port: data.port || 22,\n username: data.username,\n password: data.password_encrypted ? decrypt(data.password_encrypted) : undefined,\n privateKey: data.ssh_key_encrypted ? decrypt(data.ssh_key_encrypted) : undefined,\n passphrase: data.ssh_key_passphrase_encrypted ? decrypt(data.ssh_key_passphrase_encrypted) : undefined,\n };\n\n const needsProxy = data.allowed_ssh_ips !== null && serverId !== SSH_PROXY_SERVER_ID;\n const proxy = needsProxy ? await getProxyConnection() : undefined;\n\n return { conn, proxy };\n}\n\n/**\n * Execute an SSH command, optionally tunnelling through a proxy (ProxyJump).\n * When proxy is provided, the target server only sees the proxy's IP.\n */\nasync function sshExec(opts: SshConnectionOptions, command: string, proxy?: SshConnectionOptions): Promise<SshResult> {\n if (proxy) return sshExecViaProxy(proxy, opts, command);\n\n return new Promise((resolve) => {\n const ssh = new SshClient();\n let stdout = '';\n let stderr = '';\n let done = false;\n const timeout = opts.timeout || 60_000;\n\n const timer = setTimeout(() => {\n if (!done) { done = true; ssh.end(); resolve({ stdout, stderr, exitCode: -1 }); }\n }, timeout);\n\n ssh.on('ready', () => {\n ssh.exec(command, (err, stream) => {\n if (err) {\n if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve({ stdout, stderr, exitCode: -1 }); }\n return;\n }\n stream.on('data', (d: Buffer) => { stdout += d.toString(); });\n stream.stderr.on('data', (d: Buffer) => { stderr += d.toString(); });\n stream.on('close', (code: number | null) => {\n if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve({ stdout, stderr, exitCode: code ?? 0 }); }\n });\n });\n });\n\n ssh.on('error', (err) => {\n if (!done) { done = true; clearTimeout(timer); resolve({ stdout, stderr: err.message, exitCode: -1 }); }\n });\n\n ssh.connect({\n host: opts.hostname, port: opts.port, username: opts.username,\n password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase,\n readyTimeout: timeout,\n });\n });\n}\n\nfunction sshExecViaProxy(proxyOpts: SshConnectionOptions, targetOpts: SshConnectionOptions, command: string): Promise<SshResult> {\n return new Promise((resolve) => {\n const proxyClient = new SshClient();\n let done = false;\n const timeout = targetOpts.timeout || 60_000;\n\n const timer = setTimeout(() => {\n if (!done) { done = true; proxyClient.end(); resolve({ stdout: '', stderr: 'SSH proxy command timeout', exitCode: -1 }); }\n }, timeout);\n\n const cleanup = () => { clearTimeout(timer); proxyClient.end(); };\n\n proxyClient.on('ready', () => {\n proxyClient.forwardOut('127.0.0.1', 0, targetOpts.hostname, targetOpts.port, (err, tunnel) => {\n if (err) {\n if (!done) { done = true; cleanup(); resolve({ stdout: '', stderr: err.message, exitCode: -1 }); }\n return;\n }\n\n const targetClient = new SshClient();\n let stdout = '';\n let stderr = '';\n\n targetClient.on('ready', () => {\n targetClient.exec(command, (execErr, stream) => {\n if (execErr) {\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout, stderr, exitCode: -1 }); }\n return;\n }\n stream.on('data', (d: Buffer) => { stdout += d.toString(); });\n stream.stderr.on('data', (d: Buffer) => { stderr += d.toString(); });\n stream.on('close', (code: number | null) => {\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout, stderr, exitCode: code ?? 0 }); }\n });\n });\n });\n\n targetClient.on('error', (targetErr) => {\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout, stderr: targetErr.message, exitCode: -1 }); }\n });\n\n targetClient.connect({\n sock: tunnel,\n username: targetOpts.username, password: targetOpts.password,\n privateKey: targetOpts.privateKey, passphrase: targetOpts.passphrase,\n readyTimeout: timeout,\n });\n });\n });\n\n proxyClient.on('error', (err) => {\n if (!done) { done = true; cleanup(); resolve({ stdout: '', stderr: err.message, exitCode: -1 }); }\n });\n\n proxyClient.connect({\n host: proxyOpts.hostname, port: proxyOpts.port, username: proxyOpts.username,\n password: proxyOpts.password, privateKey: proxyOpts.privateKey, passphrase: proxyOpts.passphrase,\n readyTimeout: proxyOpts.timeout || 30_000,\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// SFTP helpers\n// ---------------------------------------------------------------------------\n\nfunction sanitizePath(path: string): string {\n let normalized = path.replace(/\\\\/g, '/').replace(/\\0/g, '');\n const parts = normalized.split('/');\n const resolved: string[] = [];\n for (const part of parts) {\n if (part === '..') { if (resolved.length > 0 && resolved[resolved.length - 1] !== '') resolved.pop(); }\n else if (part !== '.' && part !== '') resolved.push(part);\n }\n return '/' + resolved.join('/');\n}\n\nconst PROTECTED_PATHS = ['/etc/', '/boot/', '/usr/', '/bin/', '/sbin/', '/lib/', '/lib64/'];\n\nfunction assertWritablePath(path: string): void {\n const safe = sanitizePath(path);\n for (const p of PROTECTED_PATHS) {\n if (safe === p.slice(0, -1) || safe.startsWith(p)) {\n throw new Error(`Write access denied to protected path: ${safe}`);\n }\n }\n}\n\nasync function sftpReaddir(opts: SshConnectionOptions, dirPath: string): Promise<string> {\n const safe = sanitizePath(dirPath);\n return new Promise((resolve) => {\n const ssh = new SshClient();\n let done = false;\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 30_000);\n\n ssh.on('ready', () => {\n ssh.sftp((err, sftp) => {\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\n sftp.readdir(safe, (err, list) => {\n done = true; clearTimeout(timer);\n if (err) { ssh.end(); resolve(`Error: ${err.message}`); return; }\n const entries = list.map(item => {\n const mode = item.attrs.mode || 0;\n const isDir = (mode & 0o170000) === 0o040000;\n const size = item.attrs.size || 0;\n const mtime = item.attrs.mtime ? new Date(item.attrs.mtime * 1000).toISOString() : '';\n return `${isDir ? 'd' : '-'} ${String(size).padStart(10)} ${mtime} ${item.filename}`;\n });\n ssh.end();\n resolve(entries.join('\\n'));\n });\n });\n });\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 30_000 });\n });\n}\n\nasync function sftpRead(opts: SshConnectionOptions, filePath: string): Promise<string> {\n const safe = sanitizePath(filePath);\n return new Promise((resolve) => {\n const ssh = new SshClient();\n let done = false;\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 60_000);\n\n ssh.on('ready', () => {\n ssh.sftp((err, sftp) => {\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\n sftp.stat(safe, (err, stats) => {\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\n if ((stats.size || 0) > 1_048_576) {\n if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: file too large (${stats.size} bytes, max 1MB)`); }\n return;\n }\n const chunks: Buffer[] = [];\n const rs = sftp.createReadStream(safe);\n rs.on('data', (c: Buffer) => chunks.push(c));\n rs.on('end', () => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(Buffer.concat(chunks.map(c => new Uint8Array(c))).toString('utf-8')); } });\n rs.on('error', (e: Error) => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${e.message}`); } });\n });\n });\n });\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 60_000 });\n });\n}\n\nasync function sftpWrite(opts: SshConnectionOptions, filePath: string, content: string): Promise<string> {\n const safe = sanitizePath(filePath);\n assertWritablePath(safe);\n return new Promise((resolve) => {\n const ssh = new SshClient();\n let done = false;\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 60_000);\n\n ssh.on('ready', () => {\n ssh.sftp((err, sftp) => {\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\n const ws = sftp.createWriteStream(safe, { mode: 0o644 });\n ws.on('close', () => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Written ${content.length} bytes to ${safe}`); } });\n ws.on('error', (e: Error) => { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${e.message}`); } });\n ws.end(Buffer.from(content, 'utf-8'));\n });\n });\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 60_000 });\n });\n}\n\nasync function sftpDelete(opts: SshConnectionOptions, filePath: string): Promise<string> {\n const safe = sanitizePath(filePath);\n assertWritablePath(safe);\n return new Promise((resolve) => {\n const ssh = new SshClient();\n let done = false;\n const timer = setTimeout(() => { if (!done) { done = true; ssh.end(); resolve('Error: timeout'); } }, 30_000);\n\n ssh.on('ready', () => {\n ssh.sftp((err, sftp) => {\n if (err) { if (!done) { done = true; clearTimeout(timer); ssh.end(); resolve(`Error: ${err.message}`); } return; }\n sftp.unlink(safe, (err) => {\n if (err) {\n sftp.rmdir(safe, (err2) => {\n done = true; clearTimeout(timer); ssh.end();\n resolve(err2 ? `Error: ${err.message}` : `Deleted directory ${safe}`);\n });\n } else {\n done = true; clearTimeout(timer); ssh.end();\n resolve(`Deleted file ${safe}`);\n }\n });\n });\n });\n ssh.on('error', (e) => { if (!done) { done = true; clearTimeout(timer); resolve(`Error: ${e.message}`); } });\n ssh.connect({ host: opts.hostname, port: opts.port, username: opts.username, password: opts.password, privateKey: opts.privateKey, passphrase: opts.passphrase, readyTimeout: 30_000 });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Safety: dangerous command blocklist\n// ---------------------------------------------------------------------------\n\nconst BLOCKED_COMMANDS = [\n 'rm -rf /', 'rm -fr /', 'mkfs', 'dd if=', ':(){ :|:& };:',\n 'shutdown', 'halt', 'init 0', 'init 6',\n '> /dev/sda', 'mv /* /dev/null', 'chmod -R 000 /',\n];\n\nfunction assertSafeCommand(command: string): void {\n const lower = command.toLowerCase().trim();\n for (const blocked of BLOCKED_COMMANDS) {\n if (lower.includes(blocked)) {\n throw new Error(`Blocked dangerous command pattern: \"${blocked}\"`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// MySQL / Database helpers\n// ---------------------------------------------------------------------------\n\ninterface DbCredentials {\n host: string;\n user: string;\n password: string;\n database: string;\n port: number;\n sitePath: string;\n appType: string;\n}\n\n/**\n * Discovers web applications under /var/www and extracts DB credentials\n * from their config files (WordPress, PrestaShop, Laravel, custom .env).\n */\nasync function discoverSiteDatabases(conn: SshConnectionOptions, proxy?: SshConnectionOptions): Promise<DbCredentials[]> {\n const script = `\ncheck_dir() {\n local base=\"$1\" root=\"$2\"\n # WordPress\n if [ -f \"$root/wp-config.php\" ]; then\n echo \"WP|$base|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_NAME'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_USER'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_PASSWORD'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_HOST'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\"\n return\n fi\n # PrestaShop 1.7+\n if [ -f \"$root/app/config/parameters.php\" ]; then\n echo \"PS|$base|$(grep -oP \"'database_name'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)|$(grep -oP \"'database_user'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)|$(grep -oP \"'database_password'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)|$(grep -oP \"'database_host'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\"\n return\n fi\n # PrestaShop 1.6\n if [ -f \"$root/config/settings.inc.php\" ]; then\n echo \"PS|$base|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_NAME_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_USER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_PASSWD_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)|$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_SERVER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\"\n return\n fi\n # Laravel / generic .env\n if [ -f \"$root/.env\" ]; then\n DB_CONN=$(grep -oP '^DB_CONNECTION=\\\\K.*' \"$root/.env\" 2>/dev/null)\n if [ -n \"$DB_CONN\" ] && [ \"$DB_CONN\" != \"sqlite\" ]; then\n echo \"ENV|$base|$(grep -oP '^DB_DATABASE=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_USERNAME=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_PASSWORD=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_HOST=\\\\K.*' \"$root/.env\" 2>/dev/null)|$(grep -oP '^DB_PORT=\\\\K.*' \"$root/.env\" 2>/dev/null)\"\n return\n fi\n fi\n}\nfor dir in /var/www/*/; do\n [ -d \"$dir\" ] || continue\n check_dir \"$dir\" \"$dir\"\n # Also check common subdirectories: html, public_html, public, httpdocs\n for sub in html public_html public httpdocs; do\n [ -d \"$dir$sub\" ] && check_dir \"$dir\" \"$dir$sub\"\n done\ndone\n`.trim();\n\n const result = await sshExec(conn, script, proxy);\n const sites: DbCredentials[] = [];\n\n for (const line of result.stdout.split('\\n')) {\n if (!line.trim()) continue;\n const parts = line.split('|');\n if (parts.length < 6) continue;\n\n const [type, sitePath, database, user, password, host, port] = parts;\n if (!database || !user || !type || !sitePath) continue;\n\n const appTypes: Record<string, string> = { WP: 'WordPress', PS: 'PrestaShop', ENV: 'Laravel/.env' };\n\n sites.push({\n appType: appTypes[type] || type,\n sitePath: sitePath.replace(/\\/$/, ''),\n database,\n user,\n password: password || '',\n host: host || 'localhost',\n port: parseInt(port || '3306', 10),\n });\n }\n\n return sites;\n}\n\nfunction escapeMysqlShell(value: string): string {\n return value.replace(/'/g, \"'\\\\''\");\n}\n\nconst BLOCKED_SQL_PATTERNS = [\n /\\bDROP\\s+DATABASE\\b/i,\n /\\bDROP\\s+TABLE\\b/i,\n /\\bDROP\\s+INDEX\\b/i,\n /\\bTRUNCATE\\b/i,\n /\\bALTER\\s+TABLE\\s+\\w+\\s+DROP\\b/i,\n /\\bDELETE\\s+FROM\\s+\\w+\\s*$/i,\n];\n\nfunction assertSafeSql(query: string): void {\n const trimmed = query.trim();\n for (const pattern of BLOCKED_SQL_PATTERNS) {\n if (pattern.test(trimmed)) {\n throw new Error(`Blocked destructive SQL pattern: ${pattern.source}`);\n }\n }\n}\n\n/**\n * Builds a shell snippet that discovers DB credentials for a site path\n * and then executes a MySQL query, all in a single SSH session.\n */\nfunction buildSiteMysqlCommand(sitePath: string, query: string): string {\n const safePath = escapeMysqlShell(sitePath.replace(/\\/$/, ''));\n const safeQuery = escapeMysqlShell(query);\n\n return `\nSITE='${safePath}'\nDB_USER=\"\" DB_PASS=\"\" DB_NAME=\"\" DB_HOST=\"localhost\" DB_PORT=\"3306\"\nfor root in \"$SITE\" \"$SITE/html\" \"$SITE/public_html\" \"$SITE/public\" \"$SITE/httpdocs\"; do\n [ -d \"$root\" ] || continue\n if [ -f \"$root/wp-config.php\" ]; then\n DB_NAME=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_NAME'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\n DB_USER=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_USER'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\n DB_PASS=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_PASSWORD'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\n DB_HOST=$(grep -oP \"define\\\\s*\\\\(\\\\s*'DB_HOST'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/wp-config.php\" 2>/dev/null)\n break\n elif [ -f \"$root/app/config/parameters.php\" ]; then\n DB_NAME=$(grep -oP \"'database_name'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\n DB_USER=$(grep -oP \"'database_user'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\n DB_PASS=$(grep -oP \"'database_password'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\n DB_HOST=$(grep -oP \"'database_host'\\\\s*=>\\\\s*'\\\\K[^']+\" \"$root/app/config/parameters.php\" 2>/dev/null)\n break\n elif [ -f \"$root/config/settings.inc.php\" ]; then\n DB_NAME=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_NAME_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\n DB_USER=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_USER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\n DB_PASS=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_PASSWD_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\n DB_HOST=$(grep -oP \"define\\\\s*\\\\(\\\\s*'_DB_SERVER_'\\\\s*,\\\\s*'\\\\K[^']+\" \"$root/config/settings.inc.php\" 2>/dev/null)\n break\n elif [ -f \"$root/.env\" ]; then\n DB_CONN=$(grep -oP '^DB_CONNECTION=\\\\K.*' \"$root/.env\" 2>/dev/null)\n if [ -n \"$DB_CONN\" ] && [ \"$DB_CONN\" != \"sqlite\" ]; then\n DB_NAME=$(grep -oP '^DB_DATABASE=\\\\K.*' \"$root/.env\" 2>/dev/null)\n DB_USER=$(grep -oP '^DB_USERNAME=\\\\K.*' \"$root/.env\" 2>/dev/null)\n DB_PASS=$(grep -oP '^DB_PASSWORD=\\\\K.*' \"$root/.env\" 2>/dev/null)\n DB_HOST=$(grep -oP '^DB_HOST=\\\\K.*' \"$root/.env\" 2>/dev/null)\n DB_PORT=$(grep -oP '^DB_PORT=\\\\K.*' \"$root/.env\" 2>/dev/null)\n break\n fi\n fi\ndone\n[ -z \"$DB_NAME\" ] || [ -z \"$DB_USER\" ] && echo \"ERROR: No database config found at $SITE\" && exit 1\nDB_HOST=\\${DB_HOST:-localhost}\nDB_PORT=\\${DB_PORT:-3306}\nmysql --user=\"$DB_USER\" --password=\"$DB_PASS\" --host=\"$DB_HOST\" --port=\"$DB_PORT\" -t -e '${safeQuery}' \"$DB_NAME\" 2>&1 | grep -v \"\\\\[Warning\\\\].*password\"\n`.trim();\n}\n\n/**\n * Execute a MySQL query for a site in a single SSH session.\n * Discovers credentials and runs the query in one command.\n */\nasync function execSiteMysql(conn: SshConnectionOptions, sitePath: string, query: string, proxy?: SshConnectionOptions): Promise<string> {\n const cmd = buildSiteMysqlCommand(sitePath, query);\n const result = await sshExec(conn, cmd, proxy);\n const output = (result.stdout || '').trim();\n if (output.startsWith('ERROR: No database config found')) {\n throw new Error(output);\n }\n if (result.exitCode !== 0 && !output) {\n throw new Error(result.stderr || 'MySQL command failed');\n }\n return output;\n}\n\n// ---------------------------------------------------------------------------\n// mijn.host API helpers\n// ---------------------------------------------------------------------------\n\nconst MIJNHOST_BASE_URL = 'https://mijn.host/api/v2';\n\ninterface MijnHostApiResponse<T = unknown> {\n status: number;\n status_description: string;\n data: T;\n}\n\nfunction requireMijnhostApiKey(): string {\n if (!mijnhostApiKey) {\n throw new Error('mijn.host API key not configured. Use --mijnhost-api-key=xxx or set MIJNHOST_API_KEY');\n }\n return mijnhostApiKey;\n}\n\nasync function mijnhostFetch<T>(path: string, options: RequestInit = {}): Promise<MijnHostApiResponse<T>> {\n const key = requireMijnhostApiKey();\n\n const res = await fetch(`${MIJNHOST_BASE_URL}${path}`, {\n ...options,\n headers: {\n 'API-Key': key,\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n 'User-Agent': 'mg-dashboard-mcp/2.2.0',\n ...((options.headers as Record<string, string>) || {}),\n },\n });\n\n const json: unknown = await res.json();\n const body = json as MijnHostApiResponse<T>;\n\n if (!res.ok) {\n throw new Error(body?.status_description || `mijn.host API error: ${res.status}`);\n }\n\n return body;\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nconst TOOLS = [\n {\n name: 'list-servers',\n description: 'List all SSH servers you have access to. Returns id, name, hostname, and tags for each server.',\n inputSchema: { type: 'object' as const, properties: {}, required: [] },\n },\n {\n name: 'ssh-execute',\n description: 'Execute a shell command on a remote server via SSH. Some dangerous commands are blocked for safety.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n command: { type: 'string', description: 'Shell command to execute' },\n timeout: { type: 'number', description: 'Timeout in milliseconds (default: 60000)' },\n },\n required: ['serverId', 'command'],\n },\n },\n {\n name: 'sftp-list',\n description: 'List files and directories at a given path on a remote server via SFTP.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n path: { type: 'string', description: 'Directory path to list (default: /)' },\n },\n required: ['serverId'],\n },\n },\n {\n name: 'sftp-read',\n description: 'Read the contents of a text file on a remote server via SFTP (max 1MB).',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n path: { type: 'string', description: 'File path to read' },\n },\n required: ['serverId', 'path'],\n },\n },\n {\n name: 'sftp-write',\n description: 'Write content to a file on a remote server via SFTP. Protected system paths are blocked.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n path: { type: 'string', description: 'File path to write' },\n content: { type: 'string', description: 'File content to write' },\n },\n required: ['serverId', 'path', 'content'],\n },\n },\n {\n name: 'sftp-delete',\n description: 'Delete a file or empty directory on a remote server via SFTP. Protected system paths are blocked.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n path: { type: 'string', description: 'File or directory path to delete' },\n },\n required: ['serverId', 'path'],\n },\n },\n {\n name: 'docker-list',\n description: 'List all Docker containers on a remote server (running and stopped).',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n },\n required: ['serverId'],\n },\n },\n {\n name: 'docker-logs',\n description: 'Get recent logs from a Docker container.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n containerName: { type: 'string', description: 'Container name or ID' },\n lines: { type: 'number', description: 'Number of log lines to retrieve (default: 100)' },\n },\n required: ['serverId', 'containerName'],\n },\n },\n {\n name: 'db-discover',\n description: 'Scan /var/www on a server for web applications (WordPress, PrestaShop, Laravel, .env) and list their database credentials. Use this first to find available sites before running other db-* tools.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n },\n required: ['serverId'],\n },\n },\n {\n name: 'db-tables',\n description: 'List all tables in a site database with row counts and sizes. Credentials are auto-discovered from the site config files (wp-config.php, parameters.php, .env).',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com)' },\n },\n required: ['serverId', 'sitePath'],\n },\n },\n {\n name: 'db-describe',\n description: 'Show the structure of a database table (columns, types, keys, defaults). Credentials are auto-discovered from site config files.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com)' },\n table: { type: 'string', description: 'Table name' },\n },\n required: ['serverId', 'sitePath', 'table'],\n },\n },\n {\n name: 'db-query',\n description: 'Execute a SQL query on a site database. Credentials are auto-discovered from site config files. Destructive operations (DROP, TRUNCATE) are blocked.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com)' },\n query: { type: 'string', description: 'SQL query to execute' },\n },\n required: ['serverId', 'sitePath', 'query'],\n },\n },\n {\n name: 'env-list',\n description: 'List all stored environment configurations with their release profile names.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n releaseProfile: { type: 'string', description: 'Release profile name to filter by (usually matches the project folder name or git repo name, e.g. prefabaanbouw). Omit to list all.' },\n },\n },\n },\n {\n name: 'env-get',\n description: 'Retrieve the decrypted .env content for a specific app and environment.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n appName: { type: 'string', description: 'Application name (e.g. backoffice, api, web)' },\n environment: { type: 'string', description: 'Environment name (e.g. production, staging, development, local)' },\n releaseProfile: { type: 'string', description: 'Release profile name (usually matches the project folder name or git repo name, e.g. prefabaanbouw). Required when multiple profiles exist. Use env-list to discover available profiles.' },\n },\n required: ['appName', 'environment'],\n },\n },\n {\n name: 'env-store',\n description: 'Store or update an encrypted .env configuration for an app and environment.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n appName: { type: 'string', description: 'Application name (e.g. backoffice, api, web)' },\n environment: { type: 'string', description: 'Environment name (e.g. production, staging, development, local)' },\n content: { type: 'string', description: 'The .env file content to store' },\n description: { type: 'string', description: 'Optional description' },\n releaseProfile: { type: 'string', description: 'Release profile name (usually matches the project folder name or git repo name, e.g. prefabaanbouw). Required when multiple profiles exist. Use env-list to discover available profiles.' },\n },\n required: ['appName', 'environment', 'content'],\n },\n },\n {\n name: 'cache-purge',\n description: 'Purge ALL caches on a server in one operation: OPcache (kills lsphp), LiteSpeed cache, WordPress object cache (wp-cli or file-based), PrestaShop Smarty/app cache, Redis FLUSHALL, and Memcached flush. Returns a per-cache status report.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n serverId: { type: 'string', description: 'UUID of the SSH server' },\n },\n required: ['serverId'],\n },\n },\n // ----- Domains (mijn.host) -----\n {\n name: 'domain-list',\n description: 'List all domains from the mijn.host account. Returns domain name, status, renewal date, and tags. Requires MIJNHOST_API_KEY.',\n inputSchema: { type: 'object' as const, properties: {}, required: [] },\n },\n {\n name: 'domain-get',\n description: 'Get detailed information about a specific domain: status, renewal date, lock state, managed DNS, DNSSEC, nameservers, contact handles, and messages.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\n },\n required: ['domain'],\n },\n },\n {\n name: 'dns-list',\n description: 'List all DNS records for a domain. Returns type (A, AAAA, CNAME, MX, TXT, etc.), name, value, and TTL for each record.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\n },\n required: ['domain'],\n },\n },\n {\n name: 'dns-create',\n description: 'Add a new DNS record to a domain. Uses PATCH to add without replacing existing records.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\n type: { type: 'string', description: 'Record type: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, or TLSA' },\n name: { type: 'string', description: 'Record name (e.g. @ or subdomain)' },\n value: { type: 'string', description: 'Record value (e.g. IP address, hostname)' },\n ttl: { type: 'number', description: 'TTL in seconds (min 60, default 3600)' },\n },\n required: ['domain', 'type', 'name', 'value'],\n },\n },\n {\n name: 'dns-update',\n description: 'Update an existing DNS record. Identifies the record by type+name+oldValue, then replaces it with new values via PATCH.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\n type: { type: 'string', description: 'Record type: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, or TLSA' },\n name: { type: 'string', description: 'Record name' },\n oldValue: { type: 'string', description: 'Current value of the record to update' },\n newValue: { type: 'string', description: 'New value for the record' },\n ttl: { type: 'number', description: 'New TTL in seconds (min 60)' },\n },\n required: ['domain', 'type', 'name', 'oldValue', 'newValue'],\n },\n },\n {\n name: 'dns-delete',\n description: 'Delete a DNS record by type, name, and value. Fetches all records, removes the matching one, then replaces the full set.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n domain: { type: 'string', description: 'Domain name (e.g. example.com)' },\n type: { type: 'string', description: 'Record type to delete' },\n name: { type: 'string', description: 'Record name to delete' },\n value: { type: 'string', description: 'Record value to delete (must match exactly)' },\n },\n required: ['domain', 'type', 'name', 'value'],\n },\n },\n // ----- Trigger.dev -----\n ...TRIGGER_TOOLS,\n // ----- Scripts -----\n ...SCRIPT_TOOLS,\n // ----- Agent Reporting -----\n ...AGENT_TOOLS,\n];\n\n// ---------------------------------------------------------------------------\n// MCP Server\n// ---------------------------------------------------------------------------\n\nconst MCP_VERSION = '2.3.1';\n\nasync function handleListTools() {\n if (!authContext) return { tools: TOOLS };\n\n const accessible = TOOLS.filter((tool) => {\n const requiredModule = TOOL_MODULE_MAP[tool.name];\n if (!requiredModule) return true;\n return authContext!.permissions.modules[requiredModule] === true;\n });\n\n return { tools: accessible };\n}\n\nasync function handleCallTool(request: { params: { name: string; arguments?: Record<string, unknown> } }) {\n if (!authContext) {\n return { content: [{ type: 'text', text: 'Error: not authenticated' }] };\n }\n\n const { name, arguments: toolArgs } = request.params;\n const a = (toolArgs || {}) as Record<string, unknown>;\n\n // Module-level permission check\n const requiredModule = TOOL_MODULE_MAP[name];\n if (requiredModule && authContext.permissions.modules[requiredModule] !== true) {\n return {\n content: [{\n type: 'text',\n text: `Access denied: you do not have permission for the \"${requiredModule}\" module (tool: ${name})`,\n }],\n };\n }\n\n try {\n switch (name) {\n // ----- Servers -----\n case 'list-servers': {\n let query = supabase\n .from('ssh_server')\n .select('id, name, hostname, port, username, tags, hosted_by, created_at')\n .order('name');\n\n if (authContext.allowedServerIds !== null) {\n query = query.in('id', authContext.allowedServerIds);\n }\n\n const { data, error } = await query;\n if (error) throw new Error(error.message);\n\n const lines = (data || []).map(s => {\n const tags = Array.isArray(s.tags) ? (s.tags as string[]).join(', ') : '';\n return `${s.id} ${s.name} ${s.hostname}:${s.port} ${s.username} [${tags}] ${s.hosted_by || ''}`;\n });\n\n return { content: [{ type: 'text', text: lines.length ? lines.join('\\n') : 'No servers found' }] };\n }\n\n // ----- SSH -----\n case 'ssh-execute': {\n const command = String(a.command);\n assertSafeCommand(command);\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n if (a.timeout) conn.timeout = Number(a.timeout);\n const result = await sshExec(conn, command, proxy);\n const output = [`Exit code: ${result.exitCode}`];\n if (result.stdout) output.push(`--- stdout ---\\n${result.stdout}`);\n if (result.stderr) output.push(`--- stderr ---\\n${result.stderr}`);\n return { content: [{ type: 'text', text: output.join('\\n') }] };\n }\n\n // ----- SFTP (no proxy support yet — direct connection only) -----\n case 'sftp-list': {\n const { conn } = await getServerConnection(String(a.serverId));\n const listing = await sftpReaddir(conn, String(a.path || '/'));\n return { content: [{ type: 'text', text: listing }] };\n }\n\n case 'sftp-read': {\n const { conn } = await getServerConnection(String(a.serverId));\n const content = await sftpRead(conn, String(a.path));\n return { content: [{ type: 'text', text: content }] };\n }\n\n case 'sftp-write': {\n const { conn } = await getServerConnection(String(a.serverId));\n const result = await sftpWrite(conn, String(a.path), String(a.content));\n return { content: [{ type: 'text', text: result }] };\n }\n\n case 'sftp-delete': {\n const { conn } = await getServerConnection(String(a.serverId));\n const result = await sftpDelete(conn, String(a.path));\n return { content: [{ type: 'text', text: result }] };\n }\n\n // ----- Docker -----\n case 'docker-list': {\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n const result = await sshExec(conn, 'docker ps -a --format \"table {{.Names}}\\t{{.Image}}\\t{{.Status}}\\t{{.Ports}}\"', proxy);\n return { content: [{ type: 'text', text: result.exitCode === 0 ? result.stdout : `Error: ${result.stderr}` }] };\n }\n\n case 'docker-logs': {\n const container = String(a.containerName).replace(/[^a-zA-Z0-9._-]/g, '');\n const lines = Number(a.lines) || 100;\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n const result = await sshExec(conn, `docker logs --tail ${lines} ${container} 2>&1`, proxy);\n return { content: [{ type: 'text', text: result.exitCode === 0 ? result.stdout : `Error: ${result.stderr}` }] };\n }\n\n // ----- Database -----\n case 'db-discover': {\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n const sites = await discoverSiteDatabases(conn, proxy);\n if (!sites.length) {\n return { content: [{ type: 'text', text: 'No web applications with database configs found in /var/www/' }] };\n }\n const lines = sites.map(s =>\n `${s.sitePath} [${s.appType}] db=${s.database} user=${s.user} host=${s.host}:${s.port}`\n );\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\n }\n\n case 'db-tables': {\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n const sql = \"SELECT TABLE_NAME, ENGINE, TABLE_ROWS, ROUND(DATA_LENGTH/1024/1024, 2) AS `Size (MB)`, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME\";\n const output = await execSiteMysql(conn, String(a.sitePath), sql, proxy);\n return { content: [{ type: 'text', text: output || 'No tables found' }] };\n }\n\n case 'db-describe': {\n const table = String(a.table).replace(/[^a-zA-Z0-9_]/g, '');\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n const output = await execSiteMysql(conn, String(a.sitePath),\n `DESCRIBE \\`${table}\\`; SHOW INDEX FROM \\`${table}\\``, proxy);\n return { content: [{ type: 'text', text: output }] };\n }\n\n case 'db-query': {\n const query = String(a.query).trim();\n assertSafeSql(query);\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n const output = await execSiteMysql(conn, String(a.sitePath), query, proxy);\n return { content: [{ type: 'text', text: output || 'Query executed successfully (no output)' }] };\n }\n\n // ----- Env Config -----\n case 'env-list': {\n let query = supabase\n .from('env_config')\n .select('id, app_name, environment, description, updated_at, release_profile_stage_id')\n .order('app_name')\n .order('environment');\n\n if (a.releaseProfile) {\n const { stageIds } = await resolveReleaseProfileStageIds(String(a.releaseProfile));\n query = query.in('release_profile_stage_id', stageIds);\n }\n\n const { data, error } = await query;\n if (error) throw new Error(error.message);\n\n const stageIds = (data || [])\n .map((e) => e.release_profile_stage_id)\n .filter(Boolean) as string[];\n const profileNames = await getProfileNamesForStageIds(stageIds);\n\n const lines = (data || []).map((e) => {\n const profile = e.release_profile_stage_id\n ? profileNames[e.release_profile_stage_id] || 'unknown'\n : 'unlinked';\n return `${e.app_name}/${e.environment} [${profile}] (updated: ${e.updated_at})`;\n });\n return { content: [{ type: 'text', text: lines.length ? lines.join('\\n') : 'No environment configs stored' }] };\n }\n\n case 'env-get': {\n let query = supabase\n .from('env_config')\n .select('env_data_encrypted, release_profile_stage_id')\n .eq('app_name', String(a.appName))\n .eq('environment', String(a.environment));\n\n if (a.releaseProfile) {\n const { stageIds } = await resolveReleaseProfileStageIds(String(a.releaseProfile));\n query = query.in('release_profile_stage_id', stageIds);\n }\n\n const { data, error } = await query;\n\n if (error) throw new Error(`Env config query failed: ${error.message}`);\n if (!data || data.length === 0) {\n throw new Error(`Env config not found: ${a.appName}/${a.environment}${a.releaseProfile ? ` (profile: ${a.releaseProfile})` : ''}`);\n }\n if (data.length > 1) {\n const stageIds = data\n .map((r) => r.release_profile_stage_id)\n .filter(Boolean) as string[];\n const profileNames = await getProfileNamesForStageIds(stageIds);\n const names = [...new Set(Object.values(profileNames))].join(', ');\n throw new Error(\n `Multiple env configs found for ${a.appName}/${a.environment} across profiles: ${names}. ` +\n `Pass releaseProfile parameter to select one (e.g. releaseProfile: \"${Object.values(profileNames)[0] || '...'}\")`,\n );\n }\n\n const decrypted = decrypt(data[0]!.env_data_encrypted);\n return { content: [{ type: 'text', text: decrypted }] };\n }\n\n case 'env-store': {\n const appName = String(a.appName);\n const environment = String(a.environment);\n const encrypted = encrypt(String(a.content));\n\n let resolvedStageIds: string[] | null = null;\n if (a.releaseProfile) {\n const { stageIds } = await resolveReleaseProfileStageIds(String(a.releaseProfile));\n resolvedStageIds = stageIds;\n }\n\n let existQuery = supabase\n .from('env_config')\n .select('id, release_profile_stage_id')\n .eq('app_name', appName)\n .eq('environment', environment);\n\n if (resolvedStageIds) {\n existQuery = existQuery.in('release_profile_stage_id', resolvedStageIds);\n }\n\n const { data: existingRows, error: existErr } = await existQuery;\n if (existErr) throw new Error(`Lookup failed: ${existErr.message}`);\n\n if (existingRows && existingRows.length > 1 && !resolvedStageIds) {\n const stageIds = existingRows\n .map((r) => r.release_profile_stage_id)\n .filter(Boolean) as string[];\n const profileNames = await getProfileNamesForStageIds(stageIds);\n const names = [...new Set(Object.values(profileNames))].join(', ');\n throw new Error(\n `Multiple env configs found for ${appName}/${environment} across profiles: ${names}. ` +\n `Pass releaseProfile parameter to select one.`,\n );\n }\n\n const existing = existingRows?.[0] ?? null;\n let saveMsg: string;\n if (existing) {\n const { error } = await supabase\n .from('env_config')\n .update({\n env_data_encrypted: encrypted,\n description: a.description ? String(a.description) : undefined,\n updated_by: authContext!.userId,\n updated_at: new Date().toISOString(),\n })\n .eq('id', existing.id);\n if (error) throw new Error(error.message);\n saveMsg = `Updated env config: ${appName}/${environment}`;\n } else {\n const insertData: Record<string, unknown> = {\n app_name: appName,\n environment,\n env_data_encrypted: encrypted,\n description: a.description ? String(a.description) : null,\n created_by: authContext!.userId,\n updated_by: authContext!.userId,\n };\n if (resolvedStageIds?.[0]) {\n insertData.release_profile_stage_id = resolvedStageIds[0];\n }\n const { error } = await supabase.from('env_config').insert(insertData);\n if (error) throw new Error(error.message);\n saveMsg = `Stored env config: ${appName}/${environment}`;\n }\n\n const syncStageId = existing?.release_profile_stage_id ?? resolvedStageIds?.[0];\n const vercelStatus = await attemptVercelSync(appName, environment, syncStageId);\n return { content: [{ type: 'text', text: `${saveMsg}. ${vercelStatus}` }] };\n }\n\n // ----- Cache Purge -----\n case 'cache-purge': {\n const { conn, proxy } = await getServerConnection(String(a.serverId));\n conn.timeout = 120_000;\n const script = `\nR=\"\"\n# 1. OPcache – kill lsphp so it respawns with a fresh OPcache\nif pgrep -x lsphp >/dev/null 2>&1; then\n sudo killall lsphp 2>/dev/null && R=\"\\${R}[OK] OPcache: killed lsphp processes\\\\n\" || R=\"\\${R}[FAIL] OPcache: could not kill lsphp\\\\n\"\nelse\n R=\"\\${R}[SKIP] OPcache: no lsphp processes running\\\\n\"\nfi\n# 2. LiteSpeed cache directories\nLS=0\nfor cdir in /tmp/lshttpd/swap /usr/local/lsws/cachedata; do\n if [ -d \"\\$cdir\" ] && [ \"\\$(ls -A \"\\$cdir\" 2>/dev/null)\" ]; then\n sudo rm -rf \"\\$cdir\"/* 2>/dev/null && R=\"\\${R}[OK] LS cache: cleared \\$cdir\\\\n\" && LS=1 || R=\"\\${R}[FAIL] LS cache: \\$cdir\\\\n\"\n fi\ndone\n[ \"\\$LS\" -eq 0 ] && R=\"\\${R}[SKIP] LS cache: no cache dirs with content\\\\n\"\n# 3. LiteSpeed graceful restart\nif [ -x /usr/local/lsws/bin/lswsctrl ]; then\n sudo /usr/local/lsws/bin/lswsctrl restart 2>/dev/null && R=\"\\${R}[OK] LiteSpeed: graceful restart\\\\n\" || R=\"\\${R}[FAIL] LiteSpeed: restart failed\\\\n\"\nelif systemctl is-active lsws >/dev/null 2>&1 || systemctl is-active lshttpd >/dev/null 2>&1; then\n sudo systemctl restart lsws 2>/dev/null || sudo systemctl restart lshttpd 2>/dev/null\n R=\"\\${R}[OK] LiteSpeed: restarted via systemctl\\\\n\"\nelse\n R=\"\\${R}[SKIP] LiteSpeed: not detected\\\\n\"\nfi\n# 4. WordPress caches\nWP=0\nfor dir in /var/www/*/; do\n [ -d \"\\$dir\" ] || continue\n for root in \"\\$dir\" \"\\${dir}html\" \"\\${dir}public_html\" \"\\${dir}public\" \"\\${dir}httpdocs\"; do\n [ -f \"\\$root/wp-config.php\" ] || continue\n WP=1; SITE=\\$(basename \"\\$dir\")\n if command -v wp >/dev/null 2>&1; then\n wp cache flush --allow-root --path=\"\\$root\" 2>/dev/null && R=\"\\${R}[OK] WP (\\$SITE): wp cache flush\\\\n\" || R=\"\\${R}[FAIL] WP (\\$SITE): wp cache flush\\\\n\"\n elif [ -d \"\\$root/wp-content/cache\" ]; then\n rm -rf \"\\$root/wp-content/cache\"/* 2>/dev/null && R=\"\\${R}[OK] WP (\\$SITE): cleared wp-content/cache\\\\n\"\n else\n R=\"\\${R}[SKIP] WP (\\$SITE): no cache dir, no wp-cli\\\\n\"\n fi\n break\n done\ndone\n[ \"\\$WP\" -eq 0 ] && R=\"\\${R}[SKIP] WordPress: no sites found\\\\n\"\n# 5. PrestaShop caches\nPS=0\nfor dir in /var/www/*/; do\n [ -d \"\\$dir\" ] || continue\n for root in \"\\$dir\" \"\\${dir}html\" \"\\${dir}public_html\" \"\\${dir}public\" \"\\${dir}httpdocs\"; do\n IS=0\n [ -f \"\\$root/app/config/parameters.php\" ] && IS=1\n [ -f \"\\$root/config/settings.inc.php\" ] && IS=1\n [ \"\\$IS\" -eq 0 ] && continue\n PS=1; SITE=\\$(basename \"\\$dir\"); C=\"\"\n [ -d \"\\$root/var/cache\" ] && rm -rf \"\\$root/var/cache\"/* 2>/dev/null && C=\"\\${C}var/cache \"\n [ -d \"\\$root/cache/smarty/compile\" ] && rm -rf \"\\$root/cache/smarty/compile\"/* 2>/dev/null && C=\"\\${C}smarty/compile \"\n [ -d \"\\$root/cache/smarty/cache\" ] && rm -rf \"\\$root/cache/smarty/cache\"/* 2>/dev/null && C=\"\\${C}smarty/cache \"\n [ -n \"\\$C\" ] && R=\"\\${R}[OK] PS (\\$SITE): cleared \\${C}\\\\n\" || R=\"\\${R}[SKIP] PS (\\$SITE): no cache dirs\\\\n\"\n break\n done\ndone\n[ \"\\$PS\" -eq 0 ] && R=\"\\${R}[SKIP] PrestaShop: no sites found\\\\n\"\n# 6. Redis\nif command -v redis-cli >/dev/null 2>&1 && redis-cli ping >/dev/null 2>&1; then\n redis-cli FLUSHALL 2>/dev/null && R=\"\\${R}[OK] Redis: FLUSHALL\\\\n\" || R=\"\\${R}[FAIL] Redis: FLUSHALL failed\\\\n\"\nelse\n R=\"\\${R}[SKIP] Redis: not available\\\\n\"\nfi\n# 7. Memcached\nif systemctl is-active memcached >/dev/null 2>&1; then\n if command -v memcflush >/dev/null 2>&1; then\n memcflush --servers=localhost 2>/dev/null && R=\"\\${R}[OK] Memcached: flushed\\\\n\" || R=\"\\${R}[FAIL] Memcached: flush failed\\\\n\"\n else\n echo \"flush_all\" | nc -q1 localhost 11211 2>/dev/null && R=\"\\${R}[OK] Memcached: flushed via nc\\\\n\" || R=\"\\${R}[FAIL] Memcached: flush failed\\\\n\"\n fi\nelse\n R=\"\\${R}[SKIP] Memcached: not active\\\\n\"\nfi\necho -e \"\\$R\"\n`.trim();\n const result = await sshExec(conn, script, proxy);\n const output = (result.stdout || '').trim();\n return { content: [{ type: 'text', text: output || 'Cache purge completed (no output)' }] };\n }\n\n // ----- Domains (mijn.host) -----\n case 'domain-list': {\n interface DomainListItem {\n id: number;\n domain: string;\n renewal_date: string;\n status: string;\n status_id: number;\n tags: string[];\n }\n\n const res = await mijnhostFetch<{ domains: DomainListItem[] }>('/domains');\n const domains = res.data.domains;\n\n if (!domains.length) {\n return { content: [{ type: 'text', text: 'No domains found' }] };\n }\n\n const lines = domains.map(d => {\n const tags = d.tags?.length ? ` [${d.tags.join(', ')}]` : '';\n return `${d.domain} status=${d.status} renewal=${d.renewal_date}${tags}`;\n });\n\n return { content: [{ type: 'text', text: `${domains.length} domain(s):\\n\\n${lines.join('\\n')}` }] };\n }\n\n case 'domain-get': {\n const domain = String(a.domain);\n if (!domain) throw new Error('domain is required');\n\n interface DomainDetail {\n domain: string;\n renewal_date: string;\n is_lockable: boolean;\n is_locked: boolean;\n dnssec_enabled: number;\n nameservers: string[];\n managed_dns: boolean;\n whitelabel_ns: boolean;\n handles: {\n owner: { type: string; name: string; handle_id: number };\n tech: { type: string; name: string; handle_id: number };\n admin: { type: string; name: string; handle_id: number };\n reseller: { type: string; name: string; handle_id: number };\n };\n status: string;\n messages: string[];\n }\n\n const res = await mijnhostFetch<DomainDetail>(`/domains/${encodeURIComponent(domain)}`);\n const d = res.data;\n\n const sections = [\n `=== ${d.domain} ===`,\n `Status: ${d.status}`,\n `Renewal: ${d.renewal_date}`,\n `Locked: ${d.is_locked ? 'Yes' : 'No'} (lockable: ${d.is_lockable ? 'Yes' : 'No'})`,\n `Managed DNS: ${d.managed_dns ? 'Yes' : 'No'}`,\n `DNSSEC: ${d.dnssec_enabled ? 'Enabled' : 'Disabled'}`,\n `Nameservers: ${d.nameservers.join(', ')}`,\n '',\n '--- Contact Handles ---',\n `Owner: ${d.handles?.owner?.name ?? '-'}`,\n `Admin: ${d.handles?.admin?.name ?? '-'}`,\n `Tech: ${d.handles?.tech?.name ?? '-'}`,\n `Reseller: ${d.handles?.reseller?.name ?? '-'}`,\n ];\n\n if (d.messages?.length) {\n sections.push('', '--- Messages ---', ...d.messages);\n }\n\n return { content: [{ type: 'text', text: sections.join('\\n') }] };\n }\n\n case 'dns-list': {\n const domain = String(a.domain);\n if (!domain) throw new Error('domain is required');\n\n interface DnsRecord { type: string; name: string; value: string; ttl: number; }\n\n const res = await mijnhostFetch<{ domain: string; records: DnsRecord[] }>(\n `/domains/${encodeURIComponent(domain)}/dns`\n );\n const records = res.data.records;\n\n if (!records.length) {\n return { content: [{ type: 'text', text: `No DNS records found for ${domain}` }] };\n }\n\n const header = 'TYPE NAME VALUE TTL';\n const sep = '-'.repeat(90);\n const lines = records.map(r =>\n `${r.type.padEnd(10)}${r.name.padEnd(31)}${r.value.substring(0, 40).padEnd(41)}${r.ttl}`\n );\n\n return { content: [{ type: 'text', text: `DNS records for ${domain} (${records.length}):\\n\\n${header}\\n${sep}\\n${lines.join('\\n')}` }] };\n }\n\n case 'dns-create': {\n const domain = String(a.domain);\n const type = String(a.type).toUpperCase();\n const dnsName = String(a.name);\n const value = String(a.value);\n const ttl = Number(a.ttl) || 3600;\n\n if (!domain || !type || !dnsName || !value) {\n throw new Error('domain, type, name, and value are required');\n }\n\n interface DnsRecordCreate { type: string; name: string; value: string; ttl: number; }\n\n const current = await mijnhostFetch<{ domain: string; records: DnsRecordCreate[] }>(\n `/domains/${encodeURIComponent(domain)}/dns`\n );\n\n const records = [...current.data.records, { type, name: dnsName, value, ttl }];\n\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\n method: 'PUT',\n body: JSON.stringify({ records }),\n });\n\n return { content: [{ type: 'text', text: `DNS record created: ${type} ${dnsName} → ${value} (TTL: ${ttl})` }] };\n }\n\n case 'dns-update': {\n const domain = String(a.domain);\n const type = String(a.type).toUpperCase();\n const dnsName = String(a.name);\n const oldValue = String(a.oldValue);\n const newValue = String(a.newValue);\n const ttl = Number(a.ttl) || undefined;\n\n if (!domain || !type || !dnsName || !oldValue || !newValue) {\n throw new Error('domain, type, name, oldValue, and newValue are required');\n }\n\n interface DnsRecord { type: string; name: string; value: string; ttl: number; }\n\n const current = await mijnhostFetch<{ domain: string; records: DnsRecord[] }>(\n `/domains/${encodeURIComponent(domain)}/dns`\n );\n\n const idx = current.data.records.findIndex(\n r => r.type === type && r.name === dnsName && r.value === oldValue\n );\n\n if (idx === -1) {\n throw new Error(`No matching DNS record found: ${type} ${dnsName} = ${oldValue}`);\n }\n\n const updated = [...current.data.records];\n const existingTtl = updated[idx]!.ttl;\n updated[idx] = {\n type,\n name: dnsName,\n value: newValue,\n ttl: ttl ?? existingTtl,\n };\n\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\n method: 'PUT',\n body: JSON.stringify({ records: updated }),\n });\n\n return { content: [{ type: 'text', text: `DNS record updated: ${type} ${dnsName} → ${newValue}${ttl ? ` (TTL: ${ttl})` : ''}` }] };\n }\n\n case 'dns-delete': {\n const domain = String(a.domain);\n const type = String(a.type).toUpperCase();\n const dnsName = String(a.name);\n const value = String(a.value);\n\n if (!domain || !type || !dnsName || !value) {\n throw new Error('domain, type, name, and value are required');\n }\n\n interface DnsRecord { type: string; name: string; value: string; ttl: number; }\n\n const current = await mijnhostFetch<{ domain: string; records: DnsRecord[] }>(\n `/domains/${encodeURIComponent(domain)}/dns`\n );\n\n const before = current.data.records.length;\n const remaining = current.data.records.filter(\n r => !(r.type === type && r.name === dnsName && r.value === value)\n );\n\n if (remaining.length === before) {\n throw new Error(`No matching DNS record found: ${type} ${dnsName} = ${value}`);\n }\n\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\n method: 'PUT',\n body: JSON.stringify({ records: remaining }),\n });\n\n return { content: [{ type: 'text', text: `DNS record deleted: ${type} ${dnsName} = ${value} (${remaining.length} records remaining)` }] };\n }\n\n default:\n if (TRIGGER_TOOL_NAMES.has(name)) {\n return handleTriggerTool(name, a, { sshExec, getServerConnection });\n }\n if (SCRIPT_TOOL_NAMES.has(name)) {\n return handleScriptTool(name, a);\n }\n if (AGENT_TOOL_NAMES.has(name)) {\n return handleAgentTool(name, a, { supabase, workspaceId: agentWorkspaceId });\n }\n return { content: [{ type: 'text', text: `Unknown tool: ${name}` }] };\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return { content: [{ type: 'text', text: `Error: ${message}` }] };\n }\n}\n\n/** Create a configured MCP Server instance with handlers attached. */\nfunction createMcpServer(): Server {\n const s = new Server(\n { name: 'mg-dashboard-mcp', version: MCP_VERSION },\n { capabilities: { tools: {} } },\n );\n s.setRequestHandler(ListToolsRequestSchema, handleListTools);\n s.setRequestHandler(CallToolRequestSchema, handleCallTool as Parameters<typeof s.setRequestHandler>[1]);\n return s;\n}\n\nconst server = createMcpServer();\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nasync function main() {\n console.error('Starting MG Dashboard MCP Server...');\n\n authContext = await validateApiKey(apiKey!);\n if (!authContext) {\n console.error('API key validation failed');\n process.exit(1);\n }\n\n const toolNames = TOOLS.map(t => t.name).join(', ');\n\n if (httpMode) {\n console.error(`API key validated. Starting Streamable HTTP transport on port ${httpPort}...`);\n\n const transports = new Map<string, StreamableHTTPServerTransport>();\n\n // Map REST path → MCP tool name for agent convenience endpoints\n const REST_TOOL_MAP: Record<string, string> = {\n '/api/report-coverage': 'agent-report-coverage',\n '/api/report-finding': 'agent-report-finding',\n '/api/save-documentation': 'agent-save-documentation',\n '/api/list-findings': 'agent-list-findings',\n '/api/get-documentation': 'agent-get-documentation',\n };\n\n const httpServer = createHttpServer(async (req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost:${httpPort}`);\n\n // ── Simple REST endpoints for agents that can't use MCP protocol ──\n const restToolName = REST_TOOL_MAP[url.pathname];\n if (restToolName && req.method === 'POST') {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n let toolArgs: Record<string, unknown>;\n try {\n toolArgs = JSON.parse(Buffer.concat(chunks).toString());\n } catch {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Invalid JSON' }));\n return;\n }\n try {\n const result = await handleAgentTool(restToolName, toolArgs, { supabase, workspaceId: agentWorkspaceId });\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, result }));\n } catch (err) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));\n }\n return;\n }\n\n if (url.pathname === '/api/tools' && req.method === 'GET') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ tools: Object.keys(REST_TOOL_MAP) }));\n return;\n }\n\n if (url.pathname !== '/mcp') {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n return;\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, mcp-session-id',\n 'Access-Control-Expose-Headers': 'mcp-session-id',\n });\n res.end();\n return;\n }\n\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Expose-Headers', 'mcp-session-id');\n\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n let body: Record<string, unknown> | undefined;\n if (req.method === 'POST') {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n try {\n body = JSON.parse(Buffer.concat(chunks).toString());\n } catch {\n res.writeHead(400, { 'Content-Type': 'text/plain' });\n res.end('Invalid JSON');\n return;\n }\n }\n\n if (sessionId && transports.has(sessionId)) {\n await transports.get(sessionId)!.handleRequest(req, res, body);\n return;\n }\n\n if (req.method === 'POST' && body && (Array.isArray(body) ? body.some(isInitializeRequest) : isInitializeRequest(body))) {\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n transport.onclose = () => {\n if (transport.sessionId) transports.delete(transport.sessionId);\n };\n const sessionServer = createMcpServer();\n await sessionServer.connect(transport);\n if (transport.sessionId) transports.set(transport.sessionId, transport);\n await transport.handleRequest(req, res, body);\n return;\n }\n\n res.writeHead(400, { 'Content-Type': 'text/plain' });\n res.end('Bad request — missing or invalid session');\n });\n\n httpServer.listen(httpPort, () => {\n console.error(`MCP HTTP server ready on port ${httpPort}. Tools: ${toolNames}`);\n });\n } else {\n console.error('API key validated. Starting stdio transport...');\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(`MCP Server ready. Tools: ${toolNames}`);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n"]}