@mgsoftwarebv/mg-dashboard-mcp 6.0.1 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +31 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/proxy-mode.ts","../src/trigger-tools.ts","../src/vercel-tools.ts","../src/index.ts"],"names":["args","proxyUrl","apiKey","Client","sshExec","getServerConnection","name","runId","instance","waitArg","waitSeconds","getArg","runProxyMode","runProcess","spawn","join","existsSync","VERCEL_API","SshClient","sections","serverName","lines","content","conn","proxy","elapsed","r","text","ok","cmd","output","footer","stageIds","Server","ListToolsRequestSchema","CallToolRequestSchema","createHttpServer","StdioServerTransport"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Proxy-mode entry point for the MG dashboard MCP package.\r\n *\r\n * Usage:\r\n * npx @mgsoftwarebv/mg-dashboard-mcp \\\r\n * --proxy-url=https://mg-mcp.mgsoftware.nl/v1/{INSTANCE_ID}/mcp \\\r\n * --api-key=pk_xxx \\\r\n * --ssh-key=$HOME/.ssh/id_ed25519\r\n *\r\n * What it does:\r\n * 1. At startup it does an SSH-key challenge handshake against the proxy\r\n * (POST /v1/auth/ssh/challenge → ssh-keygen -Y sign → POST\r\n * /v1/auth/ssh/verify) and obtains a short-lived `pks_xxx` bearer.\r\n * 2. It then runs as a stdio MCP server, transparently forwarding every\r\n * JSON-RPC message to/from the upstream proxy URL using\r\n * `StreamableHTTPClientTransport` with the bearer attached.\r\n * 3. Before the token expires it re-runs the handshake and swaps in the\r\n * fresh bearer without dropping the connection.\r\n *\r\n * This lets a user point Cursor's mcp.json at the local stdio command with\r\n * both factors: a static `pk_` proxy key plus a linked SSH key proof. The\r\n * static key is only sent during the SSH verify step; normal MCP traffic uses\r\n * the short-lived `pks_` session token.\r\n */\r\n\r\nimport { spawn } from \"node:child_process\";\r\nimport { existsSync, readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\r\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\r\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport {\r\n CallToolRequestSchema,\r\n CallToolResultSchema,\r\n EmptyResultSchema,\r\n GetPromptRequestSchema,\r\n GetPromptResultSchema,\r\n ListPromptsRequestSchema,\r\n ListPromptsResultSchema,\r\n ListResourcesRequestSchema,\r\n ListResourcesResultSchema,\r\n ListResourceTemplatesRequestSchema,\r\n ListResourceTemplatesResultSchema,\r\n ListToolsRequestSchema,\r\n ListToolsResultSchema,\r\n ReadResourceRequestSchema,\r\n ReadResourceResultSchema,\r\n SubscribeRequestSchema,\r\n UnsubscribeRequestSchema,\r\n} from \"@modelcontextprotocol/sdk/types.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// CLI helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction getArg(args: string[], name: string): string | undefined {\r\n return args.find((a) => a.startsWith(`--${name}=`))?.split(\"=\").slice(1).join(\"=\");\r\n}\r\n\r\nfunction expandHome(path: string): string {\r\n if (!path.startsWith(\"~\")) return path;\r\n const home = process.env.HOME || process.env.USERPROFILE || \"\";\r\n return join(home, path.slice(1));\r\n}\r\n\r\nfunction resolvePubkeyPath(input: string): { pubPath: string; pubText: string } {\r\n const candidate = expandHome(input);\r\n let pubPath: string;\r\n if (candidate.endsWith(\".pub\")) {\r\n pubPath = candidate;\r\n } else if (existsSync(`${candidate}.pub`)) {\r\n pubPath = `${candidate}.pub`;\r\n } else if (existsSync(candidate)) {\r\n pubPath = candidate;\r\n } else {\r\n throw new Error(`SSH key file not found: ${candidate} (also tried ${candidate}.pub)`);\r\n }\r\n const pubText = readFileSync(pubPath, \"utf8\").trim();\r\n if (!pubText) throw new Error(`SSH public-key file is empty: ${pubPath}`);\r\n return { pubPath, pubText };\r\n}\r\n\r\nfunction runProcess(\r\n command: string,\r\n argv: string[],\r\n options: { stdin?: string } = {},\r\n): Promise<{ stdout: string; stderr: string; code: number }> {\r\n return new Promise((resolve) => {\r\n const child = spawn(command, argv, { stdio: [\"pipe\", \"pipe\", \"pipe\"] });\r\n let stdout = \"\";\r\n let stderr = \"\";\r\n child.stdout.on(\"data\", (d) => {\r\n stdout += d.toString();\r\n });\r\n child.stderr.on(\"data\", (d) => {\r\n stderr += d.toString();\r\n });\r\n child.on(\"error\", (err) => {\r\n resolve({ stdout, stderr: stderr + String(err), code: -1 });\r\n });\r\n child.on(\"close\", (code) => {\r\n resolve({ stdout, stderr, code: code ?? -1 });\r\n });\r\n if (options.stdin !== undefined) {\r\n child.stdin.write(options.stdin);\r\n child.stdin.end();\r\n } else {\r\n child.stdin.end();\r\n }\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// SSH-key handshake against /v1/auth/ssh/challenge + /v1/auth/ssh/verify\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface HandshakeResult {\r\n token: string;\r\n expiresAt: number; // ms epoch\r\n proxyKeyName: string;\r\n}\r\n\r\nfunction deriveAuthBaseUrl(proxyUrl: string): string {\r\n // proxyUrl looks like https://host/v1/{instanceId}/mcp\r\n // We need to call https://host (base) then /v1/auth/ssh/{challenge|verify}.\r\n const u = new URL(proxyUrl);\r\n return `${u.protocol}//${u.host}`;\r\n}\r\n\r\nasync function performHandshake(\r\n proxyUrl: string,\r\n apiKey: string,\r\n pubPath: string,\r\n pubText: string,\r\n): Promise<HandshakeResult> {\r\n const base = deriveAuthBaseUrl(proxyUrl);\r\n\r\n const challengeRes = await fetch(`${base}/v1/auth/ssh/challenge`, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: \"{}\",\r\n });\r\n if (!challengeRes.ok) {\r\n const txt = await challengeRes.text().catch(() => \"\");\r\n throw new Error(`Challenge request failed (${challengeRes.status}): ${txt}`);\r\n }\r\n const challenge = (await challengeRes.json()) as {\r\n challenge_id: string;\r\n nonce: string;\r\n namespace: string;\r\n };\r\n\r\n const sign = await runProcess(\r\n \"ssh-keygen\",\r\n [\"-Y\", \"sign\", \"-f\", pubPath, \"-n\", challenge.namespace, \"-q\"],\r\n { stdin: challenge.nonce },\r\n );\r\n if (sign.code !== 0 || !sign.stdout.includes(\"BEGIN SSH SIGNATURE\")) {\r\n throw new Error(\r\n `ssh-keygen sign failed (exit ${sign.code}). Make sure ssh-agent is running ` +\r\n `and has the matching private key loaded. stderr: ${sign.stderr.trim() || \"(empty)\"}`,\r\n );\r\n }\r\n\r\n const verifyRes = await fetch(`${base}/v1/auth/ssh/verify`, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({\r\n challenge_id: challenge.challenge_id,\r\n api_key: apiKey,\r\n pubkey: pubText,\r\n signature: sign.stdout,\r\n }),\r\n });\r\n if (!verifyRes.ok) {\r\n const txt = await verifyRes.text().catch(() => \"\");\r\n throw new Error(`Verify request failed (${verifyRes.status}): ${txt}`);\r\n }\r\n const verified = (await verifyRes.json()) as {\r\n token: string;\r\n expires_in_seconds: number;\r\n proxy_key_name: string;\r\n };\r\n\r\n return {\r\n token: verified.token,\r\n expiresAt: Date.now() + verified.expires_in_seconds * 1000,\r\n proxyKeyName: verified.proxy_key_name,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Bidirectional message forwarding\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Bridge between a stdio MCP server (talking to e.g. Cursor) and a remote\r\n * Streamable-HTTP MCP server (the proxy). Each incoming JSON-RPC message\r\n * is forwarded verbatim, and responses / notifications stream back.\r\n */\r\nasync function runBridge(handshake: HandshakeResult, proxyUrl: string, refresh: () => Promise<HandshakeResult>) {\r\n let currentToken = handshake.token;\r\n const requestHeaders: Record<string, string> = {\r\n Authorization: `Bearer ${currentToken}`,\r\n };\r\n\r\n const upstreamTransport = new StreamableHTTPClientTransport(new URL(proxyUrl), {\r\n requestInit: { headers: requestHeaders },\r\n });\r\n const upstream = new Client({ name: \"mg-dashboard-mcp-proxy-bridge\", version: \"1.0.0\" });\r\n\r\n // Schedule a refresh 2 minutes before expiry.\r\n const scheduleRefresh = (result: HandshakeResult) => {\r\n const msUntilRefresh = Math.max(30_000, result.expiresAt - Date.now() - 120_000);\r\n setTimeout(async () => {\r\n try {\r\n const fresh = await refresh();\r\n currentToken = fresh.token;\r\n requestHeaders.Authorization = `Bearer ${currentToken}`;\r\n console.error(`[Proxy] Token refreshed (key: ${fresh.proxyKeyName})`);\r\n scheduleRefresh(fresh);\r\n } catch (err) {\r\n console.error(`[Proxy] Token refresh failed: ${err instanceof Error ? err.message : String(err)}`);\r\n // Try again sooner on failure.\r\n setTimeout(() => scheduleRefresh({ ...result, expiresAt: Date.now() + 60_000 }), 30_000);\r\n }\r\n }, msUntilRefresh).unref();\r\n };\r\n scheduleRefresh(handshake);\r\n\r\n // Server-side stdio transport faces Cursor.\r\n const stdioServer = new Server(\r\n { name: \"mg-dashboard-mcp-proxy\", version: \"1.0.0\" },\r\n { capabilities: { tools: {}, prompts: {}, resources: {}, logging: {} } },\r\n );\r\n\r\n const forwardRequest =\r\n (resultSchema: Parameters<typeof upstream.request>[1]) =>\r\n async (request: unknown) =>\r\n upstream.request(\r\n request as Parameters<typeof upstream.request>[0],\r\n resultSchema,\r\n );\r\n\r\n // Explicitly forward first-class MCP methods. The SDK fallback only covers\r\n // truly unknown methods; Cursor's standard discovery calls need registered\r\n // handlers or the client sees an empty server.\r\n stdioServer.setRequestHandler(\r\n ListToolsRequestSchema,\r\n forwardRequest(ListToolsResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n CallToolRequestSchema,\r\n forwardRequest(CallToolResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ListPromptsRequestSchema,\r\n forwardRequest(ListPromptsResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n GetPromptRequestSchema,\r\n forwardRequest(GetPromptResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ListResourcesRequestSchema,\r\n forwardRequest(ListResourcesResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ReadResourceRequestSchema,\r\n forwardRequest(ReadResourceResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ListResourceTemplatesRequestSchema,\r\n forwardRequest(ListResourceTemplatesResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n SubscribeRequestSchema,\r\n forwardRequest(EmptyResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n UnsubscribeRequestSchema,\r\n forwardRequest(EmptyResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n\r\n // Dumb forwarder: any request from Cursor → forward to upstream → return result.\r\n stdioServer.fallbackRequestHandler = async (request: unknown) => {\r\n return await upstream.request(\r\n request as Parameters<typeof upstream.request>[0],\r\n // We don't care about the schema check on the way through — let the\r\n // upstream's actual response flow back unmodified.\r\n undefined as unknown as Parameters<typeof upstream.request>[1],\r\n );\r\n };\r\n // Same for notifications.\r\n stdioServer.fallbackNotificationHandler = async (notification: unknown) => {\r\n await upstream.notification(notification as Parameters<typeof upstream.notification>[0]);\r\n };\r\n\r\n await upstream.connect(upstreamTransport);\r\n\r\n // Forward upstream notifications back to Cursor.\r\n upstream.fallbackNotificationHandler = async (notification: unknown) => {\r\n await stdioServer.notification(notification as Parameters<typeof stdioServer.notification>[0]);\r\n };\r\n\r\n await stdioServer.connect(new StdioServerTransport());\r\n console.error(`[Proxy] Bridge ready. Forwarding stdio → ${proxyUrl}`);\r\n\r\n // In proxy mode this function is the long-lived process. Some SDK transports\r\n // finish their async `connect()` setup without leaving an obvious foreground\r\n // handle behind, which can make Node exit immediately after \"Bridge ready\".\r\n // Keep the process alive until Cursor closes stdin or the process receives a\r\n // termination signal.\r\n await new Promise<void>((resolve) => {\r\n const keepAlive = setInterval(() => undefined, 2_147_483_647);\r\n const done = () => {\r\n clearInterval(keepAlive);\r\n resolve();\r\n };\r\n process.stdin.once(\"close\", done);\r\n process.stdin.once(\"end\", done);\r\n process.once(\"SIGINT\", done);\r\n process.once(\"SIGTERM\", done);\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Public entry point\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function runProxyMode(args: string[]): Promise<void> {\r\n const proxyUrl = getArg(args, \"proxy-url\") || process.env.MG_DASHBOARD_PROXY_URL;\r\n const apiKey = getArg(args, \"api-key\") || process.env.MG_DASHBOARD_API_KEY;\r\n const sshKey = getArg(args, \"ssh-key\") || process.env.MG_DASHBOARD_SSH_KEY;\r\n\r\n if (!proxyUrl) {\r\n console.error(\"--proxy-url is required (or set MG_DASHBOARD_PROXY_URL)\");\r\n process.exit(1);\r\n }\r\n if (!apiKey) {\r\n console.error(\"--api-key is required in proxy mode (or set MG_DASHBOARD_API_KEY)\");\r\n process.exit(1);\r\n }\r\n if (!sshKey) {\r\n console.error(\"--ssh-key is required in proxy mode (or set MG_DASHBOARD_SSH_KEY)\");\r\n process.exit(1);\r\n }\r\n\r\n console.error(`[Proxy] Starting in proxy-bridge mode → ${proxyUrl}`);\r\n\r\n let resolved: { pubPath: string; pubText: string };\r\n try {\r\n resolved = resolvePubkeyPath(sshKey);\r\n } catch (err) {\r\n console.error(`[Proxy] ${err instanceof Error ? err.message : String(err)}`);\r\n process.exit(1);\r\n }\r\n\r\n const refresh = () => performHandshake(proxyUrl, apiKey, resolved.pubPath, resolved.pubText);\r\n\r\n let handshake: HandshakeResult;\r\n try {\r\n handshake = await refresh();\r\n } catch (err) {\r\n console.error(`[Proxy] Handshake failed: ${err instanceof Error ? err.message : String(err)}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`[Proxy] Authenticated as \"${handshake.proxyKeyName}\"`);\r\n console.error(`[Proxy] Token valid for ${Math.floor((handshake.expiresAt - Date.now()) / 60000)} min`);\r\n\r\n try {\r\n await runBridge(handshake, proxyUrl, refresh);\r\n } catch (err) {\r\n console.error(`[Proxy] Bridge crashed: ${err instanceof Error ? err.message : String(err)}`);\r\n process.exit(1);\r\n }\r\n}\r\n","/**\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\n/** MCP tool definitions for Trigger.dev (list projects, runs, details, test, replay). */\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.\\n\\n' +\r\n 'Common shortcuts: `failedOnly: true` returns only FAILED/CRASHED/SYSTEM_FAILURE/INTERRUPTED/TIMED_OUT. ' +\r\n '`sinceMinutes: 60` filters to runs created in the last hour (combines with status/taskIdentifier).',\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. Ignored when failedOnly is true.',\r\n },\r\n failedOnly: {\r\n type: 'boolean',\r\n description: 'Shortcut: only return FAILED + CRASHED + SYSTEM_FAILURE + INTERRUPTED + TIMED_OUT runs. Overrides `status` when true.',\r\n },\r\n taskIdentifier: { type: 'string', description: 'Filter by task identifier (e.g. \"hello-world\")' },\r\n sinceMinutes: { type: 'number', description: 'Only runs created in the last N minutes (uses Trigger filter[from]). Max 10080 (= 1 week).' },\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',\r\n description:\r\n 'Inspect, create, or replay a Trigger.dev run. Pick the mode with `action`:\\n' +\r\n '- \"detail\": fetch full run state — status, payload, output, error stack traces, and logs. Required: runId.\\n' +\r\n '- \"test\": kick off a task run and (by default) wait for it to complete, returning the final detail in one shot. Required: taskId. Optional: payload (JSON string), waitSeconds (default 60, max 300, set 0 to fire-and-forget).\\n' +\r\n '- \"replay\": re-run a previously failed/completed run with the same payload. Required: runId. Optional: waitSeconds (when >0, also waits for the new run to finish and returns its full detail).\\n\\n' +\r\n 'Tip: replace any old `trigger-run-detail` / `trigger-test-task` / `trigger-replay-run` calls with this single tool — output format is identical.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: { type: 'string', enum: ['detail', 'test', 'replay'], description: 'Which run operation to perform.' },\r\n project: { type: 'string', description: 'Project slug from trigger-list (e.g. \"mg-dashboard-bHfS\")' },\r\n runId: { type: 'string', description: 'Run ID (e.g. run_xxxxx). Required for action=\"detail\" or action=\"replay\".' },\r\n taskId: { type: 'string', description: 'Task identifier (e.g. \"hello-world\"). Required for action=\"test\".' },\r\n payload: { type: 'string', description: 'JSON payload string passed to the task (action=\"test\" only).' },\r\n waitSeconds: { type: 'number', description: 'Max seconds to wait for completion. Default 60 (action=\"test\") / 0 (action=\"replay\", fire-and-forget). Max 300. Set 0 to skip the wait.' },\r\n },\r\n required: ['action', 'project'],\r\n },\r\n },\r\n];\r\n\r\n/** Set of Trigger.dev MCP tool names for fast membership checks in the main server switch. */\r\nexport const TRIGGER_TOOL_NAMES = new Set(TRIGGER_TOOLS.map((t) => t.name));\r\n\r\n/** Maps each Trigger.dev tool name to the dashboard module key required to use it (`ci_cd`). */\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': '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\n/**\r\n * Executes a Trigger.dev–related MCP tool over SSH against the shared Docker Compose stack.\r\n *\r\n * @param name - Tool name (e.g. `trigger-list`, `trigger-runs`).\r\n * @param args - Arguments from the MCP `callTool` request.\r\n * @param deps - Injected `sshExec` and `getServerConnection` implementations.\r\n * @returns MCP-formatted result with human-readable text content.\r\n * @throws {Error} When a JSON payload for `trigger-test-task` is invalid, or discovery/API calls fail critically.\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\r\n const failedOnly = args.failedOnly === true;\r\n const statusArg = failedOnly\r\n ? 'FAILED,CRASHED,SYSTEM_FAILURE,INTERRUPTED,TIMED_OUT'\r\n : (args.status ? String(args.status) : '');\r\n if (statusArg) queryParts.push(`filter%5Bstatus%5D=${encodeURIComponent(statusArg)}`);\r\n\r\n if (args.taskIdentifier) {\r\n queryParts.push(`filter%5BtaskIdentifier%5D=${encodeURIComponent(String(args.taskIdentifier))}`);\r\n }\r\n\r\n const sinceMinutes = Number(args.sinceMinutes);\r\n if (Number.isFinite(sinceMinutes) && sinceMinutes > 0) {\r\n const capped = Math.min(sinceMinutes, 10080);\r\n const fromMs = Date.now() - capped * 60_000;\r\n queryParts.push(`filter%5Bfrom%5D=${fromMs}`);\r\n }\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': {\r\n const action = String(args.action);\r\n if (action !== 'detail' && action !== 'test' && action !== 'replay') {\r\n return { content: [{ type: 'text', text: 'Error: action must be one of: detail, test, replay' }] };\r\n }\r\n const project = String(args.project);\r\n\r\n if (action === 'detail') {\r\n const runId = String(args.runId ?? '');\r\n if (!runId) return { content: [{ type: 'text', text: 'Error: action=\"detail\" requires runId' }] };\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n return await fetchAndFormatRun(conn, proxy, sshExec, instance, runId);\r\n }\r\n\r\n if (action === 'test') {\r\n const taskId = String(args.taskId ?? '');\r\n if (!taskId) return { content: [{ type: 'text', text: 'Error: action=\"test\" requires taskId' }] };\r\n\r\n const waitArg = args.waitSeconds === undefined ? 60 : Number(args.waitSeconds);\r\n const waitSeconds = Math.min(Math.max(Number.isFinite(waitArg) ? waitArg : 60, 0), 300);\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 if (waitSeconds === 0) {\r\n return { content: [{ type: 'text', text: `Run triggered. ID: ${runId} (fire-and-forget; use action=\"detail\" to check).` }] };\r\n }\r\n\r\n return await waitForCompletion(conn, proxy, sshExec, instance, runId, waitSeconds);\r\n }\r\n\r\n // action === 'replay'\r\n const runId = String(args.runId ?? '');\r\n if (!runId) return { content: [{ type: 'text', text: 'Error: action=\"replay\" requires runId' }] };\r\n\r\n const waitArg = args.waitSeconds === undefined ? 0 : Number(args.waitSeconds);\r\n const waitSeconds = Math.min(Math.max(Number.isFinite(waitArg) ? waitArg : 0, 0), 300);\r\n if (waitSeconds > 0) conn.timeout = (waitSeconds + 30) * 1000;\r\n\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 if (!result.id) {\r\n return { content: [{ type: 'text', text: `Replay response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n if (waitSeconds === 0) {\r\n return { content: [{ type: 'text', text: `Run replayed. New run ID: ${result.id} (use action=\"detail\" to check status).` }] };\r\n }\r\n\r\n return await waitForCompletion(conn, proxy, sshExec, instance, result.id, waitSeconds);\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/** Fetch a run by ID and format it together with its console/logger output. */\r\nasync function fetchAndFormatRun(\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n instance: TriggerInstance,\r\n runId: string,\r\n): Promise<ToolResult> {\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) text += '\\n\\n--- Logs ---\\n' + logs;\r\n return { content: [{ type: 'text', text }] };\r\n}\r\n\r\n/** Poll a run until terminal status or budget expires, then return full detail. */\r\nasync function waitForCompletion(\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n instance: TriggerInstance,\r\n runId: string,\r\n waitSeconds: number,\r\n): Promise<ToolResult> {\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 action=\"detail\" with this runId to check later.`,\r\n }],\r\n };\r\n}\r\n","/**\r\n * Vercel MCP Tools\r\n *\r\n * Live-fetch tools for Vercel projects, deployments, build logs, runtime\r\n * logs, and webhook delivery history. The MCP server is shipped as a\r\n * standalone npm package and intentionally does NOT depend on\r\n * `@mgboiler/supabase` (which carries Next.js / cookie code), so all Vercel\r\n * REST calls and result formatting live in this file.\r\n *\r\n * The Vercel API token is decrypted from `app_setting.vercel_token_encrypted`\r\n * using the same AES-256-GCM scheme as the dashboard. Both the supabase\r\n * client and the `decrypt` function are injected as deps to avoid circular\r\n * imports with `index.ts`.\r\n *\r\n * @module vercel-tools\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 VercelToolDeps {\r\n supabase: SupabaseClient;\r\n decrypt: (payload: string) => string;\r\n}\r\n\r\nconst VERCEL_API = 'https://api.vercel.com';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const VERCEL_TOOLS = [\r\n {\r\n name: 'vercel-projects',\r\n description:\r\n 'List Vercel projects in the configured account/team. Returns id, name, ' +\r\n 'framework, GitHub repo link, production URL, and the latest deployment summary. ' +\r\n 'Use the project name or id as input to vercel-deployments.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n limit: { type: 'number', description: 'Max projects to return (default 50, max 200)' },\r\n search: { type: 'string', description: 'Substring filter on project name (case-insensitive)' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'vercel-deployments',\r\n description:\r\n 'List recent deployments for a Vercel project. Returns deployment ID, ' +\r\n 'state, target, branch, commit and timestamps. Use the deployment ID with ' +\r\n 'vercel-logs.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Vercel project ID or name (from vercel-projects)' },\r\n state: {\r\n type: 'string',\r\n description:\r\n 'Optional state filter: BUILDING, ERROR, INITIALIZING, QUEUED, READY, CANCELED',\r\n },\r\n target: { type: 'string', description: 'Optional target filter: production or preview' },\r\n limit: { type: 'number', description: 'Max deployments to return (default 20, max 100)' },\r\n },\r\n required: ['project'],\r\n },\r\n },\r\n {\r\n name: 'vercel-domains',\r\n description:\r\n 'Manage domains attached to a Vercel project. Use `action` to pick the operation:\\n' +\r\n '- \"list\" (default): list all domains attached to the project, including verification status and any redirect.\\n' +\r\n '- \"add\": attach a new domain to the project. Returns DNS records to set if the domain is not yet verified.\\n' +\r\n '- \"verify\": re-check verification status and surface required CNAME / A / TXT records if misconfigured.\\n' +\r\n '- \"remove\": detach a domain from the project.\\n' +\r\n 'Pick the project via vercel-projects first.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: {\r\n type: 'string',\r\n enum: ['list', 'add', 'remove', 'verify'],\r\n description: 'Which operation to perform (default: list).',\r\n },\r\n project: {\r\n type: 'string',\r\n description: 'Vercel project ID or name (from vercel-projects).',\r\n },\r\n domain: {\r\n type: 'string',\r\n description: 'Domain name (required for action=\"add\", \"remove\", or \"verify\").',\r\n },\r\n gitBranch: {\r\n type: 'string',\r\n description: 'Optional git branch this domain should deploy from (action=\"add\" only).',\r\n },\r\n redirect: {\r\n type: 'string',\r\n description: 'Optional redirect target domain (action=\"add\" only).',\r\n },\r\n redirectStatusCode: {\r\n type: 'number',\r\n description: 'Optional redirect status code, e.g. 301 / 302 / 307 / 308 (action=\"add\" only).',\r\n },\r\n },\r\n required: ['project'],\r\n },\r\n },\r\n {\r\n name: 'vercel-logs',\r\n description:\r\n 'Unified log inspector for Vercel. Use `kind` to pick the source:\\n' +\r\n '- \"build\" (default): build / deployment console events (stdout, stderr, command, exit). Requires deploymentId.\\n' +\r\n '- \"runtime\": runtime / function logs after a successful build. Requires project + deploymentId.\\n' +\r\n '- \"webhooks\": our own vercel_webhook_logs table (Telegram / push delivery history). No deployment needed.\\n' +\r\n 'Pick deployments via vercel-deployments first.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n kind: {\r\n type: 'string',\r\n enum: ['build', 'runtime', 'webhooks'],\r\n description: 'Which log stream to fetch (default: build).',\r\n },\r\n project: {\r\n type: 'string',\r\n description: 'Vercel project ID or name (required for kind=\"runtime\").',\r\n },\r\n deploymentId: {\r\n type: 'string',\r\n description: 'Vercel deployment ID (required for kind=\"build\" or \"runtime\").',\r\n },\r\n projectName: {\r\n type: 'string',\r\n description: 'Optional project_name filter (kind=\"webhooks\" only).',\r\n },\r\n status: {\r\n type: 'string',\r\n description: 'Optional status filter (kind=\"webhooks\" only): sent, skipped, error.',\r\n },\r\n sinceMinutes: {\r\n type: 'number',\r\n description:\r\n 'Time window in minutes (kind=\"runtime\" only, max 7 days). When omitted, the tool auto-detects the deployment\\'s created timestamp and queries from there with a 5-minute buffer — so you don\\'t miss logs by picking a too-small window.',\r\n },\r\n limit: {\r\n type: 'number',\r\n description:\r\n 'Max entries to return. Defaults per kind: build=500 (max 5000), runtime=200 (max 1000), webhooks=25 (max 200).',\r\n },\r\n },\r\n },\r\n },\r\n];\r\n\r\nexport const VERCEL_TOOL_NAMES = new Set(VERCEL_TOOLS.map((t) => t.name));\r\n\r\n/** All Vercel tools are gated behind the existing `ci_cd` module permission. */\r\nexport const VERCEL_TOOL_MODULE_MAP: Record<string, string> = {\r\n 'vercel-projects': 'ci_cd',\r\n 'vercel-deployments': 'ci_cd',\r\n 'vercel-logs': 'ci_cd',\r\n 'vercel-domains': 'ci_cd',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Vercel REST helpers (self-contained — mirrors packages/supabase/src/utils/vercel-api.ts)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface VercelFetchResult<T> {\r\n data: T | null;\r\n error: string | null;\r\n status: number;\r\n}\r\n\r\nasync function vercelFetch<T>(\r\n token: string,\r\n path: string,\r\n init?: { method?: string; body?: unknown },\r\n): Promise<VercelFetchResult<T>> {\r\n const res = await fetch(`${VERCEL_API}${path}`, {\r\n method: init?.method ?? 'GET',\r\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\r\n body: init?.body !== undefined ? JSON.stringify(init.body) : undefined,\r\n });\r\n const body = await res.text();\r\n let parsed: unknown = null;\r\n try {\r\n parsed = body ? JSON.parse(body) : null;\r\n } catch {\r\n // non-JSON\r\n }\r\n if (!res.ok) {\r\n const msg =\r\n (parsed as { error?: { message?: string }; message?: string })?.error?.message ??\r\n (parsed as { message?: string })?.message ??\r\n body ??\r\n `HTTP ${res.status}`;\r\n return { data: null, error: `Vercel API ${res.status}: ${msg}`, status: res.status };\r\n }\r\n return { data: parsed as T, error: null, status: res.status };\r\n}\r\n\r\ninterface VercelProjectListItem {\r\n id: string;\r\n name: string;\r\n framework: string | null;\r\n updatedAt: number;\r\n link?: { org?: string; repo?: string };\r\n latestDeployments?: { id: string; state: string; createdAt: number; url: string | null }[];\r\n targets?: { production?: { url: string | null; alias?: string[] } };\r\n}\r\n\r\ninterface VercelDeployment {\r\n uid: string;\r\n name: string;\r\n url: string | null;\r\n state: string;\r\n created: number;\r\n buildingAt?: number;\r\n ready?: number;\r\n target: string | null;\r\n meta?: {\r\n githubCommitRef?: string;\r\n githubCommitSha?: string;\r\n githubCommitMessage?: string;\r\n githubCommitAuthorLogin?: string;\r\n };\r\n}\r\n\r\ninterface VercelDeploymentEvent {\r\n type: string;\r\n created: number;\r\n payload?: { text?: string };\r\n text?: string;\r\n}\r\n\r\ninterface VercelProjectDomain {\r\n name: string;\r\n apexName?: string;\r\n projectId?: string;\r\n redirect?: string | null;\r\n redirectStatusCode?: number | null;\r\n gitBranch?: string | null;\r\n verified?: boolean;\r\n createdAt?: number;\r\n updatedAt?: number;\r\n verification?: {\r\n type: string;\r\n domain: string;\r\n value: string;\r\n reason?: string;\r\n }[];\r\n}\r\n\r\ninterface VercelDomainConfig {\r\n configuredBy?: 'CNAME' | 'A' | 'http' | null;\r\n acceptedChallenges?: string[];\r\n misconfigured?: boolean;\r\n}\r\n\r\ninterface VercelRuntimeLog {\r\n id?: string;\r\n rowId?: string;\r\n timestampInMs?: number;\r\n timestamp?: number;\r\n level?: string;\r\n message?: string;\r\n text?: string;\r\n source?: string;\r\n requestId?: string;\r\n proxy?: { host?: string; path?: string; method?: string; statusCode?: number };\r\n responseStatusCode?: number;\r\n}\r\n\r\nasync function listVercelProjectsAll(\r\n token: string,\r\n limit: number,\r\n): Promise<{ projects: VercelProjectListItem[]; error: string | null }> {\r\n const collected: VercelProjectListItem[] = [];\r\n let nextTimestamp: number | undefined;\r\n while (collected.length < limit) {\r\n const params = new URLSearchParams({ limit: String(Math.min(limit - collected.length, 100)) });\r\n if (nextTimestamp) params.set('until', String(nextTimestamp));\r\n const res = await vercelFetch<{\r\n projects: VercelProjectListItem[];\r\n pagination: { next: number | null };\r\n }>(token, `/v9/projects?${params.toString()}`);\r\n if (res.error) return { projects: [], error: res.error };\r\n if (!res.data?.projects?.length) break;\r\n collected.push(...res.data.projects);\r\n if (!res.data.pagination?.next) break;\r\n nextTimestamp = res.data.pagination.next;\r\n }\r\n return { projects: collected, error: null };\r\n}\r\n\r\nasync function listVercelDeployments(\r\n token: string,\r\n options: { projectId: string; limit: number; state?: string; target?: string },\r\n): Promise<{ deployments: VercelDeployment[]; error: string | null }> {\r\n const params = new URLSearchParams({\r\n limit: String(options.limit),\r\n projectId: options.projectId,\r\n });\r\n if (options.state) params.set('state', options.state);\r\n if (options.target) params.set('target', options.target);\r\n const res = await vercelFetch<{ deployments: VercelDeployment[] }>(\r\n token,\r\n `/v6/deployments?${params.toString()}`,\r\n );\r\n if (res.error) return { deployments: [], error: res.error };\r\n return { deployments: res.data?.deployments ?? [], error: null };\r\n}\r\n\r\nasync function getDeploymentBuildEvents(\r\n token: string,\r\n deploymentId: string,\r\n limit: number,\r\n): Promise<{ events: VercelDeploymentEvent[]; error: string | null }> {\r\n const params = new URLSearchParams({\r\n limit: String(limit),\r\n direction: 'forward',\r\n follow: '0',\r\n });\r\n const url = `${VERCEL_API}/v3/deployments/${encodeURIComponent(deploymentId)}/events?${params.toString()}`;\r\n const res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${token}` },\r\n });\r\n const body = await res.text();\r\n if (!res.ok) {\r\n let msg: string = body;\r\n try {\r\n const parsed = JSON.parse(body);\r\n msg = parsed?.error?.message ?? parsed?.message ?? body;\r\n } catch {\r\n // raw body\r\n }\r\n return { events: [], error: `Vercel API ${res.status}: ${msg}` };\r\n }\r\n const events: VercelDeploymentEvent[] = [];\r\n const trimmed = body.trim();\r\n if (!trimmed) return { events, error: null };\r\n try {\r\n const parsed = JSON.parse(trimmed);\r\n if (Array.isArray(parsed)) {\r\n for (const r of parsed) events.push(r as VercelDeploymentEvent);\r\n return { events, error: null };\r\n }\r\n } catch {\r\n // ndjson fallthrough\r\n }\r\n for (const line of trimmed.split('\\n')) {\r\n const s = line.trim();\r\n if (!s) continue;\r\n try {\r\n events.push(JSON.parse(s));\r\n } catch {\r\n // skip malformed\r\n }\r\n }\r\n return { events, error: null };\r\n}\r\n\r\n/**\r\n * Fetch the `created` timestamp of a deployment so we can size the runtime-log\r\n * window automatically. Returns null when the deployment isn't found, so the\r\n * caller can fall back to a sensible default window instead of erroring out.\r\n */\r\nasync function getDeploymentCreatedMs(\r\n token: string,\r\n deploymentId: string,\r\n): Promise<number | null> {\r\n const res = await vercelFetch<{ createdAt?: number; created?: number }>(\r\n token,\r\n `/v13/deployments/${encodeURIComponent(deploymentId)}`,\r\n );\r\n if (res.error || !res.data) return null;\r\n return res.data.createdAt ?? res.data.created ?? null;\r\n}\r\n\r\nasync function getRuntimeLogs(\r\n token: string,\r\n projectIdOrName: string,\r\n deploymentId: string,\r\n limit: number,\r\n sinceMs?: number,\r\n): Promise<{ logs: VercelRuntimeLog[]; error: string | null }> {\r\n const params = new URLSearchParams({\r\n limit: String(Math.min(Math.max(limit, 1), 1000)),\r\n });\r\n if (sinceMs) params.set('since', String(sinceMs));\r\n const url = `${VERCEL_API}/v1/projects/${encodeURIComponent(projectIdOrName)}/deployments/${encodeURIComponent(deploymentId)}/runtime-logs?${params.toString()}`;\r\n const res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${token}` },\r\n });\r\n const body = await res.text();\r\n if (!res.ok) {\r\n let msg: string = body;\r\n try {\r\n const parsed = JSON.parse(body);\r\n msg = parsed?.error?.message ?? parsed?.message ?? body;\r\n } catch {\r\n // raw body\r\n }\r\n return { logs: [], error: `Vercel API ${res.status}: ${msg}` };\r\n }\r\n const logs: VercelRuntimeLog[] = [];\r\n const trimmed = body.trim();\r\n if (!trimmed) return { logs, error: null };\r\n try {\r\n const parsed = JSON.parse(trimmed);\r\n if (Array.isArray(parsed)) {\r\n for (const r of parsed) logs.push(r as VercelRuntimeLog);\r\n return { logs, error: null };\r\n }\r\n } catch {\r\n // ndjson fallthrough\r\n }\r\n for (const line of trimmed.split('\\n')) {\r\n const s = line.trim();\r\n if (!s) continue;\r\n try {\r\n logs.push(JSON.parse(s));\r\n } catch {\r\n // skip\r\n }\r\n }\r\n return { logs, error: null };\r\n}\r\n\r\nasync function listProjectDomains(\r\n token: string,\r\n projectId: string,\r\n): Promise<{ domains: VercelProjectDomain[]; error: string | null }> {\r\n const res = await vercelFetch<{ domains: VercelProjectDomain[] }>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectId)}/domains?limit=100`,\r\n );\r\n if (res.error) return { domains: [], error: res.error };\r\n return { domains: res.data?.domains ?? [], error: null };\r\n}\r\n\r\nasync function addProjectDomain(\r\n token: string,\r\n projectId: string,\r\n body: {\r\n name: string;\r\n gitBranch?: string;\r\n redirect?: string;\r\n redirectStatusCode?: number;\r\n },\r\n): Promise<{ domain: VercelProjectDomain | null; error: string | null }> {\r\n const res = await vercelFetch<VercelProjectDomain>(\r\n token,\r\n `/v10/projects/${encodeURIComponent(projectId)}/domains`,\r\n { method: 'POST', body },\r\n );\r\n if (res.error) return { domain: null, error: res.error };\r\n return { domain: res.data, error: null };\r\n}\r\n\r\nasync function removeProjectDomain(\r\n token: string,\r\n projectId: string,\r\n domain: string,\r\n): Promise<{ error: string | null }> {\r\n const res = await vercelFetch<unknown>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(domain)}`,\r\n { method: 'DELETE' },\r\n );\r\n return { error: res.error };\r\n}\r\n\r\nasync function getProjectDomain(\r\n token: string,\r\n projectId: string,\r\n domain: string,\r\n): Promise<{ domain: VercelProjectDomain | null; error: string | null }> {\r\n const res = await vercelFetch<VercelProjectDomain>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(domain)}`,\r\n );\r\n if (res.error) return { domain: null, error: res.error };\r\n return { domain: res.data, error: null };\r\n}\r\n\r\nasync function getDomainConfig(\r\n token: string,\r\n domain: string,\r\n): Promise<{ config: VercelDomainConfig | null; error: string | null }> {\r\n const res = await vercelFetch<VercelDomainConfig>(\r\n token,\r\n `/v6/domains/${encodeURIComponent(domain)}/config`,\r\n );\r\n if (res.error) return { config: null, error: res.error };\r\n return { config: res.data, error: null };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Token resolution\r\n// ---------------------------------------------------------------------------\r\n\r\nasync function getVercelToken(deps: VercelToolDeps): Promise<string> {\r\n const { data, error } = await deps.supabase\r\n .from('app_setting')\r\n .select('vercel_token_encrypted')\r\n .maybeSingle();\r\n if (error) throw new Error(`Could not read app_setting: ${error.message}`);\r\n if (!data?.vercel_token_encrypted) {\r\n throw new Error('Vercel API token is not configured. Add it in dashboard Settings.');\r\n }\r\n try {\r\n return deps.decrypt(data.vercel_token_encrypted);\r\n } catch {\r\n throw new Error('Failed to decrypt the stored Vercel API token.');\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a project name or ID to its Vercel project ID.\r\n * Vercel's deployment list endpoint accepts both, but we still need the\r\n * canonical ID for the runtime-logs endpoint and to match by-name lookups.\r\n */\r\nasync function resolveProjectId(token: string, projectInput: string): Promise<string> {\r\n const res = await vercelFetch<{ id: string }>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectInput)}`,\r\n );\r\n if (res.error || !res.data?.id) {\r\n throw new Error(\r\n `Could not resolve Vercel project \"${projectInput}\": ${res.error ?? 'not found'}`,\r\n );\r\n }\r\n return res.data.id;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Output formatters\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction formatTimestamp(ms: number | undefined): string {\r\n if (!ms) return '';\r\n return new Date(ms).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' });\r\n}\r\n\r\nfunction formatProjectsTable(projects: VercelProjectListItem[]): string {\r\n if (projects.length === 0) return 'No Vercel projects found';\r\n const lines = projects.map((p) => {\r\n const repo = p.link ? `${p.link.org ?? ''}/${p.link.repo ?? ''}` : '';\r\n const prodUrl =\r\n p.targets?.production?.alias?.[0] ?? p.targets?.production?.url ?? '';\r\n const latest = p.latestDeployments?.[0];\r\n const latestStr = latest ? `${latest.state} @ ${formatTimestamp(latest.createdAt)}` : '';\r\n return `${p.id.padEnd(28)} ${(p.name || '').padEnd(40)} ${(p.framework || '-').padEnd(10)} ${repo.padEnd(40)} ${prodUrl.padEnd(35)} ${latestStr}`;\r\n });\r\n const header = `${'ID'.padEnd(28)} ${'NAME'.padEnd(40)} ${'FRAMEWORK'.padEnd(10)} ${'REPO'.padEnd(40)} ${'PROD URL'.padEnd(35)} LATEST`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\nfunction formatDeploymentsTable(deployments: VercelDeployment[]): string {\r\n if (deployments.length === 0) return 'No deployments found';\r\n const lines = deployments.map((d) => {\r\n const branch = d.meta?.githubCommitRef ?? '';\r\n const sha = d.meta?.githubCommitSha?.slice(0, 7) ?? '';\r\n const msg = (d.meta?.githubCommitMessage ?? '').replace(/\\n.*/s, '').slice(0, 60);\r\n return `${d.uid.padEnd(28)} ${d.state.padEnd(11)} ${(d.target || '-').padEnd(10)} ${branch.padEnd(20)} ${sha.padEnd(8)} ${formatTimestamp(d.created).padEnd(20)} ${msg}`;\r\n });\r\n const header = `${'ID'.padEnd(28)} ${'STATE'.padEnd(11)} ${'TARGET'.padEnd(10)} ${'BRANCH'.padEnd(20)} ${'COMMIT'.padEnd(8)} ${'CREATED'.padEnd(20)} MESSAGE`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\nfunction formatBuildEvents(events: VercelDeploymentEvent[]): string {\r\n if (events.length === 0) return 'No build events found for this deployment';\r\n const filtered = events.filter((e) =>\r\n ['command', 'stdout', 'stderr', 'exit', 'delimiter', 'deployment-state'].includes(e.type),\r\n );\r\n return filtered\r\n .map((e) => {\r\n const time = e.created\r\n ? new Date(e.created).toISOString().slice(11, 19)\r\n : '--:--:--';\r\n const text = (e.payload?.text ?? e.text ?? '').replace(/\\s+$/u, '');\r\n const prefix = e.type === 'stderr' ? '!' : ' ';\r\n return `${prefix}${time} [${e.type.padEnd(16)}] ${text}`;\r\n })\r\n .join('\\n');\r\n}\r\n\r\nfunction formatRuntimeLogs(logs: VercelRuntimeLog[]): string {\r\n if (logs.length === 0) {\r\n return 'No runtime logs found for this deployment in the requested window';\r\n }\r\n return logs\r\n .map((l) => {\r\n const ts = l.timestampInMs ?? l.timestamp ?? 0;\r\n const time = ts ? new Date(ts).toISOString().slice(11, 23) : '--:--:--';\r\n const level = (l.level ?? 'info').toUpperCase().padEnd(5);\r\n const status = l.proxy?.statusCode ?? l.responseStatusCode;\r\n const reqInfo = l.proxy?.method\r\n ? `${l.proxy.method} ${l.proxy.path ?? ''} ${status ?? ''}`.trim()\r\n : '';\r\n const message = (l.message ?? l.text ?? '').replace(/\\s+$/u, '');\r\n const reqId = l.requestId ? ` [${l.requestId.slice(0, 12)}]` : '';\r\n const head = reqInfo ? `${reqInfo}${reqId}` : reqId.trim();\r\n return `${time} [${level}] ${head ? head + ' ' : ''}${message}`;\r\n })\r\n .join('\\n');\r\n}\r\n\r\ninterface WebhookLogRow {\r\n id: string;\r\n event_type: string;\r\n status: string;\r\n project_name: string | null;\r\n deployment_id: string | null;\r\n target: string | null;\r\n message: string | null;\r\n error_message: string | null;\r\n created_at: string;\r\n}\r\n\r\nfunction formatWebhookHistory(rows: WebhookLogRow[]): string {\r\n if (rows.length === 0) return 'No webhook log rows match those filters';\r\n const lines = rows.map((r) => {\r\n const ts = new Date(r.created_at).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' });\r\n const note = r.error_message ?? r.message ?? '';\r\n return `${ts.padEnd(20)} ${r.event_type.padEnd(22)} ${r.status.padEnd(8)} ${(r.project_name ?? '').padEnd(40)} ${(r.target ?? '').padEnd(10)} ${(r.deployment_id ?? '').padEnd(28)} ${note}`;\r\n });\r\n const header = `${'WHEN'.padEnd(20)} ${'EVENT'.padEnd(22)} ${'STATUS'.padEnd(8)} ${'PROJECT'.padEnd(40)} ${'TARGET'.padEnd(10)} ${'DEPLOYMENT'.padEnd(28)} NOTE`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\nfunction formatDomainsTable(domains: VercelProjectDomain[]): string {\r\n if (domains.length === 0) return 'No domains attached to this project';\r\n const lines = domains.map((d) => {\r\n const verified = d.verified ? 'yes' : 'no';\r\n const branch = d.gitBranch ?? '';\r\n const redirect = d.redirect\r\n ? `${d.redirect}${d.redirectStatusCode ? ` (${d.redirectStatusCode})` : ''}`\r\n : '';\r\n return `${d.name.padEnd(45)} ${verified.padEnd(9)} ${branch.padEnd(20)} ${redirect.padEnd(35)} ${formatTimestamp(d.createdAt)}`;\r\n });\r\n const header = `${'DOMAIN'.padEnd(45)} ${'VERIFIED'.padEnd(9)} ${'GIT BRANCH'.padEnd(20)} ${'REDIRECT'.padEnd(35)} CREATED`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\n/**\r\n * Render a single domain's status: verified/misconfigured plus any verification\r\n * records the user still needs to add to DNS.\r\n */\r\nfunction formatDomainStatus(\r\n domain: VercelProjectDomain,\r\n config: VercelDomainConfig | null,\r\n): string {\r\n const lines: string[] = [];\r\n lines.push(`Domain: ${domain.name}`);\r\n lines.push(`Verified: ${domain.verified ? 'yes' : 'no'}`);\r\n if (config) {\r\n lines.push(`Misconfigured: ${config.misconfigured ? 'yes' : 'no'}`);\r\n if (config.configuredBy) lines.push(`Configured by: ${config.configuredBy}`);\r\n }\r\n if (domain.gitBranch) lines.push(`Git branch: ${domain.gitBranch}`);\r\n if (domain.redirect) {\r\n lines.push(\r\n `Redirect: ${domain.redirect}${domain.redirectStatusCode ? ` (${domain.redirectStatusCode})` : ''}`,\r\n );\r\n }\r\n if (domain.verification && domain.verification.length > 0) {\r\n lines.push('');\r\n lines.push('Required DNS records to verify ownership:');\r\n for (const v of domain.verification) {\r\n lines.push(` ${v.type.padEnd(6)} ${v.domain.padEnd(45)} ${v.value}${v.reason ? ` // ${v.reason}` : ''}`);\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main handler\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Dispatch a `vercel-*` MCP tool. Resolves the Vercel API token from\r\n * `app_setting.vercel_token_encrypted` on every call (cheap, single-row\r\n * lookup); avoids any process-level token caching to ensure rotated\r\n * tokens are picked up immediately.\r\n */\r\nexport async function handleVercelTool(\r\n name: string,\r\n args: Record<string, unknown>,\r\n deps: VercelToolDeps,\r\n): Promise<ToolResult> {\r\n switch (name) {\r\n case 'vercel-projects': {\r\n const token = await getVercelToken(deps);\r\n const limit = Math.min(Math.max(Number(args.limit) || 50, 1), 200);\r\n const search = typeof args.search === 'string' ? args.search.toLowerCase() : null;\r\n const { projects, error } = await listVercelProjectsAll(token, limit);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n const filtered = search\r\n ? projects.filter((p) => (p.name || '').toLowerCase().includes(search))\r\n : projects;\r\n return { content: [{ type: 'text', text: formatProjectsTable(filtered) }] };\r\n }\r\n\r\n case 'vercel-deployments': {\r\n const token = await getVercelToken(deps);\r\n const projectInput = String(args.project);\r\n const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);\r\n const projectId = await resolveProjectId(token, projectInput);\r\n const { deployments, error } = await listVercelDeployments(token, {\r\n projectId,\r\n limit,\r\n state: args.state ? String(args.state) : undefined,\r\n target: args.target ? String(args.target) : undefined,\r\n });\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: formatDeploymentsTable(deployments) }] };\r\n }\r\n\r\n case 'vercel-logs': {\r\n const kind = (args.kind ? String(args.kind) : 'build').toLowerCase();\r\n\r\n if (kind === 'build') {\r\n if (!args.deploymentId) {\r\n return { content: [{ type: 'text', text: 'Error: kind=\"build\" requires deploymentId.' }] };\r\n }\r\n const token = await getVercelToken(deps);\r\n const deploymentId = String(args.deploymentId);\r\n const limit = Math.min(Math.max(Number(args.limit) || 500, 1), 5000);\r\n const { events, error } = await getDeploymentBuildEvents(token, deploymentId, limit);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: formatBuildEvents(events) }] };\r\n }\r\n\r\n if (kind === 'runtime') {\r\n if (!args.project || !args.deploymentId) {\r\n return {\r\n content: [\r\n { type: 'text', text: 'Error: kind=\"runtime\" requires both project and deploymentId.' },\r\n ],\r\n };\r\n }\r\n const token = await getVercelToken(deps);\r\n const projectInput = String(args.project);\r\n const deploymentId = String(args.deploymentId);\r\n const limit = Math.min(Math.max(Number(args.limit) || 200, 1), 1000);\r\n\r\n const sinceMinutesRaw = Number(args.sinceMinutes);\r\n const sinceExplicit = Number.isFinite(sinceMinutesRaw) && sinceMinutesRaw > 0;\r\n\r\n // Resolve project ID and (when needed) deployment createdAt in parallel\r\n // so the implicit auto-window costs only one extra round trip.\r\n const [projectId, deploymentCreatedMs] = await Promise.all([\r\n resolveProjectId(token, projectInput),\r\n sinceExplicit ? Promise.resolve(null) : getDeploymentCreatedMs(token, deploymentId),\r\n ]);\r\n\r\n // Vercel's runtime-logs endpoint has a 5-minute server-side query\r\n // budget that scales with window size — wider windows are far more\r\n // likely to time out than to actually return more useful data. So\r\n // we deliberately bias toward narrow windows: auto-default is 30 min\r\n // max even for very old deployments. Callers can still override via\r\n // `sinceMinutes` up to 7 days, but they get a clear warning when the\r\n // auto picks something noticeably shorter than the deployment age.\r\n const maxWindowMin = 7 * 24 * 60;\r\n const autoCapMin = 30;\r\n let sinceMs: number;\r\n let windowNote = '';\r\n if (sinceExplicit) {\r\n const capped = Math.min(sinceMinutesRaw, maxWindowMin);\r\n sinceMs = Date.now() - capped * 60_000;\r\n windowNote = `window: last ${capped} min (caller-specified)`;\r\n } else if (deploymentCreatedMs) {\r\n const bufferMs = 5 * 60_000;\r\n const sinceDeploymentMs = deploymentCreatedMs - bufferMs;\r\n const ageMin = Math.max(1, Math.round((Date.now() - sinceDeploymentMs) / 60_000));\r\n if (ageMin <= autoCapMin) {\r\n sinceMs = sinceDeploymentMs;\r\n windowNote = `window: auto ${ageMin} min from deployment createdAt - 5 min buffer`;\r\n } else {\r\n sinceMs = Date.now() - autoCapMin * 60_000;\r\n windowNote = `window: capped to last ${autoCapMin} min (deployment is ${ageMin} min old — pass sinceMinutes to widen up to ${maxWindowMin})`;\r\n }\r\n } else {\r\n sinceMs = Date.now() - autoCapMin * 60_000;\r\n windowNote = `window: last ${autoCapMin} min (deployment metadata unavailable, used fallback)`;\r\n }\r\n\r\n const { logs, error } = await getRuntimeLogs(\r\n token,\r\n projectId,\r\n deploymentId,\r\n limit,\r\n sinceMs,\r\n );\r\n if (error) {\r\n const hint =\r\n error.includes('404') || error.includes('400')\r\n ? '\\n\\nThis endpoint requires both project ID and deployment ID and may not be available on every Vercel plan. Use kind=\"webhooks\" or the supabase MCP (vercel_deployment_log table) for archived runtime logs.'\r\n : '';\r\n return { content: [{ type: 'text', text: `Error: ${error}${hint}` }] };\r\n }\r\n const body = formatRuntimeLogs(logs);\r\n // Vercel returns \"Exceeded query duration limit of 5 minutes\" inline\r\n // as a synthetic log entry when its server can't finish scanning the\r\n // window. Catch it and add a hint instead of leaving the LLM\r\n // confused by what looks like a normal log line.\r\n const hitDurationLimit = /Exceeded query duration limit/i.test(body);\r\n const footer = hitDurationLimit\r\n ? `\\n\\n[${windowNote}]\\n[hint] Vercel hit its 5-min query budget for this window. Try a smaller sinceMinutes (e.g. 5-10), lower limit, or use kind=\"webhooks\" / the supabase MCP vercel_deployment_log table for archived logs.`\r\n : `\\n\\n[${windowNote}]`;\r\n return { content: [{ type: 'text', text: body + footer }] };\r\n }\r\n\r\n if (kind === 'webhooks') {\r\n const limit = Math.min(Math.max(Number(args.limit) || 25, 1), 200);\r\n let query = deps.supabase\r\n .from('vercel_webhook_logs')\r\n .select(\r\n 'id, event_type, status, project_name, deployment_id, target, message, error_message, created_at',\r\n )\r\n .order('created_at', { ascending: false })\r\n .limit(limit);\r\n if (args.projectName) query = query.eq('project_name', String(args.projectName));\r\n if (args.status) query = query.eq('status', String(args.status));\r\n const { data, error } = await query;\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error.message}` }] };\r\n return {\r\n content: [{ type: 'text', text: formatWebhookHistory((data as WebhookLogRow[]) ?? []) }],\r\n };\r\n }\r\n\r\n return {\r\n content: [\r\n { type: 'text', text: `Error: unknown kind \"${kind}\". Use build, runtime, or webhooks.` },\r\n ],\r\n };\r\n }\r\n\r\n case 'vercel-domains': {\r\n const action = (args.action ? String(args.action) : 'list').toLowerCase();\r\n if (!args.project) {\r\n return { content: [{ type: 'text', text: 'Error: vercel-domains requires \"project\".' }] };\r\n }\r\n const token = await getVercelToken(deps);\r\n const projectInput = String(args.project);\r\n const projectId = await resolveProjectId(token, projectInput);\r\n\r\n if (action === 'list') {\r\n const { domains, error } = await listProjectDomains(token, projectId);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: formatDomainsTable(domains) }] };\r\n }\r\n\r\n if (action === 'add') {\r\n if (!args.domain) {\r\n return { content: [{ type: 'text', text: 'Error: action=\"add\" requires \"domain\".' }] };\r\n }\r\n const body: {\r\n name: string;\r\n gitBranch?: string;\r\n redirect?: string;\r\n redirectStatusCode?: number;\r\n } = { name: String(args.domain) };\r\n if (args.gitBranch) body.gitBranch = String(args.gitBranch);\r\n if (args.redirect) body.redirect = String(args.redirect);\r\n if (args.redirectStatusCode) body.redirectStatusCode = Number(args.redirectStatusCode);\r\n const { domain, error } = await addProjectDomain(token, projectId, body);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n if (!domain) {\r\n return { content: [{ type: 'text', text: `Domain ${body.name} added (no detail returned).` }] };\r\n }\r\n const { config } = await getDomainConfig(token, domain.name);\r\n const status = formatDomainStatus(domain, config);\r\n const headline = domain.verified\r\n ? `Domain ${domain.name} added and verified.`\r\n : `Domain ${domain.name} added. DNS verification still pending.`;\r\n return { content: [{ type: 'text', text: `${headline}\\n\\n${status}` }] };\r\n }\r\n\r\n if (action === 'verify') {\r\n if (!args.domain) {\r\n return { content: [{ type: 'text', text: 'Error: action=\"verify\" requires \"domain\".' }] };\r\n }\r\n const domainName = String(args.domain);\r\n const { domain, error } = await getProjectDomain(token, projectId, domainName);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n if (!domain) {\r\n return { content: [{ type: 'text', text: `Domain ${domainName} not found on this project.` }] };\r\n }\r\n const { config } = await getDomainConfig(token, domainName);\r\n return { content: [{ type: 'text', text: formatDomainStatus(domain, config) }] };\r\n }\r\n\r\n if (action === 'remove') {\r\n if (!args.domain) {\r\n return { content: [{ type: 'text', text: 'Error: action=\"remove\" requires \"domain\".' }] };\r\n }\r\n const domainName = String(args.domain);\r\n const { error } = await removeProjectDomain(token, projectId, domainName);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: `Domain ${domainName} removed from project.` }] };\r\n }\r\n\r\n return {\r\n content: [\r\n { type: 'text', text: `Error: unknown action \"${action}\". Use list, add, verify, or remove.` },\r\n ],\r\n };\r\n }\r\n\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown vercel 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 { spawn } from 'node:child_process';\r\nimport { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';\r\nimport { createReadStream, existsSync, statSync } from 'node:fs';\r\nimport { tmpdir } from 'node:os';\r\nimport { isAbsolute, join } from 'node:path';\r\nimport { Readable } from 'node:stream';\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 VERCEL_TOOLS,\r\n VERCEL_TOOL_NAMES,\r\n VERCEL_TOOL_MODULE_MAP,\r\n handleVercelTool,\r\n} from './vercel-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\n// ---------------------------------------------------------------------------\r\n// Proxy-bridge mode: when --proxy-url is given we bypass the rest of this\r\n// file entirely and run as a thin SSH-key-authenticated bridge to a remote\r\n// MCP HTTP endpoint (used for the Supabase MCPs behind apps/mcp-proxy).\r\n// ---------------------------------------------------------------------------\r\nconst proxyUrl = getArg('proxy-url') || process.env.MG_DASHBOARD_PROXY_URL;\r\nif (proxyUrl) {\r\n const { runProxyMode } = await import('./proxy-mode.js');\r\n await runProxyMode(args);\r\n // runProxyMode never resolves under normal operation; if it does, exit.\r\n process.exit(0);\r\n}\r\n\r\nconst apiKey = getArg('api-key') || process.env.MG_DASHBOARD_API_KEY;\r\nconst sshKeyPath = getArg('ssh-key') || process.env.MG_DASHBOARD_SSH_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 httpMode = args.includes('--http');\r\nconst httpPort = Number(getArg('port')) || 3100;\r\n\r\nif (!apiKey || !sshKeyPath) {\r\n console.error('Authentication required. Use both --api-key=dk_xxx and --ssh-key=PATH (path to your SSH private or public key), or set MG_DASHBOARD_API_KEY and MG_DASHBOARD_SSH_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// Tool-level rate limiting was previously gated per category (ssh / sftp / db\r\n// / default) with hourly buckets. Removed because legitimate dev sessions\r\n// regularly burst over those caps and the resulting \"MCP Rate Limit\" stalls\r\n// were strictly noise — auth-level rate limiting (failed login attempts)\r\n// remains in place above for the actual security concern.\r\n\r\n// ---------------------------------------------------------------------------\r\n// Audit logging\r\n// ---------------------------------------------------------------------------\r\n\r\nconst SENSITIVE_KEYS = new Set(['password', 'private_key', 'passphrase', 'secret', 'token', 'key', 'api_key', 'credentials']);\r\n\r\nfunction redactSensitiveArgs(args: Record<string, unknown>): Record<string, unknown> {\r\n const redacted: Record<string, unknown> = {};\r\n for (const [k, v] of Object.entries(args)) {\r\n if (SENSITIVE_KEYS.has(k.toLowerCase())) {\r\n redacted[k] = '[REDACTED]';\r\n } else if (typeof v === 'string' && v.length > 500) {\r\n redacted[k] = v.slice(0, 500) + '...[truncated]';\r\n } else {\r\n redacted[k] = v;\r\n }\r\n }\r\n return redacted;\r\n}\r\n\r\nasync function writeAuditLog(entry: {\r\n toolName: string;\r\n arguments?: Record<string, unknown>;\r\n ipAddress?: string;\r\n serverId?: string;\r\n resultStatus: 'success' | 'error';\r\n errorMessage?: string;\r\n durationMs?: number;\r\n}): Promise<void> {\r\n if (!authContext) return;\r\n try {\r\n await supabase.from('mcp_audit_log').insert({\r\n api_key_id: authContext.apiKeyId,\r\n user_id: authContext.userId,\r\n tool_name: entry.toolName,\r\n arguments: entry.arguments ? redactSensitiveArgs(entry.arguments) : null,\r\n ip_address: entry.ipAddress || null,\r\n server_id: entry.serverId || null,\r\n result_status: entry.resultStatus,\r\n error_message: entry.errorMessage?.slice(0, 1000) || null,\r\n duration_ms: entry.durationMs || null,\r\n });\r\n } catch (err) {\r\n console.error('[Audit] Failed to write audit log:', err instanceof Error ? err.message : err);\r\n }\r\n}\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', 'domains',\r\n 'settings',\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\r\n domains?: boolean;\r\n settings?: 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 'docker-exec': 'ssh_servers',\r\n 'docker-compose': 'ssh_servers',\r\n 'wait-for': 'ssh_servers',\r\n 'db-discover': 'ssh_servers',\r\n 'db-tables': '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 'dns-list': 'domains',\r\n 'dns-record': 'domains',\r\n ...TRIGGER_TOOL_MODULE_MAP,\r\n ...VERCEL_TOOL_MODULE_MAP,\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Auth context\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface AuthContext {\r\n apiKeyId: string;\r\n apiKeyName: string;\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, name, 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 apiKeyId: data.id,\r\n apiKeyName: data.name || 'Unknown',\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// SSH-key authentication\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Run a child process and return { stdout, stderr, code }. Never throws. */\r\nfunction runProcess(\r\n command: string,\r\n argv: string[],\r\n options: { stdin?: string; cwd?: string } = {},\r\n): Promise<{ stdout: string; stderr: string; code: number }> {\r\n return new Promise((resolve) => {\r\n const child = spawn(command, argv, { cwd: options.cwd, stdio: ['pipe', 'pipe', 'pipe'] });\r\n let stdout = '';\r\n let stderr = '';\r\n child.stdout.on('data', (d) => { stdout += d.toString(); });\r\n child.stderr.on('data', (d) => { stderr += d.toString(); });\r\n child.on('error', (err) => {\r\n resolve({ stdout, stderr: stderr + String(err), code: -1 });\r\n });\r\n child.on('close', (code) => {\r\n resolve({ stdout, stderr, code: code ?? -1 });\r\n });\r\n if (options.stdin !== undefined) {\r\n child.stdin.write(options.stdin);\r\n child.stdin.end();\r\n } else {\r\n child.stdin.end();\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Resolve the user's SSH public-key file from the path they passed.\r\n *\r\n * Accepts either a `.pub` file directly, or a private-key path (in which case\r\n * we look for `${path}.pub` next to it). Returns the public-key file path and\r\n * its contents trimmed.\r\n */\r\nasync function resolvePubkeyFile(input: string): Promise<{ pubPath: string; pubText: string }> {\r\n const expand = (p: string) => p.startsWith('~')\r\n ? join(process.env.HOME || process.env.USERPROFILE || '', p.slice(1))\r\n : p;\r\n const candidate = expand(input);\r\n let pubPath: string;\r\n if (candidate.endsWith('.pub')) {\r\n pubPath = candidate;\r\n } else if (existsSync(`${candidate}.pub`)) {\r\n pubPath = `${candidate}.pub`;\r\n } else if (existsSync(candidate)) {\r\n // Caller passed a public-key file without `.pub` extension; tolerate it.\r\n pubPath = candidate;\r\n } else {\r\n throw new Error(`SSH key file not found: ${candidate} (also tried ${candidate}.pub)`);\r\n }\r\n const pubText = (await readFile(pubPath, 'utf8')).trim();\r\n if (!pubText) {\r\n throw new Error(`SSH public-key file is empty: ${pubPath}`);\r\n }\r\n return { pubPath, pubText };\r\n}\r\n\r\n/**\r\n * Compute the OpenSSH SHA256 fingerprint (\"SHA256:abc...\") of a public-key\r\n * line. This matches the format that `ssh-keygen -lf <pubkey>` prints and\r\n * what we store in `dashboard_mcp_ssh_key.fingerprint_sha256`.\r\n */\r\nfunction computeOpenSshFingerprint(pubkeyLine: string): string {\r\n const parts = pubkeyLine.trim().split(/\\s+/);\r\n if (parts.length < 2 || !parts[1]) {\r\n throw new Error('Invalid SSH public-key line (expected \"<type> <base64> [comment]\")');\r\n }\r\n const bodyBytes = Buffer.from(parts[1], 'base64');\r\n const hash = createHash('sha256').update(bodyBytes).digest('base64').replace(/=+$/, '');\r\n return `SHA256:${hash}`;\r\n}\r\n\r\n/**\r\n * Sign a challenge with the user's SSH key (via ssh-agent or on-disk key).\r\n * Uses `ssh-keygen -Y sign` (SSHSIG format, OpenSSH >= 8.2).\r\n *\r\n * Returns the armored signature (\"-----BEGIN SSH SIGNATURE----- ...\").\r\n */\r\nasync function sshKeygenSign(pubkeyPath: string, challenge: string, namespace: string): Promise<string> {\r\n const result = await runProcess(\r\n 'ssh-keygen',\r\n ['-Y', 'sign', '-f', pubkeyPath, '-n', namespace, '-q'],\r\n { stdin: challenge },\r\n );\r\n if (result.code !== 0) {\r\n throw new Error(\r\n `ssh-keygen sign failed (exit ${result.code}). ` +\r\n `Make sure ssh-agent is running and has the matching private key loaded ` +\r\n `(or that the private key is at the path next to the .pub file). ` +\r\n `stderr: ${result.stderr.trim() || '(empty)'}`,\r\n );\r\n }\r\n if (!result.stdout.includes('BEGIN SSH SIGNATURE')) {\r\n throw new Error(`ssh-keygen sign produced no signature (stderr: ${result.stderr.trim() || '(empty)'})`);\r\n }\r\n return result.stdout;\r\n}\r\n\r\n/**\r\n * Verify an SSHSIG armored signature against a known public-key line.\r\n * Returns true if the signature is valid.\r\n */\r\nasync function sshKeygenVerify(\r\n pubkeyLine: string,\r\n signature: string,\r\n challenge: string,\r\n namespace: string,\r\n): Promise<boolean> {\r\n const dir = await mkdtemp(join(tmpdir(), 'mcp-ssh-verify-'));\r\n try {\r\n const allowedSigners = `mcp@local ${pubkeyLine.trim()}\\n`;\r\n const allowedPath = join(dir, 'allowed_signers');\r\n const sigPath = join(dir, 'sig');\r\n await writeFile(allowedPath, allowedSigners, 'utf8');\r\n await writeFile(sigPath, signature, 'utf8');\r\n const result = await runProcess(\r\n 'ssh-keygen',\r\n ['-Y', 'verify', '-f', allowedPath, '-I', 'mcp@local', '-n', namespace, '-s', sigPath, '-q'],\r\n { stdin: challenge },\r\n );\r\n return result.code === 0;\r\n } finally {\r\n await rm(dir, { recursive: true, force: true }).catch(() => undefined);\r\n }\r\n}\r\n\r\n/**\r\n * Authenticate to the dashboard using an SSH key.\r\n *\r\n * 1. Read the user's pubkey file and compute its SHA256 fingerprint.\r\n * 2. Generate a fresh nonce, sign it via `ssh-keygen -Y sign` (uses ssh-agent\r\n * or the private key on disk), then locally verify the signature against\r\n * the pubkey we read. This proves the caller actually possesses the\r\n * private key (or has it loaded in ssh-agent), not just a stolen pubkey.\r\n * 3. Look up the fingerprint in `dashboard_mcp_ssh_key`, require it to be\r\n * linked to the already validated API key, then load permissions exactly\r\n * like the bearer-token path does.\r\n *\r\n * The signature step is optional but defaults to ON. Set\r\n * `MG_DASHBOARD_SSH_SKIP_VERIFY=1` to skip it (e.g. for first-time enrollment\r\n * before the key is registered, where you just want to print the fingerprint).\r\n */\r\nasync function validateSshKey(\r\n pubkeyPathInput: string,\r\n expectedApiKeyId: string,\r\n): Promise<AuthContext | null> {\r\n let pubPath: string;\r\n let pubText: string;\r\n try {\r\n const resolved = await resolvePubkeyFile(pubkeyPathInput);\r\n pubPath = resolved.pubPath;\r\n pubText = resolved.pubText;\r\n } catch (err) {\r\n console.error(`SSH key error: ${err instanceof Error ? err.message : String(err)}`);\r\n return null;\r\n }\r\n\r\n let fingerprint: string;\r\n try {\r\n fingerprint = computeOpenSshFingerprint(pubText);\r\n } catch (err) {\r\n console.error(`SSH key error: ${err instanceof Error ? err.message : String(err)}`);\r\n return null;\r\n }\r\n\r\n const rateCheck = authRateLimiter.check(fingerprint);\r\n if (!rateCheck.allowed) {\r\n const retryMin = Math.ceil(rateCheck.retryAfterMs / 60_000);\r\n console.error(`Rate limited: too many failed SSH-key auth attempts. Retry in ${retryMin} minute(s).`);\r\n return null;\r\n }\r\n\r\n const skipVerify = process.env.MG_DASHBOARD_SSH_SKIP_VERIFY === '1';\r\n if (!skipVerify) {\r\n try {\r\n const challenge = randomBytes(32).toString('hex');\r\n const signature = await sshKeygenSign(pubPath, challenge, 'mg-dashboard-mcp');\r\n const verified = await sshKeygenVerify(pubText, signature, challenge, 'mg-dashboard-mcp');\r\n if (!verified) {\r\n console.error('SSH-key challenge verification failed (signature did not validate against the public key).');\r\n return null;\r\n }\r\n } catch (err) {\r\n console.error(`SSH-key challenge failed: ${err instanceof Error ? err.message : String(err)}`);\r\n console.error('Tip: set MG_DASHBOARD_SSH_SKIP_VERIFY=1 to skip the challenge if you only need to print the fingerprint for enrollment.');\r\n return null;\r\n }\r\n }\r\n\r\n const { data: keyRow, error: keyErr } = await supabase\r\n .from('dashboard_mcp_ssh_key')\r\n .select('id, name, api_key_id, is_active')\r\n .eq('fingerprint_sha256', fingerprint)\r\n .eq('is_active', true)\r\n .maybeSingle();\r\n\r\n if (keyErr || !keyRow) {\r\n console.error(\r\n `SSH key not registered (fingerprint ${fingerprint}; ${rateCheck.remaining} attempts remaining). ` +\r\n `Add it under MCP API Keys → SSH Keys in the dashboard.`,\r\n );\r\n return null;\r\n }\r\n\r\n if (keyRow.api_key_id !== expectedApiKeyId) {\r\n console.error(\r\n `SSH key \"${keyRow.name}\" is registered, but it is not linked to the provided MCP API key. ` +\r\n `Add this SSH key under the same MCP API Key entry used by --api-key.`,\r\n );\r\n return null;\r\n }\r\n\r\n const { data: apiRow, error: apiErr } = await supabase\r\n .from('dashboard_mcp_api_key')\r\n .select('id, name, created_by, allowed_server_ids, is_active, expires_at')\r\n .eq('id', keyRow.api_key_id)\r\n .eq('is_active', true)\r\n .maybeSingle();\r\n\r\n if (apiErr || !apiRow) {\r\n console.error('SSH key is linked to an inactive or missing MCP API key entry.');\r\n return null;\r\n }\r\n\r\n if (apiRow.expires_at && new Date(apiRow.expires_at) < new Date()) {\r\n console.error('Linked MCP API key entry has expired.');\r\n return null;\r\n }\r\n\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', apiRow.created_by)\r\n .single();\r\n\r\n if (userError || !userData) {\r\n console.error(`User not found for SSH key creator: ${apiRow.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 apiRow.allowed_server_ids,\r\n permissions.resources.ssh_servers,\r\n );\r\n\r\n const nowIso = new Date().toISOString();\r\n await Promise.all([\r\n supabase.from('dashboard_mcp_ssh_key').update({ last_used_at: nowIso }).eq('id', keyRow.id),\r\n supabase.from('dashboard_mcp_api_key').update({ last_used_at: nowIso }).eq('id', apiRow.id),\r\n ]);\r\n\r\n const moduleCount = MODULE_KEYS.filter((k) => permissions.modules[k]).length;\r\n console.error(\r\n `Authenticated via SSH key \"${keyRow.name}\" (fp ${fingerprint.slice(0, 24)}...) ` +\r\n `as user ${apiRow.created_by} (role: ${roleName}, modules: ${moduleCount}/${MODULE_KEYS.length})`,\r\n );\r\n\r\n return {\r\n apiKeyId: apiRow.id,\r\n apiKeyName: `${apiRow.name || 'Unknown'} (ssh: ${keyRow.name})`,\r\n userId: apiRow.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: 'encrypted';\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: 'encrypted' 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\n// ---------------------------------------------------------------------------\r\n// Shell quoting / OS-aware command builders\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * POSIX shell single-quote escape. Wraps in `'...'` and escapes any embedded\r\n * `'` as `'\\''`. Bare-word fast-path for safe characters skips quoting.\r\n * Used by ssh-execute (linux mode), docker-exec, sftp-list pattern building,\r\n * and anywhere we previously relied on the LLM to escape `$`, `#`, spaces,\r\n * etc. inside command strings.\r\n */\r\nfunction posixQuote(arg: string): string {\r\n if (arg === '') return \"''\";\r\n if (/^[A-Za-z0-9._\\/=:@%+\\-]+$/.test(arg)) return arg;\r\n return \"'\" + arg.replace(/'/g, \"'\\\\''\") + \"'\";\r\n}\r\n\r\n/**\r\n * Build a POSIX shell command line from a program + argv. The program itself\r\n * is NOT quoted if it's a simple identifier/path (so `cd` / `docker compose`\r\n * keep working when passed as `command: 'docker compose'` with args).\r\n */\r\nfunction buildPosixCommand(command: string, args: string[]): string {\r\n const program = /^[A-Za-z0-9._\\/\\- ]+$/.test(command) ? command : posixQuote(command);\r\n if (args.length === 0) return program;\r\n return `${program} ${args.map(posixQuote).join(' ')}`;\r\n}\r\n\r\n/**\r\n * Build a PowerShell `-EncodedCommand` invocation. PowerShell decodes the\r\n * UTF-16LE-base64 payload itself, so embedded `$`, `'`, `\"`, `#`, spaces, etc.\r\n * never see cmd.exe parsing — this is the only quoting-safe way to call\r\n * PowerShell over SSH on Windows servers.\r\n */\r\nfunction buildPowerShellEncodedCommand(command: string, args: string[]): string {\r\n const psSingleQuote = (s: string) => \"'\" + s.replace(/'/g, \"''\") + \"'\";\r\n let body: string;\r\n if (args.length === 0) {\r\n body = command;\r\n } else {\r\n body = `& ${psSingleQuote(command)} ${args.map(psSingleQuote).join(' ')}`;\r\n }\r\n // Suppress PowerShell's progress CLIXML stream that otherwise pollutes stderr\r\n // with `<Objs Version=\"1.1.0.1\" ...>` blobs on first use of certain cmdlets.\r\n const psExpr = `$ProgressPreference='SilentlyContinue'; ${body}`;\r\n const utf16 = Buffer.from(psExpr, 'utf16le');\r\n const b64 = utf16.toString('base64');\r\n // -OutputFormat Text disables PowerShell's CLIXML serialization of errors/objects\r\n // when run as a subprocess (default is XML for non-interactive). Combined with\r\n // $ProgressPreference above, this gives clean text on stdout/stderr.\r\n return `powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -OutputFormat Text -EncodedCommand ${b64}`;\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\ntype ServerOs = 'linux' | 'windows';\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\n * Also returns the server's `os_type` so callers (notably ssh-execute) can\r\n * pick the right shell wrapper (bash vs PowerShell -EncodedCommand).\r\n */\r\nasync function getServerConnection(\r\n serverId: string,\r\n): Promise<{ conn: SshConnectionOptions; proxy?: SshConnectionOptions; os: ServerOs }> {\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, os_type')\r\n .eq('id', serverId)\r\n .single();\r\n\r\n if (error || !data) {\r\n // Fuzzy hint based on the running cache of names. Helps when the LLM\r\n // typos a UUID or, more usefully, when a tool was somehow invoked with\r\n // a name string instead of an id.\r\n const candidates = Array.from(KNOWN_SERVER_NAMES.values()).flatMap(s => [s.name, s.id]);\r\n const hits = suggestSimilar(serverId, candidates);\r\n const hint = hits.length ? ` Did you mean: ${hits.join(', ')}?` : '';\r\n throw new Error(`Server not found: ${serverId}.${hint}`);\r\n }\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 const os: ServerOs = (data as { os_type?: string }).os_type === 'windows' ? 'windows' : 'linux';\r\n\r\n return { conn, proxy, os };\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\n * `stdin` lets callers pipe data into the remote process (used by ssh-execute\r\n * smart mode + db-* helpers to avoid command-line escape hell with passwords,\r\n * SQL queries, scripts containing `$` or `#`, etc.).\r\n */\r\nasync function sshExec(\r\n opts: SshConnectionOptions,\r\n command: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { stdin?: string; pty?: boolean; idleTimeoutMs?: number; noRetry?: boolean },\r\n): Promise<SshResult> {\r\n // Single inline retry on transient failures (connect refused, DNS hiccup,\r\n // socket reset, etc). Eats 80% of \"errors\" in the wild without leaking the\r\n // distinction up to the LLM. Suppress with `noRetry: true` for non-idempotent\r\n // commands the caller wants to control.\r\n const first = await sshExecOnce(opts, command, proxy, options);\r\n if (options?.noRetry) return first;\r\n if (!isTransientSshError(first.stderr, first.exitCode)) return first;\r\n await new Promise((r) => setTimeout(r, 1000));\r\n const second = await sshExecOnce(opts, command, proxy, options);\r\n // Annotate stderr so debugging is obvious if the retry also fails.\r\n if (second.exitCode === -1 && second.stderr) {\r\n second.stderr = `[retry-1 also failed] ${second.stderr}`;\r\n }\r\n return second;\r\n}\r\n\r\nasync function sshExecOnce(\r\n opts: SshConnectionOptions,\r\n command: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { stdin?: string; pty?: boolean; idleTimeoutMs?: number },\r\n): Promise<SshResult> {\r\n if (proxy) return sshExecViaProxy(proxy, opts, command, options);\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 wallTimeout = opts.timeout || 60_000;\r\n const idleTimeout = options?.idleTimeoutMs;\r\n\r\n const wallTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(idleTimer); ssh.end(); resolve({ stdout, stderr: stderr || `idle/wall timeout after ${wallTimeout}ms`, exitCode: -1 }); }\r\n }, wallTimeout);\r\n\r\n let idleTimer: NodeJS.Timeout | undefined;\r\n const armIdle = () => {\r\n if (!idleTimeout) return;\r\n if (idleTimer) clearTimeout(idleTimer);\r\n idleTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(wallTimer); ssh.end(); resolve({ stdout, stderr: stderr || `idle timeout after ${idleTimeout}ms with no output`, exitCode: -1 }); }\r\n }, idleTimeout);\r\n };\r\n armIdle();\r\n\r\n ssh.on('ready', () => {\r\n // Allocating a PTY collapses stderr into stdout (a real terminal has no\r\n // separate stderr fd) which is exactly what callers want for tty-mode\r\n // commands like `psql`/`mysql`/`bash`. Without pty: stderr is captured\r\n // separately so structured tools still get clean stderr.\r\n const execOpts = options?.pty ? { pty: true } : {};\r\n ssh.exec(command, execOpts, (err, stream) => {\r\n if (err) {\r\n if (!done) { done = true; clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); ssh.end(); resolve({ stdout, stderr: err.message || stderr, exitCode: -1 }); }\r\n return;\r\n }\r\n stream.on('data', (d: Buffer) => { stdout += d.toString(); armIdle(); });\r\n stream.stderr.on('data', (d: Buffer) => { stderr += d.toString(); armIdle(); });\r\n stream.on('close', (code: number | null) => {\r\n if (!done) { done = true; clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); ssh.end(); resolve({ stdout, stderr, exitCode: code ?? 0 }); }\r\n });\r\n if (options?.stdin !== undefined) {\r\n stream.end(options.stdin);\r\n }\r\n });\r\n });\r\n\r\n ssh.on('error', (err) => {\r\n if (!done) { done = true; clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); 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: wallTimeout,\r\n });\r\n });\r\n}\r\n\r\nfunction sshExecViaProxy(\r\n proxyOpts: SshConnectionOptions,\r\n targetOpts: SshConnectionOptions,\r\n command: string,\r\n options?: { stdin?: string; pty?: boolean; idleTimeoutMs?: number },\r\n): Promise<SshResult> {\r\n return new Promise((resolve) => {\r\n const proxyClient = new SshClient();\r\n let done = false;\r\n const wallTimeout = targetOpts.timeout || 60_000;\r\n const idleTimeout = options?.idleTimeoutMs;\r\n\r\n const wallTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(idleTimer); proxyClient.end(); resolve({ stdout: '', stderr: 'SSH proxy command timeout', exitCode: -1 }); }\r\n }, wallTimeout);\r\n\r\n let idleTimer: NodeJS.Timeout | undefined;\r\n let stdoutBuf = '';\r\n let stderrBuf = '';\r\n const armIdle = () => {\r\n if (!idleTimeout) return;\r\n if (idleTimer) clearTimeout(idleTimer);\r\n idleTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(wallTimer); proxyClient.end(); resolve({ stdout: stdoutBuf, stderr: stderrBuf || `idle timeout after ${idleTimeout}ms with no output`, exitCode: -1 }); }\r\n }, idleTimeout);\r\n };\r\n armIdle();\r\n\r\n const cleanup = () => { clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); 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\r\n targetClient.on('ready', () => {\r\n const execOpts = options?.pty ? { pty: true } : {};\r\n targetClient.exec(command, execOpts, (execErr, stream) => {\r\n if (execErr) {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout: stdoutBuf, stderr: stderrBuf, exitCode: -1 }); }\r\n return;\r\n }\r\n stream.on('data', (d: Buffer) => { stdoutBuf += d.toString(); armIdle(); });\r\n stream.stderr.on('data', (d: Buffer) => { stderrBuf += d.toString(); armIdle(); });\r\n stream.on('close', (code: number | null) => {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout: stdoutBuf, stderr: stderrBuf, exitCode: code ?? 0 }); }\r\n });\r\n if (options?.stdin !== undefined) {\r\n stream.end(options.stdin);\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: stdoutBuf, 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: wallTimeout,\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// Shared SSH connection helper (supports proxy tunnelling)\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction connectSshClient(\r\n opts: SshConnectionOptions,\r\n proxy?: SshConnectionOptions,\r\n readyTimeout = 60_000,\r\n extraConnect?: { compress?: boolean | 'force' },\r\n): Promise<{ client: SshClient; cleanup: () => void }> {\r\n const compress = extraConnect?.compress;\r\n if (!proxy) {\r\n return new Promise((resolve, reject) => {\r\n const ssh = new SshClient();\r\n ssh.on('ready', () => resolve({ client: ssh, cleanup: () => ssh.end() }));\r\n ssh.on('error', (e) => reject(e));\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,\r\n ...(compress ? { compress } : {}),\r\n });\r\n });\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const proxyClient = new SshClient();\r\n\r\n proxyClient.on('ready', () => {\r\n proxyClient.forwardOut('127.0.0.1', 0, opts.hostname, opts.port, (err, tunnel) => {\r\n if (err) { proxyClient.end(); reject(err); return; }\r\n\r\n const targetClient = new SshClient();\r\n targetClient.on('ready', () =>\r\n resolve({\r\n client: targetClient,\r\n cleanup: () => { targetClient.end(); proxyClient.end(); },\r\n }),\r\n );\r\n targetClient.on('error', (e) => { proxyClient.end(); reject(e); });\r\n targetClient.connect({\r\n sock: tunnel,\r\n username: opts.username, password: opts.password,\r\n privateKey: opts.privateKey, passphrase: opts.passphrase,\r\n readyTimeout,\r\n ...(compress ? { compress } : {}),\r\n });\r\n });\r\n });\r\n\r\n proxyClient.on('error', (e) => reject(e));\r\n proxyClient.connect({\r\n host: proxy.hostname, port: proxy.port, username: proxy.username,\r\n password: proxy.password, privateKey: proxy.privateKey, passphrase: proxy.passphrase,\r\n readyTimeout: proxy.timeout || 30_000,\r\n });\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// R2 (Cloudflare S3-compatible) helpers\r\n//\r\n// The four sftp-* tools route to R2 instead of an SSH server when the caller\r\n// passes `bucket: <name>`. Credentials come from env vars (R2_ENDPOINT +\r\n// R2_ACCESS_KEY_ID + R2_SECRET_ACCESS_KEY), so the MCP runs against any\r\n// Cloudflare R2 account without per-call config. The bucket *name* is part of\r\n// the call so the same MCP can address multiple buckets (backup, assets, etc.).\r\n// ---------------------------------------------------------------------------\r\n\r\nimport {\r\n S3Client,\r\n ListObjectsV2Command,\r\n GetObjectCommand,\r\n PutObjectCommand,\r\n CopyObjectCommand,\r\n DeleteObjectCommand,\r\n DeleteObjectsCommand,\r\n HeadObjectCommand,\r\n CreateMultipartUploadCommand,\r\n UploadPartCommand,\r\n CompleteMultipartUploadCommand,\r\n AbortMultipartUploadCommand,\r\n type _Object,\r\n type CommonPrefix,\r\n} from '@aws-sdk/client-s3';\r\n\r\nlet _r2Client: S3Client | null = null;\r\n\r\nfunction getR2Client(): S3Client {\r\n if (_r2Client) return _r2Client;\r\n const endpoint = process.env.R2_ENDPOINT;\r\n const accessKeyId = process.env.R2_ACCESS_KEY_ID;\r\n const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY;\r\n if (!endpoint || !accessKeyId || !secretAccessKey) {\r\n throw new Error(\r\n 'R2 not configured. Set R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY in the MCP env (mcp.json).',\r\n );\r\n }\r\n _r2Client = new S3Client({ region: 'auto', endpoint, credentials: { accessKeyId, secretAccessKey } });\r\n return _r2Client;\r\n}\r\n\r\n/** Strip a leading `/` so callers can use familiar paths (`/foo/bar.txt`)\r\n * while R2 keys are stored without the slash (`foo/bar.txt`). */\r\nfunction r2Key(path: string): string {\r\n return path.replace(/^\\/+/, '');\r\n}\r\n\r\ninterface R2ListEntry {\r\n key: string;\r\n size: number;\r\n mtime: string;\r\n isPrefix: boolean;\r\n}\r\n\r\nasync function r2List(\r\n bucket: string,\r\n prefix: string,\r\n options: { recursive: boolean; maxResults: number },\r\n): Promise<R2ListEntry[]> {\r\n const client = getR2Client();\r\n const entries: R2ListEntry[] = [];\r\n let continuationToken: string | undefined;\r\n // Folder mode uses delimiter so we get CommonPrefixes (one entry per \"directory\").\r\n // Recursive mode omits delimiter and walks every key.\r\n const delimiter = options.recursive ? undefined : '/';\r\n\r\n do {\r\n const result = await client.send(new ListObjectsV2Command({\r\n Bucket: bucket,\r\n Prefix: prefix || undefined,\r\n Delimiter: delimiter,\r\n ContinuationToken: continuationToken,\r\n MaxKeys: Math.min(1000, options.maxResults - entries.length),\r\n }));\r\n\r\n for (const cp of (result.CommonPrefixes || []) as CommonPrefix[]) {\r\n if (cp.Prefix) entries.push({ key: cp.Prefix, size: 0, mtime: '', isPrefix: true });\r\n if (entries.length >= options.maxResults) break;\r\n }\r\n for (const obj of (result.Contents || []) as _Object[]) {\r\n if (entries.length >= options.maxResults) break;\r\n entries.push({\r\n key: obj.Key || '',\r\n size: obj.Size || 0,\r\n mtime: obj.LastModified ? obj.LastModified.toISOString() : '',\r\n isPrefix: false,\r\n });\r\n }\r\n continuationToken = result.IsTruncated ? result.NextContinuationToken : undefined;\r\n } while (continuationToken && entries.length < options.maxResults);\r\n\r\n return entries;\r\n}\r\n\r\n/** Translate the aws-sdk's terse error names (\"NotFound\" / \"NoSuchKey\" /\r\n * \"UnknownError\") into actionable messages that include the bucket+key. */\r\nfunction r2WrapError(bucket: string, key: string, e: unknown): Error {\r\n const err = e as { name?: string; $metadata?: { httpStatusCode?: number }; message?: string };\r\n const status = err?.$metadata?.httpStatusCode;\r\n const name = err?.name || '';\r\n if (name === 'NoSuchKey' || name === 'NotFound' || status === 404) {\r\n return new Error(`r2://${bucket}/${key} not found`);\r\n }\r\n if (name === 'NoSuchBucket') return new Error(`R2 bucket \"${bucket}\" not found`);\r\n if (status === 403 || name === 'AccessDenied') return new Error(`Access denied for r2://${bucket}/${key} (check R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY)`);\r\n return new Error(`R2 error (${name || 'unknown'}${status ? ` ${status}` : ''}): ${err?.message || String(e)}`);\r\n}\r\n\r\nasync function r2GetObject(bucket: string, key: string, maxBytes: number): Promise<string> {\r\n const client = getR2Client();\r\n let size = 0;\r\n try {\r\n // Cheap HEAD first so we can refuse oversized objects without downloading them.\r\n const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n if (size > maxBytes) {\r\n throw new Error(`Object too large: ${size} bytes (max ${maxBytes} for inline read; use sftp-write with sourcePath to mirror locally instead, or pass { offset, length } for a ranged read)`);\r\n }\r\n try {\r\n const result = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));\r\n const body = result.Body as unknown as { transformToString?: () => Promise<string> };\r\n if (!body?.transformToString) throw new Error('R2 returned no readable body');\r\n return await body.transformToString();\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\nasync function r2GetObjectRange(\r\n bucket: string,\r\n key: string,\r\n range: { offset: number; length?: number },\r\n): Promise<string> {\r\n const client = getR2Client();\r\n let size = 0;\r\n try {\r\n const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n if (range.offset >= size && size > 0) throw new Error(`offset ${range.offset} is past end of object (size ${size})`);\r\n const MAX = 1_048_576;\r\n const remaining = Math.max(0, size - range.offset);\r\n const effectiveLen = range.length !== undefined ? Math.min(range.length, remaining, MAX) : Math.min(remaining, MAX);\r\n const end = range.offset + effectiveLen - 1;\r\n try {\r\n // S3 Range header is inclusive on both ends.\r\n const result = await client.send(new GetObjectCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n Range: `bytes=${range.offset}-${end}`,\r\n }));\r\n const body = result.Body as unknown as { transformToString?: () => Promise<string> };\r\n if (!body?.transformToString) throw new Error('R2 returned no readable body');\r\n const text = await body.transformToString();\r\n const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;\r\n return `${header}\\n${text}`;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\nasync function r2PutObject(bucket: string, key: string, body: Buffer | Readable, contentLength?: number): Promise<void> {\r\n const client = getR2Client();\r\n try {\r\n await client.send(new PutObjectCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n Body: body,\r\n ContentLength: contentLength,\r\n ContentType: 'application/octet-stream',\r\n }));\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\nasync function r2DeleteObject(bucket: string, key: string): Promise<void> {\r\n const client = getR2Client();\r\n try {\r\n await client.send(new DeleteObjectCommand({ Bucket: bucket, Key: key }));\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\n/** Delete all objects under a prefix. R2's DeleteObjects supports up to 1000\r\n * keys per request, so we loop list→delete in pages. Returns deleted count. */\r\nasync function r2DeletePrefix(bucket: string, prefix: string): Promise<number> {\r\n const client = getR2Client();\r\n let deleted = 0;\r\n let continuationToken: string | undefined;\r\n do {\r\n const list = await client.send(new ListObjectsV2Command({\r\n Bucket: bucket,\r\n Prefix: prefix,\r\n ContinuationToken: continuationToken,\r\n MaxKeys: 1000,\r\n }));\r\n const keys = (list.Contents || []).map(o => o.Key).filter((k): k is string => !!k);\r\n if (keys.length === 0) break;\r\n await client.send(new DeleteObjectsCommand({\r\n Bucket: bucket,\r\n Delete: { Objects: keys.map(k => ({ Key: k })), Quiet: true },\r\n }));\r\n deleted += keys.length;\r\n continuationToken = list.IsTruncated ? list.NextContinuationToken : undefined;\r\n } while (continuationToken);\r\n return deleted;\r\n}\r\n\r\n/** Multipart upload for files larger than ~4.5 GB (R2 single-PUT limit is 5 GB\r\n * with a safety margin). Streams the local file in 100 MB parts. */\r\nconst R2_MULTIPART_THRESHOLD = 4.5 * 1024 * 1024 * 1024; // 4.5 GB\r\nconst R2_MULTIPART_PART_SIZE = 100 * 1024 * 1024; // 100 MB\r\n\r\nasync function r2PutObjectMultipart(\r\n bucket: string,\r\n key: string,\r\n localPath: string,\r\n totalBytes: number,\r\n onProgress?: (bytes: number) => void,\r\n): Promise<void> {\r\n const client = getR2Client();\r\n const create = await client.send(new CreateMultipartUploadCommand({ Bucket: bucket, Key: key }));\r\n const uploadId = create.UploadId;\r\n if (!uploadId) throw new Error('R2 returned no UploadId for multipart create');\r\n\r\n const parts: { PartNumber: number; ETag: string }[] = [];\r\n try {\r\n let partNumber = 1;\r\n let uploaded = 0;\r\n let offset = 0;\r\n while (offset < totalBytes) {\r\n const end = Math.min(offset + R2_MULTIPART_PART_SIZE, totalBytes);\r\n // Read this part into memory (100 MB max). Streaming a single part with\r\n // unknown length is unreliable across SDK versions; buffering keeps us\r\n // simple and predictable.\r\n const chunk = await new Promise<Buffer>((resolve, reject) => {\r\n const chunks: Buffer[] = [];\r\n const rs = createReadStream(localPath, { start: offset, end: end - 1 });\r\n rs.on('data', (c: string | Buffer) => { chunks.push(typeof c === 'string' ? Buffer.from(c) : c); });\r\n rs.on('end', () => resolve(Buffer.concat(chunks.map(b => new Uint8Array(b)))));\r\n rs.on('error', reject);\r\n });\r\n const partResult = await client.send(new UploadPartCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n UploadId: uploadId,\r\n PartNumber: partNumber,\r\n Body: chunk,\r\n ContentLength: chunk.length,\r\n }));\r\n if (!partResult.ETag) throw new Error(`Part ${partNumber} returned no ETag`);\r\n parts.push({ PartNumber: partNumber, ETag: partResult.ETag });\r\n uploaded += chunk.length;\r\n onProgress?.(uploaded);\r\n offset = end;\r\n partNumber++;\r\n }\r\n await client.send(new CompleteMultipartUploadCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n UploadId: uploadId,\r\n MultipartUpload: { Parts: parts },\r\n }));\r\n } catch (e) {\r\n // Best-effort abort to avoid orphaned parts (R2 charges for them).\r\n try { await client.send(new AbortMultipartUploadCommand({ Bucket: bucket, Key: key, UploadId: uploadId })); } catch { /* ignore */ }\r\n throw e;\r\n }\r\n}\r\n\r\n/** Server-side copy within R2 (same bucket or cross-bucket). No data egress. */\r\nasync function r2CopyObject(srcBucket: string, srcKey: string, dstBucket: string, dstKey: string): Promise<{ size: number }> {\r\n const client = getR2Client();\r\n // We need the size for the response footer; HEAD it cheaply first.\r\n let size = 0;\r\n try {\r\n const head = await client.send(new HeadObjectCommand({ Bucket: srcBucket, Key: srcKey }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(srcBucket, srcKey, e); }\r\n try {\r\n await client.send(new CopyObjectCommand({\r\n CopySource: encodeURIComponent(`${srcBucket}/${srcKey}`).replace(/%2F/g, '/'),\r\n Bucket: dstBucket,\r\n Key: dstKey,\r\n }));\r\n } catch (e) { throw r2WrapError(dstBucket, dstKey, e); }\r\n return { size };\r\n}\r\n\r\n/** Stream R2 GetObject body. Caller is responsible for consuming/destroying it. */\r\nasync function r2GetObjectStream(bucket: string, key: string): Promise<{ stream: Readable; size: number }> {\r\n const client = getR2Client();\r\n let size = 0;\r\n try {\r\n const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n try {\r\n const result = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));\r\n const body = result.Body as Readable | undefined;\r\n if (!body) throw new Error('R2 returned no readable body');\r\n return { stream: body, size };\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\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\n/** Convert a glob pattern (`*`, `?`, character classes) to a RegExp anchored\r\n * to the basename only. Used by sftp-list for filtering. */\r\nfunction globToRegExp(pattern: string): RegExp {\r\n let re = '';\r\n for (const c of pattern) {\r\n if (c === '*') re += '.*';\r\n else if (c === '?') re += '.';\r\n else if (/[.+^${}()|[\\]\\\\]/.test(c)) re += '\\\\' + c;\r\n else re += c;\r\n }\r\n return new RegExp(`^${re}$`);\r\n}\r\n\r\ninterface SftpEntry {\r\n kind: 'd' | '-';\r\n size: number;\r\n mtime: string; // ISO; '' if unknown\r\n mtimeMs: number; // 0 if unknown; used for sorting\r\n path: string; // full or basename (depending on recursive mode)\r\n}\r\n\r\nasync function sftpReaddir(\r\n opts: SshConnectionOptions,\r\n dirPath: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { recursive?: boolean; maxDepth?: number; pattern?: string; maxResults?: number },\r\n): Promise<{ entries: SftpEntry[]; truncated: boolean; error?: string }> {\r\n const recursive = options?.recursive === true;\r\n const maxDepth = Math.max(1, Math.min(20, options?.maxDepth ?? 5));\r\n const maxResults = Math.max(1, Math.min(50_000, options?.maxResults ?? 5_000));\r\n const matcher = options?.pattern ? globToRegExp(options.pattern) : null;\r\n const rootSafe = sanitizePath(dirPath);\r\n\r\n let cleanup: (() => void) | undefined;\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 30_000);\r\n cleanup = c;\r\n return await new Promise<{ entries: SftpEntry[]; truncated: boolean; error?: string }>((resolve) => {\r\n const timer = setTimeout(() => { cleanup?.(); resolve({ entries: [], truncated: false, error: 'timeout' }); cleanup = undefined; }, 60_000);\r\n\r\n client.sftp((err, sftp) => {\r\n if (err) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve({ entries: [], truncated: false, error: err.message }); return; }\r\n\r\n const entries: SftpEntry[] = [];\r\n let truncated = false;\r\n const errors: string[] = [];\r\n\r\n const readOne = (path: string, depth: number): Promise<void> =>\r\n new Promise((resolveOne) => {\r\n sftp.readdir(path, (err2, list) => {\r\n if (err2) {\r\n errors.push(`error reading ${path}: ${err2.message}`);\r\n return resolveOne();\r\n }\r\n const subdirs: string[] = [];\r\n for (const item of list) {\r\n if (entries.length >= maxResults) { truncated = true; break; }\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 mtimeMs = item.attrs.mtime ? item.attrs.mtime * 1000 : 0;\r\n const mtime = mtimeMs ? new Date(mtimeMs).toISOString() : '';\r\n const fullPath = path === '/' ? `/${item.filename}` : `${path}/${item.filename}`;\r\n const include = !matcher || matcher.test(item.filename);\r\n if (include) {\r\n entries.push({ kind: isDir ? 'd' : '-', size, mtime, mtimeMs, path: recursive ? fullPath : item.filename });\r\n }\r\n if (isDir && recursive && depth < maxDepth) subdirs.push(fullPath);\r\n }\r\n if (truncated || subdirs.length === 0) return resolveOne();\r\n // Walk subdirs sequentially to keep one SFTP session calm.\r\n (async () => {\r\n for (const sub of subdirs) {\r\n if (truncated) break;\r\n await readOne(sub, depth + 1);\r\n }\r\n resolveOne();\r\n })();\r\n });\r\n });\r\n\r\n readOne(rootSafe, 1).then(() => {\r\n clearTimeout(timer);\r\n cleanup?.(); cleanup = undefined;\r\n resolve({ entries, truncated, error: errors.length ? errors.join('; ') : undefined });\r\n });\r\n });\r\n });\r\n } catch (e: any) {\r\n cleanup?.();\r\n return { entries: [], truncated: false, error: e.message };\r\n }\r\n}\r\n\r\nasync function sftpRead(\r\n opts: SshConnectionOptions,\r\n filePath: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { offset?: number; length?: number },\r\n): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n const offset = Math.max(0, Math.floor(options?.offset ?? 0));\r\n // Cap at 1 MiB regardless of how much the caller asks for; LLM context can't\r\n // sensibly absorb more than that and large reads should use SFTP→local file.\r\n const MAX = 1_048_576;\r\n const requestedLen = options?.length !== undefined ? Math.max(0, Math.floor(options.length)) : undefined;\r\n\r\n let cleanup: (() => void) | undefined;\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 60_000);\r\n cleanup = c;\r\n return await new Promise<string>((resolve) => {\r\n const timer = setTimeout(() => { cleanup?.(); resolve('Error: timeout'); cleanup = undefined; }, 60_000);\r\n client.sftp((err, sftp) => {\r\n if (err) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${err.message}`); return; }\r\n sftp.stat(safe, (err2, stats) => {\r\n if (err2) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${err2.message}`); return; }\r\n const total = stats.size || 0;\r\n if (offset >= total && total > 0) {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Error: offset ${offset} is past end of file (size ${total})`);\r\n return;\r\n }\r\n const remaining = Math.max(0, total - offset);\r\n // Effective read length = caller-requested OR remaining-from-offset,\r\n // whichever is smaller, but never above MAX. In whole-file mode (no\r\n // offset/length) we still refuse files >MAX so the contract matches.\r\n const effectiveLen = requestedLen !== undefined\r\n ? Math.min(requestedLen, remaining, MAX)\r\n : Math.min(remaining, MAX);\r\n const isWholeFileRequest = options === undefined || (offset === 0 && requestedLen === undefined);\r\n if (isWholeFileRequest && total > MAX) {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Error: file too large (${total} bytes, max ${MAX}). Use { offset, length } for ranged reads.`);\r\n return;\r\n }\r\n const chunks: Buffer[] = [];\r\n // ssh2 createReadStream supports `start` (inclusive) and `end` (inclusive).\r\n const rs = sftp.createReadStream(safe, { start: offset, end: offset + effectiveLen - 1 });\r\n rs.on('data', (ch: Buffer) => chunks.push(ch));\r\n rs.on('end', () => {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n const text = Buffer.concat(chunks.map(ch => new Uint8Array(ch))).toString('utf-8');\r\n // For ranged reads, prepend a one-line header so the LLM knows the\r\n // window. Whole-file reads stay unchanged for backwards compat.\r\n if (!isWholeFileRequest) {\r\n const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;\r\n resolve(`${header}\\n${text}`);\r\n } else {\r\n resolve(text);\r\n }\r\n });\r\n rs.on('error', (e: Error) => { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${e.message}`); });\r\n });\r\n });\r\n });\r\n } catch (e: any) {\r\n cleanup?.();\r\n return `Error: ${e.message}`;\r\n }\r\n}\r\n\r\n// SFTP tuning. ssh2 fastPut uses 64 concurrent in-flight WRITE packets which\r\n// gives near-linerate throughput on modern OpenSSH (>= 8.6). The 64 KiB chunk\r\n// size is the safe upper bound for servers without the limits@openssh.com\r\n// extension; with it most OpenSSH builds happily accept up to 256 KiB.\r\nconst SFTP_FASTPUT_CONCURRENCY = 64;\r\nconst SFTP_FASTPUT_CHUNK_SIZE = 65_536;\r\n// Watchdog: kill the upload if no progress is observed for this long. Reset on\r\n// every fastPut step callback. Tighter than a wall-clock timeout because it\r\n// adapts to file size automatically.\r\nconst SFTP_IDLE_TIMEOUT_MS = 120_000;\r\n// Inline writes have no progress events, so we use a wall-clock cap.\r\nconst SFTP_INLINE_TIMEOUT_MS = 60_000;\r\nconst SFTP_PROGRESS_LOG_BYTES = 50 * 1024 * 1024;\r\n\r\nexport type SftpWriteInput =\r\n | { content: string }\r\n | { sourcePath: string };\r\n\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\r\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\r\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Universal output processing (truncate, footer, fuzzy hints, cache, retry)\r\n// Applied centrally in handleCallTool so every tool benefits without per-case\r\n// boilerplate. Designed to be inert when not applicable (small outputs, etc).\r\n// ---------------------------------------------------------------------------\r\n\r\nconst RESPONSE_MAX_BYTES = 8192;\r\n\r\n// Sentinel used to suppress the response footer for tools that should stay raw\r\n// (e.g. things consumed verbatim by other tooling). None today, but the hook\r\n// is here so we can flag a tool name later via `NO_FOOTER_TOOLS.add('foo')`.\r\nconst NO_FOOTER_TOOLS = new Set<string>();\r\n\r\n// Tools that should be cached on the server side. Cache key is the tool name +\r\n// stable JSON of args (minus `noCache`). Set TTL to 0 to disable explicitly.\r\nconst TOOL_CACHE_TTL_MS: Record<string, number> = {\r\n 'list-servers': 60_000,\r\n 'docker-list': 30_000,\r\n};\r\n\r\ninterface CacheEntry { value: { content: { type: string; text: string }[] }; expiresAt: number }\r\nconst TOOL_CACHE = new Map<string, CacheEntry>();\r\n\r\nfunction cacheKeyFor(name: string, args: Record<string, unknown>): string {\r\n const { noCache: _ignored, ...rest } = args;\r\n void _ignored;\r\n // Stable stringify (sorted keys) so { a:1, b:2 } and { b:2, a:1 } collide.\r\n const sorted = Object.fromEntries(Object.entries(rest).sort(([a], [b]) => a.localeCompare(b)));\r\n return `${name}::${JSON.stringify(sorted)}`;\r\n}\r\n\r\nfunction getCachedTool(name: string, args: Record<string, unknown>): { content: { type: string; text: string }[] } | undefined {\r\n const ttl = TOOL_CACHE_TTL_MS[name];\r\n if (!ttl || ttl <= 0) return undefined;\r\n if (args.noCache === true) return undefined;\r\n const k = cacheKeyFor(name, args);\r\n const e = TOOL_CACHE.get(k);\r\n if (!e) return undefined;\r\n if (e.expiresAt < Date.now()) { TOOL_CACHE.delete(k); return undefined; }\r\n return e.value;\r\n}\r\n\r\nfunction setCachedTool(name: string, args: Record<string, unknown>, value: { content: { type: string; text: string }[] }): void {\r\n const ttl = TOOL_CACHE_TTL_MS[name];\r\n if (!ttl || ttl <= 0) return;\r\n if (args.noCache === true) return;\r\n TOOL_CACHE.set(cacheKeyFor(name, args), { value, expiresAt: Date.now() + ttl });\r\n}\r\n\r\n// Fuzzy match: small Levenshtein for typo hints like \"Did you mean: foo?\".\r\n// Only used in error paths so the cost is irrelevant.\r\nfunction levenshtein(a: string, b: string): number {\r\n if (a === b) return 0;\r\n const m = a.length; const n = b.length;\r\n if (m === 0) return n;\r\n if (n === 0) return m;\r\n const dp: number[] = new Array(n + 1);\r\n for (let j = 0; j <= n; j++) dp[j] = j;\r\n for (let i = 1; i <= m; i++) {\r\n let prev = dp[0]!;\r\n dp[0] = i;\r\n for (let j = 1; j <= n; j++) {\r\n const tmp = dp[j]!;\r\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\r\n dp[j] = Math.min(dp[j]! + 1, dp[j - 1]! + 1, prev + cost);\r\n prev = tmp;\r\n }\r\n }\r\n return dp[n]!;\r\n}\r\n\r\nfunction suggestSimilar(input: string, candidates: string[], max = 3): string[] {\r\n if (!input || !candidates.length) return [];\r\n const lo = input.toLowerCase();\r\n const threshold = Math.max(2, Math.ceil(input.length / 3));\r\n return candidates\r\n .map(c => ({ c, d: levenshtein(lo, c.toLowerCase()) }))\r\n .filter(x => x.d <= threshold)\r\n .sort((a, b) => a.d - b.d)\r\n .slice(0, max)\r\n .map(x => x.c);\r\n}\r\n\r\n// Lightweight running cache of recently-seen names. Populated by tools that\r\n// list things (servers, containers); consumed by tools that error on a name.\r\nconst KNOWN_SERVER_NAMES = new Map<string, { id: string; name: string }>(); // key=id\r\nconst KNOWN_CONTAINERS_BY_SERVER = new Map<string, { names: string[]; capturedAt: number }>();\r\n\r\nfunction rememberServers(servers: Array<{ id: string; name: string }>): void {\r\n for (const s of servers) KNOWN_SERVER_NAMES.set(s.id, s);\r\n}\r\nfunction rememberContainers(serverId: string, names: string[]): void {\r\n KNOWN_CONTAINERS_BY_SERVER.set(serverId, { names, capturedAt: Date.now() });\r\n}\r\n\r\n// Auto-context hints for list-servers: cheap pattern matching on tags +\r\n// hostnames so the LLM gets a 1-line \"what runs here\" summary on the first\r\n// listing call. Pure heuristics — no SSH probes.\r\nfunction buildServerContextHints(\r\n servers: Array<{ name: string; hostname: string; tags?: string[] | null }>,\r\n): string[] {\r\n const hints: string[] = [];\r\n for (const s of servers) {\r\n const tagSet = new Set<string>((s.tags || []).map((t) => String(t).toLowerCase()));\r\n const name = (s.name || '').toLowerCase();\r\n const host = (s.hostname || '').toLowerCase();\r\n const found: string[] = [];\r\n if (tagSet.has('trigger') || /trigger/.test(name) || /trigger/.test(host)) found.push('Trigger.dev self-hosted');\r\n if (tagSet.has('supabase') || /supabase/.test(name) || /supabase/.test(host)) found.push('Supabase stack');\r\n if (tagSet.has('proxy') || /proxy|jump/.test(name)) found.push('SSH ProxyJump host');\r\n if (tagSet.has('giga') || /giga/.test(name)) found.push('shared workloads');\r\n if (tagSet.has('vca') || /vca/.test(name)) found.push('VCA hosting');\r\n if (tagSet.has('mg-boilers') || /boiler/.test(name)) found.push('boiler API');\r\n if (tagSet.has('refront') || /refront|tickets/.test(name) || /refront|tickets/.test(host)) found.push('Refront/tickets');\r\n if (found.length) hints.push(`- ${s.name}: ${found.join(', ')}`);\r\n }\r\n return hints;\r\n}\r\nfunction getKnownContainers(serverId: string, maxAgeMs = 5 * 60_000): string[] | undefined {\r\n const e = KNOWN_CONTAINERS_BY_SERVER.get(serverId);\r\n if (!e) return undefined;\r\n if (Date.now() - e.capturedAt > maxAgeMs) return undefined;\r\n return e.names;\r\n}\r\n\r\n// Truncate a text payload by UTF-8 byte budget, returning whether we cut.\r\nfunction truncateForLLM(text: string, maxBytes: number): { text: string; truncated: boolean; totalBytes: number; shownBytes: number } {\r\n const totalBytes = Buffer.byteLength(text, 'utf8');\r\n if (totalBytes <= maxBytes) return { text, truncated: false, totalBytes, shownBytes: totalBytes };\r\n const buf = Buffer.from(text, 'utf8');\r\n // Cut on a code-point boundary by scanning back from maxBytes to avoid\r\n // producing a broken multibyte sequence at the slice point.\r\n let cut = maxBytes;\r\n while (cut > 0 && (buf[cut]! & 0xc0) === 0x80) cut--;\r\n const head = buf.subarray(0, cut).toString('utf8');\r\n return { text: head, truncated: true, totalBytes, shownBytes: cut };\r\n}\r\n\r\nfunction buildTruncationHint(name: string, args: Record<string, unknown>, total: number, shown: number): string {\r\n const base = `(showing first ${shown} of ${total} bytes;`;\r\n if (name === 'sftp-read') {\r\n const off = Number(args.offset) || 0;\r\n const next = off + shown;\r\n return `${base} pass { offset: ${next}, length: ${RESPONSE_MAX_BYTES} } to read more)`;\r\n }\r\n if (name === 'docker-logs') {\r\n return `${base} use \\`tail\\`, \\`since\\`, or \\`grep\\` to narrow the window)`;\r\n }\r\n if (name === 'ssh-execute') {\r\n return `${base} pipe through head/tail/grep server-side, or use sftp-read with offset for huge logs)`;\r\n }\r\n return `${base} narrow your query, paginate, or grep server-side to read the rest)`;\r\n}\r\n\r\n// Detect transient SSH/network failures worth a single retry. We're\r\n// intentionally conservative: only obvious connect-time hiccups, not generic\r\n// command failures (that would mask real bugs).\r\nconst TRANSIENT_RE = /(ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|ENETUNREACH|EHOSTUNREACH|connection\\s+refused|connection\\s+reset|getaddrinfo|connect\\s+ETIMEDOUT|socket\\s+hang\\s*up|read\\s+ECONNRESET|All configured authentication methods failed)/i;\r\n\r\nfunction isTransientSshError(stderr: string | undefined, exitCode: number): boolean {\r\n if (exitCode !== -1) return false;\r\n if (!stderr) return false;\r\n return TRANSIENT_RE.test(stderr);\r\n}\r\n\r\n// Result post-processing: cache write + truncate + footer. Pure function over\r\n// the result content. Idempotent for already-small outputs.\r\nfunction postprocessResult(\r\n result: { content: { type: string; text: string }[] },\r\n meta: { startedAtMs: number; serverIdLabel?: string; toolName: string; args: Record<string, unknown>; cached?: boolean },\r\n): { content: { type: string; text: string }[] } {\r\n if (!result.content?.length) return result;\r\n const block = result.content[0]!;\r\n let text = String(block.text ?? '');\r\n\r\n const trunc = truncateForLLM(text, RESPONSE_MAX_BYTES);\r\n if (trunc.truncated) {\r\n text = trunc.text + '\\n\\n... ' + buildTruncationHint(meta.toolName, meta.args, trunc.totalBytes, trunc.shownBytes);\r\n }\r\n\r\n if (!NO_FOOTER_TOOLS.has(meta.toolName)) {\r\n const tookMs = Date.now() - meta.startedAtMs;\r\n const tookStr = tookMs < 1000 ? `${tookMs}ms` : `${(tookMs / 1000).toFixed(1)}s`;\r\n const sizeStr = trunc.totalBytes >= 1024\r\n ? `${(trunc.totalBytes / 1024).toFixed(1)} KB`\r\n : `${trunc.totalBytes} B`;\r\n const parts = [`took ${tookStr}`, sizeStr];\r\n if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);\r\n if (meta.cached) parts.push('cached');\r\n text = `${text}\\n\\n[${parts.join(', ')}]`;\r\n }\r\n\r\n return { ...result, content: [{ ...block, text }] };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// ssh-execute composition helpers (pipeline / repeat / format=ndjson)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface PipelineSegment { index: number; command: string; output: string; exitCode: number }\r\ninterface IterationResult { index: number; startedAt: number; durationMs: number; result: SshResult }\r\n\r\n// Build a wrapper script that runs N commands sequentially in a single SSH\r\n// session, with a unique marker between each so we can split outputs back\r\n// apart. Stderr is merged into stdout per command (so we can section it);\r\n// the original cumulative stderr stays available on the SshResult for diag.\r\nfunction buildPipelineScript(\r\n commands: string[],\r\n shell: 'bash' | 'powershell',\r\n marker: string,\r\n stopOnError: boolean,\r\n): string {\r\n if (shell === 'powershell') {\r\n // PowerShell: redirect Error stream into Output (2>&1) per cmd, capture\r\n // $LASTEXITCODE after each. `iex` (Invoke-Expression) lets us run the\r\n // raw command strings without re-quoting.\r\n const lines: string[] = [\"$ErrorActionPreference='Continue'\", \"$ProgressPreference='SilentlyContinue'\"];\r\n for (let i = 0; i < commands.length; i++) {\r\n lines.push(`Write-Output '${marker} ${i} begin'`);\r\n lines.push(`& { ${commands[i]} } 2>&1`);\r\n lines.push(`$__c = if ($null -eq $LASTEXITCODE) { 0 } else { $LASTEXITCODE }`);\r\n lines.push(`Write-Output ('${marker} ' + ${i} + ' end exit=' + $__c)`);\r\n if (stopOnError) lines.push(`if ($__c -ne 0) { exit $__c }`);\r\n }\r\n return buildPowerShellEncodedCommand(lines.join('; '), []);\r\n }\r\n // bash path: keep it portable so dash/sh works too. `set +e` per cmd\r\n // ensures continue-on-error mode actually continues even when the user's\r\n // script enables `set -e` somewhere inside.\r\n const sh: string[] = [];\r\n for (let i = 0; i < commands.length; i++) {\r\n sh.push(`echo \"${marker} ${i} begin\"`);\r\n sh.push(`{ ${commands[i]}; } 2>&1`);\r\n sh.push(`__c=$?`);\r\n sh.push(`echo \"${marker} ${i} end exit=$__c\"`);\r\n if (stopOnError) sh.push(`if [ \"$__c\" -ne 0 ]; then exit \"$__c\"; fi`);\r\n }\r\n return `bash -c ${posixQuote(sh.join('; '))}`;\r\n}\r\n\r\n// Split a pipeline stdout payload back into per-command segments. Tolerates\r\n// missing markers (e.g. the script aborted mid-pipeline due to stop-on-error).\r\nfunction parsePipelineOutput(stdout: string, commands: string[], marker: string): PipelineSegment[] {\r\n const segments: PipelineSegment[] = [];\r\n // Match `<marker> <i> begin` ... `<marker> <i> end exit=<code>` for each cmd.\r\n for (let i = 0; i < commands.length; i++) {\r\n const beginRe = new RegExp(`^${escapeRegex(marker)}\\\\s+${i}\\\\s+begin\\\\s*$`, 'm');\r\n const endRe = new RegExp(`^${escapeRegex(marker)}\\\\s+${i}\\\\s+end\\\\s+exit=(-?\\\\d+)\\\\s*$`, 'm');\r\n const beginMatch = beginRe.exec(stdout);\r\n const endMatch = endRe.exec(stdout);\r\n if (!beginMatch || !endMatch) {\r\n segments.push({ index: i, command: commands[i] as string, output: '(no output captured — pipeline aborted before this step?)', exitCode: -1 });\r\n continue;\r\n }\r\n const start = beginMatch.index + beginMatch[0].length + 1; // +1 for newline\r\n const end = endMatch.index;\r\n const body = stdout.slice(start, end).replace(/\\n$/, '');\r\n const code = parseInt(endMatch[1] as string, 10);\r\n segments.push({ index: i, command: commands[i] as string, output: body, exitCode: Number.isFinite(code) ? code : -1 });\r\n }\r\n return segments;\r\n}\r\n\r\nfunction escapeRegex(s: string): string {\r\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\nfunction renderPipelineSegments(segments: PipelineSegment[], overall: SshResult, format: 'text' | 'ndjson'): string {\r\n const sections: string[] = [];\r\n for (const seg of segments) {\r\n sections.push(`>>> [${seg.index + 1}/${segments.length}] ${seg.command} (exit ${seg.exitCode})`);\r\n let body = seg.output;\r\n if (format === 'ndjson') {\r\n const parsed = tryParseNdjsonFromCommand(seg.command, body);\r\n if (parsed) body = parsed;\r\n }\r\n sections.push(body || '(no output)');\r\n }\r\n if (overall.stderr) sections.push(`--- aggregate stderr ---\\n${overall.stderr.trimEnd()}`);\r\n return sections.join('\\n');\r\n}\r\n\r\nfunction renderRepeatResult(iters: IterationResult[], mode: 'all' | 'diff' | 'last', format: 'text' | 'ndjson'): string {\r\n const formatBody = (s: string): string => {\r\n if (!format || format !== 'ndjson') return s;\r\n // We don't know the original command here; try a heuristic parse anyway.\r\n return tryParseNdjsonFromCommand('', s) || s;\r\n };\r\n if (mode === 'last') {\r\n const last = iters[iters.length - 1]!;\r\n return `--- iteration ${last.index + 1}/${iters.length} (exit ${last.result.exitCode}, ${last.durationMs}ms) ---\\n${formatBody(last.result.stdout) || '(empty)'}${last.result.stderr ? `\\n[stderr] ${last.result.stderr.trimEnd()}` : ''}`;\r\n }\r\n if (mode === 'diff') {\r\n const sections: string[] = [`(repeat: ${iters.length} runs, diff mode — only differences vs. previous run shown)`];\r\n let prev = '';\r\n for (let i = 0; i < iters.length; i++) {\r\n const cur = iters[i]!.result.stdout;\r\n if (i === 0) {\r\n sections.push(`--- iteration 1 (initial, ${iters[i]!.durationMs}ms) ---\\n${formatBody(cur) || '(empty)'}`);\r\n } else {\r\n const changes = diffLines(prev, cur);\r\n const header = `--- iteration ${i + 1} (${iters[i]!.durationMs}ms, +${changes.added.length} -${changes.removed.length}) ---`;\r\n const block: string[] = [header];\r\n if (changes.added.length === 0 && changes.removed.length === 0) {\r\n block.push('(no changes)');\r\n } else {\r\n for (const line of changes.added) block.push(`+ ${line}`);\r\n for (const line of changes.removed) block.push(`- ${line}`);\r\n }\r\n sections.push(block.join('\\n'));\r\n }\r\n prev = cur;\r\n }\r\n return sections.join('\\n');\r\n }\r\n // 'all'\r\n const sections: string[] = [`(repeat: ${iters.length} runs, all output)`];\r\n for (const it of iters) {\r\n sections.push(`--- iteration ${it.index + 1}/${iters.length} (exit ${it.result.exitCode}, ${it.durationMs}ms) ---`);\r\n sections.push(formatBody(it.result.stdout) || '(empty)');\r\n if (it.result.stderr) sections.push(`[stderr] ${it.result.stderr.trimEnd()}`);\r\n }\r\n return sections.join('\\n');\r\n}\r\n\r\nfunction diffLines(a: string, b: string): { added: string[]; removed: string[] } {\r\n const aSet = new Set(a.split('\\n'));\r\n const bSet = new Set(b.split('\\n'));\r\n const added: string[] = [];\r\n const removed: string[] = [];\r\n for (const line of bSet) if (!aSet.has(line) && line) added.push(line);\r\n for (const line of aSet) if (!bSet.has(line) && line) removed.push(line);\r\n return { added, removed };\r\n}\r\n\r\n// NDJSON parser: detect common Linux command outputs from the command string\r\n// or content shape and emit one JSON object per record. Returns null if the\r\n// content doesn't look like a known format (caller falls back to raw text).\r\nfunction tryParseNdjsonFromCommand(command: string, stdout: string): string | null {\r\n if (!stdout.trim()) return null;\r\n const c = command.toLowerCase();\r\n const looksLike = (re: RegExp) => re.test(c);\r\n // df -h / df -hT\r\n if (looksLike(/\\bdf\\b/) || /^Filesystem\\s+\\S+\\s+Used\\s+/m.test(stdout)) {\r\n return parseDf(stdout);\r\n }\r\n // free / free -m / free -h\r\n if (looksLike(/\\bfree\\b/) || /^\\s*total\\s+used\\s+free/m.test(stdout)) {\r\n return parseFree(stdout);\r\n }\r\n // ps aux / ps -ef\r\n if (looksLike(/\\bps\\b/) || /^USER\\s+PID\\s+%CPU\\s+%MEM/m.test(stdout)) {\r\n return parsePsAux(stdout);\r\n }\r\n // ss -tlnp / ss -tnlp / netstat -tlnp\r\n if (looksLike(/\\bss\\b/) || /^State\\s+Recv-Q\\s+Send-Q/m.test(stdout)) {\r\n return parseSs(stdout);\r\n }\r\n // lsblk\r\n if (looksLike(/\\blsblk\\b/) || /^NAME\\s+MAJ:MIN/m.test(stdout)) {\r\n return parseLsblk(stdout);\r\n }\r\n return null;\r\n}\r\n\r\nfunction splitCols(line: string, max?: number): string[] {\r\n const parts = line.trim().split(/\\s+/);\r\n if (max && parts.length > max) {\r\n return [...parts.slice(0, max - 1), parts.slice(max - 1).join(' ')];\r\n }\r\n return parts;\r\n}\r\n\r\nfunction parseDf(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n const header = lines[0];\r\n if (!header || !/Filesystem/i.test(header)) return null;\r\n // Normalise \"Mounted on\" → \"MountedOn\" before splitting, so we get a clean\r\n // single column instead of two (\"Mounted\" + \"on\" with empty value).\r\n const cleanHeader = header.replace(/Mounted on/i, 'MountedOn');\r\n const cols = cleanHeader.trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, cols.length);\r\n if (parts.length < 4) continue;\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < cols.length; i++) obj[cols[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parseFree(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n const out: string[] = [];\r\n for (const ln of lines) {\r\n if (/^\\s*total\\s+used\\s+free/i.test(ln)) continue;\r\n const m = ln.match(/^(\\S+):?\\s+(.+)$/);\r\n if (!m) continue;\r\n const [type, rest] = [m[1], m[2]];\r\n const cols = (rest as string).trim().split(/\\s+/);\r\n out.push(JSON.stringify({ type: (type as string).replace(/:$/, ''), values: cols.map(Number) }));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parsePsAux(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n if (!lines[0] || !/USER\\s+PID/i.test(lines[0])) return null;\r\n const headers = lines[0].trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, headers.length);\r\n if (parts.length < headers.length) continue;\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < headers.length; i++) obj[headers[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parseSs(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n if (!lines[0] || !/(State|Netid)/i.test(lines[0])) return null;\r\n const headers = lines[0].trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, headers.length);\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < headers.length; i++) obj[headers[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parseLsblk(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n if (!lines[0] || !/NAME\\s+MAJ:MIN/i.test(lines[0])) return null;\r\n const headers = lines[0].trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, headers.length);\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < headers.length; i++) obj[headers[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\n// Resolve a friendly server label for the response footer. Best-effort: falls\r\n// back to the bare ID if the supabase row isn't loaded into the cache yet.\r\nasync function resolveServerLabel(serverId: string | undefined, serverIds: unknown): Promise<string | undefined> {\r\n if (Array.isArray(serverIds) && serverIds.length > 0) return `${serverIds.length} servers`;\r\n if (!serverId) return undefined;\r\n const cached = KNOWN_SERVER_NAMES.get(serverId);\r\n if (cached) return cached.name;\r\n try {\r\n const { data } = await supabase.from('ssh_server').select('id, name').eq('id', serverId).maybeSingle();\r\n if (data?.name) {\r\n KNOWN_SERVER_NAMES.set(serverId, { id: serverId, name: data.name as string });\r\n return data.name as string;\r\n }\r\n } catch { /* swallow — footer is informational */ }\r\n return serverId.slice(0, 8);\r\n}\r\n\r\nasync function sftpWrite(\r\n opts: SshConnectionOptions,\r\n filePath: string,\r\n input: SftpWriteInput,\r\n proxy?: SshConnectionOptions,\r\n meta?: { fileMode?: number; mtimeMs?: number },\r\n): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n assertWritablePath(safe);\r\n\r\n // File permission bits: caller may override (e.g. 0o755 for executable).\r\n // Default 0o644 keeps existing behaviour for plain config writes.\r\n const fileMode = meta?.fileMode !== undefined ? (meta.fileMode & 0o7777) : 0o644;\r\n\r\n // Validate source up-front so the LLM gets a clear error before we open SSH.\r\n let mode: 'content' | 'sourcePath';\r\n let inlineBuffer: Buffer | undefined;\r\n let localPath: string | undefined;\r\n let expectedBytes = 0;\r\n\r\n if ('content' in input && typeof input.content === 'string') {\r\n mode = 'content';\r\n inlineBuffer = Buffer.from(input.content, 'utf-8');\r\n expectedBytes = inlineBuffer.length;\r\n } else if ('sourcePath' in input && typeof input.sourcePath === 'string') {\r\n mode = 'sourcePath';\r\n localPath = input.sourcePath;\r\n if (!isAbsolute(localPath)) return `Error: sourcePath must be an absolute path: ${localPath}`;\r\n if (!existsSync(localPath)) return `Error: sourcePath does not exist: ${localPath}`;\r\n const st = statSync(localPath);\r\n if (!st.isFile()) return `Error: sourcePath is not a regular file: ${localPath}`;\r\n expectedBytes = st.size;\r\n } else {\r\n return 'Error: sftp-write requires exactly one of: content (string) or sourcePath (absolute local path)';\r\n }\r\n\r\n // For inline text we leave SSH compression enabled (cheap, often 5-10x for\r\n // configs/scripts). For sourcePath we disable it: large files are usually\r\n // already-compressed (zip/jpg/mp4/dump.gz) and SSH-level compression then\r\n // wastes CPU and slows the transfer.\r\n const compress = mode === 'content';\r\n const startedAt = Date.now();\r\n let cleanup: (() => void) | undefined;\r\n\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 60_000, { compress });\r\n cleanup = c;\r\n\r\n return await new Promise<string>((resolve) => {\r\n let resolved = false;\r\n let bytesWritten = 0;\r\n\r\n const finish = (msg: string) => {\r\n if (resolved) return;\r\n resolved = true;\r\n watchdog?.cancel();\r\n wallTimer && clearTimeout(wallTimer);\r\n cleanup?.();\r\n cleanup = undefined;\r\n resolve(msg);\r\n };\r\n\r\n // For sourcePath: idle watchdog reset on every fastPut step.\r\n // For content: simple wall-clock timeout.\r\n let watchdog: { reset: () => void; cancel: () => void } | undefined;\r\n let wallTimer: NodeJS.Timeout | undefined;\r\n\r\n if (mode === 'sourcePath') {\r\n const armWatchdog = () => {\r\n let timer: NodeJS.Timeout = setTimeout(\r\n () => finish(`Error: idle timeout (no SFTP progress for ${SFTP_IDLE_TIMEOUT_MS / 1000}s, wrote ${formatBytes(bytesWritten)} of ${formatBytes(expectedBytes)})`),\r\n SFTP_IDLE_TIMEOUT_MS,\r\n );\r\n return {\r\n reset: () => { clearTimeout(timer); timer = setTimeout(\r\n () => finish(`Error: idle timeout (no SFTP progress for ${SFTP_IDLE_TIMEOUT_MS / 1000}s, wrote ${formatBytes(bytesWritten)} of ${formatBytes(expectedBytes)})`),\r\n SFTP_IDLE_TIMEOUT_MS,\r\n ); },\r\n cancel: () => clearTimeout(timer),\r\n };\r\n };\r\n watchdog = armWatchdog();\r\n } else {\r\n wallTimer = setTimeout(\r\n () => finish(`Error: timeout after ${SFTP_INLINE_TIMEOUT_MS / 1000}s`),\r\n SFTP_INLINE_TIMEOUT_MS,\r\n );\r\n }\r\n\r\n client.sftp((err, sftp) => {\r\n if (err) return finish(`Error: ${err.message}`);\r\n\r\n // Apply mtime after a successful write. SFTP `setstat` with atime+mtime\r\n // is the standard way; we leave atime equal to mtime (close enough for\r\n // tooling that cares about freshness). Errors are surfaced as a warning\r\n // suffix so the upload itself is still considered successful.\r\n const applyMtime = (then: (suffix: string) => void) => {\r\n if (meta?.mtimeMs === undefined) return then('');\r\n const secs = Math.floor(meta.mtimeMs / 1000);\r\n sftp.setstat(safe, { atime: secs, mtime: secs }, (statErr) => {\r\n then(statErr ? ` (mtime set failed: ${statErr.message})` : ` (mtime=${new Date(meta.mtimeMs!).toISOString()})`);\r\n });\r\n };\r\n\r\n if (mode === 'content') {\r\n const ws = sftp.createWriteStream(safe, { mode: fileMode });\r\n ws.on('error', (e: Error) => finish(`Error: ${e.message}`));\r\n ws.on('close', () => {\r\n const elapsed = Date.now() - startedAt;\r\n applyMtime((suffix) => finish(`Written ${expectedBytes} bytes to ${safe} in ${elapsed}ms (mode=0o${fileMode.toString(8)})${suffix}`));\r\n });\r\n ws.end(inlineBuffer!);\r\n return;\r\n }\r\n\r\n // sourcePath path: ssh2 fastPut does the heavy lifting (parallel\r\n // pipelined SFTP_WRITE packets). Step callback gives us progress for\r\n // the watchdog and periodic logs.\r\n let nextProgressLog = SFTP_PROGRESS_LOG_BYTES;\r\n sftp.fastPut(\r\n localPath!,\r\n safe,\r\n {\r\n concurrency: SFTP_FASTPUT_CONCURRENCY,\r\n chunkSize: SFTP_FASTPUT_CHUNK_SIZE,\r\n mode: fileMode,\r\n fileSize: expectedBytes,\r\n step: (transferred: number) => {\r\n bytesWritten = transferred;\r\n watchdog?.reset();\r\n if (transferred >= nextProgressLog) {\r\n console.error(\r\n `[sftp-write] ${formatBytes(transferred)} / ${formatBytes(expectedBytes)} → ${safe}`,\r\n );\r\n nextProgressLog += SFTP_PROGRESS_LOG_BYTES;\r\n }\r\n },\r\n },\r\n (fpErr) => {\r\n if (fpErr) return finish(`Error: ${fpErr.message}`);\r\n const elapsed = Date.now() - startedAt;\r\n const mbps = expectedBytes / (1024 * 1024) / Math.max(0.001, elapsed / 1000);\r\n applyMtime((suffix) => finish(\r\n `Uploaded ${formatBytes(expectedBytes)} from ${localPath} to ${safe} ` +\r\n `in ${(elapsed / 1000).toFixed(1)}s (${mbps.toFixed(1)} MB/s, mode=0o${fileMode.toString(8)})${suffix}`,\r\n ));\r\n },\r\n );\r\n });\r\n });\r\n } catch (e: unknown) {\r\n cleanup?.();\r\n return `Error: ${e instanceof Error ? e.message : String(e)}`;\r\n }\r\n}\r\n\r\nasync function sftpDelete(\r\n opts: SshConnectionOptions,\r\n filePath: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { recursive?: boolean },\r\n): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n assertWritablePath(safe);\r\n const recursive = options?.recursive === true;\r\n let cleanup: (() => void) | undefined;\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 30_000);\r\n cleanup = c;\r\n return await new Promise<string>((resolve) => {\r\n const timer = setTimeout(() => { cleanup?.(); resolve('Error: timeout'); cleanup = undefined; }, 60_000);\r\n client.sftp((err, sftp) => {\r\n if (err) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${err.message}`); return; }\r\n\r\n // Recursive directory removal: walk the tree depth-first via SFTP and\r\n // unlink files / rmdir dirs from the bottom up. Pure SFTP — no shell\r\n // shenanigans, so it works on Windows OpenSSH too.\r\n if (recursive) {\r\n const removeTree = async (target: string): Promise<{ files: number; dirs: number }> => {\r\n return new Promise((resolveTree) => {\r\n sftp.stat(target, (statErr, stats) => {\r\n if (statErr) return resolveTree({ files: 0, dirs: 0 });\r\n const mode = stats.mode || 0;\r\n const isDir = (mode & 0o170000) === 0o040000;\r\n if (!isDir) {\r\n sftp.unlink(target, () => resolveTree({ files: 1, dirs: 0 }));\r\n return;\r\n }\r\n sftp.readdir(target, async (rdErr, list) => {\r\n if (rdErr) return resolveTree({ files: 0, dirs: 0 });\r\n let files = 0; let dirs = 0;\r\n for (const item of list) {\r\n const child = target === '/' ? `/${item.filename}` : `${target}/${item.filename}`;\r\n const r = await removeTree(child);\r\n files += r.files; dirs += r.dirs;\r\n }\r\n sftp.rmdir(target, () => resolveTree({ files, dirs: dirs + 1 }));\r\n });\r\n });\r\n });\r\n };\r\n removeTree(safe).then(({ files, dirs }) => {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Removed ${safe} recursively (${files} files, ${dirs} directories)`);\r\n });\r\n return;\r\n }\r\n\r\n sftp.unlink(safe, (unlinkErr) => {\r\n if (unlinkErr) {\r\n sftp.rmdir(safe, (rmdirErr) => {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(rmdirErr ? `Error: ${unlinkErr.message}` : `Deleted directory ${safe}`);\r\n });\r\n } else {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Deleted file ${safe}`);\r\n }\r\n });\r\n });\r\n });\r\n } catch (e: any) {\r\n cleanup?.();\r\n return `Error: ${e.message}`;\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cross-endpoint copy (SSH ↔ SSH, SSH ↔ R2, R2 ↔ R2). True streaming for\r\n// SSH paths so we never round-trip through local disk for huge files.\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type CopyEndpoint =\r\n | { kind: 'ssh'; opts: SshConnectionOptions; proxy?: SshConnectionOptions; path: string }\r\n | { kind: 'r2'; bucket: string; key: string };\r\n\r\ninterface CopyResult { bytes: number; elapsedMs: number; mode: string }\r\n\r\nasync function sftpCopy(src: CopyEndpoint, dst: CopyEndpoint): Promise<CopyResult> {\r\n const startedAt = Date.now();\r\n\r\n // R2 → R2: server-side copy (zero data egress).\r\n if (src.kind === 'r2' && dst.kind === 'r2') {\r\n const { size } = await r2CopyObject(src.bucket, src.key, dst.bucket, dst.key);\r\n return { bytes: size, elapsedMs: Date.now() - startedAt, mode: 'r2-server-side' };\r\n }\r\n\r\n // R2 → SSH: stream R2 body into SFTP write stream.\r\n if (src.kind === 'r2' && dst.kind === 'ssh') {\r\n const safe = sanitizePath(dst.path);\r\n assertWritablePath(safe);\r\n const { stream, size } = await r2GetObjectStream(src.bucket, src.key);\r\n const { client, cleanup } = await connectSshClient(dst.opts, dst.proxy, 60_000);\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n client.sftp((err, sftp) => {\r\n if (err) return reject(err);\r\n const ws = sftp.createWriteStream(safe);\r\n ws.on('close', () => resolve());\r\n ws.on('error', reject);\r\n stream.on('error', reject);\r\n stream.pipe(ws);\r\n });\r\n });\r\n } finally { cleanup(); }\r\n return { bytes: size, elapsedMs: Date.now() - startedAt, mode: 'r2→ssh-stream' };\r\n }\r\n\r\n // SSH → R2: pipe SFTP read stream to R2 PutObject. The S3 SDK accepts a\r\n // Readable body; ContentLength is required for R2's API, so we HEAD-equivalent\r\n // (sftp.stat) the source first.\r\n if (src.kind === 'ssh' && dst.kind === 'r2') {\r\n const safeSrc = sanitizePath(src.path);\r\n const { client, cleanup } = await connectSshClient(src.opts, src.proxy, 60_000);\r\n try {\r\n const { stream, size } = await new Promise<{ stream: Readable; size: number }>((resolve, reject) => {\r\n client.sftp((err, sftp) => {\r\n if (err) return reject(err);\r\n sftp.stat(safeSrc, (statErr, stats) => {\r\n if (statErr) return reject(statErr);\r\n const s = (stats.size as number) || 0;\r\n const rs = sftp.createReadStream(safeSrc) as unknown as Readable;\r\n resolve({ stream: rs, size: s });\r\n });\r\n });\r\n });\r\n // For huge files (>4.5 GB) the single PUT path will fail (R2 limit).\r\n // We don't have multipart-from-stream right now, so fall back to a\r\n // clear error — caller can mirror locally first if needed.\r\n if (size > R2_MULTIPART_THRESHOLD) {\r\n cleanup();\r\n throw new Error(`Source object is ${formatBytes(size)} which exceeds R2 single-PUT cap (${formatBytes(R2_MULTIPART_THRESHOLD)}). For now: download via sftp-write { sourceRemote, target: local } first, then upload to R2 with sourcePath.`);\r\n }\r\n await r2PutObject(dst.bucket, dst.key, stream, size);\r\n return { bytes: size, elapsedMs: Date.now() - startedAt, mode: 'ssh→r2-stream' };\r\n } finally { cleanup(); }\r\n }\r\n\r\n // SSH → SSH: open both sessions, pipe read stream into write stream. No\r\n // local detour — the SFTP protocol streams chunks directly.\r\n if (src.kind === 'ssh' && dst.kind === 'ssh') {\r\n const safeSrc = sanitizePath(src.path);\r\n const safeDst = sanitizePath(dst.path);\r\n assertWritablePath(safeDst);\r\n const srcConn = await connectSshClient(src.opts, src.proxy, 60_000);\r\n let dstConn: { client: SshClient; cleanup: () => void } | undefined;\r\n try {\r\n dstConn = await connectSshClient(dst.opts, dst.proxy, 60_000);\r\n const bytes = await new Promise<number>((resolve, reject) => {\r\n srcConn.client.sftp((err, srcSftp) => {\r\n if (err) return reject(err);\r\n dstConn!.client.sftp((err2, dstSftp) => {\r\n if (err2) return reject(err2);\r\n srcSftp.stat(safeSrc, (statErr, stats) => {\r\n if (statErr) return reject(statErr);\r\n const size = (stats.size as number) || 0;\r\n const rs = srcSftp.createReadStream(safeSrc);\r\n const ws = dstSftp.createWriteStream(safeDst);\r\n ws.on('close', () => resolve(size));\r\n ws.on('error', reject);\r\n rs.on('error', reject);\r\n rs.pipe(ws);\r\n });\r\n });\r\n });\r\n });\r\n return { bytes, elapsedMs: Date.now() - startedAt, mode: 'ssh→ssh-stream' };\r\n } finally {\r\n srcConn.cleanup();\r\n dstConn?.cleanup();\r\n }\r\n }\r\n\r\n throw new Error('Unsupported copy combination');\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\n/**\r\n * Build engine-specific schema-introspection SQL for the `describe` shortcut\r\n * on `db-query`. Sanitises the identifier so a caller can't slip an arbitrary\r\n * statement through `describe`. Pass \"*\" to list all tables in the current\r\n * database/schema.\r\n */\r\nfunction buildDescribeSql(target: string, engine: 'mysql' | 'postgres' | 'mssql'): string {\r\n if (target === '*' || target === '') {\r\n if (engine === 'postgres') {\r\n return \"SELECT schemaname, tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema') ORDER BY schemaname, tablename\";\r\n }\r\n if (engine === 'mssql') {\r\n return \"SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME\";\r\n }\r\n return 'SHOW TABLES';\r\n }\r\n const safe = target.replace(/[^a-zA-Z0-9_]/g, '');\r\n if (!safe) throw new Error(`Invalid describe target: ${target}`);\r\n if (engine === 'postgres') {\r\n return (\r\n `SELECT column_name, data_type, is_nullable, column_default ` +\r\n `FROM information_schema.columns WHERE table_name='${safe}' ORDER BY ordinal_position;` +\r\n `\\nSELECT indexname, indexdef FROM pg_indexes WHERE tablename='${safe}'`\r\n );\r\n }\r\n if (engine === 'mssql') {\r\n return `EXEC sp_help '${safe}'`;\r\n }\r\n return `DESCRIBE \\`${safe}\\`; SHOW INDEX FROM \\`${safe}\\``;\r\n}\r\n\r\n/**\r\n * Build the trailing diagnostic footer for `db-query` results so the caller\r\n * can tell whether the auto-LIMIT cap kicked in (and whether they should\r\n * paginate / refine) without having to count rows.\r\n */\r\nfunction formatDbQueryFooter(\r\n output: string,\r\n appliedLimit: boolean,\r\n maxRows: number,\r\n explainMode: boolean,\r\n): string {\r\n if (explainMode) {\r\n return '\\n\\n[explain] Plan returned, no rows executed.';\r\n }\r\n if (!appliedLimit) return '';\r\n\r\n // Prefer the trailing \"(N row(s))\" summary that psql/mysql/sqlcmd all emit;\r\n // falls back to counting non-decorative lines minus a presumed header row.\r\n // We over-fetched maxRows+1 internally so the printed count can briefly\r\n // equal maxRows+1 when truncation actually occurred.\r\n const rows = parseRowCountFromOutput(output);\r\n if (rows == null) return `\\n\\n[ok] auto-LIMIT ${maxRows} applied (row count not detected).`;\r\n if (rows > maxRows) {\r\n return `\\n\\n[truncated] auto-LIMIT ${maxRows} hit — more rows available. Refine WHERE / ORDER BY or raise maxRows (max 10000).`;\r\n }\r\n return `\\n\\n[ok] returned ${rows} row(s), under auto-LIMIT ${maxRows}.`;\r\n}\r\n\r\n/**\r\n * Best-effort row-count extractor for `db-query` output. Recognises the\r\n * `(N row[s])` summary line that psql / mysql / sqlcmd all print at the end\r\n * of a result set. Returns null if no recognizable summary is found, so the\r\n * caller can fall back to a less specific footer.\r\n */\r\nfunction parseRowCountFromOutput(output: string): number | null {\r\n // Walk lines bottom-up; the summary is typically the last non-empty line.\r\n const lines = output.split('\\n');\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n const l = lines[i]?.trim();\r\n if (!l) continue;\r\n // postgres / mysql tabular: \"(5 rows)\" / \"(1 row)\"\r\n const m1 = /^\\(\\s*(\\d+)\\s+rows?\\s*\\)$/i.exec(l);\r\n if (m1?.[1]) return Number(m1[1]);\r\n // mysql shell: \"5 rows in set (..)\"\r\n const m2 = /^(\\d+)\\s+rows?\\s+in\\s+set\\b/i.exec(l);\r\n if (m2?.[1]) return Number(m2[1]);\r\n // mssql sqlcmd: \"(5 rows affected)\"\r\n const m3 = /^\\(\\s*(\\d+)\\s+rows?\\s+affected\\s*\\)$/i.exec(l);\r\n if (m3?.[1]) return Number(m3[1]);\r\n // Stop if we encounter a data row before any summary\r\n if (/[a-zA-Z0-9]/.test(l) && i < lines.length - 3) return null;\r\n }\r\n return null;\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\ninterface DnsDiffRecord { type: string; name: string; value: string; ttl: number; }\r\n\r\n/**\r\n * Render a human-readable diff of a proposed DNS-zone change for `dryRun`\r\n * mode in dns-create / dns-update / dns-delete. Highlights added vs.\r\n * removed records and warns when the change touches MX / SPF / DKIM / DMARC\r\n * — historically the riskiest mistakes to commit blindly.\r\n */\r\nfunction formatDnsDiff(\r\n domain: string,\r\n before: DnsDiffRecord[],\r\n after: DnsDiffRecord[],\r\n change: { verb: 'create' | 'update' | 'delete'; added?: DnsDiffRecord[]; removed?: DnsDiffRecord[] },\r\n): string {\r\n const fmt = (r: DnsDiffRecord): string =>\r\n `${r.type.padEnd(6)} ${r.name.padEnd(30)} ttl=${String(r.ttl).padEnd(5)} ${r.value}`;\r\n\r\n const lines: string[] = [];\r\n lines.push(`[dryRun] ${change.verb.toUpperCase()} on ${domain} — no changes applied.`);\r\n lines.push(`Records before: ${before.length} → after: ${after.length}`);\r\n\r\n if (change.removed?.length) {\r\n lines.push('', 'REMOVED:');\r\n for (const r of change.removed) lines.push(` - ${fmt(r)}`);\r\n }\r\n if (change.added?.length) {\r\n lines.push('', 'ADDED:');\r\n for (const r of change.added) lines.push(` + ${fmt(r)}`);\r\n }\r\n\r\n const sensitive = [\r\n ...(change.added ?? []),\r\n ...(change.removed ?? []),\r\n ].filter((r) => {\r\n if (r.type === 'MX') return true;\r\n if (r.type === 'TXT') {\r\n const v = r.value.toLowerCase();\r\n return v.includes('v=spf1') || v.includes('v=dmarc1') || v.includes('_domainkey') || r.name.toLowerCase().includes('_domainkey');\r\n }\r\n return false;\r\n });\r\n if (sensitive.length > 0) {\r\n lines.push('', '! WARNING: touches mail-auth records (MX / SPF / DMARC / DKIM). Double-check before re-running without dryRun.');\r\n }\r\n\r\n lines.push('', 'Re-run without `dryRun: true` to apply.');\r\n return lines.join('\\n');\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:\r\n 'List all SSH servers you have access to. Returns id, name, hostname, tags, and os_type per server. ' +\r\n 'Pass `includeStats: true` to also probe each server in parallel for container count, disk-free, and uptime ' +\r\n '(skips unreachable hosts gracefully). Cached for 60s — pass `noCache: true` to force a refresh. ' +\r\n 'Adds an \"auto-context\" footer with one-line tags inferred from server name/tags so the LLM knows which host runs Trigger / Supabase / proxy / etc. (disable with `context: false`).',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n includeStats: { type: 'boolean', description: 'When true, probe each server (in parallel, with timeout) for container count, disk-free, and uptime.' },\r\n statsParallelism: { type: 'number', description: 'Max parallel probes when includeStats is true (default 8, cap 20).' },\r\n statsTimeoutMs: { type: 'number', description: 'Per-server probe timeout in ms when includeStats is true (default 6000, range 1000-30000).' },\r\n context: { type: 'boolean', description: 'Include auto-context footer with name/tag-based hints (default true). Pass false to suppress.' },\r\n noCache: { type: 'boolean', description: 'Bypass the 60s in-memory cache.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'ssh-execute',\r\n description:\r\n 'Execute one or more commands on a remote server via SSH. OS-aware: bash on linux, `powershell -EncodedCommand` (UTF-16LE base64) on windows, so $, #, quotes, spaces inside `args` are never re-interpreted by a shell. Some dangerous commands are blocked. Use `list-servers` first to see each server\\'s os_type.\\n\\n' +\r\n 'Three modes (compose them in one call):\\n' +\r\n '- Single: `command` (+ optional `args[]`). Quick or safe.\\n' +\r\n '- Pipeline: `pipeline: [\"cmd1\",\"cmd2\",\"cmd3\"]` runs all commands sequentially in one SSH session and returns segmented per-command output (each with its own exit code). Default continues on error; pass `pipelineStopOnError: true` to abort.\\n' +\r\n '- Repeat: `repeat: N, intervalSeconds: S, output: \"all\"|\"diff\"|\"last\"`. Diff mode shows only added/removed lines vs. the previous run — perfect for \"watch this metric for 5 min\".\\n\\n' +\r\n '`stdin` pipes data into the remote process (queries, scripts, secrets) without putting it on the command line. `cwd` sets the working directory (auto `cd` on Linux / `Set-Location` on Windows).\\n\\n' +\r\n 'Idle timeout: defaults to 120s — if the remote produces no stdout/stderr for that long the call returns with a clear timeout message. Pass `idleTimeoutSeconds: 0` to disable, or e.g. `300` for slow workloads.\\n\\n' +\r\n 'Fan-out: pass `serverIds: [id1, id2, ...]` (instead of `serverId`) to run across multiple servers in parallel.\\n\\n' +\r\n 'Auto-features: outputs >8 KB are auto-truncated with a continuation hint; transient SSH failures (ECONNRESET/ETIMEDOUT/etc) get one automatic retry. Set `format: \"ndjson\"` to parse common Linux outputs (df / free / ps aux / ss / lsblk) into newline-delimited JSON instead of whitespace-padded text.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of one SSH server. Mutually exclusive with serverIds.' },\r\n serverIds: { type: 'array', items: { type: 'string' }, description: 'Fan-out: list of server UUIDs to run the command on in parallel. Mutually exclusive with serverId.' },\r\n command: { type: 'string', description: 'Program/command to run (e.g. \"mysql\", \"Get-Service\", \"df\"). Required unless `pipeline[]` is set.' },\r\n args: { type: 'array', items: { type: 'string' }, description: 'Optional argv list. When provided, each entry is safely quoted/encoded for the target OS.' },\r\n pipeline: { type: 'array', items: { type: 'string' }, description: 'Run multiple shell commands sequentially in ONE SSH session, with per-command exit codes and segmented output. Saves N round-trips for setup→test→cleanup workflows.' },\r\n pipelineStopOnError: { type: 'boolean', description: 'When pipeline is set, abort the chain on the first non-zero exit (default false: keep going so all outputs reach the LLM).' },\r\n repeat: { type: 'number', description: 'Re-run the command/pipeline N times (default 1, max 60). Combine with intervalSeconds + output to \"watch\" a metric.' },\r\n intervalSeconds: { type: 'number', description: 'When repeat>1, seconds to wait between iterations (default 0, max 600).' },\r\n output: { type: 'string', enum: ['all', 'diff', 'last'], description: 'When repeat>1: how to render iterations. `all` = full output per run; `diff` = only added/removed lines vs. previous run; `last` = only the final iteration.' },\r\n format: { type: 'string', enum: ['text', 'ndjson'], description: 'Output format. `ndjson` parses common Linux outputs (df, free, ps aux, ss, lsblk) into newline-delimited JSON.' },\r\n stdin: { type: 'string', description: 'Optional data piped to the remote process stdin.' },\r\n cwd: { type: 'string', description: 'Working directory on the remote (cd <cwd> on Linux, Set-Location on Windows).' },\r\n shell: { type: 'string', enum: ['auto', 'bash', 'powershell'], description: 'Override shell selection (default \"auto\" uses the server\\'s os_type).' },\r\n parallelism: { type: 'number', description: 'Max concurrent SSH sessions when using serverIds[] (default 5, max 20).' },\r\n timeout: { type: 'number', description: 'Wall timeout in milliseconds (default: 60000). Usually idleTimeoutSeconds is what you want instead.' },\r\n idleTimeoutSeconds: { type: 'number', description: 'Abort if no output for N seconds (default 120). Pass 0 to disable. Useful when the wall budget is hard to predict but silence usually means \"stuck\".' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'sftp-list',\r\n description:\r\n 'List files in remote storage. Two backends (provide exactly one of `serverId` or `bucket`):\\n' +\r\n '- `serverId`: list a directory on an SSH server via SFTP. Supports recursive traversal, depth cap, and glob filtering (no need for `ssh-execute \"find ...\"`).\\n' +\r\n '- `bucket`: list objects in a Cloudflare R2 bucket. `path` becomes the key prefix. Default folder mode groups by `/` delimiter; pass `recursive: true` for a flat listing of all keys under the prefix. Requires R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY env vars on the MCP.\\n\\n' +\r\n 'Sorting/summary applies to both backends: `sortBy` (name|size|mtime) + `reverse`. `summary: true` returns just totals (file count, dir count, total bytes) — useful as a cheap pre-flight before pulling a full listing.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'Directory path (SSH) or key prefix (R2). Default: /' },\r\n recursive: { type: 'boolean', description: 'Walk into subdirectories / list all keys flat (default false)' },\r\n maxDepth: { type: 'number', description: 'Maximum recursion depth for SSH mode (1-20, default 5). Ignored for R2.' },\r\n pattern: { type: 'string', description: 'Glob pattern to filter basenames (e.g. \"*.conf\", \"wp-*.php\").' },\r\n maxResults: { type: 'number', description: 'Cap total entries returned (default 5000, max 50000)' },\r\n sortBy: { type: 'string', enum: ['name', 'size', 'mtime'], description: 'Sort order (default `name`). Directories always come first within each ordering.' },\r\n reverse: { type: 'boolean', description: 'Reverse sort direction (e.g. largest-first or newest-first).' },\r\n summary: { type: 'boolean', description: 'Return only totals (file count, directory count, total bytes) instead of the full listing.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'sftp-read',\r\n description:\r\n 'Read a text file from remote storage (max 1 MiB). Two backends (provide exactly one of `serverId` or `bucket`):\\n' +\r\n '- `serverId`: read from an SSH server via SFTP.\\n' +\r\n '- `bucket`: read an object from a Cloudflare R2 bucket. `path` is the object key.\\n\\n' +\r\n 'Use `offset` and/or `length` for ranged reads — perfect for sampling a slice of a multi-MB log/dump without exceeding the 1 MiB inline limit. Ranged reads include a `# range: bytes A-B of TOTAL` header so you know what window you got.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'File path (SSH) or object key (R2)' },\r\n offset: { type: 'number', description: 'Byte offset to start reading from (0-indexed). Triggers ranged read mode.' },\r\n length: { type: 'number', description: 'Number of bytes to read (capped at 1 MiB). Defaults to remaining-from-offset when omitted.' },\r\n },\r\n required: ['path'],\r\n },\r\n },\r\n {\r\n name: 'sftp-write',\r\n description:\r\n 'Write OR copy a file in remote storage. Two target backends (`serverId` or `bucket`) and three source modes:\\n\\n' +\r\n 'Sources:\\n' +\r\n '- `content` (string): inline UTF-8 text (≈1 MB max).\\n' +\r\n '- `sourcePath` (absolute local path): streams a local file. SSH uses ssh2 fastPut; R2 uses streamed PUT (or automatic multipart for >4.5 GB). Handles GB-scale.\\n' +\r\n '- `sourceRemote: { serverId|bucket, path }`: COPY mode — pulls from one remote and writes to another in a single operation, no local detour. Supports all four directions: ssh↔ssh, ssh↔r2, r2↔ssh, r2↔r2 (R2↔R2 uses server-side CopyObject = zero data egress).\\n\\n' +\r\n 'Targets:\\n' +\r\n '- `serverId`: SSH server via SFTP. Protected system paths blocked. Optional `mode` (POSIX bits e.g. 0o755) and `mtime` (modification time) — SSH only.\\n' +\r\n '- `bucket`: Cloudflare R2 bucket. `mode`/`mtime` are ignored on R2.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'TARGET: UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'TARGET: Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'TARGET path (SSH file path or R2 object key)' },\r\n content: { type: 'string', description: 'Source: inline UTF-8 file content (mutually exclusive with sourcePath / sourceRemote)' },\r\n sourcePath: { type: 'string', description: 'Source: absolute local file path (mutually exclusive with content / sourceRemote). Use for >1 MB or binary.' },\r\n sourceRemote: { type: 'object', description: 'Source: copy from another remote. Shape: { serverId?: string, bucket?: string, path: string }. Picks the streaming strategy (ssh→ssh, r2→ssh, ssh→r2, r2→r2 server-side).', properties: { serverId: { type: 'string' }, bucket: { type: 'string' }, path: { type: 'string' } } },\r\n mode: { oneOf: [{ type: 'number' }, { type: 'string' }], description: 'POSIX file permission bits (SSH target only). Number (0o755 / 493) or octal string (\"755\" / \"0o755\"). Default 0o644.' },\r\n mtime: { oneOf: [{ type: 'number' }, { type: 'string' }], description: 'File modification time (SSH target only). ms-since-epoch number or ISO-8601 date string.' },\r\n },\r\n required: ['path'],\r\n },\r\n },\r\n {\r\n name: 'sftp-delete',\r\n description:\r\n 'Delete a file (or directory tree) from remote storage. Two backends (provide exactly one of `serverId` or `bucket`):\\n' +\r\n '- `serverId`: delete a file or empty directory on an SSH server via SFTP. Protected system paths blocked. With `recursive: true` walks the tree depth-first via SFTP and removes files + empty dirs from the bottom up (works on Windows OpenSSH too — no shell tricks).\\n' +\r\n '- `bucket`: delete an object from a Cloudflare R2 bucket. `path` is the object key. With `recursive: true`, treats `path` as a key prefix and batch-deletes every object beneath it.\\n\\n' +\r\n 'Safety nets:\\n' +\r\n '- `dryRun: true` → returns \"Would delete N items (size)\" with a sample preview, no actual deletion.\\n' +\r\n '- `confirmAbove: N` + `confirmCount: <exact>` → refuses recursive deletes touching more than N items unless the caller passes `confirmCount` matching the actual count.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'File path / object key (or directory / key prefix when recursive)' },\r\n recursive: { type: 'boolean', description: 'Recursively remove a directory tree (SSH) or all objects under a key prefix (R2).' },\r\n dryRun: { type: 'boolean', description: 'Preview-only mode: returns what would be deleted (count, total size, sample paths) without touching anything.' },\r\n confirmAbove: { type: 'number', description: 'Refuse recursive deletes that touch more than N items unless `confirmCount` matches the actual count.' },\r\n confirmCount: { type: 'number', description: 'When confirmAbove gates a delete, pass the exact item count from the dry-run output to confirm intent.' },\r\n },\r\n required: ['path'],\r\n },\r\n },\r\n {\r\n name: 'docker-list',\r\n description:\r\n 'List Docker containers on one or more remote servers. Sorted by compose project then name, with a HEALTH column (healthy / unhealthy / starting / no-check). Filter by `nameFilter` (string OR array of substring/glob entries — passes if ANY entry matches), restrict to compose containers with `composeOnly`, or group output per project with `groupByProject`.\\n\\n' +\r\n 'Fan-out: pass `serverIds: [...]` (instead of `serverId`) to query multiple servers in parallel — perfect for \"show all unhealthy containers across the fleet\". Per-server sections are clearly headed.\\n\\n' +\r\n 'Cached for 30s — pass `noCache: true` to bypass.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of one SSH server. Mutually exclusive with serverIds.' },\r\n serverIds: { type: 'array', items: { type: 'string' }, description: 'Fan-out: list of server UUIDs to query in parallel. Mutually exclusive with serverId.' },\r\n format: { type: 'string', enum: ['table', 'json'], description: 'Output format: human table (default) or NDJSON. JSON adds a \"Server\" field per row in fan-out mode.' },\r\n composeOnly: { type: 'boolean', description: 'Only show containers that have a docker-compose project label.' },\r\n nameFilter: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'Filter by container name. Single entry or array; each entry is glob (* or ?) or substring. A row passes when ANY entry matches.' },\r\n groupByProject: { type: 'boolean', description: 'Group output per compose project with a `=== project (count) ===` header (single-server mode only).' },\r\n parallelism: { type: 'number', description: 'Max concurrent SSH sessions when using serverIds[] (default 5, max 20).' },\r\n noCache: { type: 'boolean', description: 'Bypass the 30s in-memory cache.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'docker-logs',\r\n description:\r\n 'Get logs from one or more Docker containers, optionally across multiple servers. `containerName` accepts a string OR array — multi-container output is line-prefixed with `[name]`. Supports time-window (`since`), server-side `grep`, line-count (`tail`), and real-time follow (`followSeconds`). Always merges stderr into stdout. Outputs >8 KB get a continuation hint.\\n\\n' +\r\n 'Fan-out: pass `serverIds: [...]` to tail the same container(s) across multiple servers in one call (e.g. all kong instances). Per-server output is grouped under headers.\\n\\n' +\r\n 'Fuzzy hint: if a container name typo is detected, the error includes \"Did you mean: ...\" suggestions from the docker-list cache.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of one SSH server. Mutually exclusive with serverIds.' },\r\n serverIds: { type: 'array', items: { type: 'string' }, description: 'Fan-out: list of server UUIDs to tail in parallel. Mutually exclusive with serverId.' },\r\n containerName: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'Single container name/ID or an array for multi-container tail. Multi mode prefixes each line with [name].' },\r\n tail: { type: 'number', description: 'Number of recent log lines per container (default 100, default 0 in follow mode).' },\r\n lines: { type: 'number', description: 'Deprecated alias for `tail`. Prefer `tail`.' },\r\n since: { type: 'string', description: 'Time window, e.g. \"10m\", \"2h\", \"24h\", or an absolute \"2026-05-09T10:00:00\".' },\r\n grep: { type: 'string', description: 'Case-insensitive regex/literal filter applied server-side (saves tokens for noisy containers).' },\r\n followSeconds: { type: 'number', description: 'When >0, stream new log lines for N seconds via `docker logs -f`, then exit (max 300). Multi-container follow runs all streams in parallel.' },\r\n parallelism: { type: 'number', description: 'Max concurrent SSH sessions when using serverIds[] (default 5, max 20).' },\r\n },\r\n required: ['containerName'],\r\n },\r\n },\r\n {\r\n name: 'docker-exec',\r\n description:\r\n 'Run a command inside a running Docker container. `args[]` are quoted safely (no shell-escape hell with $ or quotes). Optional `stdin` pipes data into the container process (for SQL, scripts, etc.). Pass `interactive: true` to allocate a TTY (`docker exec -it`) so commands like `psql`/`mysql`/`bash` produce human-friendly output. Use this instead of `ssh-execute \"docker exec ...\"`.',\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 container: { type: 'string', description: 'Container name or ID' },\r\n command: { type: 'string', description: 'Program to run inside the container (e.g. \"psql\", \"wp\", \"node\").' },\r\n args: { type: 'array', items: { type: 'string' }, description: 'Argument list, each safely quoted.' },\r\n stdin: { type: 'string', description: 'Optional data piped to the container process stdin.' },\r\n interactive: { type: 'boolean', description: 'Allocate a TTY (`docker exec -it`). Useful for tools that probe isatty(stdout) — collapses stderr into stdout when enabled.' },\r\n workdir: { type: 'string', description: 'Working directory inside the container (-w).' },\r\n user: { type: 'string', description: 'User to run as inside the container (-u).' },\r\n timeout: { type: 'number', description: 'Timeout in milliseconds (default: 60000)' },\r\n },\r\n required: ['serverId', 'container', 'command'],\r\n },\r\n },\r\n {\r\n name: 'docker-compose',\r\n description:\r\n 'Run a docker-compose action against a project on a remote server. Replaces the common `ssh-execute \"cd /opt/x && docker compose ...\"` pattern. Action enum keeps the surface tiny.',\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 projectPath: { type: 'string', description: 'Absolute path to the directory containing docker-compose.yml.' },\r\n action: { type: 'string', enum: ['up', 'down', 'restart', 'logs', 'ps', 'pull', 'build'], description: 'Compose action.' },\r\n service: { type: 'string', description: 'Optional service name to scope the action to (e.g. \"studio\"). Omit to act on the whole project.' },\r\n tail: { type: 'number', description: 'For `logs`: number of lines (default 200).' },\r\n timeout: { type: 'number', description: 'Timeout in milliseconds (default: 120000 — compose ops can be slow).' },\r\n },\r\n required: ['serverId', 'projectPath', 'action'],\r\n },\r\n },\r\n {\r\n name: 'wait-for',\r\n description:\r\n 'Poll until a condition holds (or timeout). Replaces 30+ ad-hoc loops the LLM would otherwise build itself. Four condition types:\\n' +\r\n '- `url`: `target: \"https://...\"`, `until: 200` (HTTP status, default 200). 10s per probe.\\n' +\r\n '- `container-health`: `serverId`, `target: \"container-name\"`, `until: \"healthy\" | \"running\" | \"exited\"` (default \"healthy\"). Uses `docker inspect`.\\n' +\r\n '- `file-exists`: `serverId`, `target: \"/path/to/file\"` — SSH stat check.\\n' +\r\n '- `sftp-exists`: same as file-exists but with `bucket: \"name\"` instead of serverId for R2.\\n\\n' +\r\n 'Returns a per-attempt trail so you can see how long it took to converge.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n type: { type: 'string', enum: ['url', 'container-health', 'file-exists', 'sftp-exists'], description: 'Condition type to wait on.' },\r\n target: { type: 'string', description: 'Target identifier: URL, container name, file path, or R2 key (depends on type).' },\r\n until: { description: 'Expected end-state (depends on type): for url an HTTP status (default 200), for container-health a state string (default \"healthy\"). Omit for file-exists/sftp-exists.' },\r\n serverId: { type: 'string', description: 'SSH server UUID (required for container-health and file-exists).' },\r\n bucket: { type: 'string', description: 'R2 bucket name (used with sftp-exists when checking an R2 object).' },\r\n path: { type: 'string', description: 'Alias for `target` for file-exists/sftp-exists.' },\r\n intervalSeconds: { type: 'number', description: 'Poll interval in seconds (default 3, max 60).' },\r\n timeout: { type: 'number', description: 'Total deadline in seconds (default 120, max 1800).' },\r\n },\r\n required: ['type', 'target'],\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-query',\r\n description:\r\n 'Execute a SQL query against any database. Two routing modes:\\n' +\r\n '- MySQL via `/var/www` autodiscover (default): pass `sitePath` (and `engine: \"mysql\"` implicitly). Credentials are read from wp-config.php, parameters.php, .env. Same behaviour as before.\\n' +\r\n '- Direct via Docker container: pass `containerName` (the container running the DB server). Engine defaults to `postgres`; pass `engine: \"mysql\"` or `\"mssql\"` to override. The query is piped via stdin so quotes / `$` / `;` are never re-interpreted.\\n\\n' +\r\n 'Postgres example: `{ serverId, containerName: \"supabase-db\", engine: \"postgres\", dbName: \"main\", dbUser: \"postgres\", query: \"SELECT 1\" }`. Defaults: dbUser=postgres, dbName=postgres.\\n' +\r\n 'MSSQL example: `{ serverId, containerName: \"mssql-1\", engine: \"mssql\", dbUser: \"sa\", dbPass: \"...\", query: \"SELECT 1\" }`.\\n\\n' +\r\n 'Result safety: `maxRows` (default 1000, max 10000) auto-injects a `LIMIT` for SELECT queries that don\\'t have one, so unbounded scans never blow up the token budget. The footer reports whether the cap was applied. Pass `maxRows: 0` to disable.\\n\\n' +\r\n 'Diagnostics: `explain: true` prepends EXPLAIN (postgres / mysql) or runs `SET SHOWPLAN_TEXT ON` (mssql) so you can inspect the query plan without rewriting the query.\\n\\n' +\r\n 'Schema introspection: pass `describe: \"tablename\"` to get columns + indexes (replaces the old db-describe tool, works for mysql, postgres, and mssql). Pass `describe: \"*\"` to list all tables in the current database. When `describe` is set, `query` is ignored.\\n\\n' +\r\n 'Destructive operations (DROP, TRUNCATE, etc.) 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 query: { type: 'string', description: 'SQL query to execute (ignored when describe is set)' },\r\n describe: { type: 'string', description: 'Schema introspection shortcut. Pass a table name for columns + indexes, or \"*\" to list all tables. Works for mysql / postgres / mssql.' },\r\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com). Used only with engine=mysql autodiscover.' },\r\n containerName: { type: 'string', description: 'Docker container running the DB server (e.g. \"supabase-db\", \"trigger-postgres\"). Activates direct-query mode.' },\r\n engine: { type: 'string', enum: ['mysql', 'postgres', 'mssql'], description: 'DB engine. Defaults to \"mysql\" with sitePath, \"postgres\" with containerName.' },\r\n dbName: { type: 'string', description: 'Database name (containerName mode). Defaults: postgres → \"postgres\", mysql → server default, mssql → server default.' },\r\n dbUser: { type: 'string', description: 'Database user (containerName mode). Defaults: postgres → \"postgres\", mysql → \"root\", mssql → \"sa\".' },\r\n dbPass: { type: 'string', description: 'Database password (containerName mode). Required for mssql; optional for mysql; postgres uses trust auth by default.' },\r\n maxRows: { type: 'number', description: 'Auto-inject LIMIT for unbounded SELECTs. Default 1000, max 10000, set 0 to disable.' },\r\n explain: { type: 'boolean', description: 'Prepend EXPLAIN (postgres/mysql) or SHOWPLAN (mssql) instead of executing. Useful for slow-query diagnosis.' },\r\n },\r\n required: ['serverId'],\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', enum: ['production', 'staging', 'development', 'local'], description: 'Environment name' },\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', enum: ['production', 'staging', 'development', 'local'], description: 'Environment name' },\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:\r\n 'List all domains from the mijn.host account. Returns domain name, status, renewal date (= expiration), and tags. Requires MIJNHOST_API_KEY.\\n\\n' +\r\n 'Pass `details: true` to also fetch DNS zone summary per domain in parallel: MX target(s) and presence of SPF/DMARC TXT records. Useful as a single-call overview instead of N follow-up dns-list calls. Skipped for inactive/expired domains.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n details: { type: 'boolean', description: 'Inline DNS zone summary (NS, MX, SPF/DMARC presence) per domain. Adds N parallel API calls — use sparingly on large accounts.' },\r\n concurrency: { type: 'number', description: 'Max concurrent DNS lookups when details=true (default 8, max 20).' },\r\n },\r\n required: [],\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-record',\r\n description:\r\n 'Mutate a single DNS record on a mijn.host domain. Pick the mutation with `action`:\\n' +\r\n '- \"create\": add a new record. Required: type, name, value. Optional: ttl (default 3600).\\n' +\r\n '- \"update\": replace an existing record. Required: type, name, oldValue, newValue. Optional: ttl.\\n' +\r\n '- \"delete\": remove a record. Required: type, name, value.\\n\\n' +\r\n 'Always pass `dryRun: true` first when touching MX / SPF / DKIM / DMARC — returns a full before/after diff with a mail-auth warning and applies nothing. Re-run without dryRun once the diff looks correct.\\n\\n' +\r\n 'Use `dns-list` to inspect the current zone first if you need to identify the right `oldValue`. Requires MIJNHOST_API_KEY.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: { type: 'string', enum: ['create', 'update', 'delete'], description: 'Which mutation to perform.' },\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. Required for create + delete. Use newValue for update.' },\r\n oldValue: { type: 'string', description: 'Current value of the record (update only) — used to identify which record to replace.' },\r\n newValue: { type: 'string', description: 'New value for the record (update only).' },\r\n ttl: { type: 'number', description: 'TTL in seconds (min 60). Default 3600 for create; defaults to existing TTL for update.' },\r\n dryRun: { type: 'boolean', description: 'Preview the change (returns proposed diff) without applying. Recommended for MX/SPF/DKIM/DMARC.' },\r\n },\r\n required: ['action', 'domain', 'type', 'name'],\r\n },\r\n },\r\n // ----- Trigger.dev -----\r\n ...TRIGGER_TOOLS,\r\n // ----- Vercel -----\r\n ...VERCEL_TOOLS,\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// MCP Server\r\n// ---------------------------------------------------------------------------\r\n\r\nconst MCP_VERSION = '6.0.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 const startTime = Date.now();\r\n const serverId = (a.serverId || a.server_id) as string | undefined;\r\n const serverIds = a.serverIds;\r\n\r\n // Cache lookup. Hit returns immediately with the same payload (we still\r\n // re-postprocess so the footer reflects the original-but-cached cost).\r\n const cached = getCachedTool(name, a);\r\n let cameFromCache = false;\r\n let result: { content: { type: string; text: string }[] };\r\n if (cached) {\r\n result = cached;\r\n cameFromCache = true;\r\n } else {\r\n result = await executeToolCall(name, a, serverId);\r\n }\r\n\r\n const durationMs = Date.now() - startTime;\r\n const isError = result.content?.[0]?.text?.startsWith('Error:');\r\n\r\n // Cache successful results only — never an Error: payload.\r\n if (!cameFromCache && !isError) {\r\n setCachedTool(name, a, result);\r\n }\r\n\r\n void writeAuditLog({\r\n toolName: name,\r\n arguments: a,\r\n serverId,\r\n resultStatus: isError ? 'error' : 'success',\r\n errorMessage: isError ? result.content?.[0]?.text : undefined,\r\n durationMs,\r\n });\r\n\r\n // Universal post-processing: truncate huge outputs + append cost footer.\r\n // Run *after* audit so the footer doesn't leak into log fields.\r\n const serverIdLabel = await resolveServerLabel(serverId, serverIds);\r\n return postprocessResult(result, {\r\n startedAtMs: startTime,\r\n serverIdLabel,\r\n toolName: name,\r\n args: a,\r\n cached: cameFromCache,\r\n });\r\n}\r\n\r\nasync function executeToolCall(\r\n name: string,\r\n a: Record<string, unknown>,\r\n _serverId: string | undefined,\r\n): Promise<{ content: { type: string; text: string }[] }> {\r\n const ctx = authContext!;\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, os_type, created_at')\r\n .order('name');\r\n\r\n if (ctx.allowedServerIds !== null) {\r\n query = query.in('id', ctx.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 includeStats = a.includeStats === true;\r\n const servers = data || [];\r\n\r\n // Populate the running cache so fuzzy \"did you mean?\" hints work and\r\n // so the response footer can show server names without re-querying.\r\n rememberServers(servers.map(s => ({ id: s.id, name: s.name })));\r\n\r\n // Stats are opt-in because they require an SSH round-trip per server.\r\n // We probe in parallel with a short per-server timeout so a single\r\n // unreachable host can't stall the listing.\r\n type Stats = { containers?: number; diskFreeHuman?: string; uptimeHuman?: string; reachable: boolean; error?: string };\r\n let statsByServer: Map<string, Stats> = new Map();\r\n if (includeStats && servers.length > 0) {\r\n const parallelism = Math.max(1, Math.min(20, Number(a.statsParallelism) || 8));\r\n const probeTimeoutMs = Math.max(1000, Math.min(30_000, Number(a.statsTimeoutMs) || 6000));\r\n\r\n // Combined one-shot probe per server. Three pipe-delimited values:\r\n // <containerCount>|<diskFreeHuman>|<uptimeHuman>\r\n // Missing tools are tolerated (returns 0/N/A).\r\n const linuxProbe =\r\n \"echo \\\"$(docker ps -q 2>/dev/null | wc -l)|$(df -h / 2>/dev/null | awk 'NR==2{print $4}')|$(uptime -p 2>/dev/null || uptime)\\\"\";\r\n const windowsProbe = [\r\n \"$ProgressPreference='SilentlyContinue';\",\r\n \"$c = (docker ps -q 2>$null | Measure-Object).Count;\",\r\n \"$d = try { '{0:N1} GB' -f ((Get-PSDrive C).Free/1GB) } catch { 'N/A' };\",\r\n \"$u = try { (Get-Uptime).ToString() } catch { ((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime).ToString() };\",\r\n \"Write-Output \\\"$c|$d|$u\\\"\",\r\n ].join(' ');\r\n\r\n const probeOne = async (s: typeof servers[number]): Promise<[string, Stats]> => {\r\n try {\r\n const { conn, proxy, os } = await getServerConnection(s.id);\r\n conn.timeout = probeTimeoutMs;\r\n const wrapped = os === 'windows'\r\n ? buildPowerShellEncodedCommand(windowsProbe, [])\r\n : `bash -c ${posixQuote(linuxProbe)}`;\r\n const result = await sshExec(conn, wrapped, proxy);\r\n if (result.exitCode !== 0) {\r\n return [s.id, { reachable: false, error: (result.stderr || result.stdout || 'probe failed').trim().slice(0, 120) }];\r\n }\r\n const parts = result.stdout.trim().split('|');\r\n return [s.id, {\r\n reachable: true,\r\n containers: Number(parts[0]) || 0,\r\n diskFreeHuman: (parts[1] || '').trim() || 'N/A',\r\n uptimeHuman: (parts[2] || '').trim() || 'N/A',\r\n }];\r\n } catch (err) {\r\n return [s.id, { reachable: false, error: err instanceof Error ? err.message.slice(0, 120) : String(err).slice(0, 120) }];\r\n }\r\n };\r\n\r\n // Bounded parallelism so we don't open 50 SSH sessions at once.\r\n const results: Array<[string, Stats]> = [];\r\n for (let i = 0; i < servers.length; i += parallelism) {\r\n const batch = servers.slice(i, i + parallelism);\r\n const chunk = await Promise.all(batch.map(probeOne));\r\n results.push(...chunk);\r\n }\r\n statsByServer = new Map(results);\r\n }\r\n\r\n const lines = servers.map(s => {\r\n const tags = Array.isArray(s.tags) ? (s.tags as string[]).join(', ') : '';\r\n const os = (s as Record<string, unknown>).os_type || 'linux';\r\n const base = `${s.id} ${s.name} ${s.hostname}:${s.port} ${s.username} [${tags}] ${s.hosted_by || ''} os:${os}`;\r\n if (!includeStats) return base;\r\n const st = statsByServer.get(s.id);\r\n if (!st) return `${base} stats:skipped`;\r\n if (!st.reachable) return `${base} UNREACHABLE (${st.error || 'unknown'})`;\r\n return `${base} containers:${st.containers} disk_free:${st.diskFreeHuman} uptime:${st.uptimeHuman}`;\r\n });\r\n\r\n // Auto-context: short hints about well-known servers, derived from\r\n // tags + hostnames so the LLM knows e.g. which host runs Trigger.\r\n const contextHints = a.context !== false ? buildServerContextHints(servers as Array<{ name: string; hostname: string; tags?: string[] | null }>) : [];\r\n const out = lines.length ? lines.join('\\n') : 'No servers found';\r\n return { content: [{ type: 'text', text: contextHints.length ? `${out}\\n\\n--- context ---\\n${contextHints.join('\\n')}` : out }] };\r\n }\r\n\r\n // ----- SSH -----\r\n case 'ssh-execute': {\r\n // Parse modes: pipeline (multi-cmd one session), repeat (loop), format (parser).\r\n const pipeline: string[] = Array.isArray(a.pipeline)\r\n ? (a.pipeline as unknown[]).map(String).filter(Boolean)\r\n : [];\r\n const command = pipeline.length > 0 ? '' : String(a.command || '');\r\n if (!command && pipeline.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `command` or `pipeline[]`' }] };\r\n }\r\n if (command) assertSafeCommand(command);\r\n for (const c of pipeline) assertSafeCommand(c);\r\n\r\n const args = Array.isArray(a.args) ? (a.args as unknown[]).map(String) : undefined;\r\n const stdin = typeof a.stdin === 'string' ? a.stdin : undefined;\r\n const shellOverride = typeof a.shell === 'string' ? (a.shell as 'auto' | 'bash' | 'powershell') : 'auto';\r\n const cwd = typeof a.cwd === 'string' && a.cwd ? a.cwd : undefined;\r\n const timeoutMs = a.timeout ? Number(a.timeout) : undefined;\r\n // Idle timeout default 120s — covers 99% of \"is this hung?\" cases\r\n // without forcing the LLM to think about wall budgets. Pass 0 to disable.\r\n const rawIdle = a.idleTimeoutSeconds !== undefined ? Number(a.idleTimeoutSeconds) : 120;\r\n const idleTimeoutMs = Number.isFinite(rawIdle) && rawIdle > 0 ? rawIdle * 1000 : undefined;\r\n // Repeat / diff / format are post-processing modes layered on top of\r\n // the single-shot or pipeline run. Repeat returns combined timing data.\r\n const repeat = Math.max(1, Math.min(60, Number(a.repeat) || 1));\r\n const intervalSeconds = Math.max(0, Math.min(600, Number(a.intervalSeconds) || 0));\r\n const repeatOutput = a.output === 'diff' || a.output === 'last' ? a.output : 'all';\r\n const format = a.format === 'ndjson' ? 'ndjson' : 'text';\r\n // Pipeline error policy: stop-on-first-fail vs continue (default continue\r\n // so all outputs reach the LLM in one round-trip).\r\n const pipelineStopOnError = a.pipelineStopOnError === true;\r\n\r\n // Resolve target list. `serverIds` (array) wins over `serverId` (single).\r\n // Both forms are supported so the existing `serverId` API stays intact.\r\n const targetIds: string[] = Array.isArray(a.serverIds) && a.serverIds.length > 0\r\n ? (a.serverIds as unknown[]).map(String)\r\n : a.serverId ? [String(a.serverId)] : [];\r\n if (targetIds.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `serverId` or `serverIds[]`' }] };\r\n }\r\n\r\n const parallelism = Math.max(1, Math.min(20, Number(a.parallelism) || 5));\r\n\r\n // Per-server runner. Resolves connection, builds OS-aware command, runs.\r\n // Returns the final SshResult; pipeline parsing happens after the call.\r\n const runOne = async (serverId: string): Promise<{ serverId: string; serverName: string; os: ServerOs; shell: 'bash' | 'powershell'; result: SshResult; pipelineSegments?: PipelineSegment[]; iterations?: IterationResult[] }> => {\r\n const { conn, proxy, os } = await getServerConnection(serverId);\r\n if (timeoutMs) conn.timeout = timeoutMs;\r\n const shell = shellOverride === 'auto' ? (os === 'windows' ? 'powershell' : 'bash') : shellOverride;\r\n\r\n // Build the body (single command OR pipeline wrapper). Pipeline mode\r\n // overrides any args/cwd-on-command behavior — cwd applies to the\r\n // whole script wrapper instead.\r\n let body: string;\r\n let pipelineMarker: string | null = null;\r\n if (pipeline.length > 0) {\r\n pipelineMarker = `__MCP_BREAK_${randomBytes(8).toString('hex')}__`;\r\n body = buildPipelineScript(pipeline, shell, pipelineMarker, pipelineStopOnError);\r\n } else if (args && args.length > 0) {\r\n body = shell === 'powershell'\r\n ? buildPowerShellEncodedCommand(command, args)\r\n : buildPosixCommand(command, args);\r\n } else if (shell === 'powershell' && !/^powershell\\b/i.test(command.trim())) {\r\n // For Windows raw strings, still wrap so $/quotes don't get reinterpreted.\r\n body = buildPowerShellEncodedCommand(command, []);\r\n } else {\r\n body = command;\r\n }\r\n\r\n // Apply cwd. For PowerShell with EncodedCommand, we can't simply\r\n // prepend `cd ... && ...` because `body` is already a full\r\n // `powershell -EncodedCommand <b64>` invocation. Instead we re-encode\r\n // a wrapper script that does `Set-Location` then runs the original.\r\n const applyCwd = (rawBody: string): string => {\r\n if (!cwd) return rawBody;\r\n if (shell === 'bash') return `cd ${posixQuote(cwd)} && ${rawBody}`;\r\n const ecMatch = rawBody.match(/-EncodedCommand\\s+(\\S+)$/);\r\n if (!ecMatch) return rawBody;\r\n const decoded = Buffer.from(ecMatch[1] as string, 'base64').toString('utf16le');\r\n const wrapped = `Set-Location -LiteralPath '${cwd.replace(/'/g, \"''\")}'; ${decoded}`;\r\n const reencoded = Buffer.from(wrapped, 'utf16le').toString('base64');\r\n return rawBody.replace(/-EncodedCommand\\s+\\S+$/, `-EncodedCommand ${reencoded}`);\r\n };\r\n const finalCmd = applyCwd(body);\r\n\r\n // Repeat mode: run finalCmd N times with optional sleep between.\r\n // We never sleep server-side; we sleep here so each iteration gets\r\n // its own SSH session and clean idle timer.\r\n if (repeat > 1) {\r\n const iterations: IterationResult[] = [];\r\n for (let i = 0; i < repeat; i++) {\r\n const startedAt = Date.now();\r\n const r = await sshExec(conn, finalCmd, proxy, {\r\n ...(stdin !== undefined ? { stdin } : {}),\r\n idleTimeoutMs,\r\n });\r\n iterations.push({ index: i, startedAt, durationMs: Date.now() - startedAt, result: r });\r\n if (i < repeat - 1 && intervalSeconds > 0) {\r\n await new Promise((res) => setTimeout(res, intervalSeconds * 1000));\r\n }\r\n }\r\n const last = iterations[iterations.length - 1]!.result;\r\n let serverName = serverId;\r\n try {\r\n const { data } = await supabase.from('ssh_server').select('name').eq('id', serverId).maybeSingle();\r\n if (data?.name) serverName = data.name as string;\r\n } catch { /* fall back to id */ }\r\n return { serverId, serverName, os, shell, result: last, iterations };\r\n }\r\n\r\n const result = await sshExec(conn, finalCmd, proxy, {\r\n ...(stdin !== undefined ? { stdin } : {}),\r\n idleTimeoutMs,\r\n });\r\n let pipelineSegments: PipelineSegment[] | undefined;\r\n if (pipelineMarker && pipeline.length > 0) {\r\n pipelineSegments = parsePipelineOutput(result.stdout, pipeline, pipelineMarker);\r\n }\r\n let serverName = serverId;\r\n try {\r\n const { data } = await supabase.from('ssh_server').select('name').eq('id', serverId).maybeSingle();\r\n if (data?.name) serverName = data.name as string;\r\n } catch { /* fall back to id */ }\r\n return { serverId, serverName, os, shell, result, pipelineSegments };\r\n };\r\n\r\n // Render helper for a single per-server result (pipeline/repeat aware).\r\n const renderOne = (r: Awaited<ReturnType<typeof runOne>>): string => {\r\n if (r.iterations && r.iterations.length > 0) {\r\n return renderRepeatResult(r.iterations, repeatOutput, format);\r\n }\r\n if (r.pipelineSegments) {\r\n return renderPipelineSegments(r.pipelineSegments, r.result, format);\r\n }\r\n const output = [`Exit code: ${r.result.exitCode} (os: ${r.os}, shell: ${r.shell})`];\r\n let stdoutText = r.result.stdout;\r\n if (format === 'ndjson' && stdoutText) {\r\n const parsed = tryParseNdjsonFromCommand(command, stdoutText);\r\n if (parsed) stdoutText = parsed;\r\n }\r\n if (stdoutText) output.push(`--- stdout ---\\n${stdoutText}`);\r\n if (r.result.stderr) output.push(`--- stderr ---\\n${r.result.stderr}`);\r\n return output.join('\\n');\r\n };\r\n\r\n // Single-target: keep the original output format unchanged.\r\n if (targetIds.length === 1) {\r\n const r = await runOne(targetIds[0] as string);\r\n return { content: [{ type: 'text', text: renderOne(r) }] };\r\n }\r\n\r\n // Fan-out: bounded parallel execution. We run in batches of `parallelism`.\r\n const allResults: Array<Awaited<ReturnType<typeof runOne>> | { serverId: string; error: string }> = [];\r\n for (let i = 0; i < targetIds.length; i += parallelism) {\r\n const batch = targetIds.slice(i, i + parallelism);\r\n const settled = await Promise.allSettled(batch.map(id => runOne(id)));\r\n for (let j = 0; j < settled.length; j++) {\r\n const s = settled[j]!;\r\n if (s.status === 'fulfilled') allResults.push(s.value);\r\n else allResults.push({ serverId: batch[j] as string, error: s.reason instanceof Error ? s.reason.message : String(s.reason) });\r\n }\r\n }\r\n\r\n // Render per-server sections + a 1-line summary at the bottom.\r\n const sections: string[] = [];\r\n let okCount = 0;\r\n let failCount = 0;\r\n for (const r of allResults) {\r\n if ('error' in r) {\r\n failCount++;\r\n sections.push(`=== ${r.serverId} === !! connection error: ${r.error}`);\r\n continue;\r\n }\r\n if (r.result.exitCode === 0) okCount++; else failCount++;\r\n const header = `=== ${r.serverName} (${r.os}, exit ${r.result.exitCode}) ===`;\r\n sections.push(`${header}\\n${renderOne(r)}`);\r\n }\r\n sections.push(`--- fan-out summary: ${okCount} ok / ${failCount} failed across ${allResults.length} servers (parallelism ${parallelism}) ---`);\r\n return { content: [{ type: 'text', text: sections.join('\\n\\n') }] };\r\n }\r\n\r\n // ----- SFTP -----\r\n case 'sftp-list': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const recursive = a.recursive === true;\r\n const maxResults = Math.max(1, Math.min(50_000, Number(a.maxResults) || 5_000));\r\n const pattern = typeof a.pattern === 'string' ? a.pattern : '';\r\n const summary = a.summary === true;\r\n // Sort key: 'name' (default), 'size', 'mtime'. `reverse: true` flips.\r\n const sortBy = (a.sortBy === 'size' || a.sortBy === 'mtime' || a.sortBy === 'name') ? a.sortBy : 'name';\r\n const reverse = a.reverse === true;\r\n\r\n // Collect into a backend-agnostic shape so sort/reverse/summary apply\r\n // identically to SSH and R2 listings.\r\n let entries: SftpEntry[];\r\n let truncated = false;\r\n let warning = '';\r\n\r\n if (bucket) {\r\n const prefix = r2Key(String(a.path || ''));\r\n const matcher = pattern ? globToRegExp(pattern) : null;\r\n const r2Entries = await r2List(bucket, prefix, { recursive, maxResults });\r\n const filtered = matcher\r\n ? r2Entries.filter(e => matcher.test(e.key.split('/').pop() || e.key))\r\n : r2Entries;\r\n entries = filtered.map(e => {\r\n const ms = e.mtime ? Date.parse(e.mtime) : 0;\r\n return {\r\n kind: e.isPrefix ? 'd' as const : '-' as const,\r\n size: e.size,\r\n mtime: e.mtime,\r\n mtimeMs: Number.isFinite(ms) ? ms : 0,\r\n path: e.key,\r\n };\r\n });\r\n } else {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const result = await sftpReaddir(conn, String(a.path || '/'), proxy, {\r\n recursive,\r\n maxDepth: typeof a.maxDepth === 'number' ? a.maxDepth : undefined,\r\n pattern: pattern || undefined,\r\n maxResults,\r\n });\r\n if (result.error && result.entries.length === 0) {\r\n return { content: [{ type: 'text', text: `Error: ${result.error}` }] };\r\n }\r\n entries = result.entries;\r\n truncated = result.truncated;\r\n if (result.error) warning = result.error;\r\n }\r\n\r\n // Summary mode short-circuits before sorting (we just aggregate).\r\n if (summary) {\r\n const files = entries.filter(e => e.kind === '-');\r\n const dirs = entries.filter(e => e.kind === 'd');\r\n const totalSize = files.reduce((acc, e) => acc + (e.size || 0), 0);\r\n const lines = [\r\n `Files: ${files.length}`,\r\n `Directories: ${dirs.length}`,\r\n `Total size: ${totalSize} bytes (${(totalSize / (1024 * 1024)).toFixed(2)} MB)`,\r\n ];\r\n if (truncated) lines.push(`(truncated at ${maxResults}; counts may be partial)`);\r\n if (warning) lines.push(`(warnings: ${warning})`);\r\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\r\n }\r\n\r\n // Sort. Directories first within the chosen sort, both ascending by\r\n // default; `reverse: true` flips the secondary order. `name` uses\r\n // localeCompare so digits/dots sort naturally.\r\n entries.sort((x, y) => {\r\n if (x.kind !== y.kind) return x.kind === 'd' ? -1 : 1;\r\n let cmp = 0;\r\n if (sortBy === 'size') cmp = x.size - y.size;\r\n else if (sortBy === 'mtime') cmp = x.mtimeMs - y.mtimeMs;\r\n else cmp = x.path.localeCompare(y.path);\r\n return reverse ? -cmp : cmp;\r\n });\r\n\r\n if (entries.length === 0) return { content: [{ type: 'text', text: 'No entries' }] };\r\n const lines = entries.map(e => {\r\n const sizeCol = e.kind === 'd' && bucket ? '(prefix)' : String(e.size);\r\n return `${e.kind} ${sizeCol.padStart(10)} ${(e.mtime || '').padEnd(24)} ${e.path}`;\r\n });\r\n if (truncated) lines.push(`... (truncated at ${maxResults} entries; raise maxResults or narrow path/pattern)`);\r\n if (warning) lines.push(`! ${warning}`);\r\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\r\n }\r\n\r\n case 'sftp-read': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const offset = a.offset !== undefined ? Math.max(0, Number(a.offset)) : undefined;\r\n const length = a.length !== undefined ? Math.max(0, Number(a.length)) : undefined;\r\n const hasRange = offset !== undefined || length !== undefined;\r\n\r\n if (bucket) {\r\n const key = r2Key(String(a.path));\r\n if (!key) return { content: [{ type: 'text', text: 'Error: path is required' }] };\r\n try {\r\n if (hasRange) {\r\n const content = await r2GetObjectRange(bucket, key, { offset: offset ?? 0, length });\r\n return { content: [{ type: 'text', text: content }] };\r\n }\r\n const content = await r2GetObject(bucket, key, 1_048_576);\r\n return { content: [{ type: 'text', text: content }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const content = await sftpRead(conn, String(a.path), proxy, hasRange ? { offset, length } : undefined);\r\n return { content: [{ type: 'text', text: content }] };\r\n }\r\n\r\n case 'sftp-write': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n\r\n // Cross-endpoint copy mode. Activates when `sourceRemote` is set:\r\n // sourceRemote: { serverId|bucket, path }\r\n // target endpoint: top-level { serverId|bucket, path } (the existing\r\n // sftp-write target shape — no schema change for the LLM).\r\n // Supported directions: ssh↔ssh, ssh↔r2, r2↔ssh, r2↔r2 (server-side).\r\n if (a.sourceRemote && typeof a.sourceRemote === 'object') {\r\n const srcRaw = a.sourceRemote as Record<string, unknown>;\r\n const srcBucket = typeof srcRaw.bucket === 'string' && srcRaw.bucket ? String(srcRaw.bucket) : '';\r\n const srcServerId = typeof srcRaw.serverId === 'string' && srcRaw.serverId ? String(srcRaw.serverId) : '';\r\n const srcPath = String(srcRaw.path || '');\r\n if (!srcPath) return { content: [{ type: 'text', text: 'Error: sourceRemote.path is required' }] };\r\n if (!srcBucket && !srcServerId) return { content: [{ type: 'text', text: 'Error: sourceRemote needs `serverId` or `bucket`' }] };\r\n if (srcBucket && srcServerId) return { content: [{ type: 'text', text: 'Error: sourceRemote can have either `serverId` or `bucket`, not both' }] };\r\n\r\n const dstPath = String(a.path || '');\r\n if (!dstPath) return { content: [{ type: 'text', text: 'Error: target `path` is required' }] };\r\n\r\n let srcEp: CopyEndpoint;\r\n if (srcBucket) {\r\n const k = r2Key(srcPath);\r\n if (!k) return { content: [{ type: 'text', text: 'Error: sourceRemote.path resolves to empty key' }] };\r\n srcEp = { kind: 'r2', bucket: srcBucket, key: k };\r\n } else {\r\n const { conn, proxy } = await getServerConnection(srcServerId);\r\n srcEp = { kind: 'ssh', opts: conn, proxy, path: srcPath };\r\n }\r\n\r\n let dstEp: CopyEndpoint;\r\n if (bucket) {\r\n const k = r2Key(dstPath);\r\n if (!k) return { content: [{ type: 'text', text: 'Error: target path resolves to empty key' }] };\r\n dstEp = { kind: 'r2', bucket, key: k };\r\n } else if (a.serverId) {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n dstEp = { kind: 'ssh', opts: conn, proxy, path: dstPath };\r\n } else {\r\n return { content: [{ type: 'text', text: 'Error: target needs `serverId` or `bucket`' }] };\r\n }\r\n\r\n try {\r\n const { bytes, elapsedMs, mode } = await sftpCopy(srcEp, dstEp);\r\n const srcLabel = srcEp.kind === 'r2' ? `r2://${srcEp.bucket}/${srcEp.key}` : `ssh:${srcPath}`;\r\n const dstLabel = dstEp.kind === 'r2' ? `r2://${dstEp.bucket}/${dstEp.key}` : `ssh:${dstPath}`;\r\n const mbps = bytes > 0 && elapsedMs > 0 ? (bytes / (1024 * 1024)) / (elapsedMs / 1000) : 0;\r\n return { content: [{ type: 'text', text: `Copied ${formatBytes(bytes)} from ${srcLabel} → ${dstLabel} via ${mode} in ${(elapsedMs / 1000).toFixed(2)}s${mbps > 0 ? ` (${mbps.toFixed(1)} MB/s)` : ''}` }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n\r\n // Optional file metadata. `mode` accepts a number (0o755) or a string\r\n // (\"755\" or \"0o755\") so the LLM can write either form. mtime accepts\r\n // ms since epoch or an ISO date string.\r\n let fileMode: number | undefined;\r\n if (typeof a.mode === 'number' && Number.isFinite(a.mode)) fileMode = a.mode & 0o7777;\r\n else if (typeof a.mode === 'string' && a.mode) {\r\n const cleaned = a.mode.replace(/^0o?/i, '');\r\n const parsed = parseInt(cleaned, 8);\r\n if (!Number.isNaN(parsed)) fileMode = parsed & 0o7777;\r\n }\r\n let mtimeMs: number | undefined;\r\n if (typeof a.mtime === 'number' && Number.isFinite(a.mtime)) mtimeMs = a.mtime;\r\n else if (typeof a.mtime === 'string' && a.mtime) {\r\n const parsed = Date.parse(a.mtime);\r\n if (!Number.isNaN(parsed)) mtimeMs = parsed;\r\n }\r\n\r\n if (bucket) {\r\n const key = r2Key(String(a.path));\r\n if (!key) return { content: [{ type: 'text', text: 'Error: path is required' }] };\r\n if (fileMode !== undefined || mtimeMs !== undefined) {\r\n // R2 (S3) has no POSIX mode/mtime. Surface this so the user knows\r\n // the params were ignored rather than silently dropping them.\r\n // We continue with the upload anyway.\r\n }\r\n try {\r\n if (typeof a.sourcePath === 'string' && a.sourcePath.length > 0) {\r\n const local = a.sourcePath;\r\n if (!isAbsolute(local)) return { content: [{ type: 'text', text: `Error: sourcePath must be an absolute path: ${local}` }] };\r\n if (!existsSync(local)) return { content: [{ type: 'text', text: `Error: sourcePath does not exist: ${local}` }] };\r\n const st = statSync(local);\r\n if (!st.isFile()) return { content: [{ type: 'text', text: `Error: sourcePath is not a regular file: ${local}` }] };\r\n const startedAt = Date.now();\r\n if (st.size > R2_MULTIPART_THRESHOLD) {\r\n // Multipart path: streams the local file in 100 MB parts and\r\n // logs progress per part. Up to ~5 TB per object on R2.\r\n let lastLog = 0;\r\n await r2PutObjectMultipart(bucket, key, local, st.size, (uploaded) => {\r\n if (uploaded - lastLog >= 500 * 1024 * 1024) {\r\n console.error(`[r2-write] ${formatBytes(uploaded)} / ${formatBytes(st.size)} → r2://${bucket}/${key}`);\r\n lastLog = uploaded;\r\n }\r\n });\r\n const elapsed = Date.now() - startedAt;\r\n const mbps = st.size / (1024 * 1024) / Math.max(0.001, elapsed / 1000);\r\n const noteParts: string[] = [];\r\n if (fileMode !== undefined) noteParts.push('mode ignored (R2)');\r\n if (mtimeMs !== undefined) noteParts.push('mtime ignored (R2)');\r\n const note = noteParts.length ? ` [${noteParts.join(', ')}]` : '';\r\n return { content: [{ type: 'text', text: `Uploaded ${formatBytes(st.size)} from ${local} to r2://${bucket}/${key} via multipart in ${(elapsed / 1000).toFixed(1)}s (${mbps.toFixed(1)} MB/s)${note}` }] };\r\n }\r\n const stream = createReadStream(local);\r\n await r2PutObject(bucket, key, stream, st.size);\r\n const elapsed = Date.now() - startedAt;\r\n return { content: [{ type: 'text', text: `Uploaded ${st.size} bytes from ${local} to r2://${bucket}/${key} in ${elapsed}ms` }] };\r\n }\r\n const buf = Buffer.from(String(a.content ?? ''), 'utf-8');\r\n await r2PutObject(bucket, key, buf, buf.length);\r\n return { content: [{ type: 'text', text: `Wrote ${buf.length} bytes to r2://${bucket}/${key}` }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const input: SftpWriteInput =\r\n typeof a.sourcePath === 'string' && a.sourcePath.length > 0\r\n ? { sourcePath: a.sourcePath }\r\n : { content: String(a.content ?? '') };\r\n const result = await sftpWrite(conn, String(a.path), input, proxy, { fileMode, mtimeMs });\r\n return { content: [{ type: 'text', text: result }] };\r\n }\r\n\r\n case 'sftp-delete': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const recursive = a.recursive === true;\r\n const dryRun = a.dryRun === true;\r\n const confirmAbove = a.confirmAbove !== undefined ? Math.max(0, Number(a.confirmAbove)) : undefined;\r\n const confirmCount = a.confirmCount !== undefined ? Number(a.confirmCount) : undefined;\r\n\r\n // Helper: enforce confirmAbove gate on a known item count (or refuse).\r\n const guard = (count: number, sizeBytes: number, where: string): { content: [{ type: 'text'; text: string }] } | null => {\r\n if (confirmAbove !== undefined && count > confirmAbove) {\r\n if (confirmCount === count) return null; // user explicitly opted in\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Refusing to delete ${count} item(s) (${formatBytes(sizeBytes)}) under ${where}: exceeds confirmAbove=${confirmAbove}. To proceed, re-issue the call with confirmCount: ${count}.`,\r\n }],\r\n };\r\n }\r\n return null;\r\n };\r\n\r\n if (bucket) {\r\n const key = r2Key(String(a.path));\r\n if (!key) return { content: [{ type: 'text', text: 'Error: path is required' }] };\r\n try {\r\n if (recursive) {\r\n // For recursive R2 we need to list first to count + size, both\r\n // for the dryRun preview and for the confirmAbove gate.\r\n if (dryRun || confirmAbove !== undefined) {\r\n const listed = await r2List(bucket, key, { recursive: true, maxResults: 50_000 });\r\n const objects = listed.filter(e => !e.isPrefix);\r\n const totalSize = objects.reduce((s, o) => s + (o.size || 0), 0);\r\n if (dryRun) {\r\n const sample = objects.slice(0, 5).map(o => ` - r2://${bucket}/${o.key} (${formatBytes(o.size || 0)})`);\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete ${objects.length} object(s) totalling ${formatBytes(totalSize)} under r2://${bucket}/${key}${objects.length > 5 ? `\\n${sample.join('\\n')}\\n ... and ${objects.length - 5} more` : objects.length ? `\\n${sample.join('\\n')}` : ''}` }] };\r\n }\r\n const block = guard(objects.length, totalSize, `r2://${bucket}/${key}`);\r\n if (block) return block;\r\n }\r\n const deleted = await r2DeletePrefix(bucket, key);\r\n return { content: [{ type: 'text', text: `Deleted ${deleted} object(s) under r2://${bucket}/${key}` }] };\r\n }\r\n // Single-object delete: dryRun shows size; no confirmAbove gate needed.\r\n if (dryRun) {\r\n try {\r\n const head = await getR2Client().send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete r2://${bucket}/${key} (${formatBytes(head.ContentLength || 0)})` }] };\r\n } catch {\r\n return { content: [{ type: 'text', text: `[dry-run] r2://${bucket}/${key} not found (delete would 404)` }] };\r\n }\r\n }\r\n await r2DeleteObject(bucket, key);\r\n return { content: [{ type: 'text', text: `Deleted r2://${bucket}/${key}` }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n\r\n // SSH path: dryRun + confirmAbove for recursive — we list first so the\r\n // preview/gate has the same data the actual delete would.\r\n if (recursive && (dryRun || confirmAbove !== undefined)) {\r\n const listed = await sftpReaddir(conn, String(a.path), proxy, {\r\n recursive: true,\r\n maxResults: 50_000,\r\n });\r\n const files = listed.entries.filter(e => e.kind === '-');\r\n const dirs = listed.entries.filter(e => e.kind === 'd');\r\n const totalSize = files.reduce((s, f) => s + (f.size || 0), 0);\r\n if (dryRun) {\r\n const sample = files.slice(0, 5).map(f => ` - ${f.path} (${formatBytes(f.size || 0)})`);\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete ${files.length} file(s) + ${dirs.length} directory(ies) totalling ${formatBytes(totalSize)} under ${a.path}${files.length ? `\\n${sample.join('\\n')}${files.length > 5 ? `\\n ... and ${files.length - 5} more` : ''}` : ''}` }] };\r\n }\r\n const block = guard(files.length + dirs.length, totalSize, String(a.path));\r\n if (block) return block;\r\n } else if (dryRun) {\r\n // Single-file dry-run: just print intent. Avoids an extra round-trip\r\n // and works equally well for files that don't exist (the real delete\r\n // would surface that anyway).\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete ${a.path} (single file/dir; pass recursive: true to preview tree contents)` }] };\r\n }\r\n const result = await sftpDelete(conn, String(a.path), proxy, { recursive });\r\n return { content: [{ type: 'text', text: result }] };\r\n }\r\n\r\n // ----- Docker -----\r\n case 'docker-list': {\r\n const format = a.format === 'json' ? 'json' : 'table';\r\n const composeOnly = a.composeOnly === true;\r\n const groupByProject = a.groupByProject === true;\r\n const nameFiltersRaw: string[] = Array.isArray(a.nameFilter)\r\n ? (a.nameFilter as unknown[]).map(v => String(v).trim()).filter(Boolean)\r\n : (typeof a.nameFilter === 'string' && a.nameFilter.trim() ? [a.nameFilter.trim()] : []);\r\n\r\n // Resolve target list — same fan-out idiom as ssh-execute.\r\n const targetIds: string[] = Array.isArray(a.serverIds) && a.serverIds.length > 0\r\n ? (a.serverIds as unknown[]).map(String)\r\n : a.serverId ? [String(a.serverId)] : [];\r\n if (targetIds.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `serverId` or `serverIds[]`' }] };\r\n }\r\n const parallelism = Math.max(1, Math.min(20, Number(a.parallelism) || 5));\r\n\r\n type DockerPsRow = { Names?: string; Image?: string; Status?: string; Ports?: string; Labels?: string; Project?: string; Health?: string };\r\n\r\n const filterArg = composeOnly ? ` --filter \"label=com.docker.compose.project\"` : '';\r\n const cmd = `docker ps -a${filterArg} --format '{{json .}}'`;\r\n\r\n const probeOne = async (serverId: string): Promise<{ serverId: string; serverName: string; rows: DockerPsRow[]; error?: string }> => {\r\n let serverName = serverId.slice(0, 8);\r\n try {\r\n const { conn, proxy } = await getServerConnection(serverId);\r\n const r = await sshExec(conn, cmd, proxy);\r\n const cached = KNOWN_SERVER_NAMES.get(serverId);\r\n if (cached) serverName = cached.name;\r\n if (r.exitCode !== 0) {\r\n return { serverId, serverName, rows: [], error: (r.stderr || r.stdout || 'exit ' + r.exitCode).trim().slice(0, 200) };\r\n }\r\n const rows: DockerPsRow[] = [];\r\n for (const line of r.stdout.split('\\n')) {\r\n const t = line.trim();\r\n if (!t) continue;\r\n try { rows.push(JSON.parse(t) as DockerPsRow); } catch { /* skip malformed */ }\r\n }\r\n for (const c of rows) {\r\n const m = (c.Labels || '').match(/com\\.docker\\.compose\\.project=([^,]+)/);\r\n c.Project = m ? m[1] : '';\r\n const status = c.Status || '';\r\n if (/\\(unhealthy\\)/i.test(status)) c.Health = 'unhealthy';\r\n else if (/\\(health: starting\\)|\\(starting\\)/i.test(status)) c.Health = 'starting';\r\n else if (/\\(healthy\\)/i.test(status)) c.Health = 'healthy';\r\n else if (/^Up\\b/i.test(status)) c.Health = 'no-check';\r\n else c.Health = '';\r\n }\r\n // Stash names for fuzzy hints later.\r\n rememberContainers(serverId, rows.map(r => r.Names || '').filter(Boolean));\r\n return { serverId, serverName, rows };\r\n } catch (err) {\r\n return { serverId, serverName, rows: [], error: err instanceof Error ? err.message.slice(0, 200) : String(err).slice(0, 200) };\r\n }\r\n };\r\n\r\n const perServer: Awaited<ReturnType<typeof probeOne>>[] = [];\r\n for (let i = 0; i < targetIds.length; i += parallelism) {\r\n const batch = targetIds.slice(i, i + parallelism);\r\n const chunk = await Promise.all(batch.map(probeOne));\r\n perServer.push(...chunk);\r\n }\r\n\r\n // Per-row apply name filter, tagging origin server when fan-out > 1.\r\n const applyFilter = (rows: DockerPsRow[]): DockerPsRow[] => {\r\n if (nameFiltersRaw.length === 0) return rows;\r\n const matchers = nameFiltersRaw.map(raw => {\r\n if (raw.includes('*') || raw.includes('?')) return { kind: 'glob' as const, re: globToRegExp(raw) };\r\n return { kind: 'sub' as const, lower: raw.toLowerCase() };\r\n });\r\n return rows.filter(c => {\r\n const name = c.Names || '';\r\n const lower = name.toLowerCase();\r\n return matchers.some(m => m.kind === 'glob' ? m.re.test(name) : lower.includes(m.lower));\r\n });\r\n };\r\n const sortRows = (rows: DockerPsRow[]) => rows.sort((x, y) => {\r\n const px = x.Project || '~';\r\n const py = y.Project || '~';\r\n const p = px.localeCompare(py);\r\n return p !== 0 ? p : (x.Names || '').localeCompare(y.Names || '');\r\n });\r\n\r\n const fmtRow = (r: DockerPsRow) =>\r\n `${(r.Names || '').padEnd(36)} ${(r.Image || '').padEnd(40)} ${(r.Status || '').padEnd(24)} ${(r.Health || '').padEnd(10)} ${(r.Ports || '').padEnd(40)}`;\r\n\r\n // Single-server: keep original (terse, unprefixed) layout.\r\n if (targetIds.length === 1) {\r\n const only = perServer[0]!;\r\n if (only.error) return { content: [{ type: 'text', text: `Error: ${only.error}` }] };\r\n const filtered = sortRows(applyFilter(only.rows));\r\n if (format === 'json') {\r\n const text = filtered.map(c => JSON.stringify(c)).join('\\n') || '(no containers)';\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n if (groupByProject) {\r\n const groups = new Map<string, DockerPsRow[]>();\r\n for (const c of filtered) {\r\n const key = c.Project || '(no compose project)';\r\n const list = groups.get(key);\r\n if (list) list.push(c); else groups.set(key, [c]);\r\n }\r\n const out: string[] = [];\r\n for (const [project, rows] of groups) {\r\n out.push(`=== ${project} (${rows.length}) ===`);\r\n for (const r of rows) out.push(' ' + fmtRow(r));\r\n out.push('');\r\n }\r\n return { content: [{ type: 'text', text: out.join('\\n').trimEnd() || '(no containers)' }] };\r\n }\r\n const header = `${'NAMES'.padEnd(36)} ${'IMAGE'.padEnd(40)} ${'STATUS'.padEnd(24)} ${'HEALTH'.padEnd(10)} ${'PORTS'.padEnd(40)} PROJECT`;\r\n const body = filtered.map(r => `${fmtRow(r)} ${r.Project || ''}`);\r\n const text = filtered.length === 0 ? '(no containers match)' : [header, ...body].join('\\n');\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n\r\n // Fan-out: per-server header, then filtered rows. JSON format produces\r\n // one obj per line with an extra \"Server\" field so downstream tools\r\n // can tell containers apart.\r\n if (format === 'json') {\r\n const lines: string[] = [];\r\n for (const ps of perServer) {\r\n if (ps.error) {\r\n lines.push(JSON.stringify({ Server: ps.serverName, Error: ps.error }));\r\n continue;\r\n }\r\n const filtered = sortRows(applyFilter(ps.rows));\r\n for (const c of filtered) lines.push(JSON.stringify({ Server: ps.serverName, ...c }));\r\n }\r\n return { content: [{ type: 'text', text: lines.join('\\n') || '(no containers)' }] };\r\n }\r\n\r\n const sections: string[] = [];\r\n let totalRows = 0;\r\n let serversWithRows = 0;\r\n for (const ps of perServer) {\r\n if (ps.error) {\r\n sections.push(`=== ${ps.serverName} === !! ${ps.error}`);\r\n continue;\r\n }\r\n const filtered = sortRows(applyFilter(ps.rows));\r\n if (filtered.length === 0) {\r\n sections.push(`=== ${ps.serverName} === (no containers match)`);\r\n continue;\r\n }\r\n serversWithRows++;\r\n totalRows += filtered.length;\r\n sections.push(`=== ${ps.serverName} (${filtered.length} container(s)) ===`);\r\n const header = `${'NAMES'.padEnd(36)} ${'IMAGE'.padEnd(40)} ${'STATUS'.padEnd(24)} ${'HEALTH'.padEnd(10)} ${'PORTS'.padEnd(40)} PROJECT`;\r\n sections.push(header);\r\n for (const r of filtered) sections.push(`${fmtRow(r)} ${r.Project || ''}`);\r\n }\r\n sections.push(`--- fan-out summary: ${totalRows} container(s) across ${serversWithRows}/${perServer.length} server(s) ---`);\r\n return { content: [{ type: 'text', text: sections.join('\\n') }] };\r\n }\r\n\r\n case 'docker-logs': {\r\n const rawNames = Array.isArray(a.containerName)\r\n ? (a.containerName as unknown[]).map(String)\r\n : [String(a.containerName)];\r\n const containers = rawNames\r\n .map(n => n.replace(/[^a-zA-Z0-9._-]/g, ''))\r\n .filter(n => n.length > 0);\r\n if (containers.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: no valid containerName provided' }] };\r\n }\r\n\r\n const followSeconds = Math.max(0, Math.min(300, Number(a.followSeconds) || 0));\r\n const userTail = a.tail !== undefined ? Number(a.tail) : (a.lines !== undefined ? Number(a.lines) : undefined);\r\n const tailArg = userTail !== undefined && Number.isFinite(userTail) && userTail >= 0\r\n ? userTail\r\n : (followSeconds > 0 ? 0 : 100);\r\n const sinceRaw = typeof a.since === 'string' ? a.since.trim() : '';\r\n const grepRaw = typeof a.grep === 'string' ? a.grep : '';\r\n\r\n if (sinceRaw && !/^\\d+[smhd]$/i.test(sinceRaw) && !/^\\d{4}-\\d{2}-\\d{2}/.test(sinceRaw)) {\r\n return { content: [{ type: 'text', text: 'Error: invalid `since` format (expected e.g. \"10m\", \"2h\", or ISO timestamp)' }] };\r\n }\r\n const sinceArg = sinceRaw ? ` --since ${posixQuote(sinceRaw)}` : '';\r\n const grepSuffix = grepRaw ? ` | grep -i -E ${posixQuote(grepRaw)} --line-buffered` : '';\r\n\r\n // Resolve target server list (fan-out support for \"show kong logs across all servers\").\r\n const targetIds: string[] = Array.isArray(a.serverIds) && a.serverIds.length > 0\r\n ? (a.serverIds as unknown[]).map(String)\r\n : a.serverId ? [String(a.serverId)] : [];\r\n if (targetIds.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `serverId` or `serverIds[]`' }] };\r\n }\r\n const parallelism = Math.max(1, Math.min(20, Number(a.parallelism) || 5));\r\n\r\n const wallSeconds = followSeconds > 0 ? followSeconds : 30;\r\n const followFlag = followSeconds > 0 ? ' -f' : '';\r\n\r\n // Build the `docker logs` invocation — same shell command for every\r\n // server. Single-container mode produces unprefixed output; multi\r\n // adds [name] prefixes so streams stay distinguishable.\r\n const buildCmd = (): string => {\r\n if (containers.length === 1) {\r\n const c = containers[0];\r\n const inner = `docker logs${followFlag} --tail ${tailArg}${sinceArg} ${c} 2>&1${grepSuffix}`;\r\n return `timeout --signal=INT ${wallSeconds} sh -c ${posixQuote(inner)}`;\r\n }\r\n const subShells = containers.map(c => {\r\n const inner = `docker logs${followFlag} --tail ${tailArg}${sinceArg} ${c} 2>&1${grepSuffix}`;\r\n return `(${inner} | sed -u -e ${posixQuote(`s/^/[${c}] /`)})`;\r\n });\r\n const innerCmd = subShells.join(' & ') + ' & wait';\r\n return `timeout --signal=INT ${wallSeconds} sh -c ${posixQuote(innerCmd)}`;\r\n };\r\n const cmd = buildCmd();\r\n\r\n const probeOne = async (serverId: string): Promise<{ serverId: string; serverName: string; result: SshResult }> => {\r\n const { conn, proxy } = await getServerConnection(serverId);\r\n conn.timeout = (wallSeconds + 10) * 1000;\r\n const result = await sshExec(conn, cmd, proxy);\r\n const cached = KNOWN_SERVER_NAMES.get(serverId);\r\n return { serverId, serverName: cached?.name || serverId.slice(0, 8), result };\r\n };\r\n\r\n const acceptableCode = (code: number) => code === 0 || code === 124 || code === 130 || code === 143 || (!!grepRaw && code === 1);\r\n\r\n // Single-server: keep the original (unprefixed) output for back-compat.\r\n if (targetIds.length === 1) {\r\n const r = await probeOne(targetIds[0] as string);\r\n const result = r.result;\r\n // Combined output: docker pipes stderr→stdout via `2>&1`, so the\r\n // \"No such container\" error lives in stdout. Look for it explicitly.\r\n const combined = `${result.stdout}\\n${result.stderr}`;\r\n const noSuchMatch = /No such container:\\s*(\\S+)/i.exec(combined);\r\n const fuzzyHint = (): string => {\r\n if (!noSuchMatch) return '';\r\n const known = getKnownContainers(targetIds[0] as string);\r\n if (!known?.length) return '';\r\n const hits = suggestSimilar(noSuchMatch[1] as string, known);\r\n return hits.length ? `\\n(hint) Did you mean: ${hits.join(', ')}?` : '';\r\n };\r\n\r\n if (!acceptableCode(result.exitCode) && !result.stdout) {\r\n return { content: [{ type: 'text', text: `Error (exit ${result.exitCode}): ${result.stderr || '(no output)'}${fuzzyHint()}` }] };\r\n }\r\n // Even when stdout has data, surface the fuzzy hint if docker reported\r\n // \"No such container\" — otherwise the LLM mistakes the error for log lines.\r\n const note = result.exitCode === 124 ? `\\n(note: command exceeded ${wallSeconds}s wall budget; partial output)` : '';\r\n return { content: [{ type: 'text', text: (result.stdout || '(no log lines matched)') + note + fuzzyHint() }] };\r\n }\r\n\r\n // Fan-out: per-server section. Each server's stdout is shown verbatim\r\n // (already [name]-prefixed if multi-container).\r\n const perServer: Awaited<ReturnType<typeof probeOne>>[] = [];\r\n for (let i = 0; i < targetIds.length; i += parallelism) {\r\n const batch = targetIds.slice(i, i + parallelism);\r\n const chunk = await Promise.all(batch.map(probeOne));\r\n perServer.push(...chunk);\r\n }\r\n const sections: string[] = [];\r\n let okCount = 0;\r\n for (const ps of perServer) {\r\n if (acceptableCode(ps.result.exitCode) || ps.result.stdout) {\r\n okCount++;\r\n const note = ps.result.exitCode === 124 ? ` (timed out after ${wallSeconds}s; partial)` : '';\r\n sections.push(`=== ${ps.serverName}${note} ===`);\r\n sections.push(ps.result.stdout || '(no log lines matched)');\r\n } else {\r\n sections.push(`=== ${ps.serverName} === !! exit ${ps.result.exitCode}: ${ps.result.stderr.trim().slice(0, 200) || '(no output)'}`);\r\n }\r\n }\r\n sections.push(`--- fan-out summary: ${okCount}/${perServer.length} server(s) returned logs ---`);\r\n return { content: [{ type: 'text', text: sections.join('\\n') }] };\r\n }\r\n\r\n case 'docker-exec': {\r\n const container = String(a.container).replace(/[^a-zA-Z0-9._-]/g, '');\r\n if (!container) return { content: [{ type: 'text', text: 'Error: invalid container name' }] };\r\n const command = String(a.command);\r\n const args = Array.isArray(a.args) ? (a.args as unknown[]).map(String) : [];\r\n const stdin = typeof a.stdin === 'string' ? a.stdin : undefined;\r\n const interactive = a.interactive === true;\r\n const workdir = typeof a.workdir === 'string' && a.workdir ? ['-w', a.workdir] : [];\r\n const user = typeof a.user === 'string' && a.user ? ['-u', a.user] : [];\r\n\r\n // Flag matrix:\r\n // - stdin given: -i (attach stdin)\r\n // - interactive: -t (allocate TTY) so commands like psql / mysql / bash\r\n // that probe `isatty(stdout)` produce human-friendly output AND don't\r\n // complain (\"the input device is not a TTY\"). Combine with -i for full\r\n // interactive use; -t alone is allowed for tty-only programs.\r\n const flags: string[] = [];\r\n if (stdin !== undefined || interactive) flags.push('-i');\r\n if (interactive) flags.push('-t');\r\n\r\n // docker exec [-it] [-w DIR] [-u USER] CONTAINER CMD [ARG ...]\r\n const dockerArgs = [...flags, ...workdir, ...user, container, command, ...args];\r\n const fullCmd = buildPosixCommand('docker', ['exec', ...dockerArgs]);\r\n\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, fullCmd, proxy, {\r\n stdin,\r\n pty: interactive,\r\n });\r\n const output = [`Exit code: ${result.exitCode}`];\r\n if (result.stdout) output.push(`--- stdout ---\\n${result.stdout}`);\r\n if (result.stderr) {\r\n let stderrOut = result.stderr;\r\n // Fuzzy hint: docker emits \"No such container: <name>\" when the\r\n // identifier is wrong. Use the docker-list cache (if recent) for\r\n // a \"did you mean?\" suggestion.\r\n const noSuch = /No such container:\\s*(\\S+)/i.exec(result.stderr);\r\n if (noSuch) {\r\n const known = getKnownContainers(String(a.serverId));\r\n if (known && known.length) {\r\n const hits = suggestSimilar(noSuch[1] as string, known);\r\n if (hits.length) stderrOut += `\\n(hint) Did you mean: ${hits.join(', ')}?`;\r\n }\r\n }\r\n output.push(`--- stderr ---\\n${stderrOut}`);\r\n }\r\n return { content: [{ type: 'text', text: output.join('\\n') }] };\r\n }\r\n\r\n case 'docker-compose': {\r\n const projectPath = String(a.projectPath);\r\n if (!projectPath || !projectPath.startsWith('/')) {\r\n return { content: [{ type: 'text', text: 'Error: projectPath must be an absolute path' }] };\r\n }\r\n const action = String(a.action);\r\n const allowedActions = ['up', 'down', 'restart', 'logs', 'ps', 'pull', 'build'] as const;\r\n if (!allowedActions.includes(action as typeof allowedActions[number])) {\r\n return { content: [{ type: 'text', text: `Error: invalid action (allowed: ${allowedActions.join(', ')})` }] };\r\n }\r\n const service = typeof a.service === 'string' && a.service ? a.service : '';\r\n const tail = Number(a.tail) > 0 ? Number(a.tail) : 200;\r\n\r\n let composeArgs: string[];\r\n switch (action) {\r\n case 'up': composeArgs = service ? ['up', '-d', service] : ['up', '-d']; break;\r\n case 'down': composeArgs = service ? ['down', service] : ['down']; break;\r\n case 'restart': composeArgs = service ? ['restart', service] : ['restart']; break;\r\n case 'logs': composeArgs = service ? ['logs', '--no-color', `--tail=${tail}`, service] : ['logs', '--no-color', `--tail=${tail}`]; break;\r\n case 'ps': composeArgs = service ? ['ps', service] : ['ps']; break;\r\n case 'pull': composeArgs = service ? ['pull', service] : ['pull']; break;\r\n case 'build': composeArgs = service ? ['build', service] : ['build']; break;\r\n default: composeArgs = []; // unreachable\r\n }\r\n\r\n const composeCmd = buildPosixCommand('docker', ['compose', ...composeArgs]);\r\n const fullCmd = `cd ${posixQuote(projectPath)} && ${composeCmd} 2>&1`;\r\n\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n conn.timeout = Number(a.timeout) > 0 ? Number(a.timeout) : 120_000;\r\n const result = await sshExec(conn, fullCmd, proxy);\r\n const output = [`Exit code: ${result.exitCode} (compose ${action}${service ? ` ${service}` : ''} @ ${projectPath})`];\r\n if (result.stdout) output.push(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 // ----- wait-for: poll until a condition holds (one tool, four types) -----\r\n case 'wait-for': {\r\n const type = String(a.type || '');\r\n if (!['url', 'container-health', 'file-exists', 'sftp-exists'].includes(type)) {\r\n return { content: [{ type: 'text', text: 'Error: type must be one of: url, container-health, file-exists, sftp-exists' }] };\r\n }\r\n const timeoutSeconds = Math.max(1, Math.min(1800, Number(a.timeout) || 120));\r\n const intervalSeconds = Math.max(1, Math.min(60, Number(a.intervalSeconds) || 3));\r\n const deadline = Date.now() + timeoutSeconds * 1000;\r\n const trail: string[] = [];\r\n\r\n const check = async (): Promise<{ ok: boolean; observed: string }> => {\r\n if (type === 'url') {\r\n const target = String(a.target || '');\r\n if (!target) return { ok: false, observed: 'no target url' };\r\n const expectStatus = a.until !== undefined ? Number(a.until) : 200;\r\n try {\r\n const ctrl = new AbortController();\r\n const t = setTimeout(() => ctrl.abort(), 10_000);\r\n const res = await fetch(target, { signal: ctrl.signal, redirect: 'manual' });\r\n clearTimeout(t);\r\n const ok = res.status === expectStatus || (expectStatus === 200 && res.status >= 200 && res.status < 300);\r\n return { ok, observed: `HTTP ${res.status}` };\r\n } catch (e) {\r\n return { ok: false, observed: e instanceof Error ? e.message : String(e) };\r\n }\r\n }\r\n if (type === 'container-health') {\r\n // target = container name; until = 'healthy' (default), 'running', 'exited'\r\n const containerName = String(a.target || '').replace(/[^a-zA-Z0-9._-]/g, '');\r\n const until = String(a.until || 'healthy');\r\n if (!containerName) return { ok: false, observed: 'no container name' };\r\n if (!a.serverId) return { ok: false, observed: 'serverId is required for container-health' };\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const cmd = `docker inspect --format '{{json .State}}' ${containerName} 2>&1`;\r\n const r = await sshExec(conn, cmd, proxy);\r\n if (r.exitCode !== 0) return { ok: false, observed: r.stderr.trim().slice(0, 80) || 'inspect failed' };\r\n try {\r\n const state = JSON.parse(r.stdout.trim()) as { Status?: string; Health?: { Status?: string } };\r\n const healthStatus = state.Health?.Status; // 'healthy' | 'unhealthy' | 'starting' | undefined\r\n if (until === 'healthy') {\r\n return { ok: healthStatus === 'healthy', observed: `Status=${state.Status} Health=${healthStatus || 'no-check'}` };\r\n }\r\n return { ok: state.Status === until, observed: `Status=${state.Status}` };\r\n } catch (e) {\r\n return { ok: false, observed: 'parse error: ' + (e instanceof Error ? e.message : String(e)) };\r\n }\r\n }\r\n // file-exists / sftp-exists: same impl, the SFTP backend (R2 bucket\r\n // or SSH server) is selected by which arg is present.\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const path = String(a.target || a.path || '');\r\n if (!path) return { ok: false, observed: 'no path' };\r\n if (bucket) {\r\n try {\r\n await getR2Client().send(new HeadObjectCommand({ Bucket: bucket, Key: r2Key(path) }));\r\n return { ok: true, observed: `r2://${bucket}/${path} exists` };\r\n } catch {\r\n return { ok: false, observed: `r2://${bucket}/${path} not found` };\r\n }\r\n }\r\n if (!a.serverId) return { ok: false, observed: 'serverId or bucket is required for file-exists' };\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const safe = sanitizePath(path);\r\n const cmd = `test -e ${posixQuote(safe)} && echo OK || echo MISSING`;\r\n const r = await sshExec(conn, cmd, proxy);\r\n const ok = r.stdout.trim() === 'OK';\r\n return { ok, observed: ok ? `${safe} exists` : `${safe} missing` };\r\n };\r\n\r\n let attempts = 0;\r\n let lastObserved = '';\r\n while (Date.now() < deadline) {\r\n attempts++;\r\n const r = await check();\r\n lastObserved = r.observed;\r\n trail.push(`[${attempts}] ${new Date().toISOString().slice(11, 19)} ${r.ok ? 'OK' : '..'} ${r.observed}`);\r\n if (r.ok) {\r\n return { content: [{ type: 'text', text: `Condition met after ${attempts} attempt(s) in ${((Date.now() - (deadline - timeoutSeconds * 1000)) / 1000).toFixed(1)}s.\\nLast observation: ${r.observed}\\n\\n--- trail ---\\n${trail.join('\\n')}` }] };\r\n }\r\n if (Date.now() + intervalSeconds * 1000 >= deadline) break;\r\n await new Promise((res) => setTimeout(res, intervalSeconds * 1000));\r\n }\r\n return { content: [{ type: 'text', text: `Timed out after ${timeoutSeconds}s without seeing condition (${attempts} probe(s)).\\nLast observation: ${lastObserved}\\n\\n--- trail ---\\n${trail.join('\\n')}` }] };\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-query': {\r\n // Engine routing. Default behaviour (mysql + sitePath) is unchanged\r\n // for back-compat. Pass `containerName` to query a DB inside a Docker\r\n // container — engine defaults to postgres in that case (covers the\r\n // self-hosted Supabase / Trigger.dev stacks).\r\n const containerName = typeof a.containerName === 'string' && a.containerName ? a.containerName.replace(/[^a-zA-Z0-9._-]/g, '') : '';\r\n const explicitEngine = a.engine === 'mysql' || a.engine === 'postgres' || a.engine === 'mssql' ? a.engine : null;\r\n const engine: 'mysql' | 'postgres' | 'mssql' = explicitEngine\r\n || (containerName ? 'postgres' : 'mysql');\r\n\r\n // Schema-introspection shortcut. Replaces the old db-describe tool\r\n // and works for all three engines. Sanitises the table identifier\r\n // before string interpolation. \"*\" lists all tables.\r\n const describeArg = typeof a.describe === 'string' ? a.describe.trim() : '';\r\n\r\n // Result-size guardrail + EXPLAIN mode. Both rewrite the query string\r\n // before it hits the engine-specific path below.\r\n const explainMode = a.explain === true;\r\n const maxRowsRaw = a.maxRows === undefined ? 1000 : Number(a.maxRows);\r\n const maxRows = Math.min(Math.max(Number.isFinite(maxRowsRaw) ? maxRowsRaw : 0, 0), 10000);\r\n\r\n let rawQuery: string;\r\n if (describeArg) {\r\n rawQuery = buildDescribeSql(describeArg, engine);\r\n } else {\r\n rawQuery = String(a.query ?? '').trim();\r\n if (!rawQuery) return { content: [{ type: 'text', text: 'Error: query (or describe) is required' }] };\r\n }\r\n assertSafeSql(rawQuery);\r\n\r\n let query = rawQuery.replace(/;\\s*$/, '');\r\n let appliedLimit = false;\r\n\r\n if (explainMode && !describeArg) {\r\n if (engine === 'mssql') {\r\n // mssql has no inline EXPLAIN; prepend SET SHOWPLAN_TEXT ON and\r\n // run the statement so sqlcmd returns the plan instead of rows.\r\n query = `SET SHOWPLAN_TEXT ON;\\n${query}`;\r\n } else {\r\n // postgres + mysql both accept \"EXPLAIN <statement>\".\r\n query = `EXPLAIN ${query}`;\r\n }\r\n } else if (maxRows > 0 && !describeArg) {\r\n // Only auto-LIMIT a single bare SELECT (or WITH ... SELECT) that\r\n // doesn't already have its own LIMIT / TOP. Skip mssql since LIMIT\r\n // syntax differs (TOP / OFFSET FETCH).\r\n const isSelect = /^\\s*(with\\b[\\s\\S]+?\\bselect\\b|select\\b)/i.test(query);\r\n const alreadyLimited = /\\blimit\\s+\\d+\\b/i.test(query) || /\\btop\\s*\\(?\\s*\\d+/i.test(query);\r\n if (isSelect && !alreadyLimited && engine !== 'mssql') {\r\n query = `${query}\\nLIMIT ${maxRows + 1}`; // +1 so we can detect truncation\r\n appliedLimit = true;\r\n }\r\n }\r\n\r\n // Path A: existing MySQL-via-/var/www autodiscover. Always engine=mysql.\r\n if (!containerName && engine === 'mysql') {\r\n if (!a.sitePath) return { content: [{ type: 'text', text: 'Error: sitePath is required for mysql autodiscover (or pass containerName + engine for direct DB queries)' }] };\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const output = await execSiteMysql(conn, String(a.sitePath), query, proxy);\r\n const footer = formatDbQueryFooter(output, appliedLimit, maxRows, explainMode);\r\n return { content: [{ type: 'text', text: (output || 'Query executed successfully (no output)') + footer }] };\r\n }\r\n\r\n // Path B: docker exec into a container with the appropriate client.\r\n // Query is piped via STDIN to avoid quoting hell with `, $, ; etc.\r\n if (!containerName) {\r\n return { content: [{ type: 'text', text: `Error: engine=${engine} requires containerName (the docker container running the DB server, e.g. \"supabase-db\" or \"trigger-postgres\")` }] };\r\n }\r\n const dbName = typeof a.dbName === 'string' && a.dbName ? a.dbName.replace(/[^a-zA-Z0-9_-]/g, '') : '';\r\n const dbUser = typeof a.dbUser === 'string' && a.dbUser ? a.dbUser.replace(/[^a-zA-Z0-9_-]/g, '') : '';\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n\r\n let cmd: string;\r\n let stdinPayload: string | undefined;\r\n if (engine === 'postgres') {\r\n // psql: -t (tuples-only) -A (unaligned) is great for parsing; use\r\n // -P expanded=auto for human-friendly default.\r\n const user = dbUser || 'postgres';\r\n const db = dbName || 'postgres';\r\n // Pipe the query in via stdin so we don't need to escape it.\r\n cmd = `docker exec -i ${containerName} psql -U ${user} -d ${db} -P pager=off`;\r\n stdinPayload = query.endsWith(';') ? query : `${query};`;\r\n } else if (engine === 'mssql') {\r\n // sqlcmd path (assumes mssql-tools in container). Caller provides\r\n // dbUser + dbPass (we *only* take dbPass here for mssql since\r\n // it isn't auto-discoverable like Postgres trust).\r\n const user = dbUser || 'sa';\r\n const dbPass = typeof a.dbPass === 'string' ? a.dbPass : '';\r\n if (!dbPass) return { content: [{ type: 'text', text: 'Error: mssql requires dbPass (sqlcmd has no equivalent of pg trust auth)' }] };\r\n const dbArg = dbName ? `-d ${dbName} ` : '';\r\n // Use stdin via -i /dev/stdin pattern; sqlcmd reads from stdin when no -Q given.\r\n cmd = `docker exec -i -e MSSQL_SA_PASSWORD=${posixQuote(dbPass)} ${containerName} /opt/mssql-tools18/bin/sqlcmd -S localhost -U ${user} -P \"$MSSQL_SA_PASSWORD\" -C ${dbArg}-h -1`;\r\n stdinPayload = query.endsWith(';') ? `${query}\\nGO\\n` : `${query};\\nGO\\n`;\r\n } else {\r\n // engine === 'mysql' but with containerName: useful for dockerised\r\n // MySQL outside of /var/www, e.g. a dev stack.\r\n const user = dbUser || 'root';\r\n const db = dbName ? ` ${dbName}` : '';\r\n const dbPass = typeof a.dbPass === 'string' ? a.dbPass : '';\r\n const passArg = dbPass ? `-p${posixQuote(dbPass)} ` : '';\r\n cmd = `docker exec -i ${containerName} mysql -t -u ${user} ${passArg}${db}`;\r\n stdinPayload = query.endsWith(';') ? query : `${query};`;\r\n }\r\n\r\n const result = await sshExec(conn, cmd, proxy, { stdin: stdinPayload });\r\n const output = result.stdout.trim() || result.stderr.trim() || '(no output)';\r\n if (result.exitCode !== 0 && !result.stdout) {\r\n return { content: [{ type: 'text', text: `Error (exit ${result.exitCode}, ${engine}): ${output}` }] };\r\n }\r\n const footer = formatDbQueryFooter(output, appliedLimit, maxRows, explainMode);\r\n return { content: [{ type: 'text', text: output + footer }] };\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 details = a.details === true;\r\n if (!details) {\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 return { content: [{ type: 'text', text: `${domains.length} domain(s):\\n\\n${lines.join('\\n')}` }] };\r\n }\r\n\r\n // details: true → fetch DNS zone per active domain in parallel and\r\n // summarise NS / MX / SPF / DMARC. Inactive domains are skipped so\r\n // we don't burn API quota on records that don't exist.\r\n interface DnsRec { type: string; name: string; value: string; ttl: number; }\r\n const concurrency = Math.min(Math.max(Number(a.concurrency) || 8, 1), 20);\r\n\r\n type Summary = { mx: string[]; hasSpf: boolean; hasDmarc: boolean; error?: string };\r\n const summaries = new Map<string, Summary>();\r\n\r\n const skipStatuses = new Set(['expired', 'redemptionperiod', 'pendingdelete', 'inactive']);\r\n const activeDomains = domains.filter(d => !skipStatuses.has((d.status || '').toLowerCase()));\r\n\r\n async function fetchSummary(domain: string): Promise<Summary> {\r\n try {\r\n const r = await mijnhostFetch<{ records: DnsRec[] }>(\r\n `/domains/${encodeURIComponent(domain)}/dns`,\r\n );\r\n const recs = r.data.records || [];\r\n // mijn.host's /dns endpoint exposes records inside the zone but\r\n // not the zone's own NS delegation, so we deliberately don't\r\n // report nameservers here (was misleading \"(none)\" for every row).\r\n const mx = recs\r\n .filter(x => x.type === 'MX')\r\n .map(x => x.value)\r\n .sort();\r\n const hasSpf = recs.some(x => x.type === 'TXT' && x.value.toLowerCase().includes('v=spf1'));\r\n const hasDmarc = recs.some(x =>\r\n x.type === 'TXT' &&\r\n (x.name.toLowerCase().startsWith('_dmarc') || x.value.toLowerCase().includes('v=dmarc1')),\r\n );\r\n return { mx, hasSpf, hasDmarc };\r\n } catch (err) {\r\n return { mx: [], hasSpf: false, hasDmarc: false, error: err instanceof Error ? err.message : String(err) };\r\n }\r\n }\r\n\r\n // Simple parallel pool — keeps `concurrency` requests in flight.\r\n const queue = [...activeDomains];\r\n async function worker() {\r\n while (queue.length > 0) {\r\n const d = queue.shift();\r\n if (!d) return;\r\n summaries.set(d.domain, await fetchSummary(d.domain));\r\n }\r\n }\r\n await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, worker));\r\n\r\n const lines = domains.map(d => {\r\n const tags = d.tags?.length ? ` [${d.tags.join(', ')}]` : '';\r\n const head = `${d.domain} status=${d.status} expires=${d.renewal_date}${tags}`;\r\n const s = summaries.get(d.domain);\r\n if (!s) return head;\r\n if (s.error) return `${head}\\n dns: error: ${s.error}`;\r\n const mx = s.mx.length ? s.mx.join(', ') : '(none)';\r\n return `${head}\\n mx=${mx} spf=${s.hasSpf ? 'yes' : 'NO'} dmarc=${s.hasDmarc ? 'yes' : 'NO'}`;\r\n });\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `${domains.length} domain(s) (${activeDomains.length} with DNS lookup):\\n\\n${lines.join('\\n')}`,\r\n }],\r\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-record': {\r\n const action = String(a.action);\r\n if (action !== 'create' && action !== 'update' && action !== 'delete') {\r\n throw new Error('action must be one of: create, update, delete');\r\n }\r\n\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 dryRun = a.dryRun === true;\r\n\r\n if (!domain || !type || !dnsName) {\r\n throw new Error('domain, type, and name 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 // Build the next records[] array and the diff descriptor in one pass\r\n // per action. PUT is only called when dryRun is false.\r\n let nextRecords: DnsRecord[];\r\n let diffArgs: { verb: 'create' | 'update' | 'delete'; added?: DnsRecord[]; removed?: DnsRecord[] };\r\n let okMessage: string;\r\n\r\n if (action === 'create') {\r\n const value = typeof a.value === 'string' ? a.value : '';\r\n if (!value) throw new Error('action=\"create\" requires value');\r\n const ttl = Number(a.ttl) || 3600;\r\n const newRecord: DnsRecord = { type, name: dnsName, value, ttl };\r\n nextRecords = [...current.data.records, newRecord];\r\n diffArgs = { verb: 'create', added: [newRecord] };\r\n okMessage = `DNS record created: ${type} ${dnsName} → ${value} (TTL: ${ttl})`;\r\n } else if (action === 'update') {\r\n const oldValue = typeof a.oldValue === 'string' ? a.oldValue : '';\r\n const newValue = typeof a.newValue === 'string' ? a.newValue : '';\r\n if (!oldValue || !newValue) throw new Error('action=\"update\" requires oldValue and newValue');\r\n const ttlArg = a.ttl !== undefined ? Number(a.ttl) : undefined;\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 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 before = updated[idx]!;\r\n const after: DnsRecord = {\r\n type,\r\n name: dnsName,\r\n value: newValue,\r\n ttl: ttlArg ?? before.ttl,\r\n };\r\n updated[idx] = after;\r\n nextRecords = updated;\r\n diffArgs = { verb: 'update', removed: [before], added: [after] };\r\n okMessage = `DNS record updated: ${type} ${dnsName} → ${newValue}${ttlArg ? ` (TTL: ${ttlArg})` : ''}`;\r\n } else {\r\n const value = typeof a.value === 'string' ? a.value : '';\r\n if (!value) throw new Error('action=\"delete\" requires value');\r\n\r\n const removed = current.data.records.filter(\r\n (r) => r.type === type && r.name === dnsName && r.value === value,\r\n );\r\n const remaining = current.data.records.filter(\r\n (r) => !(r.type === type && r.name === dnsName && r.value === value),\r\n );\r\n if (removed.length === 0) {\r\n throw new Error(`No matching DNS record found: ${type} ${dnsName} = ${value}`);\r\n }\r\n nextRecords = remaining;\r\n diffArgs = { verb: 'delete', removed };\r\n okMessage = `DNS record deleted: ${type} ${dnsName} = ${value} (${remaining.length} records remaining)`;\r\n }\r\n\r\n if (dryRun) {\r\n const diff = formatDnsDiff(domain, current.data.records, nextRecords, diffArgs);\r\n return { content: [{ type: 'text', text: diff }] };\r\n }\r\n\r\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\r\n method: 'PUT',\r\n body: JSON.stringify({ records: nextRecords }),\r\n });\r\n\r\n return { content: [{ type: 'text', text: okMessage }] };\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 (VERCEL_TOOL_NAMES.has(name)) {\r\n return handleVercelTool(name, a, { supabase, decrypt });\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 const apiAuthContext = await validateApiKey(apiKey!);\r\n if (!apiAuthContext) {\r\n console.error('API key validation failed');\r\n process.exit(1);\r\n }\r\n\r\n authContext = await validateSshKey(sshKeyPath!, apiAuthContext.apiKeyId);\r\n if (!authContext) {\r\n console.error('SSH-key authentication failed');\r\n process.exit(1);\r\n }\r\n\r\n console.error(`[Security] MCP v${MCP_VERSION} | Key: ${authContext.apiKeyName}`);\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\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/proxy-mode.ts","../src/trigger-tools.ts","../src/vercel-tools.ts","../src/index.ts"],"names":["args","proxyUrl","apiKey","Client","sshExec","getServerConnection","name","runId","instance","waitArg","waitSeconds","getArg","runProxyMode","runProcess","spawn","join","existsSync","VERCEL_API","SshClient","sections","serverName","lines","content","conn","proxy","elapsed","r","text","ok","cmd","output","footer","stageIds","Server","ListToolsRequestSchema","CallToolRequestSchema","createHttpServer","StdioServerTransport"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Proxy-mode entry point for the MG dashboard MCP package.\r\n *\r\n * Usage:\r\n * npx @mgsoftwarebv/mg-dashboard-mcp \\\r\n * --proxy-url=https://mg-mcp.mgsoftware.nl/v1/{INSTANCE_ID}/mcp \\\r\n * --api-key=pk_xxx \\\r\n * --ssh-key=$HOME/.ssh/id_ed25519\r\n *\r\n * What it does:\r\n * 1. At startup it does an SSH-key challenge handshake against the proxy\r\n * (POST /v1/auth/ssh/challenge → ssh-keygen -Y sign → POST\r\n * /v1/auth/ssh/verify) and obtains a short-lived `pks_xxx` bearer.\r\n * 2. It then runs as a stdio MCP server, transparently forwarding every\r\n * JSON-RPC message to/from the upstream proxy URL using\r\n * `StreamableHTTPClientTransport` with the bearer attached.\r\n * 3. Before the token expires it re-runs the handshake and swaps in the\r\n * fresh bearer without dropping the connection.\r\n *\r\n * This lets a user point Cursor's mcp.json at the local stdio command with\r\n * both factors: a static `pk_` proxy key plus a linked SSH key proof. The\r\n * static key is only sent during the SSH verify step; normal MCP traffic uses\r\n * the short-lived `pks_` session token.\r\n */\r\n\r\nimport { spawn } from \"node:child_process\";\r\nimport { existsSync, readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\r\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\r\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport {\r\n CallToolRequestSchema,\r\n CallToolResultSchema,\r\n EmptyResultSchema,\r\n GetPromptRequestSchema,\r\n GetPromptResultSchema,\r\n ListPromptsRequestSchema,\r\n ListPromptsResultSchema,\r\n ListResourcesRequestSchema,\r\n ListResourcesResultSchema,\r\n ListResourceTemplatesRequestSchema,\r\n ListResourceTemplatesResultSchema,\r\n ListToolsRequestSchema,\r\n ListToolsResultSchema,\r\n ReadResourceRequestSchema,\r\n ReadResourceResultSchema,\r\n SubscribeRequestSchema,\r\n UnsubscribeRequestSchema,\r\n} from \"@modelcontextprotocol/sdk/types.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// CLI helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction getArg(args: string[], name: string): string | undefined {\r\n return args.find((a) => a.startsWith(`--${name}=`))?.split(\"=\").slice(1).join(\"=\");\r\n}\r\n\r\nfunction expandHome(path: string): string {\r\n if (!path.startsWith(\"~\")) return path;\r\n const home = process.env.HOME || process.env.USERPROFILE || \"\";\r\n return join(home, path.slice(1));\r\n}\r\n\r\nfunction resolvePubkeyPath(input: string): { pubPath: string; pubText: string } {\r\n const candidate = expandHome(input);\r\n let pubPath: string;\r\n if (candidate.endsWith(\".pub\")) {\r\n pubPath = candidate;\r\n } else if (existsSync(`${candidate}.pub`)) {\r\n pubPath = `${candidate}.pub`;\r\n } else if (existsSync(candidate)) {\r\n pubPath = candidate;\r\n } else {\r\n throw new Error(`SSH key file not found: ${candidate} (also tried ${candidate}.pub)`);\r\n }\r\n const pubText = readFileSync(pubPath, \"utf8\").trim();\r\n if (!pubText) throw new Error(`SSH public-key file is empty: ${pubPath}`);\r\n return { pubPath, pubText };\r\n}\r\n\r\nfunction runProcess(\r\n command: string,\r\n argv: string[],\r\n options: { stdin?: string } = {},\r\n): Promise<{ stdout: string; stderr: string; code: number }> {\r\n return new Promise((resolve) => {\r\n const child = spawn(command, argv, { stdio: [\"pipe\", \"pipe\", \"pipe\"] });\r\n let stdout = \"\";\r\n let stderr = \"\";\r\n child.stdout.on(\"data\", (d) => {\r\n stdout += d.toString();\r\n });\r\n child.stderr.on(\"data\", (d) => {\r\n stderr += d.toString();\r\n });\r\n child.on(\"error\", (err) => {\r\n resolve({ stdout, stderr: stderr + String(err), code: -1 });\r\n });\r\n child.on(\"close\", (code) => {\r\n resolve({ stdout, stderr, code: code ?? -1 });\r\n });\r\n if (options.stdin !== undefined) {\r\n child.stdin.write(options.stdin);\r\n child.stdin.end();\r\n } else {\r\n child.stdin.end();\r\n }\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// SSH-key handshake against /v1/auth/ssh/challenge + /v1/auth/ssh/verify\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface HandshakeResult {\r\n token: string;\r\n expiresAt: number; // ms epoch\r\n proxyKeyName: string;\r\n}\r\n\r\nfunction deriveAuthBaseUrl(proxyUrl: string): string {\r\n // proxyUrl looks like https://host/v1/{instanceId}/mcp\r\n // We need to call https://host (base) then /v1/auth/ssh/{challenge|verify}.\r\n const u = new URL(proxyUrl);\r\n return `${u.protocol}//${u.host}`;\r\n}\r\n\r\nasync function performHandshake(\r\n proxyUrl: string,\r\n apiKey: string,\r\n pubPath: string,\r\n pubText: string,\r\n): Promise<HandshakeResult> {\r\n const base = deriveAuthBaseUrl(proxyUrl);\r\n\r\n const challengeRes = await fetch(`${base}/v1/auth/ssh/challenge`, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: \"{}\",\r\n });\r\n if (!challengeRes.ok) {\r\n const txt = await challengeRes.text().catch(() => \"\");\r\n throw new Error(`Challenge request failed (${challengeRes.status}): ${txt}`);\r\n }\r\n const challenge = (await challengeRes.json()) as {\r\n challenge_id: string;\r\n nonce: string;\r\n namespace: string;\r\n };\r\n\r\n const sign = await runProcess(\r\n \"ssh-keygen\",\r\n [\"-Y\", \"sign\", \"-f\", pubPath, \"-n\", challenge.namespace, \"-q\"],\r\n { stdin: challenge.nonce },\r\n );\r\n if (sign.code !== 0 || !sign.stdout.includes(\"BEGIN SSH SIGNATURE\")) {\r\n throw new Error(\r\n `ssh-keygen sign failed (exit ${sign.code}). Make sure ssh-agent is running ` +\r\n `and has the matching private key loaded. stderr: ${sign.stderr.trim() || \"(empty)\"}`,\r\n );\r\n }\r\n\r\n const verifyRes = await fetch(`${base}/v1/auth/ssh/verify`, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({\r\n challenge_id: challenge.challenge_id,\r\n api_key: apiKey,\r\n pubkey: pubText,\r\n signature: sign.stdout,\r\n }),\r\n });\r\n if (!verifyRes.ok) {\r\n const txt = await verifyRes.text().catch(() => \"\");\r\n throw new Error(`Verify request failed (${verifyRes.status}): ${txt}`);\r\n }\r\n const verified = (await verifyRes.json()) as {\r\n token: string;\r\n expires_in_seconds: number;\r\n proxy_key_name: string;\r\n };\r\n\r\n return {\r\n token: verified.token,\r\n expiresAt: Date.now() + verified.expires_in_seconds * 1000,\r\n proxyKeyName: verified.proxy_key_name,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Bidirectional message forwarding\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Bridge between a stdio MCP server (talking to e.g. Cursor) and a remote\r\n * Streamable-HTTP MCP server (the proxy). Each incoming JSON-RPC message\r\n * is forwarded verbatim, and responses / notifications stream back.\r\n */\r\nasync function runBridge(handshake: HandshakeResult, proxyUrl: string, refresh: () => Promise<HandshakeResult>) {\r\n let currentToken = handshake.token;\r\n const requestHeaders: Record<string, string> = {\r\n Authorization: `Bearer ${currentToken}`,\r\n };\r\n\r\n const upstreamTransport = new StreamableHTTPClientTransport(new URL(proxyUrl), {\r\n requestInit: { headers: requestHeaders },\r\n });\r\n const upstream = new Client({ name: \"mg-dashboard-mcp-proxy-bridge\", version: \"1.0.0\" });\r\n\r\n // Schedule a refresh 2 minutes before expiry.\r\n const scheduleRefresh = (result: HandshakeResult) => {\r\n const msUntilRefresh = Math.max(30_000, result.expiresAt - Date.now() - 120_000);\r\n setTimeout(async () => {\r\n try {\r\n const fresh = await refresh();\r\n currentToken = fresh.token;\r\n requestHeaders.Authorization = `Bearer ${currentToken}`;\r\n console.error(`[Proxy] Token refreshed (key: ${fresh.proxyKeyName})`);\r\n scheduleRefresh(fresh);\r\n } catch (err) {\r\n console.error(`[Proxy] Token refresh failed: ${err instanceof Error ? err.message : String(err)}`);\r\n // Try again sooner on failure.\r\n setTimeout(() => scheduleRefresh({ ...result, expiresAt: Date.now() + 60_000 }), 30_000);\r\n }\r\n }, msUntilRefresh).unref();\r\n };\r\n scheduleRefresh(handshake);\r\n\r\n // Server-side stdio transport faces Cursor.\r\n const stdioServer = new Server(\r\n { name: \"mg-dashboard-mcp-proxy\", version: \"1.0.0\" },\r\n { capabilities: { tools: {}, prompts: {}, resources: {}, logging: {} } },\r\n );\r\n\r\n const forwardRequest =\r\n (resultSchema: Parameters<typeof upstream.request>[1]) =>\r\n async (request: unknown) =>\r\n upstream.request(\r\n request as Parameters<typeof upstream.request>[0],\r\n resultSchema,\r\n );\r\n\r\n // Explicitly forward first-class MCP methods. The SDK fallback only covers\r\n // truly unknown methods; Cursor's standard discovery calls need registered\r\n // handlers or the client sees an empty server.\r\n stdioServer.setRequestHandler(\r\n ListToolsRequestSchema,\r\n forwardRequest(ListToolsResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n CallToolRequestSchema,\r\n forwardRequest(CallToolResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ListPromptsRequestSchema,\r\n forwardRequest(ListPromptsResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n GetPromptRequestSchema,\r\n forwardRequest(GetPromptResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ListResourcesRequestSchema,\r\n forwardRequest(ListResourcesResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ReadResourceRequestSchema,\r\n forwardRequest(ReadResourceResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n ListResourceTemplatesRequestSchema,\r\n forwardRequest(ListResourceTemplatesResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n SubscribeRequestSchema,\r\n forwardRequest(EmptyResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n stdioServer.setRequestHandler(\r\n UnsubscribeRequestSchema,\r\n forwardRequest(EmptyResultSchema) as Parameters<typeof stdioServer.setRequestHandler>[1],\r\n );\r\n\r\n // Dumb forwarder: any request from Cursor → forward to upstream → return result.\r\n stdioServer.fallbackRequestHandler = async (request: unknown) => {\r\n return await upstream.request(\r\n request as Parameters<typeof upstream.request>[0],\r\n // We don't care about the schema check on the way through — let the\r\n // upstream's actual response flow back unmodified.\r\n undefined as unknown as Parameters<typeof upstream.request>[1],\r\n );\r\n };\r\n // Same for notifications.\r\n stdioServer.fallbackNotificationHandler = async (notification: unknown) => {\r\n await upstream.notification(notification as Parameters<typeof upstream.notification>[0]);\r\n };\r\n\r\n await upstream.connect(upstreamTransport);\r\n\r\n // Forward upstream notifications back to Cursor.\r\n upstream.fallbackNotificationHandler = async (notification: unknown) => {\r\n await stdioServer.notification(notification as Parameters<typeof stdioServer.notification>[0]);\r\n };\r\n\r\n await stdioServer.connect(new StdioServerTransport());\r\n console.error(`[Proxy] Bridge ready. Forwarding stdio → ${proxyUrl}`);\r\n\r\n // In proxy mode this function is the long-lived process. Some SDK transports\r\n // finish their async `connect()` setup without leaving an obvious foreground\r\n // handle behind, which can make Node exit immediately after \"Bridge ready\".\r\n // Keep the process alive until Cursor closes stdin or the process receives a\r\n // termination signal.\r\n await new Promise<void>((resolve) => {\r\n const keepAlive = setInterval(() => undefined, 2_147_483_647);\r\n const done = () => {\r\n clearInterval(keepAlive);\r\n resolve();\r\n };\r\n process.stdin.once(\"close\", done);\r\n process.stdin.once(\"end\", done);\r\n process.once(\"SIGINT\", done);\r\n process.once(\"SIGTERM\", done);\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Public entry point\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function runProxyMode(args: string[]): Promise<void> {\r\n const proxyUrl = getArg(args, \"proxy-url\") || process.env.MG_DASHBOARD_PROXY_URL;\r\n const apiKey = getArg(args, \"api-key\") || process.env.MG_DASHBOARD_API_KEY;\r\n const sshKey = getArg(args, \"ssh-key\") || process.env.MG_DASHBOARD_SSH_KEY;\r\n\r\n if (!proxyUrl) {\r\n console.error(\"--proxy-url is required (or set MG_DASHBOARD_PROXY_URL)\");\r\n process.exit(1);\r\n }\r\n if (!apiKey) {\r\n console.error(\"--api-key is required in proxy mode (or set MG_DASHBOARD_API_KEY)\");\r\n process.exit(1);\r\n }\r\n if (!sshKey) {\r\n console.error(\"--ssh-key is required in proxy mode (or set MG_DASHBOARD_SSH_KEY)\");\r\n process.exit(1);\r\n }\r\n\r\n console.error(`[Proxy] Starting in proxy-bridge mode → ${proxyUrl}`);\r\n\r\n let resolved: { pubPath: string; pubText: string };\r\n try {\r\n resolved = resolvePubkeyPath(sshKey);\r\n } catch (err) {\r\n console.error(`[Proxy] ${err instanceof Error ? err.message : String(err)}`);\r\n process.exit(1);\r\n }\r\n\r\n const refresh = () => performHandshake(proxyUrl, apiKey, resolved.pubPath, resolved.pubText);\r\n\r\n let handshake: HandshakeResult;\r\n try {\r\n handshake = await refresh();\r\n } catch (err) {\r\n console.error(`[Proxy] Handshake failed: ${err instanceof Error ? err.message : String(err)}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`[Proxy] Authenticated as \"${handshake.proxyKeyName}\"`);\r\n console.error(`[Proxy] Token valid for ${Math.floor((handshake.expiresAt - Date.now()) / 60000)} min`);\r\n\r\n try {\r\n await runBridge(handshake, proxyUrl, refresh);\r\n } catch (err) {\r\n console.error(`[Proxy] Bridge crashed: ${err instanceof Error ? err.message : String(err)}`);\r\n process.exit(1);\r\n }\r\n}\r\n","/**\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\n/** MCP tool definitions for Trigger.dev (list projects, runs, details, test, replay). */\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.\\n\\n' +\r\n 'Common shortcuts: `failedOnly: true` returns only FAILED/CRASHED/SYSTEM_FAILURE/INTERRUPTED/TIMED_OUT. ' +\r\n '`sinceMinutes: 60` filters to runs created in the last hour (combines with status/taskIdentifier).',\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. Ignored when failedOnly is true.',\r\n },\r\n failedOnly: {\r\n type: 'boolean',\r\n description: 'Shortcut: only return FAILED + CRASHED + SYSTEM_FAILURE + INTERRUPTED + TIMED_OUT runs. Overrides `status` when true.',\r\n },\r\n taskIdentifier: { type: 'string', description: 'Filter by task identifier (e.g. \"hello-world\")' },\r\n sinceMinutes: { type: 'number', description: 'Only runs created in the last N minutes (uses Trigger filter[from]). Max 10080 (= 1 week).' },\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',\r\n description:\r\n 'Inspect, create, or replay a Trigger.dev run. Pick the mode with `action`:\\n' +\r\n '- \"detail\": fetch full run state — status, payload, output, error stack traces, and logs. Required: runId.\\n' +\r\n '- \"test\": kick off a task run and (by default) wait for it to complete, returning the final detail in one shot. Required: taskId. Optional: payload (JSON string), waitSeconds (default 60, max 300, set 0 to fire-and-forget).\\n' +\r\n '- \"replay\": re-run a previously failed/completed run with the same payload. Required: runId. Optional: waitSeconds (when >0, also waits for the new run to finish and returns its full detail).\\n\\n' +\r\n 'Tip: replace any old `trigger-run-detail` / `trigger-test-task` / `trigger-replay-run` calls with this single tool — output format is identical.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: { type: 'string', enum: ['detail', 'test', 'replay'], description: 'Which run operation to perform.' },\r\n project: { type: 'string', description: 'Project slug from trigger-list (e.g. \"mg-dashboard-bHfS\")' },\r\n runId: { type: 'string', description: 'Run ID (e.g. run_xxxxx). Required for action=\"detail\" or action=\"replay\".' },\r\n taskId: { type: 'string', description: 'Task identifier (e.g. \"hello-world\"). Required for action=\"test\".' },\r\n payload: { type: 'string', description: 'JSON payload string passed to the task (action=\"test\" only).' },\r\n waitSeconds: { type: 'number', description: 'Max seconds to wait for completion. Default 60 (action=\"test\") / 0 (action=\"replay\", fire-and-forget). Max 300. Set 0 to skip the wait.' },\r\n },\r\n required: ['action', 'project'],\r\n },\r\n },\r\n];\r\n\r\n/** Set of Trigger.dev MCP tool names for fast membership checks in the main server switch. */\r\nexport const TRIGGER_TOOL_NAMES = new Set(TRIGGER_TOOLS.map((t) => t.name));\r\n\r\n/** Maps each Trigger.dev tool name to the dashboard module key required to use it (`ci_cd`). */\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': '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\n/**\r\n * Executes a Trigger.dev–related MCP tool over SSH against the shared Docker Compose stack.\r\n *\r\n * @param name - Tool name (e.g. `trigger-list`, `trigger-runs`).\r\n * @param args - Arguments from the MCP `callTool` request.\r\n * @param deps - Injected `sshExec` and `getServerConnection` implementations.\r\n * @returns MCP-formatted result with human-readable text content.\r\n * @throws {Error} When a JSON payload for `trigger-test-task` is invalid, or discovery/API calls fail critically.\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\r\n const failedOnly = args.failedOnly === true;\r\n const statusArg = failedOnly\r\n ? 'FAILED,CRASHED,SYSTEM_FAILURE,INTERRUPTED,TIMED_OUT'\r\n : (args.status ? String(args.status) : '');\r\n if (statusArg) queryParts.push(`filter%5Bstatus%5D=${encodeURIComponent(statusArg)}`);\r\n\r\n if (args.taskIdentifier) {\r\n queryParts.push(`filter%5BtaskIdentifier%5D=${encodeURIComponent(String(args.taskIdentifier))}`);\r\n }\r\n\r\n const sinceMinutes = Number(args.sinceMinutes);\r\n if (Number.isFinite(sinceMinutes) && sinceMinutes > 0) {\r\n const capped = Math.min(sinceMinutes, 10080);\r\n const fromMs = Date.now() - capped * 60_000;\r\n queryParts.push(`filter%5Bfrom%5D=${fromMs}`);\r\n }\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': {\r\n const action = String(args.action);\r\n if (action !== 'detail' && action !== 'test' && action !== 'replay') {\r\n return { content: [{ type: 'text', text: 'Error: action must be one of: detail, test, replay' }] };\r\n }\r\n const project = String(args.project);\r\n\r\n if (action === 'detail') {\r\n const runId = String(args.runId ?? '');\r\n if (!runId) return { content: [{ type: 'text', text: 'Error: action=\"detail\" requires runId' }] };\r\n const instance = await discoverInstance(project, conn, proxy, sshExec);\r\n return await fetchAndFormatRun(conn, proxy, sshExec, instance, runId);\r\n }\r\n\r\n if (action === 'test') {\r\n const taskId = String(args.taskId ?? '');\r\n if (!taskId) return { content: [{ type: 'text', text: 'Error: action=\"test\" requires taskId' }] };\r\n\r\n const waitArg = args.waitSeconds === undefined ? 60 : Number(args.waitSeconds);\r\n const waitSeconds = Math.min(Math.max(Number.isFinite(waitArg) ? waitArg : 60, 0), 300);\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 if (waitSeconds === 0) {\r\n return { content: [{ type: 'text', text: `Run triggered. ID: ${runId} (fire-and-forget; use action=\"detail\" to check).` }] };\r\n }\r\n\r\n return await waitForCompletion(conn, proxy, sshExec, instance, runId, waitSeconds);\r\n }\r\n\r\n // action === 'replay'\r\n const runId = String(args.runId ?? '');\r\n if (!runId) return { content: [{ type: 'text', text: 'Error: action=\"replay\" requires runId' }] };\r\n\r\n const waitArg = args.waitSeconds === undefined ? 0 : Number(args.waitSeconds);\r\n const waitSeconds = Math.min(Math.max(Number.isFinite(waitArg) ? waitArg : 0, 0), 300);\r\n if (waitSeconds > 0) conn.timeout = (waitSeconds + 30) * 1000;\r\n\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 if (!result.id) {\r\n return { content: [{ type: 'text', text: `Replay response:\\n${rawJson.substring(0, 500)}` }] };\r\n }\r\n\r\n if (waitSeconds === 0) {\r\n return { content: [{ type: 'text', text: `Run replayed. New run ID: ${result.id} (use action=\"detail\" to check status).` }] };\r\n }\r\n\r\n return await waitForCompletion(conn, proxy, sshExec, instance, result.id, waitSeconds);\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/** Fetch a run by ID and format it together with its console/logger output. */\r\nasync function fetchAndFormatRun(\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n instance: TriggerInstance,\r\n runId: string,\r\n): Promise<ToolResult> {\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) text += '\\n\\n--- Logs ---\\n' + logs;\r\n return { content: [{ type: 'text', text }] };\r\n}\r\n\r\n/** Poll a run until terminal status or budget expires, then return full detail. */\r\nasync function waitForCompletion(\r\n conn: SshConnectionOptions,\r\n proxy: SshConnectionOptions | undefined,\r\n sshExec: SshExecFn,\r\n instance: TriggerInstance,\r\n runId: string,\r\n waitSeconds: number,\r\n): Promise<ToolResult> {\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 action=\"detail\" with this runId to check later.`,\r\n }],\r\n };\r\n}\r\n","/**\r\n * Vercel MCP Tools\r\n *\r\n * Live-fetch tools for Vercel projects, deployments, build logs, runtime\r\n * logs, and webhook delivery history. The MCP server is shipped as a\r\n * standalone npm package and intentionally does NOT depend on\r\n * `@mgboiler/supabase` (which carries Next.js / cookie code), so all Vercel\r\n * REST calls and result formatting live in this file.\r\n *\r\n * The Vercel API token is decrypted from `app_setting.vercel_token_encrypted`\r\n * using the same AES-256-GCM scheme as the dashboard. Both the supabase\r\n * client and the `decrypt` function are injected as deps to avoid circular\r\n * imports with `index.ts`.\r\n *\r\n * @module vercel-tools\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 VercelToolDeps {\r\n supabase: SupabaseClient;\r\n decrypt: (payload: string) => string;\r\n}\r\n\r\nconst VERCEL_API = 'https://api.vercel.com';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Tool definitions\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const VERCEL_TOOLS = [\r\n {\r\n name: 'vercel-projects',\r\n description:\r\n 'List Vercel projects in the configured account/team. Returns id, name, ' +\r\n 'framework, GitHub repo link, production URL, and the latest deployment summary. ' +\r\n 'Use the project name or id as input to vercel-deployments.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n limit: { type: 'number', description: 'Max projects to return (default 50, max 200)' },\r\n search: { type: 'string', description: 'Substring filter on project name (case-insensitive)' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'vercel-deployments',\r\n description:\r\n 'List recent deployments for a Vercel project. Returns deployment ID, ' +\r\n 'state, target, branch, commit and timestamps. Use the deployment ID with ' +\r\n 'vercel-logs.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n project: { type: 'string', description: 'Vercel project ID or name (from vercel-projects)' },\r\n state: {\r\n type: 'string',\r\n description:\r\n 'Optional state filter: BUILDING, ERROR, INITIALIZING, QUEUED, READY, CANCELED',\r\n },\r\n target: { type: 'string', description: 'Optional target filter: production or preview' },\r\n limit: { type: 'number', description: 'Max deployments to return (default 20, max 100)' },\r\n },\r\n required: ['project'],\r\n },\r\n },\r\n {\r\n name: 'vercel-domains',\r\n description:\r\n 'Manage domains attached to a Vercel project. Use `action` to pick the operation:\\n' +\r\n '- \"list\" (default): list all domains attached to the project, including verification status and any redirect.\\n' +\r\n '- \"add\": attach a new domain to the project. Returns DNS records to set if the domain is not yet verified.\\n' +\r\n '- \"verify\": re-check verification status and surface required CNAME / A / TXT records if misconfigured.\\n' +\r\n '- \"remove\": detach a domain from the project.\\n' +\r\n 'Pick the project via vercel-projects first.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: {\r\n type: 'string',\r\n enum: ['list', 'add', 'remove', 'verify'],\r\n description: 'Which operation to perform (default: list).',\r\n },\r\n project: {\r\n type: 'string',\r\n description: 'Vercel project ID or name (from vercel-projects).',\r\n },\r\n domain: {\r\n type: 'string',\r\n description: 'Domain name (required for action=\"add\", \"remove\", or \"verify\").',\r\n },\r\n gitBranch: {\r\n type: 'string',\r\n description: 'Optional git branch this domain should deploy from (action=\"add\" only).',\r\n },\r\n redirect: {\r\n type: 'string',\r\n description: 'Optional redirect target domain (action=\"add\" only).',\r\n },\r\n redirectStatusCode: {\r\n type: 'number',\r\n description: 'Optional redirect status code, e.g. 301 / 302 / 307 / 308 (action=\"add\" only).',\r\n },\r\n },\r\n required: ['project'],\r\n },\r\n },\r\n {\r\n name: 'vercel-logs',\r\n description:\r\n 'Unified log inspector for Vercel. Use `kind` to pick the source:\\n' +\r\n '- \"build\" (default): build / deployment console events (stdout, stderr, command, exit). Requires deploymentId.\\n' +\r\n '- \"runtime\": runtime / function logs after a successful build. Requires project + deploymentId.\\n' +\r\n '- \"webhooks\": our own vercel_webhook_logs table (Telegram / push delivery history). No deployment needed.\\n' +\r\n 'Pick deployments via vercel-deployments first.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n kind: {\r\n type: 'string',\r\n enum: ['build', 'runtime', 'webhooks'],\r\n description: 'Which log stream to fetch (default: build).',\r\n },\r\n project: {\r\n type: 'string',\r\n description: 'Vercel project ID or name (required for kind=\"runtime\").',\r\n },\r\n deploymentId: {\r\n type: 'string',\r\n description: 'Vercel deployment ID (required for kind=\"build\" or \"runtime\").',\r\n },\r\n projectName: {\r\n type: 'string',\r\n description: 'Optional project_name filter (kind=\"webhooks\" only).',\r\n },\r\n status: {\r\n type: 'string',\r\n description: 'Optional status filter (kind=\"webhooks\" only): sent, skipped, error.',\r\n },\r\n sinceMinutes: {\r\n type: 'number',\r\n description:\r\n 'Time window in minutes (kind=\"runtime\" only, max 7 days). When omitted, the tool auto-detects the deployment\\'s created timestamp and queries from there with a 5-minute buffer — so you don\\'t miss logs by picking a too-small window.',\r\n },\r\n limit: {\r\n type: 'number',\r\n description:\r\n 'Max entries to return. Defaults per kind: build=500 (max 5000), runtime=200 (max 1000), webhooks=25 (max 200).',\r\n },\r\n },\r\n },\r\n },\r\n];\r\n\r\nexport const VERCEL_TOOL_NAMES = new Set(VERCEL_TOOLS.map((t) => t.name));\r\n\r\n/** All Vercel tools are gated behind the existing `ci_cd` module permission. */\r\nexport const VERCEL_TOOL_MODULE_MAP: Record<string, string> = {\r\n 'vercel-projects': 'ci_cd',\r\n 'vercel-deployments': 'ci_cd',\r\n 'vercel-logs': 'ci_cd',\r\n 'vercel-domains': 'ci_cd',\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Vercel REST helpers (self-contained — mirrors packages/supabase/src/utils/vercel-api.ts)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface VercelFetchResult<T> {\r\n data: T | null;\r\n error: string | null;\r\n status: number;\r\n}\r\n\r\nasync function vercelFetch<T>(\r\n token: string,\r\n path: string,\r\n init?: { method?: string; body?: unknown },\r\n): Promise<VercelFetchResult<T>> {\r\n const res = await fetch(`${VERCEL_API}${path}`, {\r\n method: init?.method ?? 'GET',\r\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\r\n body: init?.body !== undefined ? JSON.stringify(init.body) : undefined,\r\n });\r\n const body = await res.text();\r\n let parsed: unknown = null;\r\n try {\r\n parsed = body ? JSON.parse(body) : null;\r\n } catch {\r\n // non-JSON\r\n }\r\n if (!res.ok) {\r\n const msg =\r\n (parsed as { error?: { message?: string }; message?: string })?.error?.message ??\r\n (parsed as { message?: string })?.message ??\r\n body ??\r\n `HTTP ${res.status}`;\r\n return { data: null, error: `Vercel API ${res.status}: ${msg}`, status: res.status };\r\n }\r\n return { data: parsed as T, error: null, status: res.status };\r\n}\r\n\r\ninterface VercelProjectListItem {\r\n id: string;\r\n name: string;\r\n framework: string | null;\r\n updatedAt: number;\r\n link?: { org?: string; repo?: string };\r\n latestDeployments?: { id: string; state: string; createdAt: number; url: string | null }[];\r\n targets?: { production?: { url: string | null; alias?: string[] } };\r\n}\r\n\r\ninterface VercelDeployment {\r\n uid: string;\r\n name: string;\r\n url: string | null;\r\n state: string;\r\n created: number;\r\n buildingAt?: number;\r\n ready?: number;\r\n target: string | null;\r\n meta?: {\r\n githubCommitRef?: string;\r\n githubCommitSha?: string;\r\n githubCommitMessage?: string;\r\n githubCommitAuthorLogin?: string;\r\n };\r\n}\r\n\r\ninterface VercelDeploymentEvent {\r\n type: string;\r\n created: number;\r\n payload?: { text?: string };\r\n text?: string;\r\n}\r\n\r\ninterface VercelProjectDomain {\r\n name: string;\r\n apexName?: string;\r\n projectId?: string;\r\n redirect?: string | null;\r\n redirectStatusCode?: number | null;\r\n gitBranch?: string | null;\r\n verified?: boolean;\r\n createdAt?: number;\r\n updatedAt?: number;\r\n verification?: {\r\n type: string;\r\n domain: string;\r\n value: string;\r\n reason?: string;\r\n }[];\r\n}\r\n\r\ninterface VercelDomainConfig {\r\n configuredBy?: 'CNAME' | 'A' | 'http' | null;\r\n acceptedChallenges?: string[];\r\n misconfigured?: boolean;\r\n}\r\n\r\ninterface VercelRuntimeLog {\r\n id?: string;\r\n rowId?: string;\r\n timestampInMs?: number;\r\n timestamp?: number;\r\n level?: string;\r\n message?: string;\r\n text?: string;\r\n source?: string;\r\n requestId?: string;\r\n proxy?: { host?: string; path?: string; method?: string; statusCode?: number };\r\n responseStatusCode?: number;\r\n}\r\n\r\nasync function listVercelProjectsAll(\r\n token: string,\r\n limit: number,\r\n): Promise<{ projects: VercelProjectListItem[]; error: string | null }> {\r\n const collected: VercelProjectListItem[] = [];\r\n let nextTimestamp: number | undefined;\r\n while (collected.length < limit) {\r\n const params = new URLSearchParams({ limit: String(Math.min(limit - collected.length, 100)) });\r\n if (nextTimestamp) params.set('until', String(nextTimestamp));\r\n const res = await vercelFetch<{\r\n projects: VercelProjectListItem[];\r\n pagination: { next: number | null };\r\n }>(token, `/v9/projects?${params.toString()}`);\r\n if (res.error) return { projects: [], error: res.error };\r\n if (!res.data?.projects?.length) break;\r\n collected.push(...res.data.projects);\r\n if (!res.data.pagination?.next) break;\r\n nextTimestamp = res.data.pagination.next;\r\n }\r\n return { projects: collected, error: null };\r\n}\r\n\r\nasync function listVercelDeployments(\r\n token: string,\r\n options: { projectId: string; limit: number; state?: string; target?: string },\r\n): Promise<{ deployments: VercelDeployment[]; error: string | null }> {\r\n const params = new URLSearchParams({\r\n limit: String(options.limit),\r\n projectId: options.projectId,\r\n });\r\n if (options.state) params.set('state', options.state);\r\n if (options.target) params.set('target', options.target);\r\n const res = await vercelFetch<{ deployments: VercelDeployment[] }>(\r\n token,\r\n `/v6/deployments?${params.toString()}`,\r\n );\r\n if (res.error) return { deployments: [], error: res.error };\r\n return { deployments: res.data?.deployments ?? [], error: null };\r\n}\r\n\r\nasync function getDeploymentBuildEvents(\r\n token: string,\r\n deploymentId: string,\r\n limit: number,\r\n): Promise<{ events: VercelDeploymentEvent[]; error: string | null }> {\r\n const params = new URLSearchParams({\r\n limit: String(limit),\r\n direction: 'forward',\r\n follow: '0',\r\n });\r\n const url = `${VERCEL_API}/v3/deployments/${encodeURIComponent(deploymentId)}/events?${params.toString()}`;\r\n const res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${token}` },\r\n });\r\n const body = await res.text();\r\n if (!res.ok) {\r\n let msg: string = body;\r\n try {\r\n const parsed = JSON.parse(body);\r\n msg = parsed?.error?.message ?? parsed?.message ?? body;\r\n } catch {\r\n // raw body\r\n }\r\n return { events: [], error: `Vercel API ${res.status}: ${msg}` };\r\n }\r\n const events: VercelDeploymentEvent[] = [];\r\n const trimmed = body.trim();\r\n if (!trimmed) return { events, error: null };\r\n try {\r\n const parsed = JSON.parse(trimmed);\r\n if (Array.isArray(parsed)) {\r\n for (const r of parsed) events.push(r as VercelDeploymentEvent);\r\n return { events, error: null };\r\n }\r\n } catch {\r\n // ndjson fallthrough\r\n }\r\n for (const line of trimmed.split('\\n')) {\r\n const s = line.trim();\r\n if (!s) continue;\r\n try {\r\n events.push(JSON.parse(s));\r\n } catch {\r\n // skip malformed\r\n }\r\n }\r\n return { events, error: null };\r\n}\r\n\r\n/**\r\n * Fetch the `created` timestamp of a deployment so we can size the runtime-log\r\n * window automatically. Returns null when the deployment isn't found, so the\r\n * caller can fall back to a sensible default window instead of erroring out.\r\n */\r\nasync function getDeploymentCreatedMs(\r\n token: string,\r\n deploymentId: string,\r\n): Promise<number | null> {\r\n const res = await vercelFetch<{ createdAt?: number; created?: number }>(\r\n token,\r\n `/v13/deployments/${encodeURIComponent(deploymentId)}`,\r\n );\r\n if (res.error || !res.data) return null;\r\n return res.data.createdAt ?? res.data.created ?? null;\r\n}\r\n\r\nasync function getRuntimeLogs(\r\n token: string,\r\n projectIdOrName: string,\r\n deploymentId: string,\r\n limit: number,\r\n sinceMs?: number,\r\n): Promise<{ logs: VercelRuntimeLog[]; error: string | null }> {\r\n const params = new URLSearchParams({\r\n limit: String(Math.min(Math.max(limit, 1), 1000)),\r\n });\r\n if (sinceMs) params.set('since', String(sinceMs));\r\n const url = `${VERCEL_API}/v1/projects/${encodeURIComponent(projectIdOrName)}/deployments/${encodeURIComponent(deploymentId)}/runtime-logs?${params.toString()}`;\r\n const res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${token}` },\r\n });\r\n const body = await res.text();\r\n if (!res.ok) {\r\n let msg: string = body;\r\n try {\r\n const parsed = JSON.parse(body);\r\n msg = parsed?.error?.message ?? parsed?.message ?? body;\r\n } catch {\r\n // raw body\r\n }\r\n return { logs: [], error: `Vercel API ${res.status}: ${msg}` };\r\n }\r\n const logs: VercelRuntimeLog[] = [];\r\n const trimmed = body.trim();\r\n if (!trimmed) return { logs, error: null };\r\n try {\r\n const parsed = JSON.parse(trimmed);\r\n if (Array.isArray(parsed)) {\r\n for (const r of parsed) logs.push(r as VercelRuntimeLog);\r\n return { logs, error: null };\r\n }\r\n } catch {\r\n // ndjson fallthrough\r\n }\r\n for (const line of trimmed.split('\\n')) {\r\n const s = line.trim();\r\n if (!s) continue;\r\n try {\r\n logs.push(JSON.parse(s));\r\n } catch {\r\n // skip\r\n }\r\n }\r\n return { logs, error: null };\r\n}\r\n\r\nasync function listProjectDomains(\r\n token: string,\r\n projectId: string,\r\n): Promise<{ domains: VercelProjectDomain[]; error: string | null }> {\r\n const res = await vercelFetch<{ domains: VercelProjectDomain[] }>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectId)}/domains?limit=100`,\r\n );\r\n if (res.error) return { domains: [], error: res.error };\r\n return { domains: res.data?.domains ?? [], error: null };\r\n}\r\n\r\nasync function addProjectDomain(\r\n token: string,\r\n projectId: string,\r\n body: {\r\n name: string;\r\n gitBranch?: string;\r\n redirect?: string;\r\n redirectStatusCode?: number;\r\n },\r\n): Promise<{ domain: VercelProjectDomain | null; error: string | null }> {\r\n const res = await vercelFetch<VercelProjectDomain>(\r\n token,\r\n `/v10/projects/${encodeURIComponent(projectId)}/domains`,\r\n { method: 'POST', body },\r\n );\r\n if (res.error) return { domain: null, error: res.error };\r\n return { domain: res.data, error: null };\r\n}\r\n\r\nasync function removeProjectDomain(\r\n token: string,\r\n projectId: string,\r\n domain: string,\r\n): Promise<{ error: string | null }> {\r\n const res = await vercelFetch<unknown>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(domain)}`,\r\n { method: 'DELETE' },\r\n );\r\n return { error: res.error };\r\n}\r\n\r\nasync function getProjectDomain(\r\n token: string,\r\n projectId: string,\r\n domain: string,\r\n): Promise<{ domain: VercelProjectDomain | null; error: string | null }> {\r\n const res = await vercelFetch<VercelProjectDomain>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(domain)}`,\r\n );\r\n if (res.error) return { domain: null, error: res.error };\r\n return { domain: res.data, error: null };\r\n}\r\n\r\nasync function getDomainConfig(\r\n token: string,\r\n domain: string,\r\n): Promise<{ config: VercelDomainConfig | null; error: string | null }> {\r\n const res = await vercelFetch<VercelDomainConfig>(\r\n token,\r\n `/v6/domains/${encodeURIComponent(domain)}/config`,\r\n );\r\n if (res.error) return { config: null, error: res.error };\r\n return { config: res.data, error: null };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Token resolution\r\n// ---------------------------------------------------------------------------\r\n\r\nasync function getVercelToken(deps: VercelToolDeps): Promise<string> {\r\n const { data, error } = await deps.supabase\r\n .from('app_setting')\r\n .select('vercel_token_encrypted')\r\n .maybeSingle();\r\n if (error) throw new Error(`Could not read app_setting: ${error.message}`);\r\n if (!data?.vercel_token_encrypted) {\r\n throw new Error('Vercel API token is not configured. Add it in dashboard Settings.');\r\n }\r\n try {\r\n return deps.decrypt(data.vercel_token_encrypted);\r\n } catch {\r\n throw new Error('Failed to decrypt the stored Vercel API token.');\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a project name or ID to its Vercel project ID.\r\n * Vercel's deployment list endpoint accepts both, but we still need the\r\n * canonical ID for the runtime-logs endpoint and to match by-name lookups.\r\n */\r\nasync function resolveProjectId(token: string, projectInput: string): Promise<string> {\r\n const res = await vercelFetch<{ id: string }>(\r\n token,\r\n `/v9/projects/${encodeURIComponent(projectInput)}`,\r\n );\r\n if (res.error || !res.data?.id) {\r\n throw new Error(\r\n `Could not resolve Vercel project \"${projectInput}\": ${res.error ?? 'not found'}`,\r\n );\r\n }\r\n return res.data.id;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Output formatters\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction formatTimestamp(ms: number | undefined): string {\r\n if (!ms) return '';\r\n return new Date(ms).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' });\r\n}\r\n\r\nfunction formatProjectsTable(projects: VercelProjectListItem[]): string {\r\n if (projects.length === 0) return 'No Vercel projects found';\r\n const lines = projects.map((p) => {\r\n const repo = p.link ? `${p.link.org ?? ''}/${p.link.repo ?? ''}` : '';\r\n const prodUrl =\r\n p.targets?.production?.alias?.[0] ?? p.targets?.production?.url ?? '';\r\n const latest = p.latestDeployments?.[0];\r\n const latestStr = latest ? `${latest.state} @ ${formatTimestamp(latest.createdAt)}` : '';\r\n return `${p.id.padEnd(28)} ${(p.name || '').padEnd(40)} ${(p.framework || '-').padEnd(10)} ${repo.padEnd(40)} ${prodUrl.padEnd(35)} ${latestStr}`;\r\n });\r\n const header = `${'ID'.padEnd(28)} ${'NAME'.padEnd(40)} ${'FRAMEWORK'.padEnd(10)} ${'REPO'.padEnd(40)} ${'PROD URL'.padEnd(35)} LATEST`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\nfunction formatDeploymentsTable(deployments: VercelDeployment[]): string {\r\n if (deployments.length === 0) return 'No deployments found';\r\n const lines = deployments.map((d) => {\r\n const branch = d.meta?.githubCommitRef ?? '';\r\n const sha = d.meta?.githubCommitSha?.slice(0, 7) ?? '';\r\n const msg = (d.meta?.githubCommitMessage ?? '').replace(/\\n.*/s, '').slice(0, 60);\r\n return `${d.uid.padEnd(28)} ${d.state.padEnd(11)} ${(d.target || '-').padEnd(10)} ${branch.padEnd(20)} ${sha.padEnd(8)} ${formatTimestamp(d.created).padEnd(20)} ${msg}`;\r\n });\r\n const header = `${'ID'.padEnd(28)} ${'STATE'.padEnd(11)} ${'TARGET'.padEnd(10)} ${'BRANCH'.padEnd(20)} ${'COMMIT'.padEnd(8)} ${'CREATED'.padEnd(20)} MESSAGE`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\nfunction formatBuildEvents(events: VercelDeploymentEvent[]): string {\r\n if (events.length === 0) return 'No build events found for this deployment';\r\n const filtered = events.filter((e) =>\r\n ['command', 'stdout', 'stderr', 'exit', 'delimiter', 'deployment-state'].includes(e.type),\r\n );\r\n return filtered\r\n .map((e) => {\r\n const time = e.created\r\n ? new Date(e.created).toISOString().slice(11, 19)\r\n : '--:--:--';\r\n const text = (e.payload?.text ?? e.text ?? '').replace(/\\s+$/u, '');\r\n const prefix = e.type === 'stderr' ? '!' : ' ';\r\n return `${prefix}${time} [${e.type.padEnd(16)}] ${text}`;\r\n })\r\n .join('\\n');\r\n}\r\n\r\nfunction formatRuntimeLogs(logs: VercelRuntimeLog[]): string {\r\n if (logs.length === 0) {\r\n return 'No runtime logs found for this deployment in the requested window';\r\n }\r\n return logs\r\n .map((l) => {\r\n const ts = l.timestampInMs ?? l.timestamp ?? 0;\r\n const time = ts ? new Date(ts).toISOString().slice(11, 23) : '--:--:--';\r\n const level = (l.level ?? 'info').toUpperCase().padEnd(5);\r\n const status = l.proxy?.statusCode ?? l.responseStatusCode;\r\n const reqInfo = l.proxy?.method\r\n ? `${l.proxy.method} ${l.proxy.path ?? ''} ${status ?? ''}`.trim()\r\n : '';\r\n const message = (l.message ?? l.text ?? '').replace(/\\s+$/u, '');\r\n const reqId = l.requestId ? ` [${l.requestId.slice(0, 12)}]` : '';\r\n const head = reqInfo ? `${reqInfo}${reqId}` : reqId.trim();\r\n return `${time} [${level}] ${head ? head + ' ' : ''}${message}`;\r\n })\r\n .join('\\n');\r\n}\r\n\r\ninterface WebhookLogRow {\r\n id: string;\r\n event_type: string;\r\n status: string;\r\n project_name: string | null;\r\n deployment_id: string | null;\r\n target: string | null;\r\n message: string | null;\r\n error_message: string | null;\r\n created_at: string;\r\n}\r\n\r\nfunction formatWebhookHistory(rows: WebhookLogRow[]): string {\r\n if (rows.length === 0) return 'No webhook log rows match those filters';\r\n const lines = rows.map((r) => {\r\n const ts = new Date(r.created_at).toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' });\r\n const note = r.error_message ?? r.message ?? '';\r\n return `${ts.padEnd(20)} ${r.event_type.padEnd(22)} ${r.status.padEnd(8)} ${(r.project_name ?? '').padEnd(40)} ${(r.target ?? '').padEnd(10)} ${(r.deployment_id ?? '').padEnd(28)} ${note}`;\r\n });\r\n const header = `${'WHEN'.padEnd(20)} ${'EVENT'.padEnd(22)} ${'STATUS'.padEnd(8)} ${'PROJECT'.padEnd(40)} ${'TARGET'.padEnd(10)} ${'DEPLOYMENT'.padEnd(28)} NOTE`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\nfunction formatDomainsTable(domains: VercelProjectDomain[]): string {\r\n if (domains.length === 0) return 'No domains attached to this project';\r\n const lines = domains.map((d) => {\r\n const verified = d.verified ? 'yes' : 'no';\r\n const branch = d.gitBranch ?? '';\r\n const redirect = d.redirect\r\n ? `${d.redirect}${d.redirectStatusCode ? ` (${d.redirectStatusCode})` : ''}`\r\n : '';\r\n return `${d.name.padEnd(45)} ${verified.padEnd(9)} ${branch.padEnd(20)} ${redirect.padEnd(35)} ${formatTimestamp(d.createdAt)}`;\r\n });\r\n const header = `${'DOMAIN'.padEnd(45)} ${'VERIFIED'.padEnd(9)} ${'GIT BRANCH'.padEnd(20)} ${'REDIRECT'.padEnd(35)} CREATED`;\r\n return `${header}\\n${'-'.repeat(header.length)}\\n${lines.join('\\n')}`;\r\n}\r\n\r\n/**\r\n * Render a single domain's status: verified/misconfigured plus any verification\r\n * records the user still needs to add to DNS.\r\n */\r\nfunction formatDomainStatus(\r\n domain: VercelProjectDomain,\r\n config: VercelDomainConfig | null,\r\n): string {\r\n const lines: string[] = [];\r\n lines.push(`Domain: ${domain.name}`);\r\n lines.push(`Verified: ${domain.verified ? 'yes' : 'no'}`);\r\n if (config) {\r\n lines.push(`Misconfigured: ${config.misconfigured ? 'yes' : 'no'}`);\r\n if (config.configuredBy) lines.push(`Configured by: ${config.configuredBy}`);\r\n }\r\n if (domain.gitBranch) lines.push(`Git branch: ${domain.gitBranch}`);\r\n if (domain.redirect) {\r\n lines.push(\r\n `Redirect: ${domain.redirect}${domain.redirectStatusCode ? ` (${domain.redirectStatusCode})` : ''}`,\r\n );\r\n }\r\n if (domain.verification && domain.verification.length > 0) {\r\n lines.push('');\r\n lines.push('Required DNS records to verify ownership:');\r\n for (const v of domain.verification) {\r\n lines.push(` ${v.type.padEnd(6)} ${v.domain.padEnd(45)} ${v.value}${v.reason ? ` // ${v.reason}` : ''}`);\r\n }\r\n }\r\n return lines.join('\\n');\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main handler\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Dispatch a `vercel-*` MCP tool. Resolves the Vercel API token from\r\n * `app_setting.vercel_token_encrypted` on every call (cheap, single-row\r\n * lookup); avoids any process-level token caching to ensure rotated\r\n * tokens are picked up immediately.\r\n */\r\nexport async function handleVercelTool(\r\n name: string,\r\n args: Record<string, unknown>,\r\n deps: VercelToolDeps,\r\n): Promise<ToolResult> {\r\n switch (name) {\r\n case 'vercel-projects': {\r\n const token = await getVercelToken(deps);\r\n const limit = Math.min(Math.max(Number(args.limit) || 50, 1), 200);\r\n const search = typeof args.search === 'string' ? args.search.toLowerCase() : null;\r\n const { projects, error } = await listVercelProjectsAll(token, limit);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n const filtered = search\r\n ? projects.filter((p) => (p.name || '').toLowerCase().includes(search))\r\n : projects;\r\n return { content: [{ type: 'text', text: formatProjectsTable(filtered) }] };\r\n }\r\n\r\n case 'vercel-deployments': {\r\n const token = await getVercelToken(deps);\r\n const projectInput = String(args.project);\r\n const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);\r\n const projectId = await resolveProjectId(token, projectInput);\r\n const { deployments, error } = await listVercelDeployments(token, {\r\n projectId,\r\n limit,\r\n state: args.state ? String(args.state) : undefined,\r\n target: args.target ? String(args.target) : undefined,\r\n });\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: formatDeploymentsTable(deployments) }] };\r\n }\r\n\r\n case 'vercel-logs': {\r\n const kind = (args.kind ? String(args.kind) : 'build').toLowerCase();\r\n\r\n if (kind === 'build') {\r\n if (!args.deploymentId) {\r\n return { content: [{ type: 'text', text: 'Error: kind=\"build\" requires deploymentId.' }] };\r\n }\r\n const token = await getVercelToken(deps);\r\n const deploymentId = String(args.deploymentId);\r\n const limit = Math.min(Math.max(Number(args.limit) || 500, 1), 5000);\r\n const { events, error } = await getDeploymentBuildEvents(token, deploymentId, limit);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: formatBuildEvents(events) }] };\r\n }\r\n\r\n if (kind === 'runtime') {\r\n if (!args.project || !args.deploymentId) {\r\n return {\r\n content: [\r\n { type: 'text', text: 'Error: kind=\"runtime\" requires both project and deploymentId.' },\r\n ],\r\n };\r\n }\r\n const token = await getVercelToken(deps);\r\n const projectInput = String(args.project);\r\n const deploymentId = String(args.deploymentId);\r\n const limit = Math.min(Math.max(Number(args.limit) || 200, 1), 1000);\r\n\r\n const sinceMinutesRaw = Number(args.sinceMinutes);\r\n const sinceExplicit = Number.isFinite(sinceMinutesRaw) && sinceMinutesRaw > 0;\r\n\r\n // Resolve project ID and (when needed) deployment createdAt in parallel\r\n // so the implicit auto-window costs only one extra round trip.\r\n const [projectId, deploymentCreatedMs] = await Promise.all([\r\n resolveProjectId(token, projectInput),\r\n sinceExplicit ? Promise.resolve(null) : getDeploymentCreatedMs(token, deploymentId),\r\n ]);\r\n\r\n // Vercel's runtime-logs endpoint has a 5-minute server-side query\r\n // budget that scales with window size — wider windows are far more\r\n // likely to time out than to actually return more useful data. So\r\n // we deliberately bias toward narrow windows: auto-default is 30 min\r\n // max even for very old deployments. Callers can still override via\r\n // `sinceMinutes` up to 7 days, but they get a clear warning when the\r\n // auto picks something noticeably shorter than the deployment age.\r\n const maxWindowMin = 7 * 24 * 60;\r\n const autoCapMin = 30;\r\n let sinceMs: number;\r\n let windowNote = '';\r\n if (sinceExplicit) {\r\n const capped = Math.min(sinceMinutesRaw, maxWindowMin);\r\n sinceMs = Date.now() - capped * 60_000;\r\n windowNote = `window: last ${capped} min (caller-specified)`;\r\n } else if (deploymentCreatedMs) {\r\n const bufferMs = 5 * 60_000;\r\n const sinceDeploymentMs = deploymentCreatedMs - bufferMs;\r\n const ageMin = Math.max(1, Math.round((Date.now() - sinceDeploymentMs) / 60_000));\r\n if (ageMin <= autoCapMin) {\r\n sinceMs = sinceDeploymentMs;\r\n windowNote = `window: auto ${ageMin} min from deployment createdAt - 5 min buffer`;\r\n } else {\r\n sinceMs = Date.now() - autoCapMin * 60_000;\r\n windowNote = `window: capped to last ${autoCapMin} min (deployment is ${ageMin} min old — pass sinceMinutes to widen up to ${maxWindowMin})`;\r\n }\r\n } else {\r\n sinceMs = Date.now() - autoCapMin * 60_000;\r\n windowNote = `window: last ${autoCapMin} min (deployment metadata unavailable, used fallback)`;\r\n }\r\n\r\n const { logs, error } = await getRuntimeLogs(\r\n token,\r\n projectId,\r\n deploymentId,\r\n limit,\r\n sinceMs,\r\n );\r\n if (error) {\r\n const hint =\r\n error.includes('404') || error.includes('400')\r\n ? '\\n\\nThis endpoint requires both project ID and deployment ID and may not be available on every Vercel plan. Use kind=\"webhooks\" or the supabase MCP (vercel_deployment_log table) for archived runtime logs.'\r\n : '';\r\n return { content: [{ type: 'text', text: `Error: ${error}${hint}` }] };\r\n }\r\n const body = formatRuntimeLogs(logs);\r\n // Vercel returns \"Exceeded query duration limit of 5 minutes\" inline\r\n // as a synthetic log entry when its server can't finish scanning the\r\n // window. Catch it and add a hint instead of leaving the LLM\r\n // confused by what looks like a normal log line.\r\n const hitDurationLimit = /Exceeded query duration limit/i.test(body);\r\n const footer = hitDurationLimit\r\n ? `\\n\\n[${windowNote}]\\n[hint] Vercel hit its 5-min query budget for this window. Try a smaller sinceMinutes (e.g. 5-10), lower limit, or use kind=\"webhooks\" / the supabase MCP vercel_deployment_log table for archived logs.`\r\n : `\\n\\n[${windowNote}]`;\r\n return { content: [{ type: 'text', text: body + footer }] };\r\n }\r\n\r\n if (kind === 'webhooks') {\r\n const limit = Math.min(Math.max(Number(args.limit) || 25, 1), 200);\r\n let query = deps.supabase\r\n .from('vercel_webhook_logs')\r\n .select(\r\n 'id, event_type, status, project_name, deployment_id, target, message, error_message, created_at',\r\n )\r\n .order('created_at', { ascending: false })\r\n .limit(limit);\r\n if (args.projectName) query = query.eq('project_name', String(args.projectName));\r\n if (args.status) query = query.eq('status', String(args.status));\r\n const { data, error } = await query;\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error.message}` }] };\r\n return {\r\n content: [{ type: 'text', text: formatWebhookHistory((data as WebhookLogRow[]) ?? []) }],\r\n };\r\n }\r\n\r\n return {\r\n content: [\r\n { type: 'text', text: `Error: unknown kind \"${kind}\". Use build, runtime, or webhooks.` },\r\n ],\r\n };\r\n }\r\n\r\n case 'vercel-domains': {\r\n const action = (args.action ? String(args.action) : 'list').toLowerCase();\r\n if (!args.project) {\r\n return { content: [{ type: 'text', text: 'Error: vercel-domains requires \"project\".' }] };\r\n }\r\n const token = await getVercelToken(deps);\r\n const projectInput = String(args.project);\r\n const projectId = await resolveProjectId(token, projectInput);\r\n\r\n if (action === 'list') {\r\n const { domains, error } = await listProjectDomains(token, projectId);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: formatDomainsTable(domains) }] };\r\n }\r\n\r\n if (action === 'add') {\r\n if (!args.domain) {\r\n return { content: [{ type: 'text', text: 'Error: action=\"add\" requires \"domain\".' }] };\r\n }\r\n const body: {\r\n name: string;\r\n gitBranch?: string;\r\n redirect?: string;\r\n redirectStatusCode?: number;\r\n } = { name: String(args.domain) };\r\n if (args.gitBranch) body.gitBranch = String(args.gitBranch);\r\n if (args.redirect) body.redirect = String(args.redirect);\r\n if (args.redirectStatusCode) body.redirectStatusCode = Number(args.redirectStatusCode);\r\n const { domain, error } = await addProjectDomain(token, projectId, body);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n if (!domain) {\r\n return { content: [{ type: 'text', text: `Domain ${body.name} added (no detail returned).` }] };\r\n }\r\n const { config } = await getDomainConfig(token, domain.name);\r\n const status = formatDomainStatus(domain, config);\r\n const headline = domain.verified\r\n ? `Domain ${domain.name} added and verified.`\r\n : `Domain ${domain.name} added. DNS verification still pending.`;\r\n return { content: [{ type: 'text', text: `${headline}\\n\\n${status}` }] };\r\n }\r\n\r\n if (action === 'verify') {\r\n if (!args.domain) {\r\n return { content: [{ type: 'text', text: 'Error: action=\"verify\" requires \"domain\".' }] };\r\n }\r\n const domainName = String(args.domain);\r\n const { domain, error } = await getProjectDomain(token, projectId, domainName);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n if (!domain) {\r\n return { content: [{ type: 'text', text: `Domain ${domainName} not found on this project.` }] };\r\n }\r\n const { config } = await getDomainConfig(token, domainName);\r\n return { content: [{ type: 'text', text: formatDomainStatus(domain, config) }] };\r\n }\r\n\r\n if (action === 'remove') {\r\n if (!args.domain) {\r\n return { content: [{ type: 'text', text: 'Error: action=\"remove\" requires \"domain\".' }] };\r\n }\r\n const domainName = String(args.domain);\r\n const { error } = await removeProjectDomain(token, projectId, domainName);\r\n if (error) return { content: [{ type: 'text', text: `Error: ${error}` }] };\r\n return { content: [{ type: 'text', text: `Domain ${domainName} removed from project.` }] };\r\n }\r\n\r\n return {\r\n content: [\r\n { type: 'text', text: `Error: unknown action \"${action}\". Use list, add, verify, or remove.` },\r\n ],\r\n };\r\n }\r\n\r\n default:\r\n return { content: [{ type: 'text', text: `Unknown vercel 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 { spawn } from 'node:child_process';\r\nimport { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';\r\nimport { createReadStream, existsSync, statSync } from 'node:fs';\r\nimport { tmpdir } from 'node:os';\r\nimport { isAbsolute, join } from 'node:path';\r\nimport { Readable } from 'node:stream';\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 VERCEL_TOOLS,\r\n VERCEL_TOOL_NAMES,\r\n VERCEL_TOOL_MODULE_MAP,\r\n handleVercelTool,\r\n} from './vercel-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\n// ---------------------------------------------------------------------------\r\n// Proxy-bridge mode: when --proxy-url is given we bypass the rest of this\r\n// file entirely and run as a thin SSH-key-authenticated bridge to a remote\r\n// MCP HTTP endpoint (used for the Supabase MCPs behind apps/mcp-proxy).\r\n// ---------------------------------------------------------------------------\r\nconst proxyUrl = getArg('proxy-url') || process.env.MG_DASHBOARD_PROXY_URL;\r\nif (proxyUrl) {\r\n const { runProxyMode } = await import('./proxy-mode.js');\r\n await runProxyMode(args);\r\n // runProxyMode never resolves under normal operation; if it does, exit.\r\n process.exit(0);\r\n}\r\n\r\nconst apiKey = getArg('api-key') || process.env.MG_DASHBOARD_API_KEY;\r\nconst sshKeyPath = getArg('ssh-key') || process.env.MG_DASHBOARD_SSH_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 httpMode = args.includes('--http');\r\nconst httpPort = Number(getArg('port')) || 3100;\r\n\r\nif (!apiKey || !sshKeyPath) {\r\n console.error('Authentication required. Use both --api-key=dk_xxx and --ssh-key=PATH (path to your SSH private or public key), or set MG_DASHBOARD_API_KEY and MG_DASHBOARD_SSH_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// Tool-level rate limiting was previously gated per category (ssh / sftp / db\r\n// / default) with hourly buckets. Removed because legitimate dev sessions\r\n// regularly burst over those caps and the resulting \"MCP Rate Limit\" stalls\r\n// were strictly noise — auth-level rate limiting (failed login attempts)\r\n// remains in place above for the actual security concern.\r\n\r\n// ---------------------------------------------------------------------------\r\n// Audit logging\r\n// ---------------------------------------------------------------------------\r\n\r\nconst SENSITIVE_KEYS = new Set(['password', 'private_key', 'passphrase', 'secret', 'token', 'key', 'api_key', 'credentials']);\r\n\r\nfunction redactSensitiveArgs(args: Record<string, unknown>): Record<string, unknown> {\r\n const redacted: Record<string, unknown> = {};\r\n for (const [k, v] of Object.entries(args)) {\r\n if (SENSITIVE_KEYS.has(k.toLowerCase())) {\r\n redacted[k] = '[REDACTED]';\r\n } else if (typeof v === 'string' && v.length > 500) {\r\n redacted[k] = v.slice(0, 500) + '...[truncated]';\r\n } else {\r\n redacted[k] = v;\r\n }\r\n }\r\n return redacted;\r\n}\r\n\r\nasync function writeAuditLog(entry: {\r\n toolName: string;\r\n arguments?: Record<string, unknown>;\r\n ipAddress?: string;\r\n serverId?: string;\r\n resultStatus: 'success' | 'error';\r\n errorMessage?: string;\r\n durationMs?: number;\r\n}): Promise<void> {\r\n if (!authContext) return;\r\n try {\r\n await supabase.from('mcp_audit_log').insert({\r\n api_key_id: authContext.apiKeyId,\r\n user_id: authContext.userId,\r\n tool_name: entry.toolName,\r\n arguments: entry.arguments ? redactSensitiveArgs(entry.arguments) : null,\r\n ip_address: entry.ipAddress || null,\r\n server_id: entry.serverId || null,\r\n result_status: entry.resultStatus,\r\n error_message: entry.errorMessage?.slice(0, 1000) || null,\r\n duration_ms: entry.durationMs || null,\r\n });\r\n } catch (err) {\r\n console.error('[Audit] Failed to write audit log:', err instanceof Error ? err.message : err);\r\n }\r\n}\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', 'domains',\r\n 'settings',\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\r\n domains?: boolean;\r\n settings?: 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 'docker-exec': 'ssh_servers',\r\n 'docker-compose': 'ssh_servers',\r\n 'wait-for': 'ssh_servers',\r\n 'db-discover': 'ssh_servers',\r\n 'db-tables': '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 'dns-list': 'domains',\r\n 'dns-record': 'domains',\r\n ...TRIGGER_TOOL_MODULE_MAP,\r\n ...VERCEL_TOOL_MODULE_MAP,\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Auth context\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface AuthContext {\r\n apiKeyId: string;\r\n apiKeyName: string;\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, name, 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 apiKeyId: data.id,\r\n apiKeyName: data.name || 'Unknown',\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// SSH-key authentication\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Run a child process and return { stdout, stderr, code }. Never throws. */\r\nfunction runProcess(\r\n command: string,\r\n argv: string[],\r\n options: { stdin?: string; cwd?: string } = {},\r\n): Promise<{ stdout: string; stderr: string; code: number }> {\r\n return new Promise((resolve) => {\r\n const child = spawn(command, argv, { cwd: options.cwd, stdio: ['pipe', 'pipe', 'pipe'] });\r\n let stdout = '';\r\n let stderr = '';\r\n child.stdout.on('data', (d) => { stdout += d.toString(); });\r\n child.stderr.on('data', (d) => { stderr += d.toString(); });\r\n child.on('error', (err) => {\r\n resolve({ stdout, stderr: stderr + String(err), code: -1 });\r\n });\r\n child.on('close', (code) => {\r\n resolve({ stdout, stderr, code: code ?? -1 });\r\n });\r\n if (options.stdin !== undefined) {\r\n child.stdin.write(options.stdin);\r\n child.stdin.end();\r\n } else {\r\n child.stdin.end();\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Resolve the user's SSH public-key file from the path they passed.\r\n *\r\n * Accepts either a `.pub` file directly, or a private-key path (in which case\r\n * we look for `${path}.pub` next to it). Returns the public-key file path and\r\n * its contents trimmed.\r\n */\r\nasync function resolvePubkeyFile(input: string): Promise<{ pubPath: string; pubText: string }> {\r\n const expand = (p: string) => p.startsWith('~')\r\n ? join(process.env.HOME || process.env.USERPROFILE || '', p.slice(1))\r\n : p;\r\n const candidate = expand(input);\r\n let pubPath: string;\r\n if (candidate.endsWith('.pub')) {\r\n pubPath = candidate;\r\n } else if (existsSync(`${candidate}.pub`)) {\r\n pubPath = `${candidate}.pub`;\r\n } else if (existsSync(candidate)) {\r\n // Caller passed a public-key file without `.pub` extension; tolerate it.\r\n pubPath = candidate;\r\n } else {\r\n throw new Error(`SSH key file not found: ${candidate} (also tried ${candidate}.pub)`);\r\n }\r\n const pubText = (await readFile(pubPath, 'utf8')).trim();\r\n if (!pubText) {\r\n throw new Error(`SSH public-key file is empty: ${pubPath}`);\r\n }\r\n return { pubPath, pubText };\r\n}\r\n\r\n/**\r\n * Compute the OpenSSH SHA256 fingerprint (\"SHA256:abc...\") of a public-key\r\n * line. This matches the format that `ssh-keygen -lf <pubkey>` prints and\r\n * what we store in `dashboard_mcp_ssh_key.fingerprint_sha256`.\r\n */\r\nfunction computeOpenSshFingerprint(pubkeyLine: string): string {\r\n const parts = pubkeyLine.trim().split(/\\s+/);\r\n if (parts.length < 2 || !parts[1]) {\r\n throw new Error('Invalid SSH public-key line (expected \"<type> <base64> [comment]\")');\r\n }\r\n const bodyBytes = Buffer.from(parts[1], 'base64');\r\n const hash = createHash('sha256').update(bodyBytes).digest('base64').replace(/=+$/, '');\r\n return `SHA256:${hash}`;\r\n}\r\n\r\n/**\r\n * Sign a challenge with the user's SSH key (via ssh-agent or on-disk key).\r\n * Uses `ssh-keygen -Y sign` (SSHSIG format, OpenSSH >= 8.2).\r\n *\r\n * Returns the armored signature (\"-----BEGIN SSH SIGNATURE----- ...\").\r\n */\r\nasync function sshKeygenSign(pubkeyPath: string, challenge: string, namespace: string): Promise<string> {\r\n const result = await runProcess(\r\n 'ssh-keygen',\r\n ['-Y', 'sign', '-f', pubkeyPath, '-n', namespace, '-q'],\r\n { stdin: challenge },\r\n );\r\n if (result.code !== 0) {\r\n throw new Error(\r\n `ssh-keygen sign failed (exit ${result.code}). ` +\r\n `Make sure ssh-agent is running and has the matching private key loaded ` +\r\n `(or that the private key is at the path next to the .pub file). ` +\r\n `stderr: ${result.stderr.trim() || '(empty)'}`,\r\n );\r\n }\r\n if (!result.stdout.includes('BEGIN SSH SIGNATURE')) {\r\n throw new Error(`ssh-keygen sign produced no signature (stderr: ${result.stderr.trim() || '(empty)'})`);\r\n }\r\n return result.stdout;\r\n}\r\n\r\n/**\r\n * Verify an SSHSIG armored signature against a known public-key line.\r\n * Returns true if the signature is valid.\r\n */\r\nasync function sshKeygenVerify(\r\n pubkeyLine: string,\r\n signature: string,\r\n challenge: string,\r\n namespace: string,\r\n): Promise<boolean> {\r\n const dir = await mkdtemp(join(tmpdir(), 'mcp-ssh-verify-'));\r\n try {\r\n const allowedSigners = `mcp@local ${pubkeyLine.trim()}\\n`;\r\n const allowedPath = join(dir, 'allowed_signers');\r\n const sigPath = join(dir, 'sig');\r\n await writeFile(allowedPath, allowedSigners, 'utf8');\r\n await writeFile(sigPath, signature, 'utf8');\r\n const result = await runProcess(\r\n 'ssh-keygen',\r\n ['-Y', 'verify', '-f', allowedPath, '-I', 'mcp@local', '-n', namespace, '-s', sigPath, '-q'],\r\n { stdin: challenge },\r\n );\r\n return result.code === 0;\r\n } finally {\r\n await rm(dir, { recursive: true, force: true }).catch(() => undefined);\r\n }\r\n}\r\n\r\n/**\r\n * Authenticate to the dashboard using an SSH key.\r\n *\r\n * 1. Read the user's pubkey file and compute its SHA256 fingerprint.\r\n * 2. Generate a fresh nonce, sign it via `ssh-keygen -Y sign` (uses ssh-agent\r\n * or the private key on disk), then locally verify the signature against\r\n * the pubkey we read. This proves the caller actually possesses the\r\n * private key (or has it loaded in ssh-agent), not just a stolen pubkey.\r\n * 3. Look up the fingerprint in `dashboard_mcp_ssh_key`, require it to be\r\n * linked to the already validated API key, then load permissions exactly\r\n * like the bearer-token path does.\r\n *\r\n * The signature step is optional but defaults to ON. Set\r\n * `MG_DASHBOARD_SSH_SKIP_VERIFY=1` to skip it (e.g. for first-time enrollment\r\n * before the key is registered, where you just want to print the fingerprint).\r\n */\r\nasync function validateSshKey(\r\n pubkeyPathInput: string,\r\n expectedApiKeyId: string,\r\n): Promise<AuthContext | null> {\r\n let pubPath: string;\r\n let pubText: string;\r\n try {\r\n const resolved = await resolvePubkeyFile(pubkeyPathInput);\r\n pubPath = resolved.pubPath;\r\n pubText = resolved.pubText;\r\n } catch (err) {\r\n console.error(`SSH key error: ${err instanceof Error ? err.message : String(err)}`);\r\n return null;\r\n }\r\n\r\n let fingerprint: string;\r\n try {\r\n fingerprint = computeOpenSshFingerprint(pubText);\r\n } catch (err) {\r\n console.error(`SSH key error: ${err instanceof Error ? err.message : String(err)}`);\r\n return null;\r\n }\r\n\r\n const rateCheck = authRateLimiter.check(fingerprint);\r\n if (!rateCheck.allowed) {\r\n const retryMin = Math.ceil(rateCheck.retryAfterMs / 60_000);\r\n console.error(`Rate limited: too many failed SSH-key auth attempts. Retry in ${retryMin} minute(s).`);\r\n return null;\r\n }\r\n\r\n const skipVerify = process.env.MG_DASHBOARD_SSH_SKIP_VERIFY === '1';\r\n if (!skipVerify) {\r\n try {\r\n const challenge = randomBytes(32).toString('hex');\r\n const signature = await sshKeygenSign(pubPath, challenge, 'mg-dashboard-mcp');\r\n const verified = await sshKeygenVerify(pubText, signature, challenge, 'mg-dashboard-mcp');\r\n if (!verified) {\r\n console.error('SSH-key challenge verification failed (signature did not validate against the public key).');\r\n return null;\r\n }\r\n } catch (err) {\r\n console.error(`SSH-key challenge failed: ${err instanceof Error ? err.message : String(err)}`);\r\n console.error('Tip: set MG_DASHBOARD_SSH_SKIP_VERIFY=1 to skip the challenge if you only need to print the fingerprint for enrollment.');\r\n return null;\r\n }\r\n }\r\n\r\n const { data: keyRow, error: keyErr } = await supabase\r\n .from('dashboard_mcp_ssh_key')\r\n .select('id, name, api_key_id, is_active')\r\n .eq('fingerprint_sha256', fingerprint)\r\n .eq('is_active', true)\r\n .maybeSingle();\r\n\r\n if (keyErr || !keyRow) {\r\n console.error(\r\n `SSH key not registered (fingerprint ${fingerprint}; ${rateCheck.remaining} attempts remaining). ` +\r\n `Add it under MCP API Keys → SSH Keys in the dashboard.`,\r\n );\r\n return null;\r\n }\r\n\r\n if (keyRow.api_key_id !== expectedApiKeyId) {\r\n console.error(\r\n `SSH key \"${keyRow.name}\" is registered, but it is not linked to the provided MCP API key. ` +\r\n `Add this SSH key under the same MCP API Key entry used by --api-key.`,\r\n );\r\n return null;\r\n }\r\n\r\n const { data: apiRow, error: apiErr } = await supabase\r\n .from('dashboard_mcp_api_key')\r\n .select('id, name, created_by, allowed_server_ids, is_active, expires_at')\r\n .eq('id', keyRow.api_key_id)\r\n .eq('is_active', true)\r\n .maybeSingle();\r\n\r\n if (apiErr || !apiRow) {\r\n console.error('SSH key is linked to an inactive or missing MCP API key entry.');\r\n return null;\r\n }\r\n\r\n if (apiRow.expires_at && new Date(apiRow.expires_at) < new Date()) {\r\n console.error('Linked MCP API key entry has expired.');\r\n return null;\r\n }\r\n\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', apiRow.created_by)\r\n .single();\r\n\r\n if (userError || !userData) {\r\n console.error(`User not found for SSH key creator: ${apiRow.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 apiRow.allowed_server_ids,\r\n permissions.resources.ssh_servers,\r\n );\r\n\r\n const nowIso = new Date().toISOString();\r\n await Promise.all([\r\n supabase.from('dashboard_mcp_ssh_key').update({ last_used_at: nowIso }).eq('id', keyRow.id),\r\n supabase.from('dashboard_mcp_api_key').update({ last_used_at: nowIso }).eq('id', apiRow.id),\r\n ]);\r\n\r\n const moduleCount = MODULE_KEYS.filter((k) => permissions.modules[k]).length;\r\n console.error(\r\n `Authenticated via SSH key \"${keyRow.name}\" (fp ${fingerprint.slice(0, 24)}...) ` +\r\n `as user ${apiRow.created_by} (role: ${roleName}, modules: ${moduleCount}/${MODULE_KEYS.length})`,\r\n );\r\n\r\n return {\r\n apiKeyId: apiRow.id,\r\n apiKeyName: `${apiRow.name || 'Unknown'} (ssh: ${keyRow.name})`,\r\n userId: apiRow.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: 'encrypted';\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: 'encrypted' 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\n// ---------------------------------------------------------------------------\r\n// Shell quoting / OS-aware command builders\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * POSIX shell single-quote escape. Wraps in `'...'` and escapes any embedded\r\n * `'` as `'\\''`. Bare-word fast-path for safe characters skips quoting.\r\n * Used by ssh-execute (linux mode), docker-exec, sftp-list pattern building,\r\n * and anywhere we previously relied on the LLM to escape `$`, `#`, spaces,\r\n * etc. inside command strings.\r\n */\r\nfunction posixQuote(arg: string): string {\r\n if (arg === '') return \"''\";\r\n if (/^[A-Za-z0-9._\\/=:@%+\\-]+$/.test(arg)) return arg;\r\n return \"'\" + arg.replace(/'/g, \"'\\\\''\") + \"'\";\r\n}\r\n\r\n/**\r\n * Build a POSIX shell command line from a program + argv. The program itself\r\n * is NOT quoted if it's a simple identifier/path (so `cd` / `docker compose`\r\n * keep working when passed as `command: 'docker compose'` with args).\r\n */\r\nfunction buildPosixCommand(command: string, args: string[]): string {\r\n const program = /^[A-Za-z0-9._\\/\\- ]+$/.test(command) ? command : posixQuote(command);\r\n if (args.length === 0) return program;\r\n return `${program} ${args.map(posixQuote).join(' ')}`;\r\n}\r\n\r\n/**\r\n * Build a PowerShell `-EncodedCommand` invocation. PowerShell decodes the\r\n * UTF-16LE-base64 payload itself, so embedded `$`, `'`, `\"`, `#`, spaces, etc.\r\n * never see cmd.exe parsing — this is the only quoting-safe way to call\r\n * PowerShell over SSH on Windows servers.\r\n */\r\nfunction buildPowerShellEncodedCommand(command: string, args: string[]): string {\r\n const psSingleQuote = (s: string) => \"'\" + s.replace(/'/g, \"''\") + \"'\";\r\n let body: string;\r\n if (args.length === 0) {\r\n body = command;\r\n } else {\r\n body = `& ${psSingleQuote(command)} ${args.map(psSingleQuote).join(' ')}`;\r\n }\r\n // Suppress PowerShell's progress CLIXML stream that otherwise pollutes stderr\r\n // with `<Objs Version=\"1.1.0.1\" ...>` blobs on first use of certain cmdlets.\r\n const psExpr = `$ProgressPreference='SilentlyContinue'; ${body}`;\r\n const utf16 = Buffer.from(psExpr, 'utf16le');\r\n const b64 = utf16.toString('base64');\r\n // -OutputFormat Text disables PowerShell's CLIXML serialization of errors/objects\r\n // when run as a subprocess (default is XML for non-interactive). Combined with\r\n // $ProgressPreference above, this gives clean text on stdout/stderr.\r\n return `powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -OutputFormat Text -EncodedCommand ${b64}`;\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\ntype ServerOs = 'linux' | 'windows';\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\n * Also returns the server's `os_type` so callers (notably ssh-execute) can\r\n * pick the right shell wrapper (bash vs PowerShell -EncodedCommand).\r\n */\r\nasync function getServerConnection(\r\n serverId: string,\r\n): Promise<{ conn: SshConnectionOptions; proxy?: SshConnectionOptions; os: ServerOs }> {\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, os_type')\r\n .eq('id', serverId)\r\n .single();\r\n\r\n if (error || !data) {\r\n // Fuzzy hint based on the running cache of names. Helps when the LLM\r\n // typos a UUID or, more usefully, when a tool was somehow invoked with\r\n // a name string instead of an id.\r\n const candidates = Array.from(KNOWN_SERVER_NAMES.values()).flatMap(s => [s.name, s.id]);\r\n const hits = suggestSimilar(serverId, candidates);\r\n const hint = hits.length ? ` Did you mean: ${hits.join(', ')}?` : '';\r\n throw new Error(`Server not found: ${serverId}.${hint}`);\r\n }\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 const os: ServerOs = (data as { os_type?: string }).os_type === 'windows' ? 'windows' : 'linux';\r\n\r\n return { conn, proxy, os };\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\n * `stdin` lets callers pipe data into the remote process (used by ssh-execute\r\n * smart mode + db-* helpers to avoid command-line escape hell with passwords,\r\n * SQL queries, scripts containing `$` or `#`, etc.).\r\n */\r\nasync function sshExec(\r\n opts: SshConnectionOptions,\r\n command: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { stdin?: string; pty?: boolean; idleTimeoutMs?: number; noRetry?: boolean },\r\n): Promise<SshResult> {\r\n // Single inline retry on transient failures (connect refused, DNS hiccup,\r\n // socket reset, etc). Eats 80% of \"errors\" in the wild without leaking the\r\n // distinction up to the LLM. Suppress with `noRetry: true` for non-idempotent\r\n // commands the caller wants to control.\r\n const first = await sshExecOnce(opts, command, proxy, options);\r\n if (options?.noRetry) return first;\r\n if (!isTransientSshError(first.stderr, first.exitCode)) return first;\r\n await new Promise((r) => setTimeout(r, 1000));\r\n const second = await sshExecOnce(opts, command, proxy, options);\r\n // Annotate stderr so debugging is obvious if the retry also fails.\r\n if (second.exitCode === -1 && second.stderr) {\r\n second.stderr = `[retry-1 also failed] ${second.stderr}`;\r\n }\r\n return second;\r\n}\r\n\r\nasync function sshExecOnce(\r\n opts: SshConnectionOptions,\r\n command: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { stdin?: string; pty?: boolean; idleTimeoutMs?: number },\r\n): Promise<SshResult> {\r\n if (proxy) return sshExecViaProxy(proxy, opts, command, options);\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 wallTimeout = opts.timeout || 60_000;\r\n const idleTimeout = options?.idleTimeoutMs;\r\n\r\n const wallTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(idleTimer); ssh.end(); resolve({ stdout, stderr: stderr || `idle/wall timeout after ${wallTimeout}ms`, exitCode: -1 }); }\r\n }, wallTimeout);\r\n\r\n let idleTimer: NodeJS.Timeout | undefined;\r\n const armIdle = () => {\r\n if (!idleTimeout) return;\r\n if (idleTimer) clearTimeout(idleTimer);\r\n idleTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(wallTimer); ssh.end(); resolve({ stdout, stderr: stderr || `idle timeout after ${idleTimeout}ms with no output`, exitCode: -1 }); }\r\n }, idleTimeout);\r\n };\r\n armIdle();\r\n\r\n ssh.on('ready', () => {\r\n // Allocating a PTY collapses stderr into stdout (a real terminal has no\r\n // separate stderr fd) which is exactly what callers want for tty-mode\r\n // commands like `psql`/`mysql`/`bash`. Without pty: stderr is captured\r\n // separately so structured tools still get clean stderr.\r\n const execOpts = options?.pty ? { pty: true } : {};\r\n ssh.exec(command, execOpts, (err, stream) => {\r\n if (err) {\r\n if (!done) { done = true; clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); ssh.end(); resolve({ stdout, stderr: err.message || stderr, exitCode: -1 }); }\r\n return;\r\n }\r\n stream.on('data', (d: Buffer) => { stdout += d.toString(); armIdle(); });\r\n stream.stderr.on('data', (d: Buffer) => { stderr += d.toString(); armIdle(); });\r\n stream.on('close', (code: number | null) => {\r\n if (!done) { done = true; clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); ssh.end(); resolve({ stdout, stderr, exitCode: code ?? 0 }); }\r\n });\r\n if (options?.stdin !== undefined) {\r\n stream.end(options.stdin);\r\n }\r\n });\r\n });\r\n\r\n ssh.on('error', (err) => {\r\n if (!done) { done = true; clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); 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: wallTimeout,\r\n });\r\n });\r\n}\r\n\r\nfunction sshExecViaProxy(\r\n proxyOpts: SshConnectionOptions,\r\n targetOpts: SshConnectionOptions,\r\n command: string,\r\n options?: { stdin?: string; pty?: boolean; idleTimeoutMs?: number },\r\n): Promise<SshResult> {\r\n return new Promise((resolve) => {\r\n const proxyClient = new SshClient();\r\n let done = false;\r\n const wallTimeout = targetOpts.timeout || 60_000;\r\n const idleTimeout = options?.idleTimeoutMs;\r\n\r\n const wallTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(idleTimer); proxyClient.end(); resolve({ stdout: '', stderr: 'SSH proxy command timeout', exitCode: -1 }); }\r\n }, wallTimeout);\r\n\r\n let idleTimer: NodeJS.Timeout | undefined;\r\n let stdoutBuf = '';\r\n let stderrBuf = '';\r\n const armIdle = () => {\r\n if (!idleTimeout) return;\r\n if (idleTimer) clearTimeout(idleTimer);\r\n idleTimer = setTimeout(() => {\r\n if (!done) { done = true; clearTimeout(wallTimer); proxyClient.end(); resolve({ stdout: stdoutBuf, stderr: stderrBuf || `idle timeout after ${idleTimeout}ms with no output`, exitCode: -1 }); }\r\n }, idleTimeout);\r\n };\r\n armIdle();\r\n\r\n const cleanup = () => { clearTimeout(wallTimer); if (idleTimer) clearTimeout(idleTimer); 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\r\n targetClient.on('ready', () => {\r\n const execOpts = options?.pty ? { pty: true } : {};\r\n targetClient.exec(command, execOpts, (execErr, stream) => {\r\n if (execErr) {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout: stdoutBuf, stderr: stderrBuf, exitCode: -1 }); }\r\n return;\r\n }\r\n stream.on('data', (d: Buffer) => { stdoutBuf += d.toString(); armIdle(); });\r\n stream.stderr.on('data', (d: Buffer) => { stderrBuf += d.toString(); armIdle(); });\r\n stream.on('close', (code: number | null) => {\r\n if (!done) { done = true; targetClient.end(); cleanup(); resolve({ stdout: stdoutBuf, stderr: stderrBuf, exitCode: code ?? 0 }); }\r\n });\r\n if (options?.stdin !== undefined) {\r\n stream.end(options.stdin);\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: stdoutBuf, 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: wallTimeout,\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// Shared SSH connection helper (supports proxy tunnelling)\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction connectSshClient(\r\n opts: SshConnectionOptions,\r\n proxy?: SshConnectionOptions,\r\n readyTimeout = 60_000,\r\n extraConnect?: { compress?: boolean | 'force' },\r\n): Promise<{ client: SshClient; cleanup: () => void }> {\r\n const compress = extraConnect?.compress;\r\n if (!proxy) {\r\n return new Promise((resolve, reject) => {\r\n const ssh = new SshClient();\r\n ssh.on('ready', () => resolve({ client: ssh, cleanup: () => ssh.end() }));\r\n ssh.on('error', (e) => reject(e));\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,\r\n ...(compress ? { compress } : {}),\r\n });\r\n });\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const proxyClient = new SshClient();\r\n\r\n proxyClient.on('ready', () => {\r\n proxyClient.forwardOut('127.0.0.1', 0, opts.hostname, opts.port, (err, tunnel) => {\r\n if (err) { proxyClient.end(); reject(err); return; }\r\n\r\n const targetClient = new SshClient();\r\n targetClient.on('ready', () =>\r\n resolve({\r\n client: targetClient,\r\n cleanup: () => { targetClient.end(); proxyClient.end(); },\r\n }),\r\n );\r\n targetClient.on('error', (e) => { proxyClient.end(); reject(e); });\r\n targetClient.connect({\r\n sock: tunnel,\r\n username: opts.username, password: opts.password,\r\n privateKey: opts.privateKey, passphrase: opts.passphrase,\r\n readyTimeout,\r\n ...(compress ? { compress } : {}),\r\n });\r\n });\r\n });\r\n\r\n proxyClient.on('error', (e) => reject(e));\r\n proxyClient.connect({\r\n host: proxy.hostname, port: proxy.port, username: proxy.username,\r\n password: proxy.password, privateKey: proxy.privateKey, passphrase: proxy.passphrase,\r\n readyTimeout: proxy.timeout || 30_000,\r\n });\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// R2 (Cloudflare S3-compatible) helpers\r\n//\r\n// The four sftp-* tools route to R2 instead of an SSH server when the caller\r\n// passes `bucket: <name>`. Credentials come from env vars (R2_ENDPOINT +\r\n// R2_ACCESS_KEY_ID + R2_SECRET_ACCESS_KEY), so the MCP runs against any\r\n// Cloudflare R2 account without per-call config. The bucket *name* is part of\r\n// the call so the same MCP can address multiple buckets (backup, assets, etc.).\r\n// ---------------------------------------------------------------------------\r\n\r\nimport {\r\n S3Client,\r\n ListObjectsV2Command,\r\n GetObjectCommand,\r\n PutObjectCommand,\r\n CopyObjectCommand,\r\n DeleteObjectCommand,\r\n DeleteObjectsCommand,\r\n HeadObjectCommand,\r\n CreateMultipartUploadCommand,\r\n UploadPartCommand,\r\n CompleteMultipartUploadCommand,\r\n AbortMultipartUploadCommand,\r\n type _Object,\r\n type CommonPrefix,\r\n} from '@aws-sdk/client-s3';\r\n\r\nlet _r2Client: S3Client | null = null;\r\n\r\nfunction getR2Client(): S3Client {\r\n if (_r2Client) return _r2Client;\r\n const endpoint = process.env.R2_ENDPOINT;\r\n const accessKeyId = process.env.R2_ACCESS_KEY_ID;\r\n const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY;\r\n if (!endpoint || !accessKeyId || !secretAccessKey) {\r\n throw new Error(\r\n 'R2 not configured. Set R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY in the MCP env (mcp.json).',\r\n );\r\n }\r\n _r2Client = new S3Client({ region: 'auto', endpoint, credentials: { accessKeyId, secretAccessKey } });\r\n return _r2Client;\r\n}\r\n\r\n/** Strip a leading `/` so callers can use familiar paths (`/foo/bar.txt`)\r\n * while R2 keys are stored without the slash (`foo/bar.txt`). */\r\nfunction r2Key(path: string): string {\r\n return path.replace(/^\\/+/, '');\r\n}\r\n\r\ninterface R2ListEntry {\r\n key: string;\r\n size: number;\r\n mtime: string;\r\n isPrefix: boolean;\r\n}\r\n\r\nasync function r2List(\r\n bucket: string,\r\n prefix: string,\r\n options: { recursive: boolean; maxResults: number },\r\n): Promise<R2ListEntry[]> {\r\n const client = getR2Client();\r\n const entries: R2ListEntry[] = [];\r\n let continuationToken: string | undefined;\r\n // Folder mode uses delimiter so we get CommonPrefixes (one entry per \"directory\").\r\n // Recursive mode omits delimiter and walks every key.\r\n const delimiter = options.recursive ? undefined : '/';\r\n\r\n do {\r\n const result = await client.send(new ListObjectsV2Command({\r\n Bucket: bucket,\r\n Prefix: prefix || undefined,\r\n Delimiter: delimiter,\r\n ContinuationToken: continuationToken,\r\n MaxKeys: Math.min(1000, options.maxResults - entries.length),\r\n }));\r\n\r\n for (const cp of (result.CommonPrefixes || []) as CommonPrefix[]) {\r\n if (cp.Prefix) entries.push({ key: cp.Prefix, size: 0, mtime: '', isPrefix: true });\r\n if (entries.length >= options.maxResults) break;\r\n }\r\n for (const obj of (result.Contents || []) as _Object[]) {\r\n if (entries.length >= options.maxResults) break;\r\n entries.push({\r\n key: obj.Key || '',\r\n size: obj.Size || 0,\r\n mtime: obj.LastModified ? obj.LastModified.toISOString() : '',\r\n isPrefix: false,\r\n });\r\n }\r\n continuationToken = result.IsTruncated ? result.NextContinuationToken : undefined;\r\n } while (continuationToken && entries.length < options.maxResults);\r\n\r\n return entries;\r\n}\r\n\r\n/** Translate the aws-sdk's terse error names (\"NotFound\" / \"NoSuchKey\" /\r\n * \"UnknownError\") into actionable messages that include the bucket+key. */\r\nfunction r2WrapError(bucket: string, key: string, e: unknown): Error {\r\n const err = e as { name?: string; $metadata?: { httpStatusCode?: number }; message?: string };\r\n const status = err?.$metadata?.httpStatusCode;\r\n const name = err?.name || '';\r\n if (name === 'NoSuchKey' || name === 'NotFound' || status === 404) {\r\n return new Error(`r2://${bucket}/${key} not found`);\r\n }\r\n if (name === 'NoSuchBucket') return new Error(`R2 bucket \"${bucket}\" not found`);\r\n if (status === 403 || name === 'AccessDenied') return new Error(`Access denied for r2://${bucket}/${key} (check R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY)`);\r\n return new Error(`R2 error (${name || 'unknown'}${status ? ` ${status}` : ''}): ${err?.message || String(e)}`);\r\n}\r\n\r\nasync function r2GetObject(bucket: string, key: string, maxBytes: number): Promise<string> {\r\n const client = getR2Client();\r\n let size = 0;\r\n try {\r\n // Cheap HEAD first so we can refuse oversized objects without downloading them.\r\n const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n if (size > maxBytes) {\r\n throw new Error(`Object too large: ${size} bytes (max ${maxBytes} for inline read; use sftp-write with sourcePath to mirror locally instead, or pass { offset, length } for a ranged read)`);\r\n }\r\n try {\r\n const result = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));\r\n const body = result.Body as unknown as { transformToString?: () => Promise<string> };\r\n if (!body?.transformToString) throw new Error('R2 returned no readable body');\r\n return await body.transformToString();\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\nasync function r2GetObjectRange(\r\n bucket: string,\r\n key: string,\r\n range: { offset: number; length?: number },\r\n): Promise<string> {\r\n const client = getR2Client();\r\n let size = 0;\r\n try {\r\n const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n if (range.offset >= size && size > 0) throw new Error(`offset ${range.offset} is past end of object (size ${size})`);\r\n const MAX = 1_048_576;\r\n const remaining = Math.max(0, size - range.offset);\r\n const effectiveLen = range.length !== undefined ? Math.min(range.length, remaining, MAX) : Math.min(remaining, MAX);\r\n const end = range.offset + effectiveLen - 1;\r\n try {\r\n // S3 Range header is inclusive on both ends.\r\n const result = await client.send(new GetObjectCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n Range: `bytes=${range.offset}-${end}`,\r\n }));\r\n const body = result.Body as unknown as { transformToString?: () => Promise<string> };\r\n if (!body?.transformToString) throw new Error('R2 returned no readable body');\r\n const text = await body.transformToString();\r\n const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;\r\n return `${header}\\n${text}`;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\nasync function r2PutObject(bucket: string, key: string, body: Buffer | Readable, contentLength?: number): Promise<void> {\r\n const client = getR2Client();\r\n try {\r\n await client.send(new PutObjectCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n Body: body,\r\n ContentLength: contentLength,\r\n ContentType: 'application/octet-stream',\r\n }));\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\nasync function r2DeleteObject(bucket: string, key: string): Promise<void> {\r\n const client = getR2Client();\r\n try {\r\n await client.send(new DeleteObjectCommand({ Bucket: bucket, Key: key }));\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n}\r\n\r\n/** Delete all objects under a prefix. R2's DeleteObjects supports up to 1000\r\n * keys per request, so we loop list→delete in pages. Returns deleted count. */\r\nasync function r2DeletePrefix(bucket: string, prefix: string): Promise<number> {\r\n const client = getR2Client();\r\n let deleted = 0;\r\n let continuationToken: string | undefined;\r\n do {\r\n const list = await client.send(new ListObjectsV2Command({\r\n Bucket: bucket,\r\n Prefix: prefix,\r\n ContinuationToken: continuationToken,\r\n MaxKeys: 1000,\r\n }));\r\n const keys = (list.Contents || []).map(o => o.Key).filter((k): k is string => !!k);\r\n if (keys.length === 0) break;\r\n await client.send(new DeleteObjectsCommand({\r\n Bucket: bucket,\r\n Delete: { Objects: keys.map(k => ({ Key: k })), Quiet: true },\r\n }));\r\n deleted += keys.length;\r\n continuationToken = list.IsTruncated ? list.NextContinuationToken : undefined;\r\n } while (continuationToken);\r\n return deleted;\r\n}\r\n\r\n/** Multipart upload for files larger than ~4.5 GB (R2 single-PUT limit is 5 GB\r\n * with a safety margin). Streams the local file in 100 MB parts. */\r\nconst R2_MULTIPART_THRESHOLD = 4.5 * 1024 * 1024 * 1024; // 4.5 GB\r\nconst R2_MULTIPART_PART_SIZE = 100 * 1024 * 1024; // 100 MB\r\n\r\nasync function r2PutObjectMultipart(\r\n bucket: string,\r\n key: string,\r\n localPath: string,\r\n totalBytes: number,\r\n onProgress?: (bytes: number) => void,\r\n): Promise<void> {\r\n const client = getR2Client();\r\n const create = await client.send(new CreateMultipartUploadCommand({ Bucket: bucket, Key: key }));\r\n const uploadId = create.UploadId;\r\n if (!uploadId) throw new Error('R2 returned no UploadId for multipart create');\r\n\r\n const parts: { PartNumber: number; ETag: string }[] = [];\r\n try {\r\n let partNumber = 1;\r\n let uploaded = 0;\r\n let offset = 0;\r\n while (offset < totalBytes) {\r\n const end = Math.min(offset + R2_MULTIPART_PART_SIZE, totalBytes);\r\n // Read this part into memory (100 MB max). Streaming a single part with\r\n // unknown length is unreliable across SDK versions; buffering keeps us\r\n // simple and predictable.\r\n const chunk = await new Promise<Buffer>((resolve, reject) => {\r\n const chunks: Buffer[] = [];\r\n const rs = createReadStream(localPath, { start: offset, end: end - 1 });\r\n rs.on('data', (c: string | Buffer) => { chunks.push(typeof c === 'string' ? Buffer.from(c) : c); });\r\n rs.on('end', () => resolve(Buffer.concat(chunks.map(b => new Uint8Array(b)))));\r\n rs.on('error', reject);\r\n });\r\n const partResult = await client.send(new UploadPartCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n UploadId: uploadId,\r\n PartNumber: partNumber,\r\n Body: chunk,\r\n ContentLength: chunk.length,\r\n }));\r\n if (!partResult.ETag) throw new Error(`Part ${partNumber} returned no ETag`);\r\n parts.push({ PartNumber: partNumber, ETag: partResult.ETag });\r\n uploaded += chunk.length;\r\n onProgress?.(uploaded);\r\n offset = end;\r\n partNumber++;\r\n }\r\n await client.send(new CompleteMultipartUploadCommand({\r\n Bucket: bucket,\r\n Key: key,\r\n UploadId: uploadId,\r\n MultipartUpload: { Parts: parts },\r\n }));\r\n } catch (e) {\r\n // Best-effort abort to avoid orphaned parts (R2 charges for them).\r\n try { await client.send(new AbortMultipartUploadCommand({ Bucket: bucket, Key: key, UploadId: uploadId })); } catch { /* ignore */ }\r\n throw e;\r\n }\r\n}\r\n\r\n/** Server-side copy within R2 (same bucket or cross-bucket). No data egress. */\r\nasync function r2CopyObject(srcBucket: string, srcKey: string, dstBucket: string, dstKey: string): Promise<{ size: number }> {\r\n const client = getR2Client();\r\n // We need the size for the response footer; HEAD it cheaply first.\r\n let size = 0;\r\n try {\r\n const head = await client.send(new HeadObjectCommand({ Bucket: srcBucket, Key: srcKey }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(srcBucket, srcKey, e); }\r\n try {\r\n await client.send(new CopyObjectCommand({\r\n CopySource: encodeURIComponent(`${srcBucket}/${srcKey}`).replace(/%2F/g, '/'),\r\n Bucket: dstBucket,\r\n Key: dstKey,\r\n }));\r\n } catch (e) { throw r2WrapError(dstBucket, dstKey, e); }\r\n return { size };\r\n}\r\n\r\n/** Stream R2 GetObject body. Caller is responsible for consuming/destroying it. */\r\nasync function r2GetObjectStream(bucket: string, key: string): Promise<{ stream: Readable; size: number }> {\r\n const client = getR2Client();\r\n let size = 0;\r\n try {\r\n const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n size = head.ContentLength || 0;\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\r\n try {\r\n const result = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));\r\n const body = result.Body as Readable | undefined;\r\n if (!body) throw new Error('R2 returned no readable body');\r\n return { stream: body, size };\r\n } catch (e) { throw r2WrapError(bucket, key, e); }\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\n/** Convert a glob pattern (`*`, `?`, character classes) to a RegExp anchored\r\n * to the basename only. Used by sftp-list for filtering. */\r\nfunction globToRegExp(pattern: string): RegExp {\r\n let re = '';\r\n for (const c of pattern) {\r\n if (c === '*') re += '.*';\r\n else if (c === '?') re += '.';\r\n else if (/[.+^${}()|[\\]\\\\]/.test(c)) re += '\\\\' + c;\r\n else re += c;\r\n }\r\n return new RegExp(`^${re}$`);\r\n}\r\n\r\ninterface SftpEntry {\r\n kind: 'd' | '-';\r\n size: number;\r\n mtime: string; // ISO; '' if unknown\r\n mtimeMs: number; // 0 if unknown; used for sorting\r\n path: string; // full or basename (depending on recursive mode)\r\n}\r\n\r\nasync function sftpReaddir(\r\n opts: SshConnectionOptions,\r\n dirPath: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { recursive?: boolean; maxDepth?: number; pattern?: string; maxResults?: number },\r\n): Promise<{ entries: SftpEntry[]; truncated: boolean; error?: string }> {\r\n const recursive = options?.recursive === true;\r\n const maxDepth = Math.max(1, Math.min(20, options?.maxDepth ?? 5));\r\n const maxResults = Math.max(1, Math.min(50_000, options?.maxResults ?? 5_000));\r\n const matcher = options?.pattern ? globToRegExp(options.pattern) : null;\r\n const rootSafe = sanitizePath(dirPath);\r\n\r\n let cleanup: (() => void) | undefined;\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 30_000);\r\n cleanup = c;\r\n return await new Promise<{ entries: SftpEntry[]; truncated: boolean; error?: string }>((resolve) => {\r\n const timer = setTimeout(() => { cleanup?.(); resolve({ entries: [], truncated: false, error: 'timeout' }); cleanup = undefined; }, 60_000);\r\n\r\n client.sftp((err, sftp) => {\r\n if (err) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve({ entries: [], truncated: false, error: err.message }); return; }\r\n\r\n const entries: SftpEntry[] = [];\r\n let truncated = false;\r\n const errors: string[] = [];\r\n\r\n const readOne = (path: string, depth: number): Promise<void> =>\r\n new Promise((resolveOne) => {\r\n sftp.readdir(path, (err2, list) => {\r\n if (err2) {\r\n errors.push(`error reading ${path}: ${err2.message}`);\r\n return resolveOne();\r\n }\r\n const subdirs: string[] = [];\r\n for (const item of list) {\r\n if (entries.length >= maxResults) { truncated = true; break; }\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 mtimeMs = item.attrs.mtime ? item.attrs.mtime * 1000 : 0;\r\n const mtime = mtimeMs ? new Date(mtimeMs).toISOString() : '';\r\n const fullPath = path === '/' ? `/${item.filename}` : `${path}/${item.filename}`;\r\n const include = !matcher || matcher.test(item.filename);\r\n if (include) {\r\n entries.push({ kind: isDir ? 'd' : '-', size, mtime, mtimeMs, path: recursive ? fullPath : item.filename });\r\n }\r\n if (isDir && recursive && depth < maxDepth) subdirs.push(fullPath);\r\n }\r\n if (truncated || subdirs.length === 0) return resolveOne();\r\n // Walk subdirs sequentially to keep one SFTP session calm.\r\n (async () => {\r\n for (const sub of subdirs) {\r\n if (truncated) break;\r\n await readOne(sub, depth + 1);\r\n }\r\n resolveOne();\r\n })();\r\n });\r\n });\r\n\r\n readOne(rootSafe, 1).then(() => {\r\n clearTimeout(timer);\r\n cleanup?.(); cleanup = undefined;\r\n resolve({ entries, truncated, error: errors.length ? errors.join('; ') : undefined });\r\n });\r\n });\r\n });\r\n } catch (e: any) {\r\n cleanup?.();\r\n return { entries: [], truncated: false, error: e.message };\r\n }\r\n}\r\n\r\nasync function sftpRead(\r\n opts: SshConnectionOptions,\r\n filePath: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { offset?: number; length?: number },\r\n): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n const offset = Math.max(0, Math.floor(options?.offset ?? 0));\r\n // Cap at 1 MiB regardless of how much the caller asks for; LLM context can't\r\n // sensibly absorb more than that and large reads should use SFTP→local file.\r\n const MAX = 1_048_576;\r\n const requestedLen = options?.length !== undefined ? Math.max(0, Math.floor(options.length)) : undefined;\r\n\r\n let cleanup: (() => void) | undefined;\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 60_000);\r\n cleanup = c;\r\n return await new Promise<string>((resolve) => {\r\n const timer = setTimeout(() => { cleanup?.(); resolve('Error: timeout'); cleanup = undefined; }, 60_000);\r\n client.sftp((err, sftp) => {\r\n if (err) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${err.message}`); return; }\r\n sftp.stat(safe, (err2, stats) => {\r\n if (err2) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${err2.message}`); return; }\r\n const total = stats.size || 0;\r\n if (offset >= total && total > 0) {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Error: offset ${offset} is past end of file (size ${total})`);\r\n return;\r\n }\r\n const remaining = Math.max(0, total - offset);\r\n // Effective read length = caller-requested OR remaining-from-offset,\r\n // whichever is smaller, but never above MAX. In whole-file mode (no\r\n // offset/length) we still refuse files >MAX so the contract matches.\r\n const effectiveLen = requestedLen !== undefined\r\n ? Math.min(requestedLen, remaining, MAX)\r\n : Math.min(remaining, MAX);\r\n const isWholeFileRequest = options === undefined || (offset === 0 && requestedLen === undefined);\r\n if (isWholeFileRequest && total > MAX) {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Error: file too large (${total} bytes, max ${MAX}). Use { offset, length } for ranged reads.`);\r\n return;\r\n }\r\n const chunks: Buffer[] = [];\r\n // ssh2 createReadStream supports `start` (inclusive) and `end` (inclusive).\r\n const rs = sftp.createReadStream(safe, { start: offset, end: offset + effectiveLen - 1 });\r\n rs.on('data', (ch: Buffer) => chunks.push(ch));\r\n rs.on('end', () => {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n const text = Buffer.concat(chunks.map(ch => new Uint8Array(ch))).toString('utf-8');\r\n // For ranged reads, prepend a one-line header so the LLM knows the\r\n // window. Whole-file reads stay unchanged for backwards compat.\r\n if (!isWholeFileRequest) {\r\n const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;\r\n resolve(`${header}\\n${text}`);\r\n } else {\r\n resolve(text);\r\n }\r\n });\r\n rs.on('error', (e: Error) => { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${e.message}`); });\r\n });\r\n });\r\n });\r\n } catch (e: any) {\r\n cleanup?.();\r\n return `Error: ${e.message}`;\r\n }\r\n}\r\n\r\n// SFTP tuning. ssh2 fastPut uses 64 concurrent in-flight WRITE packets which\r\n// gives near-linerate throughput on modern OpenSSH (>= 8.6). The 64 KiB chunk\r\n// size is the safe upper bound for servers without the limits@openssh.com\r\n// extension; with it most OpenSSH builds happily accept up to 256 KiB.\r\nconst SFTP_FASTPUT_CONCURRENCY = 64;\r\nconst SFTP_FASTPUT_CHUNK_SIZE = 65_536;\r\n// Watchdog: kill the upload if no progress is observed for this long. Reset on\r\n// every fastPut step callback. Tighter than a wall-clock timeout because it\r\n// adapts to file size automatically.\r\nconst SFTP_IDLE_TIMEOUT_MS = 120_000;\r\n// Inline writes have no progress events, so we use a wall-clock cap.\r\nconst SFTP_INLINE_TIMEOUT_MS = 60_000;\r\nconst SFTP_PROGRESS_LOG_BYTES = 50 * 1024 * 1024;\r\n\r\nexport type SftpWriteInput =\r\n | { content: string }\r\n | { sourcePath: string };\r\n\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\r\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\r\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Universal output processing (truncate, footer, fuzzy hints, cache, retry)\r\n// Applied centrally in handleCallTool so every tool benefits without per-case\r\n// boilerplate. Designed to be inert when not applicable (small outputs, etc).\r\n// ---------------------------------------------------------------------------\r\n\r\nconst RESPONSE_MAX_BYTES = 8192;\r\n\r\n// Sentinel used to suppress the response footer for tools that should stay raw\r\n// (e.g. things consumed verbatim by other tooling). None today, but the hook\r\n// is here so we can flag a tool name later via `NO_FOOTER_TOOLS.add('foo')`.\r\nconst NO_FOOTER_TOOLS = new Set<string>();\r\n\r\n// Tools that should be cached on the server side. Cache key is the tool name +\r\n// stable JSON of args (minus `noCache`). Set TTL to 0 to disable explicitly.\r\nconst TOOL_CACHE_TTL_MS: Record<string, number> = {\r\n 'list-servers': 60_000,\r\n 'docker-list': 30_000,\r\n};\r\n\r\ninterface CacheEntry { value: { content: { type: string; text: string }[] }; expiresAt: number }\r\nconst TOOL_CACHE = new Map<string, CacheEntry>();\r\n\r\nfunction cacheKeyFor(name: string, args: Record<string, unknown>): string {\r\n const { noCache: _ignored, ...rest } = args;\r\n void _ignored;\r\n // Stable stringify (sorted keys) so { a:1, b:2 } and { b:2, a:1 } collide.\r\n const sorted = Object.fromEntries(Object.entries(rest).sort(([a], [b]) => a.localeCompare(b)));\r\n return `${name}::${JSON.stringify(sorted)}`;\r\n}\r\n\r\nfunction getCachedTool(name: string, args: Record<string, unknown>): { content: { type: string; text: string }[] } | undefined {\r\n const ttl = TOOL_CACHE_TTL_MS[name];\r\n if (!ttl || ttl <= 0) return undefined;\r\n if (args.noCache === true) return undefined;\r\n const k = cacheKeyFor(name, args);\r\n const e = TOOL_CACHE.get(k);\r\n if (!e) return undefined;\r\n if (e.expiresAt < Date.now()) { TOOL_CACHE.delete(k); return undefined; }\r\n return e.value;\r\n}\r\n\r\nfunction setCachedTool(name: string, args: Record<string, unknown>, value: { content: { type: string; text: string }[] }): void {\r\n const ttl = TOOL_CACHE_TTL_MS[name];\r\n if (!ttl || ttl <= 0) return;\r\n if (args.noCache === true) return;\r\n TOOL_CACHE.set(cacheKeyFor(name, args), { value, expiresAt: Date.now() + ttl });\r\n}\r\n\r\n// Fuzzy match: small Levenshtein for typo hints like \"Did you mean: foo?\".\r\n// Only used in error paths so the cost is irrelevant.\r\nfunction levenshtein(a: string, b: string): number {\r\n if (a === b) return 0;\r\n const m = a.length; const n = b.length;\r\n if (m === 0) return n;\r\n if (n === 0) return m;\r\n const dp: number[] = new Array(n + 1);\r\n for (let j = 0; j <= n; j++) dp[j] = j;\r\n for (let i = 1; i <= m; i++) {\r\n let prev = dp[0]!;\r\n dp[0] = i;\r\n for (let j = 1; j <= n; j++) {\r\n const tmp = dp[j]!;\r\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\r\n dp[j] = Math.min(dp[j]! + 1, dp[j - 1]! + 1, prev + cost);\r\n prev = tmp;\r\n }\r\n }\r\n return dp[n]!;\r\n}\r\n\r\nfunction suggestSimilar(input: string, candidates: string[], max = 3): string[] {\r\n if (!input || !candidates.length) return [];\r\n const lo = input.toLowerCase();\r\n const threshold = Math.max(2, Math.ceil(input.length / 3));\r\n return candidates\r\n .map(c => ({ c, d: levenshtein(lo, c.toLowerCase()) }))\r\n .filter(x => x.d <= threshold)\r\n .sort((a, b) => a.d - b.d)\r\n .slice(0, max)\r\n .map(x => x.c);\r\n}\r\n\r\n// Lightweight running cache of recently-seen names. Populated by tools that\r\n// list things (servers, containers); consumed by tools that error on a name.\r\nconst KNOWN_SERVER_NAMES = new Map<string, { id: string; name: string }>(); // key=id\r\nconst KNOWN_CONTAINERS_BY_SERVER = new Map<string, { names: string[]; capturedAt: number }>();\r\n\r\nfunction rememberServers(servers: Array<{ id: string; name: string }>): void {\r\n for (const s of servers) KNOWN_SERVER_NAMES.set(s.id, s);\r\n}\r\nfunction rememberContainers(serverId: string, names: string[]): void {\r\n KNOWN_CONTAINERS_BY_SERVER.set(serverId, { names, capturedAt: Date.now() });\r\n}\r\n\r\n// Auto-context hints for list-servers: cheap pattern matching on tags +\r\n// hostnames so the LLM gets a 1-line \"what runs here\" summary on the first\r\n// listing call. Pure heuristics — no SSH probes.\r\nfunction buildServerContextHints(\r\n servers: Array<{ name: string; hostname: string; tags?: string[] | null }>,\r\n): string[] {\r\n const hints: string[] = [];\r\n for (const s of servers) {\r\n const tagSet = new Set<string>((s.tags || []).map((t) => String(t).toLowerCase()));\r\n const name = (s.name || '').toLowerCase();\r\n const host = (s.hostname || '').toLowerCase();\r\n const found: string[] = [];\r\n if (tagSet.has('trigger') || /trigger/.test(name) || /trigger/.test(host)) found.push('Trigger.dev self-hosted');\r\n if (tagSet.has('supabase') || /supabase/.test(name) || /supabase/.test(host)) found.push('Supabase stack');\r\n if (tagSet.has('proxy') || /proxy|jump/.test(name)) found.push('SSH ProxyJump host');\r\n if (tagSet.has('giga') || /giga/.test(name)) found.push('shared workloads');\r\n if (tagSet.has('vca') || /vca/.test(name)) found.push('VCA hosting');\r\n if (tagSet.has('mg-boilers') || /boiler/.test(name)) found.push('boiler API');\r\n if (tagSet.has('refront') || /refront|tickets/.test(name) || /refront|tickets/.test(host)) found.push('Refront/tickets');\r\n if (found.length) hints.push(`- ${s.name}: ${found.join(', ')}`);\r\n }\r\n return hints;\r\n}\r\nfunction getKnownContainers(serverId: string, maxAgeMs = 5 * 60_000): string[] | undefined {\r\n const e = KNOWN_CONTAINERS_BY_SERVER.get(serverId);\r\n if (!e) return undefined;\r\n if (Date.now() - e.capturedAt > maxAgeMs) return undefined;\r\n return e.names;\r\n}\r\n\r\n// Truncate a text payload by UTF-8 byte budget, returning whether we cut.\r\nfunction truncateForLLM(text: string, maxBytes: number): { text: string; truncated: boolean; totalBytes: number; shownBytes: number } {\r\n const totalBytes = Buffer.byteLength(text, 'utf8');\r\n if (totalBytes <= maxBytes) return { text, truncated: false, totalBytes, shownBytes: totalBytes };\r\n const buf = Buffer.from(text, 'utf8');\r\n // Cut on a code-point boundary by scanning back from maxBytes to avoid\r\n // producing a broken multibyte sequence at the slice point.\r\n let cut = maxBytes;\r\n while (cut > 0 && (buf[cut]! & 0xc0) === 0x80) cut--;\r\n const head = buf.subarray(0, cut).toString('utf8');\r\n return { text: head, truncated: true, totalBytes, shownBytes: cut };\r\n}\r\n\r\nfunction buildTruncationHint(name: string, args: Record<string, unknown>, total: number, shown: number): string {\r\n const base = `(showing first ${shown} of ${total} bytes;`;\r\n if (name === 'sftp-read') {\r\n const off = Number(args.offset) || 0;\r\n const next = off + shown;\r\n return `${base} pass { offset: ${next}, length: ${RESPONSE_MAX_BYTES} } to read more)`;\r\n }\r\n if (name === 'docker-logs') {\r\n return `${base} use \\`tail\\`, \\`since\\`, or \\`grep\\` to narrow the window)`;\r\n }\r\n if (name === 'ssh-execute') {\r\n return `${base} pipe through head/tail/grep server-side, or use sftp-read with offset for huge logs)`;\r\n }\r\n return `${base} narrow your query, paginate, or grep server-side to read the rest)`;\r\n}\r\n\r\n// Detect transient SSH/network failures worth a single retry. We're\r\n// intentionally conservative: only obvious connect-time hiccups, not generic\r\n// command failures (that would mask real bugs).\r\nconst TRANSIENT_RE = /(ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|ENETUNREACH|EHOSTUNREACH|connection\\s+refused|connection\\s+reset|getaddrinfo|connect\\s+ETIMEDOUT|socket\\s+hang\\s*up|read\\s+ECONNRESET|All configured authentication methods failed)/i;\r\n\r\nfunction isTransientSshError(stderr: string | undefined, exitCode: number): boolean {\r\n if (exitCode !== -1) return false;\r\n if (!stderr) return false;\r\n return TRANSIENT_RE.test(stderr);\r\n}\r\n\r\n// Result post-processing: cache write + truncate + footer. Pure function over\r\n// the result content. Idempotent for already-small outputs.\r\nfunction postprocessResult(\r\n result: { content: { type: string; text: string }[] },\r\n meta: { startedAtMs: number; serverIdLabel?: string; toolName: string; args: Record<string, unknown>; cached?: boolean },\r\n): { content: { type: string; text: string }[] } {\r\n if (!result.content?.length) return result;\r\n const block = result.content[0]!;\r\n let text = String(block.text ?? '');\r\n\r\n const trunc = truncateForLLM(text, RESPONSE_MAX_BYTES);\r\n if (trunc.truncated) {\r\n text = trunc.text + '\\n\\n... ' + buildTruncationHint(meta.toolName, meta.args, trunc.totalBytes, trunc.shownBytes);\r\n }\r\n\r\n if (!NO_FOOTER_TOOLS.has(meta.toolName)) {\r\n const tookMs = Date.now() - meta.startedAtMs;\r\n const tookStr = tookMs < 1000 ? `${tookMs}ms` : `${(tookMs / 1000).toFixed(1)}s`;\r\n const sizeStr = trunc.totalBytes >= 1024\r\n ? `${(trunc.totalBytes / 1024).toFixed(1)} KB`\r\n : `${trunc.totalBytes} B`;\r\n const parts = [`took ${tookStr}`, sizeStr];\r\n if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);\r\n if (meta.cached) parts.push('cached');\r\n text = `${text}\\n\\n[${parts.join(', ')}]`;\r\n }\r\n\r\n return { ...result, content: [{ ...block, text }] };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// ssh-execute composition helpers (pipeline / repeat / format=ndjson)\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface PipelineSegment { index: number; command: string; output: string; exitCode: number }\r\ninterface IterationResult { index: number; startedAt: number; durationMs: number; result: SshResult }\r\n\r\n// Build a wrapper script that runs N commands sequentially in a single SSH\r\n// session, with a unique marker between each so we can split outputs back\r\n// apart. Stderr is merged into stdout per command (so we can section it);\r\n// the original cumulative stderr stays available on the SshResult for diag.\r\nfunction buildPipelineScript(\r\n commands: string[],\r\n shell: 'bash' | 'powershell',\r\n marker: string,\r\n stopOnError: boolean,\r\n): string {\r\n if (shell === 'powershell') {\r\n // PowerShell: redirect Error stream into Output (2>&1) per cmd, capture\r\n // $LASTEXITCODE after each. `iex` (Invoke-Expression) lets us run the\r\n // raw command strings without re-quoting.\r\n const lines: string[] = [\"$ErrorActionPreference='Continue'\", \"$ProgressPreference='SilentlyContinue'\"];\r\n for (let i = 0; i < commands.length; i++) {\r\n lines.push(`Write-Output '${marker} ${i} begin'`);\r\n lines.push(`& { ${commands[i]} } 2>&1`);\r\n lines.push(`$__c = if ($null -eq $LASTEXITCODE) { 0 } else { $LASTEXITCODE }`);\r\n lines.push(`Write-Output ('${marker} ' + ${i} + ' end exit=' + $__c)`);\r\n if (stopOnError) lines.push(`if ($__c -ne 0) { exit $__c }`);\r\n }\r\n return buildPowerShellEncodedCommand(lines.join('; '), []);\r\n }\r\n // bash path: keep it portable so dash/sh works too. `set +e` per cmd\r\n // ensures continue-on-error mode actually continues even when the user's\r\n // script enables `set -e` somewhere inside.\r\n const sh: string[] = [];\r\n for (let i = 0; i < commands.length; i++) {\r\n sh.push(`echo \"${marker} ${i} begin\"`);\r\n sh.push(`{ ${commands[i]}; } 2>&1`);\r\n sh.push(`__c=$?`);\r\n sh.push(`echo \"${marker} ${i} end exit=$__c\"`);\r\n if (stopOnError) sh.push(`if [ \"$__c\" -ne 0 ]; then exit \"$__c\"; fi`);\r\n }\r\n return `bash -c ${posixQuote(sh.join('; '))}`;\r\n}\r\n\r\n// Split a pipeline stdout payload back into per-command segments. Tolerates\r\n// missing markers (e.g. the script aborted mid-pipeline due to stop-on-error).\r\nfunction parsePipelineOutput(stdout: string, commands: string[], marker: string): PipelineSegment[] {\r\n const segments: PipelineSegment[] = [];\r\n // Match `<marker> <i> begin` ... `<marker> <i> end exit=<code>` for each cmd.\r\n for (let i = 0; i < commands.length; i++) {\r\n const beginRe = new RegExp(`^${escapeRegex(marker)}\\\\s+${i}\\\\s+begin\\\\s*$`, 'm');\r\n const endRe = new RegExp(`^${escapeRegex(marker)}\\\\s+${i}\\\\s+end\\\\s+exit=(-?\\\\d+)\\\\s*$`, 'm');\r\n const beginMatch = beginRe.exec(stdout);\r\n const endMatch = endRe.exec(stdout);\r\n if (!beginMatch || !endMatch) {\r\n segments.push({ index: i, command: commands[i] as string, output: '(no output captured — pipeline aborted before this step?)', exitCode: -1 });\r\n continue;\r\n }\r\n const start = beginMatch.index + beginMatch[0].length + 1; // +1 for newline\r\n const end = endMatch.index;\r\n const body = stdout.slice(start, end).replace(/\\n$/, '');\r\n const code = parseInt(endMatch[1] as string, 10);\r\n segments.push({ index: i, command: commands[i] as string, output: body, exitCode: Number.isFinite(code) ? code : -1 });\r\n }\r\n return segments;\r\n}\r\n\r\nfunction escapeRegex(s: string): string {\r\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n\r\nfunction renderPipelineSegments(segments: PipelineSegment[], overall: SshResult, format: 'text' | 'ndjson'): string {\r\n const sections: string[] = [];\r\n for (const seg of segments) {\r\n sections.push(`>>> [${seg.index + 1}/${segments.length}] ${seg.command} (exit ${seg.exitCode})`);\r\n let body = seg.output;\r\n if (format === 'ndjson') {\r\n const parsed = tryParseNdjsonFromCommand(seg.command, body);\r\n if (parsed) body = parsed;\r\n }\r\n sections.push(body || '(no output)');\r\n }\r\n if (overall.stderr) sections.push(`--- aggregate stderr ---\\n${overall.stderr.trimEnd()}`);\r\n return sections.join('\\n');\r\n}\r\n\r\nfunction renderRepeatResult(iters: IterationResult[], mode: 'all' | 'diff' | 'last', format: 'text' | 'ndjson'): string {\r\n const formatBody = (s: string): string => {\r\n if (!format || format !== 'ndjson') return s;\r\n // We don't know the original command here; try a heuristic parse anyway.\r\n return tryParseNdjsonFromCommand('', s) || s;\r\n };\r\n if (mode === 'last') {\r\n const last = iters[iters.length - 1]!;\r\n return `--- iteration ${last.index + 1}/${iters.length} (exit ${last.result.exitCode}, ${last.durationMs}ms) ---\\n${formatBody(last.result.stdout) || '(empty)'}${last.result.stderr ? `\\n[stderr] ${last.result.stderr.trimEnd()}` : ''}`;\r\n }\r\n if (mode === 'diff') {\r\n const sections: string[] = [`(repeat: ${iters.length} runs, diff mode — only differences vs. previous run shown)`];\r\n let prev = '';\r\n for (let i = 0; i < iters.length; i++) {\r\n const cur = iters[i]!.result.stdout;\r\n if (i === 0) {\r\n sections.push(`--- iteration 1 (initial, ${iters[i]!.durationMs}ms) ---\\n${formatBody(cur) || '(empty)'}`);\r\n } else {\r\n const changes = diffLines(prev, cur);\r\n const header = `--- iteration ${i + 1} (${iters[i]!.durationMs}ms, +${changes.added.length} -${changes.removed.length}) ---`;\r\n const block: string[] = [header];\r\n if (changes.added.length === 0 && changes.removed.length === 0) {\r\n block.push('(no changes)');\r\n } else {\r\n for (const line of changes.added) block.push(`+ ${line}`);\r\n for (const line of changes.removed) block.push(`- ${line}`);\r\n }\r\n sections.push(block.join('\\n'));\r\n }\r\n prev = cur;\r\n }\r\n return sections.join('\\n');\r\n }\r\n // 'all'\r\n const sections: string[] = [`(repeat: ${iters.length} runs, all output)`];\r\n for (const it of iters) {\r\n sections.push(`--- iteration ${it.index + 1}/${iters.length} (exit ${it.result.exitCode}, ${it.durationMs}ms) ---`);\r\n sections.push(formatBody(it.result.stdout) || '(empty)');\r\n if (it.result.stderr) sections.push(`[stderr] ${it.result.stderr.trimEnd()}`);\r\n }\r\n return sections.join('\\n');\r\n}\r\n\r\nfunction diffLines(a: string, b: string): { added: string[]; removed: string[] } {\r\n const aSet = new Set(a.split('\\n'));\r\n const bSet = new Set(b.split('\\n'));\r\n const added: string[] = [];\r\n const removed: string[] = [];\r\n for (const line of bSet) if (!aSet.has(line) && line) added.push(line);\r\n for (const line of aSet) if (!bSet.has(line) && line) removed.push(line);\r\n return { added, removed };\r\n}\r\n\r\n// NDJSON parser: detect common Linux command outputs from the command string\r\n// or content shape and emit one JSON object per record. Returns null if the\r\n// content doesn't look like a known format (caller falls back to raw text).\r\nfunction tryParseNdjsonFromCommand(command: string, stdout: string): string | null {\r\n if (!stdout.trim()) return null;\r\n const c = command.toLowerCase();\r\n const looksLike = (re: RegExp) => re.test(c);\r\n // df -h / df -hT\r\n if (looksLike(/\\bdf\\b/) || /^Filesystem\\s+\\S+\\s+Used\\s+/m.test(stdout)) {\r\n return parseDf(stdout);\r\n }\r\n // free / free -m / free -h\r\n if (looksLike(/\\bfree\\b/) || /^\\s*total\\s+used\\s+free/m.test(stdout)) {\r\n return parseFree(stdout);\r\n }\r\n // ps aux / ps -ef\r\n if (looksLike(/\\bps\\b/) || /^USER\\s+PID\\s+%CPU\\s+%MEM/m.test(stdout)) {\r\n return parsePsAux(stdout);\r\n }\r\n // ss -tlnp / ss -tnlp / netstat -tlnp\r\n if (looksLike(/\\bss\\b/) || /^State\\s+Recv-Q\\s+Send-Q/m.test(stdout)) {\r\n return parseSs(stdout);\r\n }\r\n // lsblk\r\n if (looksLike(/\\blsblk\\b/) || /^NAME\\s+MAJ:MIN/m.test(stdout)) {\r\n return parseLsblk(stdout);\r\n }\r\n return null;\r\n}\r\n\r\nfunction splitCols(line: string, max?: number): string[] {\r\n const parts = line.trim().split(/\\s+/);\r\n if (max && parts.length > max) {\r\n return [...parts.slice(0, max - 1), parts.slice(max - 1).join(' ')];\r\n }\r\n return parts;\r\n}\r\n\r\nfunction parseDf(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n const header = lines[0];\r\n if (!header || !/Filesystem/i.test(header)) return null;\r\n // Normalise \"Mounted on\" → \"MountedOn\" before splitting, so we get a clean\r\n // single column instead of two (\"Mounted\" + \"on\" with empty value).\r\n const cleanHeader = header.replace(/Mounted on/i, 'MountedOn');\r\n const cols = cleanHeader.trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, cols.length);\r\n if (parts.length < 4) continue;\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < cols.length; i++) obj[cols[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parseFree(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n const out: string[] = [];\r\n for (const ln of lines) {\r\n if (/^\\s*total\\s+used\\s+free/i.test(ln)) continue;\r\n const m = ln.match(/^(\\S+):?\\s+(.+)$/);\r\n if (!m) continue;\r\n const [type, rest] = [m[1], m[2]];\r\n const cols = (rest as string).trim().split(/\\s+/);\r\n out.push(JSON.stringify({ type: (type as string).replace(/:$/, ''), values: cols.map(Number) }));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parsePsAux(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n if (!lines[0] || !/USER\\s+PID/i.test(lines[0])) return null;\r\n const headers = lines[0].trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, headers.length);\r\n if (parts.length < headers.length) continue;\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < headers.length; i++) obj[headers[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parseSs(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n if (!lines[0] || !/(State|Netid)/i.test(lines[0])) return null;\r\n const headers = lines[0].trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, headers.length);\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < headers.length; i++) obj[headers[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\nfunction parseLsblk(s: string): string | null {\r\n const lines = s.split('\\n').filter(Boolean);\r\n if (!lines[0] || !/NAME\\s+MAJ:MIN/i.test(lines[0])) return null;\r\n const headers = lines[0].trim().split(/\\s+/);\r\n const out: string[] = [];\r\n for (const ln of lines.slice(1)) {\r\n const parts = splitCols(ln, headers.length);\r\n const obj: Record<string, string> = {};\r\n for (let i = 0; i < headers.length; i++) obj[headers[i] as string] = parts[i] || '';\r\n out.push(JSON.stringify(obj));\r\n }\r\n return out.length ? out.join('\\n') : null;\r\n}\r\n\r\n// Resolve a friendly server label for the response footer. Best-effort: falls\r\n// back to the bare ID if the supabase row isn't loaded into the cache yet.\r\nasync function resolveServerLabel(serverId: string | undefined, serverIds: unknown): Promise<string | undefined> {\r\n if (Array.isArray(serverIds) && serverIds.length > 0) return `${serverIds.length} servers`;\r\n if (!serverId) return undefined;\r\n const cached = KNOWN_SERVER_NAMES.get(serverId);\r\n if (cached) return cached.name;\r\n try {\r\n const { data } = await supabase.from('ssh_server').select('id, name').eq('id', serverId).maybeSingle();\r\n if (data?.name) {\r\n KNOWN_SERVER_NAMES.set(serverId, { id: serverId, name: data.name as string });\r\n return data.name as string;\r\n }\r\n } catch { /* swallow — footer is informational */ }\r\n return serverId.slice(0, 8);\r\n}\r\n\r\nasync function sftpWrite(\r\n opts: SshConnectionOptions,\r\n filePath: string,\r\n input: SftpWriteInput,\r\n proxy?: SshConnectionOptions,\r\n meta?: { fileMode?: number; mtimeMs?: number },\r\n): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n assertWritablePath(safe);\r\n\r\n // File permission bits: caller may override (e.g. 0o755 for executable).\r\n // Default 0o644 keeps existing behaviour for plain config writes.\r\n const fileMode = meta?.fileMode !== undefined ? (meta.fileMode & 0o7777) : 0o644;\r\n\r\n // Validate source up-front so the LLM gets a clear error before we open SSH.\r\n let mode: 'content' | 'sourcePath';\r\n let inlineBuffer: Buffer | undefined;\r\n let localPath: string | undefined;\r\n let expectedBytes = 0;\r\n\r\n if ('content' in input && typeof input.content === 'string') {\r\n mode = 'content';\r\n inlineBuffer = Buffer.from(input.content, 'utf-8');\r\n expectedBytes = inlineBuffer.length;\r\n } else if ('sourcePath' in input && typeof input.sourcePath === 'string') {\r\n mode = 'sourcePath';\r\n localPath = input.sourcePath;\r\n if (!isAbsolute(localPath)) return `Error: sourcePath must be an absolute path: ${localPath}`;\r\n if (!existsSync(localPath)) return `Error: sourcePath does not exist: ${localPath}`;\r\n const st = statSync(localPath);\r\n if (!st.isFile()) return `Error: sourcePath is not a regular file: ${localPath}`;\r\n expectedBytes = st.size;\r\n } else {\r\n return 'Error: sftp-write requires exactly one of: content (string) or sourcePath (absolute local path)';\r\n }\r\n\r\n // For inline text we leave SSH compression enabled (cheap, often 5-10x for\r\n // configs/scripts). For sourcePath we disable it: large files are usually\r\n // already-compressed (zip/jpg/mp4/dump.gz) and SSH-level compression then\r\n // wastes CPU and slows the transfer.\r\n const compress = mode === 'content';\r\n const startedAt = Date.now();\r\n let cleanup: (() => void) | undefined;\r\n\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 60_000, { compress });\r\n cleanup = c;\r\n\r\n return await new Promise<string>((resolve) => {\r\n let resolved = false;\r\n let bytesWritten = 0;\r\n\r\n const finish = (msg: string) => {\r\n if (resolved) return;\r\n resolved = true;\r\n watchdog?.cancel();\r\n wallTimer && clearTimeout(wallTimer);\r\n cleanup?.();\r\n cleanup = undefined;\r\n resolve(msg);\r\n };\r\n\r\n // For sourcePath: idle watchdog reset on every fastPut step.\r\n // For content: simple wall-clock timeout.\r\n let watchdog: { reset: () => void; cancel: () => void } | undefined;\r\n let wallTimer: NodeJS.Timeout | undefined;\r\n\r\n if (mode === 'sourcePath') {\r\n const armWatchdog = () => {\r\n let timer: NodeJS.Timeout = setTimeout(\r\n () => finish(`Error: idle timeout (no SFTP progress for ${SFTP_IDLE_TIMEOUT_MS / 1000}s, wrote ${formatBytes(bytesWritten)} of ${formatBytes(expectedBytes)})`),\r\n SFTP_IDLE_TIMEOUT_MS,\r\n );\r\n return {\r\n reset: () => { clearTimeout(timer); timer = setTimeout(\r\n () => finish(`Error: idle timeout (no SFTP progress for ${SFTP_IDLE_TIMEOUT_MS / 1000}s, wrote ${formatBytes(bytesWritten)} of ${formatBytes(expectedBytes)})`),\r\n SFTP_IDLE_TIMEOUT_MS,\r\n ); },\r\n cancel: () => clearTimeout(timer),\r\n };\r\n };\r\n watchdog = armWatchdog();\r\n } else {\r\n wallTimer = setTimeout(\r\n () => finish(`Error: timeout after ${SFTP_INLINE_TIMEOUT_MS / 1000}s`),\r\n SFTP_INLINE_TIMEOUT_MS,\r\n );\r\n }\r\n\r\n client.sftp((err, sftp) => {\r\n if (err) return finish(`Error: ${err.message}`);\r\n\r\n // Apply mtime after a successful write. SFTP `setstat` with atime+mtime\r\n // is the standard way; we leave atime equal to mtime (close enough for\r\n // tooling that cares about freshness). Errors are surfaced as a warning\r\n // suffix so the upload itself is still considered successful.\r\n const applyMtime = (then: (suffix: string) => void) => {\r\n if (meta?.mtimeMs === undefined) return then('');\r\n const secs = Math.floor(meta.mtimeMs / 1000);\r\n sftp.setstat(safe, { atime: secs, mtime: secs }, (statErr) => {\r\n then(statErr ? ` (mtime set failed: ${statErr.message})` : ` (mtime=${new Date(meta.mtimeMs!).toISOString()})`);\r\n });\r\n };\r\n\r\n if (mode === 'content') {\r\n const ws = sftp.createWriteStream(safe, { mode: fileMode });\r\n ws.on('error', (e: Error) => finish(`Error: ${e.message}`));\r\n ws.on('close', () => {\r\n const elapsed = Date.now() - startedAt;\r\n applyMtime((suffix) => finish(`Written ${expectedBytes} bytes to ${safe} in ${elapsed}ms (mode=0o${fileMode.toString(8)})${suffix}`));\r\n });\r\n ws.end(inlineBuffer!);\r\n return;\r\n }\r\n\r\n // sourcePath path: ssh2 fastPut does the heavy lifting (parallel\r\n // pipelined SFTP_WRITE packets). Step callback gives us progress for\r\n // the watchdog and periodic logs.\r\n let nextProgressLog = SFTP_PROGRESS_LOG_BYTES;\r\n sftp.fastPut(\r\n localPath!,\r\n safe,\r\n {\r\n concurrency: SFTP_FASTPUT_CONCURRENCY,\r\n chunkSize: SFTP_FASTPUT_CHUNK_SIZE,\r\n mode: fileMode,\r\n fileSize: expectedBytes,\r\n step: (transferred: number) => {\r\n bytesWritten = transferred;\r\n watchdog?.reset();\r\n if (transferred >= nextProgressLog) {\r\n console.error(\r\n `[sftp-write] ${formatBytes(transferred)} / ${formatBytes(expectedBytes)} → ${safe}`,\r\n );\r\n nextProgressLog += SFTP_PROGRESS_LOG_BYTES;\r\n }\r\n },\r\n },\r\n (fpErr) => {\r\n if (fpErr) return finish(`Error: ${fpErr.message}`);\r\n const elapsed = Date.now() - startedAt;\r\n const mbps = expectedBytes / (1024 * 1024) / Math.max(0.001, elapsed / 1000);\r\n applyMtime((suffix) => finish(\r\n `Uploaded ${formatBytes(expectedBytes)} from ${localPath} to ${safe} ` +\r\n `in ${(elapsed / 1000).toFixed(1)}s (${mbps.toFixed(1)} MB/s, mode=0o${fileMode.toString(8)})${suffix}`,\r\n ));\r\n },\r\n );\r\n });\r\n });\r\n } catch (e: unknown) {\r\n cleanup?.();\r\n return `Error: ${e instanceof Error ? e.message : String(e)}`;\r\n }\r\n}\r\n\r\nasync function sftpDelete(\r\n opts: SshConnectionOptions,\r\n filePath: string,\r\n proxy?: SshConnectionOptions,\r\n options?: { recursive?: boolean },\r\n): Promise<string> {\r\n const safe = sanitizePath(filePath);\r\n assertWritablePath(safe);\r\n const recursive = options?.recursive === true;\r\n let cleanup: (() => void) | undefined;\r\n try {\r\n const { client, cleanup: c } = await connectSshClient(opts, proxy, 30_000);\r\n cleanup = c;\r\n return await new Promise<string>((resolve) => {\r\n const timer = setTimeout(() => { cleanup?.(); resolve('Error: timeout'); cleanup = undefined; }, 60_000);\r\n client.sftp((err, sftp) => {\r\n if (err) { clearTimeout(timer); cleanup?.(); cleanup = undefined; resolve(`Error: ${err.message}`); return; }\r\n\r\n // Recursive directory removal: walk the tree depth-first via SFTP and\r\n // unlink files / rmdir dirs from the bottom up. Pure SFTP — no shell\r\n // shenanigans, so it works on Windows OpenSSH too.\r\n if (recursive) {\r\n const removeTree = async (target: string): Promise<{ files: number; dirs: number }> => {\r\n return new Promise((resolveTree) => {\r\n sftp.stat(target, (statErr, stats) => {\r\n if (statErr) return resolveTree({ files: 0, dirs: 0 });\r\n const mode = stats.mode || 0;\r\n const isDir = (mode & 0o170000) === 0o040000;\r\n if (!isDir) {\r\n sftp.unlink(target, () => resolveTree({ files: 1, dirs: 0 }));\r\n return;\r\n }\r\n sftp.readdir(target, async (rdErr, list) => {\r\n if (rdErr) return resolveTree({ files: 0, dirs: 0 });\r\n let files = 0; let dirs = 0;\r\n for (const item of list) {\r\n const child = target === '/' ? `/${item.filename}` : `${target}/${item.filename}`;\r\n const r = await removeTree(child);\r\n files += r.files; dirs += r.dirs;\r\n }\r\n sftp.rmdir(target, () => resolveTree({ files, dirs: dirs + 1 }));\r\n });\r\n });\r\n });\r\n };\r\n removeTree(safe).then(({ files, dirs }) => {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Removed ${safe} recursively (${files} files, ${dirs} directories)`);\r\n });\r\n return;\r\n }\r\n\r\n sftp.unlink(safe, (unlinkErr) => {\r\n if (unlinkErr) {\r\n sftp.rmdir(safe, (rmdirErr) => {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(rmdirErr ? `Error: ${unlinkErr.message}` : `Deleted directory ${safe}`);\r\n });\r\n } else {\r\n clearTimeout(timer); cleanup?.(); cleanup = undefined;\r\n resolve(`Deleted file ${safe}`);\r\n }\r\n });\r\n });\r\n });\r\n } catch (e: any) {\r\n cleanup?.();\r\n return `Error: ${e.message}`;\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cross-endpoint copy (SSH ↔ SSH, SSH ↔ R2, R2 ↔ R2). True streaming for\r\n// SSH paths so we never round-trip through local disk for huge files.\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type CopyEndpoint =\r\n | { kind: 'ssh'; opts: SshConnectionOptions; proxy?: SshConnectionOptions; path: string }\r\n | { kind: 'r2'; bucket: string; key: string };\r\n\r\ninterface CopyResult { bytes: number; elapsedMs: number; mode: string }\r\n\r\nasync function sftpCopy(src: CopyEndpoint, dst: CopyEndpoint): Promise<CopyResult> {\r\n const startedAt = Date.now();\r\n\r\n // R2 → R2: server-side copy (zero data egress).\r\n if (src.kind === 'r2' && dst.kind === 'r2') {\r\n const { size } = await r2CopyObject(src.bucket, src.key, dst.bucket, dst.key);\r\n return { bytes: size, elapsedMs: Date.now() - startedAt, mode: 'r2-server-side' };\r\n }\r\n\r\n // R2 → SSH: stream R2 body into SFTP write stream.\r\n if (src.kind === 'r2' && dst.kind === 'ssh') {\r\n const safe = sanitizePath(dst.path);\r\n assertWritablePath(safe);\r\n const { stream, size } = await r2GetObjectStream(src.bucket, src.key);\r\n const { client, cleanup } = await connectSshClient(dst.opts, dst.proxy, 60_000);\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n client.sftp((err, sftp) => {\r\n if (err) return reject(err);\r\n const ws = sftp.createWriteStream(safe);\r\n ws.on('close', () => resolve());\r\n ws.on('error', reject);\r\n stream.on('error', reject);\r\n stream.pipe(ws);\r\n });\r\n });\r\n } finally { cleanup(); }\r\n return { bytes: size, elapsedMs: Date.now() - startedAt, mode: 'r2→ssh-stream' };\r\n }\r\n\r\n // SSH → R2: pipe SFTP read stream to R2 PutObject. The S3 SDK accepts a\r\n // Readable body; ContentLength is required for R2's API, so we HEAD-equivalent\r\n // (sftp.stat) the source first.\r\n if (src.kind === 'ssh' && dst.kind === 'r2') {\r\n const safeSrc = sanitizePath(src.path);\r\n const { client, cleanup } = await connectSshClient(src.opts, src.proxy, 60_000);\r\n try {\r\n const { stream, size } = await new Promise<{ stream: Readable; size: number }>((resolve, reject) => {\r\n client.sftp((err, sftp) => {\r\n if (err) return reject(err);\r\n sftp.stat(safeSrc, (statErr, stats) => {\r\n if (statErr) return reject(statErr);\r\n const s = (stats.size as number) || 0;\r\n const rs = sftp.createReadStream(safeSrc) as unknown as Readable;\r\n resolve({ stream: rs, size: s });\r\n });\r\n });\r\n });\r\n // For huge files (>4.5 GB) the single PUT path will fail (R2 limit).\r\n // We don't have multipart-from-stream right now, so fall back to a\r\n // clear error — caller can mirror locally first if needed.\r\n if (size > R2_MULTIPART_THRESHOLD) {\r\n cleanup();\r\n throw new Error(`Source object is ${formatBytes(size)} which exceeds R2 single-PUT cap (${formatBytes(R2_MULTIPART_THRESHOLD)}). For now: download via sftp-write { sourceRemote, target: local } first, then upload to R2 with sourcePath.`);\r\n }\r\n await r2PutObject(dst.bucket, dst.key, stream, size);\r\n return { bytes: size, elapsedMs: Date.now() - startedAt, mode: 'ssh→r2-stream' };\r\n } finally { cleanup(); }\r\n }\r\n\r\n // SSH → SSH: open both sessions, pipe read stream into write stream. No\r\n // local detour — the SFTP protocol streams chunks directly.\r\n if (src.kind === 'ssh' && dst.kind === 'ssh') {\r\n const safeSrc = sanitizePath(src.path);\r\n const safeDst = sanitizePath(dst.path);\r\n assertWritablePath(safeDst);\r\n const srcConn = await connectSshClient(src.opts, src.proxy, 60_000);\r\n let dstConn: { client: SshClient; cleanup: () => void } | undefined;\r\n try {\r\n dstConn = await connectSshClient(dst.opts, dst.proxy, 60_000);\r\n const bytes = await new Promise<number>((resolve, reject) => {\r\n srcConn.client.sftp((err, srcSftp) => {\r\n if (err) return reject(err);\r\n dstConn!.client.sftp((err2, dstSftp) => {\r\n if (err2) return reject(err2);\r\n srcSftp.stat(safeSrc, (statErr, stats) => {\r\n if (statErr) return reject(statErr);\r\n const size = (stats.size as number) || 0;\r\n const rs = srcSftp.createReadStream(safeSrc);\r\n const ws = dstSftp.createWriteStream(safeDst);\r\n ws.on('close', () => resolve(size));\r\n ws.on('error', reject);\r\n rs.on('error', reject);\r\n rs.pipe(ws);\r\n });\r\n });\r\n });\r\n });\r\n return { bytes, elapsedMs: Date.now() - startedAt, mode: 'ssh→ssh-stream' };\r\n } finally {\r\n srcConn.cleanup();\r\n dstConn?.cleanup();\r\n }\r\n }\r\n\r\n throw new Error('Unsupported copy combination');\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\n/**\r\n * Build engine-specific schema-introspection SQL for the `describe` shortcut\r\n * on `db-query`. Sanitises the identifier so a caller can't slip an arbitrary\r\n * statement through `describe`. Pass \"*\" to list all tables in the current\r\n * database/schema.\r\n */\r\nfunction buildDescribeSql(target: string, engine: 'mysql' | 'postgres' | 'mssql'): string {\r\n if (target === '*' || target === '') {\r\n if (engine === 'postgres') {\r\n return \"SELECT schemaname, tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema') ORDER BY schemaname, tablename\";\r\n }\r\n if (engine === 'mssql') {\r\n return \"SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME\";\r\n }\r\n return 'SHOW TABLES';\r\n }\r\n const safe = target.replace(/[^a-zA-Z0-9_]/g, '');\r\n if (!safe) throw new Error(`Invalid describe target: ${target}`);\r\n if (engine === 'postgres') {\r\n return (\r\n `SELECT column_name, data_type, is_nullable, column_default ` +\r\n `FROM information_schema.columns WHERE table_name='${safe}' ORDER BY ordinal_position;` +\r\n `\\nSELECT indexname, indexdef FROM pg_indexes WHERE tablename='${safe}'`\r\n );\r\n }\r\n if (engine === 'mssql') {\r\n return `EXEC sp_help '${safe}'`;\r\n }\r\n return `DESCRIBE \\`${safe}\\`; SHOW INDEX FROM \\`${safe}\\``;\r\n}\r\n\r\n/**\r\n * Build the trailing diagnostic footer for `db-query` results so the caller\r\n * can tell whether the auto-LIMIT cap kicked in (and whether they should\r\n * paginate / refine) without having to count rows.\r\n */\r\nfunction formatDbQueryFooter(\r\n output: string,\r\n appliedLimit: boolean,\r\n maxRows: number,\r\n explainMode: boolean,\r\n): string {\r\n if (explainMode) {\r\n return '\\n\\n[explain] Plan returned, no rows executed.';\r\n }\r\n if (!appliedLimit) return '';\r\n\r\n // Prefer the trailing \"(N row(s))\" summary that psql/mysql/sqlcmd all emit;\r\n // falls back to counting non-decorative lines minus a presumed header row.\r\n // We over-fetched maxRows+1 internally so the printed count can briefly\r\n // equal maxRows+1 when truncation actually occurred.\r\n const rows = parseRowCountFromOutput(output);\r\n if (rows == null) return `\\n\\n[ok] auto-LIMIT ${maxRows} applied (row count not detected).`;\r\n if (rows > maxRows) {\r\n return `\\n\\n[truncated] auto-LIMIT ${maxRows} hit — more rows available. Refine WHERE / ORDER BY or raise maxRows (max 10000).`;\r\n }\r\n return `\\n\\n[ok] returned ${rows} row(s), under auto-LIMIT ${maxRows}.`;\r\n}\r\n\r\n/**\r\n * Best-effort row-count extractor for `db-query` output. Recognises the\r\n * `(N row[s])` summary line that psql / mysql / sqlcmd all print at the end\r\n * of a result set. Returns null if no recognizable summary is found, so the\r\n * caller can fall back to a less specific footer.\r\n */\r\nfunction parseRowCountFromOutput(output: string): number | null {\r\n // Walk lines bottom-up; the summary is typically the last non-empty line.\r\n const lines = output.split('\\n');\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n const l = lines[i]?.trim();\r\n if (!l) continue;\r\n // postgres / mysql tabular: \"(5 rows)\" / \"(1 row)\"\r\n const m1 = /^\\(\\s*(\\d+)\\s+rows?\\s*\\)$/i.exec(l);\r\n if (m1?.[1]) return Number(m1[1]);\r\n // mysql shell: \"5 rows in set (..)\"\r\n const m2 = /^(\\d+)\\s+rows?\\s+in\\s+set\\b/i.exec(l);\r\n if (m2?.[1]) return Number(m2[1]);\r\n // mssql sqlcmd: \"(5 rows affected)\"\r\n const m3 = /^\\(\\s*(\\d+)\\s+rows?\\s+affected\\s*\\)$/i.exec(l);\r\n if (m3?.[1]) return Number(m3[1]);\r\n // Stop if we encounter a data row before any summary\r\n if (/[a-zA-Z0-9]/.test(l) && i < lines.length - 3) return null;\r\n }\r\n return null;\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\ninterface DnsDiffRecord { type: string; name: string; value: string; ttl: number; }\r\n\r\n/**\r\n * Render a human-readable diff of a proposed DNS-zone change for `dryRun`\r\n * mode in dns-create / dns-update / dns-delete. Highlights added vs.\r\n * removed records and warns when the change touches MX / SPF / DKIM / DMARC\r\n * — historically the riskiest mistakes to commit blindly.\r\n */\r\nfunction formatDnsDiff(\r\n domain: string,\r\n before: DnsDiffRecord[],\r\n after: DnsDiffRecord[],\r\n change: { verb: 'create' | 'update' | 'delete'; added?: DnsDiffRecord[]; removed?: DnsDiffRecord[] },\r\n): string {\r\n const fmt = (r: DnsDiffRecord): string =>\r\n `${r.type.padEnd(6)} ${r.name.padEnd(30)} ttl=${String(r.ttl).padEnd(5)} ${r.value}`;\r\n\r\n const lines: string[] = [];\r\n lines.push(`[dryRun] ${change.verb.toUpperCase()} on ${domain} — no changes applied.`);\r\n lines.push(`Records before: ${before.length} → after: ${after.length}`);\r\n\r\n if (change.removed?.length) {\r\n lines.push('', 'REMOVED:');\r\n for (const r of change.removed) lines.push(` - ${fmt(r)}`);\r\n }\r\n if (change.added?.length) {\r\n lines.push('', 'ADDED:');\r\n for (const r of change.added) lines.push(` + ${fmt(r)}`);\r\n }\r\n\r\n const sensitive = [\r\n ...(change.added ?? []),\r\n ...(change.removed ?? []),\r\n ].filter((r) => {\r\n if (r.type === 'MX') return true;\r\n if (r.type === 'TXT') {\r\n const v = r.value.toLowerCase();\r\n return v.includes('v=spf1') || v.includes('v=dmarc1') || v.includes('_domainkey') || r.name.toLowerCase().includes('_domainkey');\r\n }\r\n return false;\r\n });\r\n if (sensitive.length > 0) {\r\n lines.push('', '! WARNING: touches mail-auth records (MX / SPF / DMARC / DKIM). Double-check before re-running without dryRun.');\r\n }\r\n\r\n lines.push('', 'Re-run without `dryRun: true` to apply.');\r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Build a human-readable hint listing records that share the requested type +\r\n * name when `dns-record` update/delete fails to find an exact value match.\r\n * Greatly reduces the round-trip of: error → dns-list → retry.\r\n * Falls back to \"all records for this name\" when nothing matches type+name,\r\n * which catches typos in the type (e.g. CNAME vs ALIAS).\r\n */\r\nfunction describeDnsCandidates(\r\n records: DnsDiffRecord[],\r\n type: string,\r\n name: string,\r\n attemptedValue: string,\r\n): string {\r\n const sameTypeAndName = records.filter((r) => r.type === type && r.name === name);\r\n const fmt = (r: DnsDiffRecord): string =>\r\n ` - ${r.type.padEnd(6)} ${r.name.padEnd(30)} ttl=${String(r.ttl).padEnd(5)} ${r.value}`;\r\n\r\n if (sameTypeAndName.length > 0) {\r\n const lines = ['Current records with this type + name (use one of these values verbatim):'];\r\n for (const r of sameTypeAndName.slice(0, 10)) lines.push(fmt(r));\r\n if (sameTypeAndName.length > 10) lines.push(` ...and ${sameTypeAndName.length - 10} more`);\r\n lines.push(`(attempted value: ${attemptedValue})`);\r\n return lines.join('\\n');\r\n }\r\n\r\n // Type or name typo — show everything that matches just the name.\r\n const sameName = records.filter((r) => r.name === name);\r\n if (sameName.length > 0) {\r\n const types = [...new Set(sameName.map((r) => r.type))].sort().join(', ');\r\n const lines = [\r\n `No ${type} records exist for \"${name}\", but other records do (types: ${types}). Sample:`,\r\n ];\r\n for (const r of sameName.slice(0, 10)) lines.push(fmt(r));\r\n if (sameName.length > 10) lines.push(` ...and ${sameName.length - 10} more`);\r\n return lines.join('\\n');\r\n }\r\n\r\n return `No records found at all for name \"${name}\". Run dns-list to inspect the zone.`;\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:\r\n 'List all SSH servers you have access to. Returns id, name, hostname, tags, and os_type per server. ' +\r\n 'Pass `includeStats: true` to also probe each server in parallel for container count, disk-free, and uptime ' +\r\n '(skips unreachable hosts gracefully). Cached for 60s — pass `noCache: true` to force a refresh. ' +\r\n 'Adds an \"auto-context\" footer with one-line tags inferred from server name/tags so the LLM knows which host runs Trigger / Supabase / proxy / etc. (disable with `context: false`).',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n includeStats: { type: 'boolean', description: 'When true, probe each server (in parallel, with timeout) for container count, disk-free, and uptime.' },\r\n statsParallelism: { type: 'number', description: 'Max parallel probes when includeStats is true (default 8, cap 20).' },\r\n statsTimeoutMs: { type: 'number', description: 'Per-server probe timeout in ms when includeStats is true (default 6000, range 1000-30000).' },\r\n context: { type: 'boolean', description: 'Include auto-context footer with name/tag-based hints (default true). Pass false to suppress.' },\r\n noCache: { type: 'boolean', description: 'Bypass the 60s in-memory cache.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'ssh-execute',\r\n description:\r\n 'Execute one or more commands on a remote server via SSH. OS-aware: bash on linux, `powershell -EncodedCommand` (UTF-16LE base64) on windows, so $, #, quotes, spaces inside `args` are never re-interpreted by a shell. Some dangerous commands are blocked. Use `list-servers` first to see each server\\'s os_type.\\n\\n' +\r\n 'Three modes (compose them in one call):\\n' +\r\n '- Single: `command` (+ optional `args[]`). Quick or safe.\\n' +\r\n '- Pipeline: `pipeline: [\"cmd1\",\"cmd2\",\"cmd3\"]` runs all commands sequentially in one SSH session and returns segmented per-command output (each with its own exit code). Default continues on error; pass `pipelineStopOnError: true` to abort.\\n' +\r\n '- Repeat: `repeat: N, intervalSeconds: S, output: \"all\"|\"diff\"|\"last\"`. Diff mode shows only added/removed lines vs. the previous run — perfect for \"watch this metric for 5 min\".\\n\\n' +\r\n '`stdin` pipes data into the remote process (queries, scripts, secrets) without putting it on the command line. `cwd` sets the working directory (auto `cd` on Linux / `Set-Location` on Windows).\\n\\n' +\r\n 'Idle timeout: defaults to 120s — if the remote produces no stdout/stderr for that long the call returns with a clear timeout message. Pass `idleTimeoutSeconds: 0` to disable, or e.g. `300` for slow workloads.\\n\\n' +\r\n 'Fan-out: pass `serverIds: [id1, id2, ...]` (instead of `serverId`) to run across multiple servers in parallel.\\n\\n' +\r\n 'Auto-features: outputs >8 KB are auto-truncated with a continuation hint; transient SSH failures (ECONNRESET/ETIMEDOUT/etc) get one automatic retry. Set `format: \"ndjson\"` to parse common Linux outputs (df / free / ps aux / ss / lsblk) into newline-delimited JSON instead of whitespace-padded text.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of one SSH server. Mutually exclusive with serverIds.' },\r\n serverIds: { type: 'array', items: { type: 'string' }, description: 'Fan-out: list of server UUIDs to run the command on in parallel. Mutually exclusive with serverId.' },\r\n command: { type: 'string', description: 'Program/command to run (e.g. \"mysql\", \"Get-Service\", \"df\"). Required unless `pipeline[]` is set.' },\r\n args: { type: 'array', items: { type: 'string' }, description: 'Optional argv list. When provided, each entry is safely quoted/encoded for the target OS.' },\r\n pipeline: { type: 'array', items: { type: 'string' }, description: 'Run multiple shell commands sequentially in ONE SSH session, with per-command exit codes and segmented output. Saves N round-trips for setup→test→cleanup workflows.' },\r\n pipelineStopOnError: { type: 'boolean', description: 'When pipeline is set, abort the chain on the first non-zero exit (default false: keep going so all outputs reach the LLM).' },\r\n repeat: { type: 'number', description: 'Re-run the command/pipeline N times (default 1, max 60). Combine with intervalSeconds + output to \"watch\" a metric.' },\r\n intervalSeconds: { type: 'number', description: 'When repeat>1, seconds to wait between iterations (default 0, max 600).' },\r\n output: { type: 'string', enum: ['all', 'diff', 'last'], description: 'When repeat>1: how to render iterations. `all` = full output per run; `diff` = only added/removed lines vs. previous run; `last` = only the final iteration.' },\r\n format: { type: 'string', enum: ['text', 'ndjson'], description: 'Output format. `ndjson` parses common Linux outputs (df, free, ps aux, ss, lsblk) into newline-delimited JSON.' },\r\n stdin: { type: 'string', description: 'Optional data piped to the remote process stdin.' },\r\n cwd: { type: 'string', description: 'Working directory on the remote (cd <cwd> on Linux, Set-Location on Windows).' },\r\n shell: { type: 'string', enum: ['auto', 'bash', 'powershell'], description: 'Override shell selection (default \"auto\" uses the server\\'s os_type).' },\r\n parallelism: { type: 'number', description: 'Max concurrent SSH sessions when using serverIds[] (default 5, max 20).' },\r\n timeout: { type: 'number', description: 'Wall timeout in milliseconds (default: 60000). Usually idleTimeoutSeconds is what you want instead.' },\r\n idleTimeoutSeconds: { type: 'number', description: 'Abort if no output for N seconds (default 120). Pass 0 to disable. Useful when the wall budget is hard to predict but silence usually means \"stuck\".' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'sftp-list',\r\n description:\r\n 'List files in remote storage. Two backends (provide exactly one of `serverId` or `bucket`):\\n' +\r\n '- `serverId`: list a directory on an SSH server via SFTP. Supports recursive traversal, depth cap, and glob filtering (no need for `ssh-execute \"find ...\"`).\\n' +\r\n '- `bucket`: list objects in a Cloudflare R2 bucket. `path` becomes the key prefix. Default folder mode groups by `/` delimiter; pass `recursive: true` for a flat listing of all keys under the prefix. Requires R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY env vars on the MCP.\\n\\n' +\r\n 'Sorting/summary applies to both backends: `sortBy` (name|size|mtime) + `reverse`. `summary: true` returns just totals (file count, dir count, total bytes) — useful as a cheap pre-flight before pulling a full listing.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'Directory path (SSH) or key prefix (R2). Default: /' },\r\n recursive: { type: 'boolean', description: 'Walk into subdirectories / list all keys flat (default false)' },\r\n maxDepth: { type: 'number', description: 'Maximum recursion depth for SSH mode (1-20, default 5). Ignored for R2.' },\r\n pattern: { type: 'string', description: 'Glob pattern to filter basenames (e.g. \"*.conf\", \"wp-*.php\").' },\r\n maxResults: { type: 'number', description: 'Cap total entries returned (default 5000, max 50000)' },\r\n sortBy: { type: 'string', enum: ['name', 'size', 'mtime'], description: 'Sort order (default `name`). Directories always come first within each ordering.' },\r\n reverse: { type: 'boolean', description: 'Reverse sort direction (e.g. largest-first or newest-first).' },\r\n summary: { type: 'boolean', description: 'Return only totals (file count, directory count, total bytes) instead of the full listing.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'sftp-read',\r\n description:\r\n 'Read a text file from remote storage (max 1 MiB). Two backends (provide exactly one of `serverId` or `bucket`):\\n' +\r\n '- `serverId`: read from an SSH server via SFTP.\\n' +\r\n '- `bucket`: read an object from a Cloudflare R2 bucket. `path` is the object key.\\n\\n' +\r\n 'Use `offset` and/or `length` for ranged reads — perfect for sampling a slice of a multi-MB log/dump without exceeding the 1 MiB inline limit. Ranged reads include a `# range: bytes A-B of TOTAL` header so you know what window you got.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'File path (SSH) or object key (R2)' },\r\n offset: { type: 'number', description: 'Byte offset to start reading from (0-indexed). Triggers ranged read mode.' },\r\n length: { type: 'number', description: 'Number of bytes to read (capped at 1 MiB). Defaults to remaining-from-offset when omitted.' },\r\n },\r\n required: ['path'],\r\n },\r\n },\r\n {\r\n name: 'sftp-write',\r\n description:\r\n 'Write OR copy a file in remote storage. Two target backends (`serverId` or `bucket`) and three source modes:\\n\\n' +\r\n 'Sources:\\n' +\r\n '- `content` (string): inline UTF-8 text (≈1 MB max).\\n' +\r\n '- `sourcePath` (absolute local path): streams a local file. SSH uses ssh2 fastPut; R2 uses streamed PUT (or automatic multipart for >4.5 GB). Handles GB-scale.\\n' +\r\n '- `sourceRemote: { serverId|bucket, path }`: COPY mode — pulls from one remote and writes to another in a single operation, no local detour. Supports all four directions: ssh↔ssh, ssh↔r2, r2↔ssh, r2↔r2 (R2↔R2 uses server-side CopyObject = zero data egress).\\n\\n' +\r\n 'Targets:\\n' +\r\n '- `serverId`: SSH server via SFTP. Protected system paths blocked. Optional `mode` (POSIX bits e.g. 0o755) and `mtime` (modification time) — SSH only.\\n' +\r\n '- `bucket`: Cloudflare R2 bucket. `mode`/`mtime` are ignored on R2.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'TARGET: UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'TARGET: Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'TARGET path (SSH file path or R2 object key)' },\r\n content: { type: 'string', description: 'Source: inline UTF-8 file content (mutually exclusive with sourcePath / sourceRemote)' },\r\n sourcePath: { type: 'string', description: 'Source: absolute local file path (mutually exclusive with content / sourceRemote). Use for >1 MB or binary.' },\r\n sourceRemote: { type: 'object', description: 'Source: copy from another remote. Shape: { serverId?: string, bucket?: string, path: string }. Picks the streaming strategy (ssh→ssh, r2→ssh, ssh→r2, r2→r2 server-side).', properties: { serverId: { type: 'string' }, bucket: { type: 'string' }, path: { type: 'string' } } },\r\n mode: { oneOf: [{ type: 'number' }, { type: 'string' }], description: 'POSIX file permission bits (SSH target only). Number (0o755 / 493) or octal string (\"755\" / \"0o755\"). Default 0o644.' },\r\n mtime: { oneOf: [{ type: 'number' }, { type: 'string' }], description: 'File modification time (SSH target only). ms-since-epoch number or ISO-8601 date string.' },\r\n },\r\n required: ['path'],\r\n },\r\n },\r\n {\r\n name: 'sftp-delete',\r\n description:\r\n 'Delete a file (or directory tree) from remote storage. Two backends (provide exactly one of `serverId` or `bucket`):\\n' +\r\n '- `serverId`: delete a file or empty directory on an SSH server via SFTP. Protected system paths blocked. With `recursive: true` walks the tree depth-first via SFTP and removes files + empty dirs from the bottom up (works on Windows OpenSSH too — no shell tricks).\\n' +\r\n '- `bucket`: delete an object from a Cloudflare R2 bucket. `path` is the object key. With `recursive: true`, treats `path` as a key prefix and batch-deletes every object beneath it.\\n\\n' +\r\n 'Safety nets:\\n' +\r\n '- `dryRun: true` → returns \"Would delete N items (size)\" with a sample preview, no actual deletion.\\n' +\r\n '- `confirmAbove: N` + `confirmCount: <exact>` → refuses recursive deletes touching more than N items unless the caller passes `confirmCount` matching the actual count.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of the SSH server (mutually exclusive with bucket)' },\r\n bucket: { type: 'string', description: 'Cloudflare R2 bucket name (mutually exclusive with serverId)' },\r\n path: { type: 'string', description: 'File path / object key (or directory / key prefix when recursive)' },\r\n recursive: { type: 'boolean', description: 'Recursively remove a directory tree (SSH) or all objects under a key prefix (R2).' },\r\n dryRun: { type: 'boolean', description: 'Preview-only mode: returns what would be deleted (count, total size, sample paths) without touching anything.' },\r\n confirmAbove: { type: 'number', description: 'Refuse recursive deletes that touch more than N items unless `confirmCount` matches the actual count.' },\r\n confirmCount: { type: 'number', description: 'When confirmAbove gates a delete, pass the exact item count from the dry-run output to confirm intent.' },\r\n },\r\n required: ['path'],\r\n },\r\n },\r\n {\r\n name: 'docker-list',\r\n description:\r\n 'List Docker containers on one or more remote servers. Sorted by compose project then name, with a HEALTH column (healthy / unhealthy / starting / no-check). Filter by `nameFilter` (string OR array of substring/glob entries — passes if ANY entry matches), restrict to compose containers with `composeOnly`, or group output per project with `groupByProject`.\\n\\n' +\r\n 'Fan-out: pass `serverIds: [...]` (instead of `serverId`) to query multiple servers in parallel — perfect for \"show all unhealthy containers across the fleet\". Per-server sections are clearly headed.\\n\\n' +\r\n 'Cached for 30s — pass `noCache: true` to bypass.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of one SSH server. Mutually exclusive with serverIds.' },\r\n serverIds: { type: 'array', items: { type: 'string' }, description: 'Fan-out: list of server UUIDs to query in parallel. Mutually exclusive with serverId.' },\r\n format: { type: 'string', enum: ['table', 'json'], description: 'Output format: human table (default) or NDJSON. JSON adds a \"Server\" field per row in fan-out mode.' },\r\n composeOnly: { type: 'boolean', description: 'Only show containers that have a docker-compose project label.' },\r\n nameFilter: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'Filter by container name. Single entry or array; each entry is glob (* or ?) or substring. A row passes when ANY entry matches.' },\r\n groupByProject: { type: 'boolean', description: 'Group output per compose project with a `=== project (count) ===` header (single-server mode only).' },\r\n parallelism: { type: 'number', description: 'Max concurrent SSH sessions when using serverIds[] (default 5, max 20).' },\r\n noCache: { type: 'boolean', description: 'Bypass the 30s in-memory cache.' },\r\n },\r\n },\r\n },\r\n {\r\n name: 'docker-logs',\r\n description:\r\n 'Get logs from one or more Docker containers, optionally across multiple servers. `containerName` accepts a string OR array — multi-container output is line-prefixed with `[name]`. Supports time-window (`since`), server-side `grep`, line-count (`tail`), and real-time follow (`followSeconds`). Always merges stderr into stdout. Outputs >8 KB get a continuation hint.\\n\\n' +\r\n 'Fan-out: pass `serverIds: [...]` to tail the same container(s) across multiple servers in one call (e.g. all kong instances). Per-server output is grouped under headers.\\n\\n' +\r\n 'Fuzzy hint: if a container name typo is detected, the error includes \"Did you mean: ...\" suggestions from the docker-list cache.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n serverId: { type: 'string', description: 'UUID of one SSH server. Mutually exclusive with serverIds.' },\r\n serverIds: { type: 'array', items: { type: 'string' }, description: 'Fan-out: list of server UUIDs to tail in parallel. Mutually exclusive with serverId.' },\r\n containerName: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'Single container name/ID or an array for multi-container tail. Multi mode prefixes each line with [name].' },\r\n tail: { type: 'number', description: 'Number of recent log lines per container (default 100, default 0 in follow mode).' },\r\n lines: { type: 'number', description: 'Deprecated alias for `tail`. Prefer `tail`.' },\r\n since: { type: 'string', description: 'Time window, e.g. \"10m\", \"2h\", \"24h\", or an absolute \"2026-05-09T10:00:00\".' },\r\n grep: { type: 'string', description: 'Case-insensitive regex/literal filter applied server-side (saves tokens for noisy containers).' },\r\n followSeconds: { type: 'number', description: 'When >0, stream new log lines for N seconds via `docker logs -f`, then exit (max 300). Multi-container follow runs all streams in parallel.' },\r\n parallelism: { type: 'number', description: 'Max concurrent SSH sessions when using serverIds[] (default 5, max 20).' },\r\n },\r\n required: ['containerName'],\r\n },\r\n },\r\n {\r\n name: 'docker-exec',\r\n description:\r\n 'Run a command inside a running Docker container. `args[]` are quoted safely (no shell-escape hell with $ or quotes). Optional `stdin` pipes data into the container process (for SQL, scripts, etc.). Pass `interactive: true` to allocate a TTY (`docker exec -it`) so commands like `psql`/`mysql`/`bash` produce human-friendly output. Use this instead of `ssh-execute \"docker exec ...\"`.',\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 container: { type: 'string', description: 'Container name or ID' },\r\n command: { type: 'string', description: 'Program to run inside the container (e.g. \"psql\", \"wp\", \"node\").' },\r\n args: { type: 'array', items: { type: 'string' }, description: 'Argument list, each safely quoted.' },\r\n stdin: { type: 'string', description: 'Optional data piped to the container process stdin.' },\r\n interactive: { type: 'boolean', description: 'Allocate a TTY (`docker exec -it`). Useful for tools that probe isatty(stdout) — collapses stderr into stdout when enabled.' },\r\n workdir: { type: 'string', description: 'Working directory inside the container (-w).' },\r\n user: { type: 'string', description: 'User to run as inside the container (-u).' },\r\n timeout: { type: 'number', description: 'Timeout in milliseconds (default: 60000)' },\r\n },\r\n required: ['serverId', 'container', 'command'],\r\n },\r\n },\r\n {\r\n name: 'docker-compose',\r\n description:\r\n 'Run a docker-compose action against a project on a remote server. Replaces the common `ssh-execute \"cd /opt/x && docker compose ...\"` pattern. Action enum keeps the surface tiny.',\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 projectPath: { type: 'string', description: 'Absolute path to the directory containing docker-compose.yml.' },\r\n action: { type: 'string', enum: ['up', 'down', 'restart', 'logs', 'ps', 'pull', 'build'], description: 'Compose action.' },\r\n service: { type: 'string', description: 'Optional service name to scope the action to (e.g. \"studio\"). Omit to act on the whole project.' },\r\n tail: { type: 'number', description: 'For `logs`: number of lines (default 200).' },\r\n timeout: { type: 'number', description: 'Timeout in milliseconds (default: 120000 — compose ops can be slow).' },\r\n },\r\n required: ['serverId', 'projectPath', 'action'],\r\n },\r\n },\r\n {\r\n name: 'wait-for',\r\n description:\r\n 'Poll until a condition holds (or timeout). Replaces 30+ ad-hoc loops the LLM would otherwise build itself. Four condition types:\\n' +\r\n '- `url`: `target: \"https://...\"`, `until: 200` (HTTP status, default 200). 10s per probe.\\n' +\r\n '- `container-health`: `serverId`, `target: \"container-name\"`, `until: \"healthy\" | \"running\" | \"exited\"` (default \"healthy\"). Uses `docker inspect`.\\n' +\r\n '- `file-exists`: `serverId`, `target: \"/path/to/file\"` — SSH stat check.\\n' +\r\n '- `sftp-exists`: same as file-exists but with `bucket: \"name\"` instead of serverId for R2.\\n\\n' +\r\n 'Returns a per-attempt trail so you can see how long it took to converge.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n type: { type: 'string', enum: ['url', 'container-health', 'file-exists', 'sftp-exists'], description: 'Condition type to wait on.' },\r\n target: { type: 'string', description: 'Target identifier: URL, container name, file path, or R2 key (depends on type).' },\r\n until: { description: 'Expected end-state (depends on type): for url an HTTP status (default 200), for container-health a state string (default \"healthy\"). Omit for file-exists/sftp-exists.' },\r\n serverId: { type: 'string', description: 'SSH server UUID (required for container-health and file-exists).' },\r\n bucket: { type: 'string', description: 'R2 bucket name (used with sftp-exists when checking an R2 object).' },\r\n path: { type: 'string', description: 'Alias for `target` for file-exists/sftp-exists.' },\r\n intervalSeconds: { type: 'number', description: 'Poll interval in seconds (default 3, max 60).' },\r\n timeout: { type: 'number', description: 'Total deadline in seconds (default 120, max 1800).' },\r\n },\r\n required: ['type', 'target'],\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-query',\r\n description:\r\n 'Execute a SQL query against any database. Two routing modes:\\n' +\r\n '- MySQL via `/var/www` autodiscover (default): pass `sitePath` (and `engine: \"mysql\"` implicitly). Credentials are read from wp-config.php, parameters.php, .env. Same behaviour as before.\\n' +\r\n '- Direct via Docker container: pass `containerName` (the container running the DB server). Engine defaults to `postgres`; pass `engine: \"mysql\"` or `\"mssql\"` to override. The query is piped via stdin so quotes / `$` / `;` are never re-interpreted.\\n\\n' +\r\n 'Postgres example: `{ serverId, containerName: \"supabase-db\", engine: \"postgres\", dbName: \"main\", dbUser: \"postgres\", query: \"SELECT 1\" }`. Defaults: dbUser=postgres, dbName=postgres.\\n' +\r\n 'MSSQL example: `{ serverId, containerName: \"mssql-1\", engine: \"mssql\", dbUser: \"sa\", dbPass: \"...\", query: \"SELECT 1\" }`.\\n\\n' +\r\n 'Result safety: `maxRows` (default 1000, max 10000) auto-injects a `LIMIT` for SELECT queries that don\\'t have one, so unbounded scans never blow up the token budget. The footer reports whether the cap was applied. Pass `maxRows: 0` to disable.\\n\\n' +\r\n 'Diagnostics: `explain: true` prepends EXPLAIN (postgres / mysql) or runs `SET SHOWPLAN_TEXT ON` (mssql) so you can inspect the query plan without rewriting the query.\\n\\n' +\r\n 'Schema introspection: pass `describe: \"tablename\"` to get columns + indexes (replaces the old db-describe tool, works for mysql, postgres, and mssql). Pass `describe: \"*\"` to list all tables in the current database. When `describe` is set, `query` is ignored.\\n\\n' +\r\n 'Destructive operations (DROP, TRUNCATE, etc.) 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 query: { type: 'string', description: 'SQL query to execute (ignored when describe is set)' },\r\n describe: { type: 'string', description: 'Schema introspection shortcut. Pass a table name for columns + indexes, or \"*\" to list all tables. Works for mysql / postgres / mssql.' },\r\n sitePath: { type: 'string', description: 'Site root path (e.g. /var/www/example.com). Used only with engine=mysql autodiscover.' },\r\n containerName: { type: 'string', description: 'Docker container running the DB server (e.g. \"supabase-db\", \"trigger-postgres\"). Activates direct-query mode.' },\r\n engine: { type: 'string', enum: ['mysql', 'postgres', 'mssql'], description: 'DB engine. Defaults to \"mysql\" with sitePath, \"postgres\" with containerName.' },\r\n dbName: { type: 'string', description: 'Database name (containerName mode). Defaults: postgres → \"postgres\", mysql → server default, mssql → server default.' },\r\n dbUser: { type: 'string', description: 'Database user (containerName mode). Defaults: postgres → \"postgres\", mysql → \"root\", mssql → \"sa\".' },\r\n dbPass: { type: 'string', description: 'Database password (containerName mode). Required for mssql; optional for mysql; postgres uses trust auth by default.' },\r\n maxRows: { type: 'number', description: 'Auto-inject LIMIT for unbounded SELECTs. Default 1000, max 10000, set 0 to disable.' },\r\n explain: { type: 'boolean', description: 'Prepend EXPLAIN (postgres/mysql) or SHOWPLAN (mssql) instead of executing. Useful for slow-query diagnosis.' },\r\n },\r\n required: ['serverId'],\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', enum: ['production', 'staging', 'development', 'local'], description: 'Environment name' },\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', enum: ['production', 'staging', 'development', 'local'], description: 'Environment name' },\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:\r\n 'List all domains from the mijn.host account. Returns domain name, status, renewal date (= expiration), and tags. Requires MIJNHOST_API_KEY.\\n\\n' +\r\n 'Pass `details: true` to also fetch DNS zone summary per domain in parallel: MX target(s) and presence of SPF/DMARC TXT records. Useful as a single-call overview instead of N follow-up dns-list calls. Skipped for inactive/expired domains.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n details: { type: 'boolean', description: 'Inline DNS zone summary (NS, MX, SPF/DMARC presence) per domain. Adds N parallel API calls — use sparingly on large accounts.' },\r\n concurrency: { type: 'number', description: 'Max concurrent DNS lookups when details=true (default 8, max 20).' },\r\n },\r\n required: [],\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-record',\r\n description:\r\n 'Mutate a single DNS record on a mijn.host domain. Pick the mutation with `action`:\\n' +\r\n '- \"create\": add a new record. Required: type, name, value. Optional: ttl (default 3600).\\n' +\r\n '- \"update\": replace an existing record. Required: type, name, oldValue, newValue. Optional: ttl.\\n' +\r\n '- \"delete\": remove a record. Required: type, name, value.\\n\\n' +\r\n 'Always pass `dryRun: true` first when touching MX / SPF / DKIM / DMARC — returns a full before/after diff with a mail-auth warning and applies nothing. Re-run without dryRun once the diff looks correct.\\n\\n' +\r\n 'Use `dns-list` to inspect the current zone first if you need to identify the right `oldValue`. Requires MIJNHOST_API_KEY.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: { type: 'string', enum: ['create', 'update', 'delete'], description: 'Which mutation to perform.' },\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. Required for create + delete. Use newValue for update.' },\r\n oldValue: { type: 'string', description: 'Current value of the record (update only) — used to identify which record to replace.' },\r\n newValue: { type: 'string', description: 'New value for the record (update only).' },\r\n ttl: { type: 'number', description: 'TTL in seconds (min 60). Default 3600 for create; defaults to existing TTL for update.' },\r\n dryRun: { type: 'boolean', description: 'Preview the change (returns proposed diff) without applying. Recommended for MX/SPF/DKIM/DMARC.' },\r\n },\r\n required: ['action', 'domain', 'type', 'name'],\r\n },\r\n },\r\n // ----- Trigger.dev -----\r\n ...TRIGGER_TOOLS,\r\n // ----- Vercel -----\r\n ...VERCEL_TOOLS,\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// MCP Server\r\n// ---------------------------------------------------------------------------\r\n\r\nconst MCP_VERSION = '6.0.2';\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 const startTime = Date.now();\r\n const serverId = (a.serverId || a.server_id) as string | undefined;\r\n const serverIds = a.serverIds;\r\n\r\n // Cache lookup. Hit returns immediately with the same payload (we still\r\n // re-postprocess so the footer reflects the original-but-cached cost).\r\n const cached = getCachedTool(name, a);\r\n let cameFromCache = false;\r\n let result: { content: { type: string; text: string }[] };\r\n if (cached) {\r\n result = cached;\r\n cameFromCache = true;\r\n } else {\r\n result = await executeToolCall(name, a, serverId);\r\n }\r\n\r\n const durationMs = Date.now() - startTime;\r\n const isError = result.content?.[0]?.text?.startsWith('Error:');\r\n\r\n // Cache successful results only — never an Error: payload.\r\n if (!cameFromCache && !isError) {\r\n setCachedTool(name, a, result);\r\n }\r\n\r\n void writeAuditLog({\r\n toolName: name,\r\n arguments: a,\r\n serverId,\r\n resultStatus: isError ? 'error' : 'success',\r\n errorMessage: isError ? result.content?.[0]?.text : undefined,\r\n durationMs,\r\n });\r\n\r\n // Universal post-processing: truncate huge outputs + append cost footer.\r\n // Run *after* audit so the footer doesn't leak into log fields.\r\n const serverIdLabel = await resolveServerLabel(serverId, serverIds);\r\n return postprocessResult(result, {\r\n startedAtMs: startTime,\r\n serverIdLabel,\r\n toolName: name,\r\n args: a,\r\n cached: cameFromCache,\r\n });\r\n}\r\n\r\nasync function executeToolCall(\r\n name: string,\r\n a: Record<string, unknown>,\r\n _serverId: string | undefined,\r\n): Promise<{ content: { type: string; text: string }[] }> {\r\n const ctx = authContext!;\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, os_type, created_at')\r\n .order('name');\r\n\r\n if (ctx.allowedServerIds !== null) {\r\n query = query.in('id', ctx.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 includeStats = a.includeStats === true;\r\n const servers = data || [];\r\n\r\n // Populate the running cache so fuzzy \"did you mean?\" hints work and\r\n // so the response footer can show server names without re-querying.\r\n rememberServers(servers.map(s => ({ id: s.id, name: s.name })));\r\n\r\n // Stats are opt-in because they require an SSH round-trip per server.\r\n // We probe in parallel with a short per-server timeout so a single\r\n // unreachable host can't stall the listing.\r\n type Stats = { containers?: number; diskFreeHuman?: string; uptimeHuman?: string; reachable: boolean; error?: string };\r\n let statsByServer: Map<string, Stats> = new Map();\r\n if (includeStats && servers.length > 0) {\r\n const parallelism = Math.max(1, Math.min(20, Number(a.statsParallelism) || 8));\r\n const probeTimeoutMs = Math.max(1000, Math.min(30_000, Number(a.statsTimeoutMs) || 6000));\r\n\r\n // Combined one-shot probe per server. Three pipe-delimited values:\r\n // <containerCount>|<diskFreeHuman>|<uptimeHuman>\r\n // Missing tools are tolerated (returns 0/N/A).\r\n const linuxProbe =\r\n \"echo \\\"$(docker ps -q 2>/dev/null | wc -l)|$(df -h / 2>/dev/null | awk 'NR==2{print $4}')|$(uptime -p 2>/dev/null || uptime)\\\"\";\r\n const windowsProbe = [\r\n \"$ProgressPreference='SilentlyContinue';\",\r\n \"$c = (docker ps -q 2>$null | Measure-Object).Count;\",\r\n \"$d = try { '{0:N1} GB' -f ((Get-PSDrive C).Free/1GB) } catch { 'N/A' };\",\r\n \"$u = try { (Get-Uptime).ToString() } catch { ((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime).ToString() };\",\r\n \"Write-Output \\\"$c|$d|$u\\\"\",\r\n ].join(' ');\r\n\r\n const probeOne = async (s: typeof servers[number]): Promise<[string, Stats]> => {\r\n try {\r\n const { conn, proxy, os } = await getServerConnection(s.id);\r\n conn.timeout = probeTimeoutMs;\r\n const wrapped = os === 'windows'\r\n ? buildPowerShellEncodedCommand(windowsProbe, [])\r\n : `bash -c ${posixQuote(linuxProbe)}`;\r\n const result = await sshExec(conn, wrapped, proxy);\r\n if (result.exitCode !== 0) {\r\n return [s.id, { reachable: false, error: (result.stderr || result.stdout || 'probe failed').trim().slice(0, 120) }];\r\n }\r\n const parts = result.stdout.trim().split('|');\r\n return [s.id, {\r\n reachable: true,\r\n containers: Number(parts[0]) || 0,\r\n diskFreeHuman: (parts[1] || '').trim() || 'N/A',\r\n uptimeHuman: (parts[2] || '').trim() || 'N/A',\r\n }];\r\n } catch (err) {\r\n return [s.id, { reachable: false, error: err instanceof Error ? err.message.slice(0, 120) : String(err).slice(0, 120) }];\r\n }\r\n };\r\n\r\n // Bounded parallelism so we don't open 50 SSH sessions at once.\r\n const results: Array<[string, Stats]> = [];\r\n for (let i = 0; i < servers.length; i += parallelism) {\r\n const batch = servers.slice(i, i + parallelism);\r\n const chunk = await Promise.all(batch.map(probeOne));\r\n results.push(...chunk);\r\n }\r\n statsByServer = new Map(results);\r\n }\r\n\r\n const lines = servers.map(s => {\r\n const tags = Array.isArray(s.tags) ? (s.tags as string[]).join(', ') : '';\r\n const os = (s as Record<string, unknown>).os_type || 'linux';\r\n const base = `${s.id} ${s.name} ${s.hostname}:${s.port} ${s.username} [${tags}] ${s.hosted_by || ''} os:${os}`;\r\n if (!includeStats) return base;\r\n const st = statsByServer.get(s.id);\r\n if (!st) return `${base} stats:skipped`;\r\n if (!st.reachable) return `${base} UNREACHABLE (${st.error || 'unknown'})`;\r\n return `${base} containers:${st.containers} disk_free:${st.diskFreeHuman} uptime:${st.uptimeHuman}`;\r\n });\r\n\r\n // Auto-context: short hints about well-known servers, derived from\r\n // tags + hostnames so the LLM knows e.g. which host runs Trigger.\r\n const contextHints = a.context !== false ? buildServerContextHints(servers as Array<{ name: string; hostname: string; tags?: string[] | null }>) : [];\r\n const out = lines.length ? lines.join('\\n') : 'No servers found';\r\n return { content: [{ type: 'text', text: contextHints.length ? `${out}\\n\\n--- context ---\\n${contextHints.join('\\n')}` : out }] };\r\n }\r\n\r\n // ----- SSH -----\r\n case 'ssh-execute': {\r\n // Parse modes: pipeline (multi-cmd one session), repeat (loop), format (parser).\r\n const pipeline: string[] = Array.isArray(a.pipeline)\r\n ? (a.pipeline as unknown[]).map(String).filter(Boolean)\r\n : [];\r\n const command = pipeline.length > 0 ? '' : String(a.command || '');\r\n if (!command && pipeline.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `command` or `pipeline[]`' }] };\r\n }\r\n if (command) assertSafeCommand(command);\r\n for (const c of pipeline) assertSafeCommand(c);\r\n\r\n const args = Array.isArray(a.args) ? (a.args as unknown[]).map(String) : undefined;\r\n const stdin = typeof a.stdin === 'string' ? a.stdin : undefined;\r\n const shellOverride = typeof a.shell === 'string' ? (a.shell as 'auto' | 'bash' | 'powershell') : 'auto';\r\n const cwd = typeof a.cwd === 'string' && a.cwd ? a.cwd : undefined;\r\n const timeoutMs = a.timeout ? Number(a.timeout) : undefined;\r\n // Idle timeout default 120s — covers 99% of \"is this hung?\" cases\r\n // without forcing the LLM to think about wall budgets. Pass 0 to disable.\r\n const rawIdle = a.idleTimeoutSeconds !== undefined ? Number(a.idleTimeoutSeconds) : 120;\r\n const idleTimeoutMs = Number.isFinite(rawIdle) && rawIdle > 0 ? rawIdle * 1000 : undefined;\r\n // Repeat / diff / format are post-processing modes layered on top of\r\n // the single-shot or pipeline run. Repeat returns combined timing data.\r\n const repeat = Math.max(1, Math.min(60, Number(a.repeat) || 1));\r\n const intervalSeconds = Math.max(0, Math.min(600, Number(a.intervalSeconds) || 0));\r\n const repeatOutput = a.output === 'diff' || a.output === 'last' ? a.output : 'all';\r\n const format = a.format === 'ndjson' ? 'ndjson' : 'text';\r\n // Pipeline error policy: stop-on-first-fail vs continue (default continue\r\n // so all outputs reach the LLM in one round-trip).\r\n const pipelineStopOnError = a.pipelineStopOnError === true;\r\n\r\n // Resolve target list. `serverIds` (array) wins over `serverId` (single).\r\n // Both forms are supported so the existing `serverId` API stays intact.\r\n const targetIds: string[] = Array.isArray(a.serverIds) && a.serverIds.length > 0\r\n ? (a.serverIds as unknown[]).map(String)\r\n : a.serverId ? [String(a.serverId)] : [];\r\n if (targetIds.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `serverId` or `serverIds[]`' }] };\r\n }\r\n\r\n const parallelism = Math.max(1, Math.min(20, Number(a.parallelism) || 5));\r\n\r\n // Per-server runner. Resolves connection, builds OS-aware command, runs.\r\n // Returns the final SshResult; pipeline parsing happens after the call.\r\n const runOne = async (serverId: string): Promise<{ serverId: string; serverName: string; os: ServerOs; shell: 'bash' | 'powershell'; result: SshResult; pipelineSegments?: PipelineSegment[]; iterations?: IterationResult[] }> => {\r\n const { conn, proxy, os } = await getServerConnection(serverId);\r\n if (timeoutMs) conn.timeout = timeoutMs;\r\n const shell = shellOverride === 'auto' ? (os === 'windows' ? 'powershell' : 'bash') : shellOverride;\r\n\r\n // Build the body (single command OR pipeline wrapper). Pipeline mode\r\n // overrides any args/cwd-on-command behavior — cwd applies to the\r\n // whole script wrapper instead.\r\n let body: string;\r\n let pipelineMarker: string | null = null;\r\n if (pipeline.length > 0) {\r\n pipelineMarker = `__MCP_BREAK_${randomBytes(8).toString('hex')}__`;\r\n body = buildPipelineScript(pipeline, shell, pipelineMarker, pipelineStopOnError);\r\n } else if (args && args.length > 0) {\r\n body = shell === 'powershell'\r\n ? buildPowerShellEncodedCommand(command, args)\r\n : buildPosixCommand(command, args);\r\n } else if (shell === 'powershell' && !/^powershell\\b/i.test(command.trim())) {\r\n // For Windows raw strings, still wrap so $/quotes don't get reinterpreted.\r\n body = buildPowerShellEncodedCommand(command, []);\r\n } else {\r\n body = command;\r\n }\r\n\r\n // Apply cwd. For PowerShell with EncodedCommand, we can't simply\r\n // prepend `cd ... && ...` because `body` is already a full\r\n // `powershell -EncodedCommand <b64>` invocation. Instead we re-encode\r\n // a wrapper script that does `Set-Location` then runs the original.\r\n const applyCwd = (rawBody: string): string => {\r\n if (!cwd) return rawBody;\r\n if (shell === 'bash') return `cd ${posixQuote(cwd)} && ${rawBody}`;\r\n const ecMatch = rawBody.match(/-EncodedCommand\\s+(\\S+)$/);\r\n if (!ecMatch) return rawBody;\r\n const decoded = Buffer.from(ecMatch[1] as string, 'base64').toString('utf16le');\r\n const wrapped = `Set-Location -LiteralPath '${cwd.replace(/'/g, \"''\")}'; ${decoded}`;\r\n const reencoded = Buffer.from(wrapped, 'utf16le').toString('base64');\r\n return rawBody.replace(/-EncodedCommand\\s+\\S+$/, `-EncodedCommand ${reencoded}`);\r\n };\r\n const finalCmd = applyCwd(body);\r\n\r\n // Repeat mode: run finalCmd N times with optional sleep between.\r\n // We never sleep server-side; we sleep here so each iteration gets\r\n // its own SSH session and clean idle timer.\r\n if (repeat > 1) {\r\n const iterations: IterationResult[] = [];\r\n for (let i = 0; i < repeat; i++) {\r\n const startedAt = Date.now();\r\n const r = await sshExec(conn, finalCmd, proxy, {\r\n ...(stdin !== undefined ? { stdin } : {}),\r\n idleTimeoutMs,\r\n });\r\n iterations.push({ index: i, startedAt, durationMs: Date.now() - startedAt, result: r });\r\n if (i < repeat - 1 && intervalSeconds > 0) {\r\n await new Promise((res) => setTimeout(res, intervalSeconds * 1000));\r\n }\r\n }\r\n const last = iterations[iterations.length - 1]!.result;\r\n let serverName = serverId;\r\n try {\r\n const { data } = await supabase.from('ssh_server').select('name').eq('id', serverId).maybeSingle();\r\n if (data?.name) serverName = data.name as string;\r\n } catch { /* fall back to id */ }\r\n return { serverId, serverName, os, shell, result: last, iterations };\r\n }\r\n\r\n const result = await sshExec(conn, finalCmd, proxy, {\r\n ...(stdin !== undefined ? { stdin } : {}),\r\n idleTimeoutMs,\r\n });\r\n let pipelineSegments: PipelineSegment[] | undefined;\r\n if (pipelineMarker && pipeline.length > 0) {\r\n pipelineSegments = parsePipelineOutput(result.stdout, pipeline, pipelineMarker);\r\n }\r\n let serverName = serverId;\r\n try {\r\n const { data } = await supabase.from('ssh_server').select('name').eq('id', serverId).maybeSingle();\r\n if (data?.name) serverName = data.name as string;\r\n } catch { /* fall back to id */ }\r\n return { serverId, serverName, os, shell, result, pipelineSegments };\r\n };\r\n\r\n // Render helper for a single per-server result (pipeline/repeat aware).\r\n const renderOne = (r: Awaited<ReturnType<typeof runOne>>): string => {\r\n if (r.iterations && r.iterations.length > 0) {\r\n return renderRepeatResult(r.iterations, repeatOutput, format);\r\n }\r\n if (r.pipelineSegments) {\r\n return renderPipelineSegments(r.pipelineSegments, r.result, format);\r\n }\r\n const output = [`Exit code: ${r.result.exitCode} (os: ${r.os}, shell: ${r.shell})`];\r\n let stdoutText = r.result.stdout;\r\n if (format === 'ndjson' && stdoutText) {\r\n const parsed = tryParseNdjsonFromCommand(command, stdoutText);\r\n if (parsed) stdoutText = parsed;\r\n }\r\n if (stdoutText) output.push(`--- stdout ---\\n${stdoutText}`);\r\n if (r.result.stderr) output.push(`--- stderr ---\\n${r.result.stderr}`);\r\n return output.join('\\n');\r\n };\r\n\r\n // Single-target: keep the original output format unchanged.\r\n if (targetIds.length === 1) {\r\n const r = await runOne(targetIds[0] as string);\r\n return { content: [{ type: 'text', text: renderOne(r) }] };\r\n }\r\n\r\n // Fan-out: bounded parallel execution. We run in batches of `parallelism`.\r\n const allResults: Array<Awaited<ReturnType<typeof runOne>> | { serverId: string; error: string }> = [];\r\n for (let i = 0; i < targetIds.length; i += parallelism) {\r\n const batch = targetIds.slice(i, i + parallelism);\r\n const settled = await Promise.allSettled(batch.map(id => runOne(id)));\r\n for (let j = 0; j < settled.length; j++) {\r\n const s = settled[j]!;\r\n if (s.status === 'fulfilled') allResults.push(s.value);\r\n else allResults.push({ serverId: batch[j] as string, error: s.reason instanceof Error ? s.reason.message : String(s.reason) });\r\n }\r\n }\r\n\r\n // Render per-server sections + a 1-line summary at the bottom.\r\n const sections: string[] = [];\r\n let okCount = 0;\r\n let failCount = 0;\r\n for (const r of allResults) {\r\n if ('error' in r) {\r\n failCount++;\r\n sections.push(`=== ${r.serverId} === !! connection error: ${r.error}`);\r\n continue;\r\n }\r\n if (r.result.exitCode === 0) okCount++; else failCount++;\r\n const header = `=== ${r.serverName} (${r.os}, exit ${r.result.exitCode}) ===`;\r\n sections.push(`${header}\\n${renderOne(r)}`);\r\n }\r\n sections.push(`--- fan-out summary: ${okCount} ok / ${failCount} failed across ${allResults.length} servers (parallelism ${parallelism}) ---`);\r\n return { content: [{ type: 'text', text: sections.join('\\n\\n') }] };\r\n }\r\n\r\n // ----- SFTP -----\r\n case 'sftp-list': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const recursive = a.recursive === true;\r\n const maxResults = Math.max(1, Math.min(50_000, Number(a.maxResults) || 5_000));\r\n const pattern = typeof a.pattern === 'string' ? a.pattern : '';\r\n const summary = a.summary === true;\r\n // Sort key: 'name' (default), 'size', 'mtime'. `reverse: true` flips.\r\n const sortBy = (a.sortBy === 'size' || a.sortBy === 'mtime' || a.sortBy === 'name') ? a.sortBy : 'name';\r\n const reverse = a.reverse === true;\r\n\r\n // Collect into a backend-agnostic shape so sort/reverse/summary apply\r\n // identically to SSH and R2 listings.\r\n let entries: SftpEntry[];\r\n let truncated = false;\r\n let warning = '';\r\n\r\n if (bucket) {\r\n const prefix = r2Key(String(a.path || ''));\r\n const matcher = pattern ? globToRegExp(pattern) : null;\r\n const r2Entries = await r2List(bucket, prefix, { recursive, maxResults });\r\n const filtered = matcher\r\n ? r2Entries.filter(e => matcher.test(e.key.split('/').pop() || e.key))\r\n : r2Entries;\r\n entries = filtered.map(e => {\r\n const ms = e.mtime ? Date.parse(e.mtime) : 0;\r\n return {\r\n kind: e.isPrefix ? 'd' as const : '-' as const,\r\n size: e.size,\r\n mtime: e.mtime,\r\n mtimeMs: Number.isFinite(ms) ? ms : 0,\r\n path: e.key,\r\n };\r\n });\r\n } else {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const result = await sftpReaddir(conn, String(a.path || '/'), proxy, {\r\n recursive,\r\n maxDepth: typeof a.maxDepth === 'number' ? a.maxDepth : undefined,\r\n pattern: pattern || undefined,\r\n maxResults,\r\n });\r\n if (result.error && result.entries.length === 0) {\r\n return { content: [{ type: 'text', text: `Error: ${result.error}` }] };\r\n }\r\n entries = result.entries;\r\n truncated = result.truncated;\r\n if (result.error) warning = result.error;\r\n }\r\n\r\n // Summary mode short-circuits before sorting (we just aggregate).\r\n if (summary) {\r\n const files = entries.filter(e => e.kind === '-');\r\n const dirs = entries.filter(e => e.kind === 'd');\r\n const totalSize = files.reduce((acc, e) => acc + (e.size || 0), 0);\r\n const lines = [\r\n `Files: ${files.length}`,\r\n `Directories: ${dirs.length}`,\r\n `Total size: ${totalSize} bytes (${(totalSize / (1024 * 1024)).toFixed(2)} MB)`,\r\n ];\r\n if (truncated) lines.push(`(truncated at ${maxResults}; counts may be partial)`);\r\n if (warning) lines.push(`(warnings: ${warning})`);\r\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\r\n }\r\n\r\n // Sort. Directories first within the chosen sort, both ascending by\r\n // default; `reverse: true` flips the secondary order. `name` uses\r\n // localeCompare so digits/dots sort naturally.\r\n entries.sort((x, y) => {\r\n if (x.kind !== y.kind) return x.kind === 'd' ? -1 : 1;\r\n let cmp = 0;\r\n if (sortBy === 'size') cmp = x.size - y.size;\r\n else if (sortBy === 'mtime') cmp = x.mtimeMs - y.mtimeMs;\r\n else cmp = x.path.localeCompare(y.path);\r\n return reverse ? -cmp : cmp;\r\n });\r\n\r\n if (entries.length === 0) return { content: [{ type: 'text', text: 'No entries' }] };\r\n const lines = entries.map(e => {\r\n const sizeCol = e.kind === 'd' && bucket ? '(prefix)' : String(e.size);\r\n return `${e.kind} ${sizeCol.padStart(10)} ${(e.mtime || '').padEnd(24)} ${e.path}`;\r\n });\r\n if (truncated) lines.push(`... (truncated at ${maxResults} entries; raise maxResults or narrow path/pattern)`);\r\n if (warning) lines.push(`! ${warning}`);\r\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\r\n }\r\n\r\n case 'sftp-read': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const offset = a.offset !== undefined ? Math.max(0, Number(a.offset)) : undefined;\r\n const length = a.length !== undefined ? Math.max(0, Number(a.length)) : undefined;\r\n const hasRange = offset !== undefined || length !== undefined;\r\n\r\n if (bucket) {\r\n const key = r2Key(String(a.path));\r\n if (!key) return { content: [{ type: 'text', text: 'Error: path is required' }] };\r\n try {\r\n if (hasRange) {\r\n const content = await r2GetObjectRange(bucket, key, { offset: offset ?? 0, length });\r\n return { content: [{ type: 'text', text: content }] };\r\n }\r\n const content = await r2GetObject(bucket, key, 1_048_576);\r\n return { content: [{ type: 'text', text: content }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const content = await sftpRead(conn, String(a.path), proxy, hasRange ? { offset, length } : undefined);\r\n return { content: [{ type: 'text', text: content }] };\r\n }\r\n\r\n case 'sftp-write': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n\r\n // Cross-endpoint copy mode. Activates when `sourceRemote` is set:\r\n // sourceRemote: { serverId|bucket, path }\r\n // target endpoint: top-level { serverId|bucket, path } (the existing\r\n // sftp-write target shape — no schema change for the LLM).\r\n // Supported directions: ssh↔ssh, ssh↔r2, r2↔ssh, r2↔r2 (server-side).\r\n if (a.sourceRemote && typeof a.sourceRemote === 'object') {\r\n const srcRaw = a.sourceRemote as Record<string, unknown>;\r\n const srcBucket = typeof srcRaw.bucket === 'string' && srcRaw.bucket ? String(srcRaw.bucket) : '';\r\n const srcServerId = typeof srcRaw.serverId === 'string' && srcRaw.serverId ? String(srcRaw.serverId) : '';\r\n const srcPath = String(srcRaw.path || '');\r\n if (!srcPath) return { content: [{ type: 'text', text: 'Error: sourceRemote.path is required' }] };\r\n if (!srcBucket && !srcServerId) return { content: [{ type: 'text', text: 'Error: sourceRemote needs `serverId` or `bucket`' }] };\r\n if (srcBucket && srcServerId) return { content: [{ type: 'text', text: 'Error: sourceRemote can have either `serverId` or `bucket`, not both' }] };\r\n\r\n const dstPath = String(a.path || '');\r\n if (!dstPath) return { content: [{ type: 'text', text: 'Error: target `path` is required' }] };\r\n\r\n let srcEp: CopyEndpoint;\r\n if (srcBucket) {\r\n const k = r2Key(srcPath);\r\n if (!k) return { content: [{ type: 'text', text: 'Error: sourceRemote.path resolves to empty key' }] };\r\n srcEp = { kind: 'r2', bucket: srcBucket, key: k };\r\n } else {\r\n const { conn, proxy } = await getServerConnection(srcServerId);\r\n srcEp = { kind: 'ssh', opts: conn, proxy, path: srcPath };\r\n }\r\n\r\n let dstEp: CopyEndpoint;\r\n if (bucket) {\r\n const k = r2Key(dstPath);\r\n if (!k) return { content: [{ type: 'text', text: 'Error: target path resolves to empty key' }] };\r\n dstEp = { kind: 'r2', bucket, key: k };\r\n } else if (a.serverId) {\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n dstEp = { kind: 'ssh', opts: conn, proxy, path: dstPath };\r\n } else {\r\n return { content: [{ type: 'text', text: 'Error: target needs `serverId` or `bucket`' }] };\r\n }\r\n\r\n try {\r\n const { bytes, elapsedMs, mode } = await sftpCopy(srcEp, dstEp);\r\n const srcLabel = srcEp.kind === 'r2' ? `r2://${srcEp.bucket}/${srcEp.key}` : `ssh:${srcPath}`;\r\n const dstLabel = dstEp.kind === 'r2' ? `r2://${dstEp.bucket}/${dstEp.key}` : `ssh:${dstPath}`;\r\n const mbps = bytes > 0 && elapsedMs > 0 ? (bytes / (1024 * 1024)) / (elapsedMs / 1000) : 0;\r\n return { content: [{ type: 'text', text: `Copied ${formatBytes(bytes)} from ${srcLabel} → ${dstLabel} via ${mode} in ${(elapsedMs / 1000).toFixed(2)}s${mbps > 0 ? ` (${mbps.toFixed(1)} MB/s)` : ''}` }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n\r\n // Optional file metadata. `mode` accepts a number (0o755) or a string\r\n // (\"755\" or \"0o755\") so the LLM can write either form. mtime accepts\r\n // ms since epoch or an ISO date string.\r\n let fileMode: number | undefined;\r\n if (typeof a.mode === 'number' && Number.isFinite(a.mode)) fileMode = a.mode & 0o7777;\r\n else if (typeof a.mode === 'string' && a.mode) {\r\n const cleaned = a.mode.replace(/^0o?/i, '');\r\n const parsed = parseInt(cleaned, 8);\r\n if (!Number.isNaN(parsed)) fileMode = parsed & 0o7777;\r\n }\r\n let mtimeMs: number | undefined;\r\n if (typeof a.mtime === 'number' && Number.isFinite(a.mtime)) mtimeMs = a.mtime;\r\n else if (typeof a.mtime === 'string' && a.mtime) {\r\n const parsed = Date.parse(a.mtime);\r\n if (!Number.isNaN(parsed)) mtimeMs = parsed;\r\n }\r\n\r\n if (bucket) {\r\n const key = r2Key(String(a.path));\r\n if (!key) return { content: [{ type: 'text', text: 'Error: path is required' }] };\r\n if (fileMode !== undefined || mtimeMs !== undefined) {\r\n // R2 (S3) has no POSIX mode/mtime. Surface this so the user knows\r\n // the params were ignored rather than silently dropping them.\r\n // We continue with the upload anyway.\r\n }\r\n try {\r\n if (typeof a.sourcePath === 'string' && a.sourcePath.length > 0) {\r\n const local = a.sourcePath;\r\n if (!isAbsolute(local)) return { content: [{ type: 'text', text: `Error: sourcePath must be an absolute path: ${local}` }] };\r\n if (!existsSync(local)) return { content: [{ type: 'text', text: `Error: sourcePath does not exist: ${local}` }] };\r\n const st = statSync(local);\r\n if (!st.isFile()) return { content: [{ type: 'text', text: `Error: sourcePath is not a regular file: ${local}` }] };\r\n const startedAt = Date.now();\r\n if (st.size > R2_MULTIPART_THRESHOLD) {\r\n // Multipart path: streams the local file in 100 MB parts and\r\n // logs progress per part. Up to ~5 TB per object on R2.\r\n let lastLog = 0;\r\n await r2PutObjectMultipart(bucket, key, local, st.size, (uploaded) => {\r\n if (uploaded - lastLog >= 500 * 1024 * 1024) {\r\n console.error(`[r2-write] ${formatBytes(uploaded)} / ${formatBytes(st.size)} → r2://${bucket}/${key}`);\r\n lastLog = uploaded;\r\n }\r\n });\r\n const elapsed = Date.now() - startedAt;\r\n const mbps = st.size / (1024 * 1024) / Math.max(0.001, elapsed / 1000);\r\n const noteParts: string[] = [];\r\n if (fileMode !== undefined) noteParts.push('mode ignored (R2)');\r\n if (mtimeMs !== undefined) noteParts.push('mtime ignored (R2)');\r\n const note = noteParts.length ? ` [${noteParts.join(', ')}]` : '';\r\n return { content: [{ type: 'text', text: `Uploaded ${formatBytes(st.size)} from ${local} to r2://${bucket}/${key} via multipart in ${(elapsed / 1000).toFixed(1)}s (${mbps.toFixed(1)} MB/s)${note}` }] };\r\n }\r\n const stream = createReadStream(local);\r\n await r2PutObject(bucket, key, stream, st.size);\r\n const elapsed = Date.now() - startedAt;\r\n return { content: [{ type: 'text', text: `Uploaded ${st.size} bytes from ${local} to r2://${bucket}/${key} in ${elapsed}ms` }] };\r\n }\r\n const buf = Buffer.from(String(a.content ?? ''), 'utf-8');\r\n await r2PutObject(bucket, key, buf, buf.length);\r\n return { content: [{ type: 'text', text: `Wrote ${buf.length} bytes to r2://${bucket}/${key}` }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const input: SftpWriteInput =\r\n typeof a.sourcePath === 'string' && a.sourcePath.length > 0\r\n ? { sourcePath: a.sourcePath }\r\n : { content: String(a.content ?? '') };\r\n const result = await sftpWrite(conn, String(a.path), input, proxy, { fileMode, mtimeMs });\r\n return { content: [{ type: 'text', text: result }] };\r\n }\r\n\r\n case 'sftp-delete': {\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const recursive = a.recursive === true;\r\n const dryRun = a.dryRun === true;\r\n const confirmAbove = a.confirmAbove !== undefined ? Math.max(0, Number(a.confirmAbove)) : undefined;\r\n const confirmCount = a.confirmCount !== undefined ? Number(a.confirmCount) : undefined;\r\n\r\n // Helper: enforce confirmAbove gate on a known item count (or refuse).\r\n const guard = (count: number, sizeBytes: number, where: string): { content: [{ type: 'text'; text: string }] } | null => {\r\n if (confirmAbove !== undefined && count > confirmAbove) {\r\n if (confirmCount === count) return null; // user explicitly opted in\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Refusing to delete ${count} item(s) (${formatBytes(sizeBytes)}) under ${where}: exceeds confirmAbove=${confirmAbove}. To proceed, re-issue the call with confirmCount: ${count}.`,\r\n }],\r\n };\r\n }\r\n return null;\r\n };\r\n\r\n if (bucket) {\r\n const key = r2Key(String(a.path));\r\n if (!key) return { content: [{ type: 'text', text: 'Error: path is required' }] };\r\n try {\r\n if (recursive) {\r\n // For recursive R2 we need to list first to count + size, both\r\n // for the dryRun preview and for the confirmAbove gate.\r\n if (dryRun || confirmAbove !== undefined) {\r\n const listed = await r2List(bucket, key, { recursive: true, maxResults: 50_000 });\r\n const objects = listed.filter(e => !e.isPrefix);\r\n const totalSize = objects.reduce((s, o) => s + (o.size || 0), 0);\r\n if (dryRun) {\r\n const sample = objects.slice(0, 5).map(o => ` - r2://${bucket}/${o.key} (${formatBytes(o.size || 0)})`);\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete ${objects.length} object(s) totalling ${formatBytes(totalSize)} under r2://${bucket}/${key}${objects.length > 5 ? `\\n${sample.join('\\n')}\\n ... and ${objects.length - 5} more` : objects.length ? `\\n${sample.join('\\n')}` : ''}` }] };\r\n }\r\n const block = guard(objects.length, totalSize, `r2://${bucket}/${key}`);\r\n if (block) return block;\r\n }\r\n const deleted = await r2DeletePrefix(bucket, key);\r\n return { content: [{ type: 'text', text: `Deleted ${deleted} object(s) under r2://${bucket}/${key}` }] };\r\n }\r\n // Single-object delete: dryRun shows size; no confirmAbove gate needed.\r\n if (dryRun) {\r\n try {\r\n const head = await getR2Client().send(new HeadObjectCommand({ Bucket: bucket, Key: key }));\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete r2://${bucket}/${key} (${formatBytes(head.ContentLength || 0)})` }] };\r\n } catch {\r\n return { content: [{ type: 'text', text: `[dry-run] r2://${bucket}/${key} not found (delete would 404)` }] };\r\n }\r\n }\r\n await r2DeleteObject(bucket, key);\r\n return { content: [{ type: 'text', text: `Deleted r2://${bucket}/${key}` }] };\r\n } catch (e) {\r\n return { content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }] };\r\n }\r\n }\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n\r\n // SSH path: dryRun + confirmAbove for recursive — we list first so the\r\n // preview/gate has the same data the actual delete would.\r\n if (recursive && (dryRun || confirmAbove !== undefined)) {\r\n const listed = await sftpReaddir(conn, String(a.path), proxy, {\r\n recursive: true,\r\n maxResults: 50_000,\r\n });\r\n const files = listed.entries.filter(e => e.kind === '-');\r\n const dirs = listed.entries.filter(e => e.kind === 'd');\r\n const totalSize = files.reduce((s, f) => s + (f.size || 0), 0);\r\n if (dryRun) {\r\n const sample = files.slice(0, 5).map(f => ` - ${f.path} (${formatBytes(f.size || 0)})`);\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete ${files.length} file(s) + ${dirs.length} directory(ies) totalling ${formatBytes(totalSize)} under ${a.path}${files.length ? `\\n${sample.join('\\n')}${files.length > 5 ? `\\n ... and ${files.length - 5} more` : ''}` : ''}` }] };\r\n }\r\n const block = guard(files.length + dirs.length, totalSize, String(a.path));\r\n if (block) return block;\r\n } else if (dryRun) {\r\n // Single-file dry-run: just print intent. Avoids an extra round-trip\r\n // and works equally well for files that don't exist (the real delete\r\n // would surface that anyway).\r\n return { content: [{ type: 'text', text: `[dry-run] Would delete ${a.path} (single file/dir; pass recursive: true to preview tree contents)` }] };\r\n }\r\n const result = await sftpDelete(conn, String(a.path), proxy, { recursive });\r\n return { content: [{ type: 'text', text: result }] };\r\n }\r\n\r\n // ----- Docker -----\r\n case 'docker-list': {\r\n const format = a.format === 'json' ? 'json' : 'table';\r\n const composeOnly = a.composeOnly === true;\r\n const groupByProject = a.groupByProject === true;\r\n const nameFiltersRaw: string[] = Array.isArray(a.nameFilter)\r\n ? (a.nameFilter as unknown[]).map(v => String(v).trim()).filter(Boolean)\r\n : (typeof a.nameFilter === 'string' && a.nameFilter.trim() ? [a.nameFilter.trim()] : []);\r\n\r\n // Resolve target list — same fan-out idiom as ssh-execute.\r\n const targetIds: string[] = Array.isArray(a.serverIds) && a.serverIds.length > 0\r\n ? (a.serverIds as unknown[]).map(String)\r\n : a.serverId ? [String(a.serverId)] : [];\r\n if (targetIds.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `serverId` or `serverIds[]`' }] };\r\n }\r\n const parallelism = Math.max(1, Math.min(20, Number(a.parallelism) || 5));\r\n\r\n type DockerPsRow = { Names?: string; Image?: string; Status?: string; Ports?: string; Labels?: string; Project?: string; Health?: string };\r\n\r\n const filterArg = composeOnly ? ` --filter \"label=com.docker.compose.project\"` : '';\r\n const cmd = `docker ps -a${filterArg} --format '{{json .}}'`;\r\n\r\n const probeOne = async (serverId: string): Promise<{ serverId: string; serverName: string; rows: DockerPsRow[]; error?: string }> => {\r\n let serverName = serverId.slice(0, 8);\r\n try {\r\n const { conn, proxy } = await getServerConnection(serverId);\r\n const r = await sshExec(conn, cmd, proxy);\r\n const cached = KNOWN_SERVER_NAMES.get(serverId);\r\n if (cached) serverName = cached.name;\r\n if (r.exitCode !== 0) {\r\n return { serverId, serverName, rows: [], error: (r.stderr || r.stdout || 'exit ' + r.exitCode).trim().slice(0, 200) };\r\n }\r\n const rows: DockerPsRow[] = [];\r\n for (const line of r.stdout.split('\\n')) {\r\n const t = line.trim();\r\n if (!t) continue;\r\n try { rows.push(JSON.parse(t) as DockerPsRow); } catch { /* skip malformed */ }\r\n }\r\n for (const c of rows) {\r\n const m = (c.Labels || '').match(/com\\.docker\\.compose\\.project=([^,]+)/);\r\n c.Project = m ? m[1] : '';\r\n const status = c.Status || '';\r\n if (/\\(unhealthy\\)/i.test(status)) c.Health = 'unhealthy';\r\n else if (/\\(health: starting\\)|\\(starting\\)/i.test(status)) c.Health = 'starting';\r\n else if (/\\(healthy\\)/i.test(status)) c.Health = 'healthy';\r\n else if (/^Up\\b/i.test(status)) c.Health = 'no-check';\r\n else c.Health = '';\r\n }\r\n // Stash names for fuzzy hints later.\r\n rememberContainers(serverId, rows.map(r => r.Names || '').filter(Boolean));\r\n return { serverId, serverName, rows };\r\n } catch (err) {\r\n return { serverId, serverName, rows: [], error: err instanceof Error ? err.message.slice(0, 200) : String(err).slice(0, 200) };\r\n }\r\n };\r\n\r\n const perServer: Awaited<ReturnType<typeof probeOne>>[] = [];\r\n for (let i = 0; i < targetIds.length; i += parallelism) {\r\n const batch = targetIds.slice(i, i + parallelism);\r\n const chunk = await Promise.all(batch.map(probeOne));\r\n perServer.push(...chunk);\r\n }\r\n\r\n // Per-row apply name filter, tagging origin server when fan-out > 1.\r\n const applyFilter = (rows: DockerPsRow[]): DockerPsRow[] => {\r\n if (nameFiltersRaw.length === 0) return rows;\r\n const matchers = nameFiltersRaw.map(raw => {\r\n if (raw.includes('*') || raw.includes('?')) return { kind: 'glob' as const, re: globToRegExp(raw) };\r\n return { kind: 'sub' as const, lower: raw.toLowerCase() };\r\n });\r\n return rows.filter(c => {\r\n const name = c.Names || '';\r\n const lower = name.toLowerCase();\r\n return matchers.some(m => m.kind === 'glob' ? m.re.test(name) : lower.includes(m.lower));\r\n });\r\n };\r\n const sortRows = (rows: DockerPsRow[]) => rows.sort((x, y) => {\r\n const px = x.Project || '~';\r\n const py = y.Project || '~';\r\n const p = px.localeCompare(py);\r\n return p !== 0 ? p : (x.Names || '').localeCompare(y.Names || '');\r\n });\r\n\r\n const fmtRow = (r: DockerPsRow) =>\r\n `${(r.Names || '').padEnd(36)} ${(r.Image || '').padEnd(40)} ${(r.Status || '').padEnd(24)} ${(r.Health || '').padEnd(10)} ${(r.Ports || '').padEnd(40)}`;\r\n\r\n // Single-server: keep original (terse, unprefixed) layout.\r\n if (targetIds.length === 1) {\r\n const only = perServer[0]!;\r\n if (only.error) return { content: [{ type: 'text', text: `Error: ${only.error}` }] };\r\n const filtered = sortRows(applyFilter(only.rows));\r\n if (format === 'json') {\r\n const text = filtered.map(c => JSON.stringify(c)).join('\\n') || '(no containers)';\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n if (groupByProject) {\r\n const groups = new Map<string, DockerPsRow[]>();\r\n for (const c of filtered) {\r\n const key = c.Project || '(no compose project)';\r\n const list = groups.get(key);\r\n if (list) list.push(c); else groups.set(key, [c]);\r\n }\r\n const out: string[] = [];\r\n for (const [project, rows] of groups) {\r\n out.push(`=== ${project} (${rows.length}) ===`);\r\n for (const r of rows) out.push(' ' + fmtRow(r));\r\n out.push('');\r\n }\r\n return { content: [{ type: 'text', text: out.join('\\n').trimEnd() || '(no containers)' }] };\r\n }\r\n const header = `${'NAMES'.padEnd(36)} ${'IMAGE'.padEnd(40)} ${'STATUS'.padEnd(24)} ${'HEALTH'.padEnd(10)} ${'PORTS'.padEnd(40)} PROJECT`;\r\n const body = filtered.map(r => `${fmtRow(r)} ${r.Project || ''}`);\r\n const text = filtered.length === 0 ? '(no containers match)' : [header, ...body].join('\\n');\r\n return { content: [{ type: 'text', text }] };\r\n }\r\n\r\n // Fan-out: per-server header, then filtered rows. JSON format produces\r\n // one obj per line with an extra \"Server\" field so downstream tools\r\n // can tell containers apart.\r\n if (format === 'json') {\r\n const lines: string[] = [];\r\n for (const ps of perServer) {\r\n if (ps.error) {\r\n lines.push(JSON.stringify({ Server: ps.serverName, Error: ps.error }));\r\n continue;\r\n }\r\n const filtered = sortRows(applyFilter(ps.rows));\r\n for (const c of filtered) lines.push(JSON.stringify({ Server: ps.serverName, ...c }));\r\n }\r\n return { content: [{ type: 'text', text: lines.join('\\n') || '(no containers)' }] };\r\n }\r\n\r\n const sections: string[] = [];\r\n let totalRows = 0;\r\n let serversWithRows = 0;\r\n for (const ps of perServer) {\r\n if (ps.error) {\r\n sections.push(`=== ${ps.serverName} === !! ${ps.error}`);\r\n continue;\r\n }\r\n const filtered = sortRows(applyFilter(ps.rows));\r\n if (filtered.length === 0) {\r\n sections.push(`=== ${ps.serverName} === (no containers match)`);\r\n continue;\r\n }\r\n serversWithRows++;\r\n totalRows += filtered.length;\r\n sections.push(`=== ${ps.serverName} (${filtered.length} container(s)) ===`);\r\n const header = `${'NAMES'.padEnd(36)} ${'IMAGE'.padEnd(40)} ${'STATUS'.padEnd(24)} ${'HEALTH'.padEnd(10)} ${'PORTS'.padEnd(40)} PROJECT`;\r\n sections.push(header);\r\n for (const r of filtered) sections.push(`${fmtRow(r)} ${r.Project || ''}`);\r\n }\r\n sections.push(`--- fan-out summary: ${totalRows} container(s) across ${serversWithRows}/${perServer.length} server(s) ---`);\r\n return { content: [{ type: 'text', text: sections.join('\\n') }] };\r\n }\r\n\r\n case 'docker-logs': {\r\n const rawNames = Array.isArray(a.containerName)\r\n ? (a.containerName as unknown[]).map(String)\r\n : [String(a.containerName)];\r\n const containers = rawNames\r\n .map(n => n.replace(/[^a-zA-Z0-9._-]/g, ''))\r\n .filter(n => n.length > 0);\r\n if (containers.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: no valid containerName provided' }] };\r\n }\r\n\r\n const followSeconds = Math.max(0, Math.min(300, Number(a.followSeconds) || 0));\r\n const userTail = a.tail !== undefined ? Number(a.tail) : (a.lines !== undefined ? Number(a.lines) : undefined);\r\n const tailArg = userTail !== undefined && Number.isFinite(userTail) && userTail >= 0\r\n ? userTail\r\n : (followSeconds > 0 ? 0 : 100);\r\n const sinceRaw = typeof a.since === 'string' ? a.since.trim() : '';\r\n const grepRaw = typeof a.grep === 'string' ? a.grep : '';\r\n\r\n if (sinceRaw && !/^\\d+[smhd]$/i.test(sinceRaw) && !/^\\d{4}-\\d{2}-\\d{2}/.test(sinceRaw)) {\r\n return { content: [{ type: 'text', text: 'Error: invalid `since` format (expected e.g. \"10m\", \"2h\", or ISO timestamp)' }] };\r\n }\r\n const sinceArg = sinceRaw ? ` --since ${posixQuote(sinceRaw)}` : '';\r\n const grepSuffix = grepRaw ? ` | grep -i -E ${posixQuote(grepRaw)} --line-buffered` : '';\r\n\r\n // Resolve target server list (fan-out support for \"show kong logs across all servers\").\r\n const targetIds: string[] = Array.isArray(a.serverIds) && a.serverIds.length > 0\r\n ? (a.serverIds as unknown[]).map(String)\r\n : a.serverId ? [String(a.serverId)] : [];\r\n if (targetIds.length === 0) {\r\n return { content: [{ type: 'text', text: 'Error: pass either `serverId` or `serverIds[]`' }] };\r\n }\r\n const parallelism = Math.max(1, Math.min(20, Number(a.parallelism) || 5));\r\n\r\n const wallSeconds = followSeconds > 0 ? followSeconds : 30;\r\n const followFlag = followSeconds > 0 ? ' -f' : '';\r\n\r\n // Build the `docker logs` invocation — same shell command for every\r\n // server. Single-container mode produces unprefixed output; multi\r\n // adds [name] prefixes so streams stay distinguishable.\r\n const buildCmd = (): string => {\r\n if (containers.length === 1) {\r\n const c = containers[0];\r\n const inner = `docker logs${followFlag} --tail ${tailArg}${sinceArg} ${c} 2>&1${grepSuffix}`;\r\n return `timeout --signal=INT ${wallSeconds} sh -c ${posixQuote(inner)}`;\r\n }\r\n const subShells = containers.map(c => {\r\n const inner = `docker logs${followFlag} --tail ${tailArg}${sinceArg} ${c} 2>&1${grepSuffix}`;\r\n return `(${inner} | sed -u -e ${posixQuote(`s/^/[${c}] /`)})`;\r\n });\r\n const innerCmd = subShells.join(' & ') + ' & wait';\r\n return `timeout --signal=INT ${wallSeconds} sh -c ${posixQuote(innerCmd)}`;\r\n };\r\n const cmd = buildCmd();\r\n\r\n const probeOne = async (serverId: string): Promise<{ serverId: string; serverName: string; result: SshResult }> => {\r\n const { conn, proxy } = await getServerConnection(serverId);\r\n conn.timeout = (wallSeconds + 10) * 1000;\r\n const result = await sshExec(conn, cmd, proxy);\r\n const cached = KNOWN_SERVER_NAMES.get(serverId);\r\n return { serverId, serverName: cached?.name || serverId.slice(0, 8), result };\r\n };\r\n\r\n const acceptableCode = (code: number) => code === 0 || code === 124 || code === 130 || code === 143 || (!!grepRaw && code === 1);\r\n\r\n // Single-server: keep the original (unprefixed) output for back-compat.\r\n if (targetIds.length === 1) {\r\n const r = await probeOne(targetIds[0] as string);\r\n const result = r.result;\r\n // Combined output: docker pipes stderr→stdout via `2>&1`, so the\r\n // \"No such container\" error lives in stdout. Look for it explicitly.\r\n const combined = `${result.stdout}\\n${result.stderr}`;\r\n const noSuchMatch = /No such container:\\s*(\\S+)/i.exec(combined);\r\n const fuzzyHint = (): string => {\r\n if (!noSuchMatch) return '';\r\n const known = getKnownContainers(targetIds[0] as string);\r\n if (!known?.length) return '';\r\n const hits = suggestSimilar(noSuchMatch[1] as string, known);\r\n return hits.length ? `\\n(hint) Did you mean: ${hits.join(', ')}?` : '';\r\n };\r\n\r\n if (!acceptableCode(result.exitCode) && !result.stdout) {\r\n return { content: [{ type: 'text', text: `Error (exit ${result.exitCode}): ${result.stderr || '(no output)'}${fuzzyHint()}` }] };\r\n }\r\n // Even when stdout has data, surface the fuzzy hint if docker reported\r\n // \"No such container\" — otherwise the LLM mistakes the error for log lines.\r\n const note = result.exitCode === 124 ? `\\n(note: command exceeded ${wallSeconds}s wall budget; partial output)` : '';\r\n return { content: [{ type: 'text', text: (result.stdout || '(no log lines matched)') + note + fuzzyHint() }] };\r\n }\r\n\r\n // Fan-out: per-server section. Each server's stdout is shown verbatim\r\n // (already [name]-prefixed if multi-container).\r\n const perServer: Awaited<ReturnType<typeof probeOne>>[] = [];\r\n for (let i = 0; i < targetIds.length; i += parallelism) {\r\n const batch = targetIds.slice(i, i + parallelism);\r\n const chunk = await Promise.all(batch.map(probeOne));\r\n perServer.push(...chunk);\r\n }\r\n const sections: string[] = [];\r\n let okCount = 0;\r\n for (const ps of perServer) {\r\n if (acceptableCode(ps.result.exitCode) || ps.result.stdout) {\r\n okCount++;\r\n const note = ps.result.exitCode === 124 ? ` (timed out after ${wallSeconds}s; partial)` : '';\r\n sections.push(`=== ${ps.serverName}${note} ===`);\r\n sections.push(ps.result.stdout || '(no log lines matched)');\r\n } else {\r\n sections.push(`=== ${ps.serverName} === !! exit ${ps.result.exitCode}: ${ps.result.stderr.trim().slice(0, 200) || '(no output)'}`);\r\n }\r\n }\r\n sections.push(`--- fan-out summary: ${okCount}/${perServer.length} server(s) returned logs ---`);\r\n return { content: [{ type: 'text', text: sections.join('\\n') }] };\r\n }\r\n\r\n case 'docker-exec': {\r\n const container = String(a.container).replace(/[^a-zA-Z0-9._-]/g, '');\r\n if (!container) return { content: [{ type: 'text', text: 'Error: invalid container name' }] };\r\n const command = String(a.command);\r\n const args = Array.isArray(a.args) ? (a.args as unknown[]).map(String) : [];\r\n const stdin = typeof a.stdin === 'string' ? a.stdin : undefined;\r\n const interactive = a.interactive === true;\r\n const workdir = typeof a.workdir === 'string' && a.workdir ? ['-w', a.workdir] : [];\r\n const user = typeof a.user === 'string' && a.user ? ['-u', a.user] : [];\r\n\r\n // Flag matrix:\r\n // - stdin given: -i (attach stdin)\r\n // - interactive: -t (allocate TTY) so commands like psql / mysql / bash\r\n // that probe `isatty(stdout)` produce human-friendly output AND don't\r\n // complain (\"the input device is not a TTY\"). Combine with -i for full\r\n // interactive use; -t alone is allowed for tty-only programs.\r\n const flags: string[] = [];\r\n if (stdin !== undefined || interactive) flags.push('-i');\r\n if (interactive) flags.push('-t');\r\n\r\n // docker exec [-it] [-w DIR] [-u USER] CONTAINER CMD [ARG ...]\r\n const dockerArgs = [...flags, ...workdir, ...user, container, command, ...args];\r\n const fullCmd = buildPosixCommand('docker', ['exec', ...dockerArgs]);\r\n\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, fullCmd, proxy, {\r\n stdin,\r\n pty: interactive,\r\n });\r\n const output = [`Exit code: ${result.exitCode}`];\r\n if (result.stdout) output.push(`--- stdout ---\\n${result.stdout}`);\r\n if (result.stderr) {\r\n let stderrOut = result.stderr;\r\n // Fuzzy hint: docker emits \"No such container: <name>\" when the\r\n // identifier is wrong. Use the docker-list cache (if recent) for\r\n // a \"did you mean?\" suggestion.\r\n const noSuch = /No such container:\\s*(\\S+)/i.exec(result.stderr);\r\n if (noSuch) {\r\n const known = getKnownContainers(String(a.serverId));\r\n if (known && known.length) {\r\n const hits = suggestSimilar(noSuch[1] as string, known);\r\n if (hits.length) stderrOut += `\\n(hint) Did you mean: ${hits.join(', ')}?`;\r\n }\r\n }\r\n output.push(`--- stderr ---\\n${stderrOut}`);\r\n }\r\n return { content: [{ type: 'text', text: output.join('\\n') }] };\r\n }\r\n\r\n case 'docker-compose': {\r\n const projectPath = String(a.projectPath);\r\n if (!projectPath || !projectPath.startsWith('/')) {\r\n return { content: [{ type: 'text', text: 'Error: projectPath must be an absolute path' }] };\r\n }\r\n const action = String(a.action);\r\n const allowedActions = ['up', 'down', 'restart', 'logs', 'ps', 'pull', 'build'] as const;\r\n if (!allowedActions.includes(action as typeof allowedActions[number])) {\r\n return { content: [{ type: 'text', text: `Error: invalid action (allowed: ${allowedActions.join(', ')})` }] };\r\n }\r\n const service = typeof a.service === 'string' && a.service ? a.service : '';\r\n const tail = Number(a.tail) > 0 ? Number(a.tail) : 200;\r\n\r\n let composeArgs: string[];\r\n switch (action) {\r\n case 'up': composeArgs = service ? ['up', '-d', service] : ['up', '-d']; break;\r\n case 'down': composeArgs = service ? ['down', service] : ['down']; break;\r\n case 'restart': composeArgs = service ? ['restart', service] : ['restart']; break;\r\n case 'logs': composeArgs = service ? ['logs', '--no-color', `--tail=${tail}`, service] : ['logs', '--no-color', `--tail=${tail}`]; break;\r\n case 'ps': composeArgs = service ? ['ps', service] : ['ps']; break;\r\n case 'pull': composeArgs = service ? ['pull', service] : ['pull']; break;\r\n case 'build': composeArgs = service ? ['build', service] : ['build']; break;\r\n default: composeArgs = []; // unreachable\r\n }\r\n\r\n const composeCmd = buildPosixCommand('docker', ['compose', ...composeArgs]);\r\n const fullCmd = `cd ${posixQuote(projectPath)} && ${composeCmd} 2>&1`;\r\n\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n conn.timeout = Number(a.timeout) > 0 ? Number(a.timeout) : 120_000;\r\n const result = await sshExec(conn, fullCmd, proxy);\r\n const output = [`Exit code: ${result.exitCode} (compose ${action}${service ? ` ${service}` : ''} @ ${projectPath})`];\r\n if (result.stdout) output.push(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 // ----- wait-for: poll until a condition holds (one tool, four types) -----\r\n case 'wait-for': {\r\n const type = String(a.type || '');\r\n if (!['url', 'container-health', 'file-exists', 'sftp-exists'].includes(type)) {\r\n return { content: [{ type: 'text', text: 'Error: type must be one of: url, container-health, file-exists, sftp-exists' }] };\r\n }\r\n const timeoutSeconds = Math.max(1, Math.min(1800, Number(a.timeout) || 120));\r\n const intervalSeconds = Math.max(1, Math.min(60, Number(a.intervalSeconds) || 3));\r\n const deadline = Date.now() + timeoutSeconds * 1000;\r\n const trail: string[] = [];\r\n\r\n const check = async (): Promise<{ ok: boolean; observed: string }> => {\r\n if (type === 'url') {\r\n const target = String(a.target || '');\r\n if (!target) return { ok: false, observed: 'no target url' };\r\n const expectStatus = a.until !== undefined ? Number(a.until) : 200;\r\n try {\r\n const ctrl = new AbortController();\r\n const t = setTimeout(() => ctrl.abort(), 10_000);\r\n const res = await fetch(target, { signal: ctrl.signal, redirect: 'manual' });\r\n clearTimeout(t);\r\n const ok = res.status === expectStatus || (expectStatus === 200 && res.status >= 200 && res.status < 300);\r\n return { ok, observed: `HTTP ${res.status}` };\r\n } catch (e) {\r\n return { ok: false, observed: e instanceof Error ? e.message : String(e) };\r\n }\r\n }\r\n if (type === 'container-health') {\r\n // target = container name; until = 'healthy' (default), 'running', 'exited'\r\n const containerName = String(a.target || '').replace(/[^a-zA-Z0-9._-]/g, '');\r\n const until = String(a.until || 'healthy');\r\n if (!containerName) return { ok: false, observed: 'no container name' };\r\n if (!a.serverId) return { ok: false, observed: 'serverId is required for container-health' };\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const cmd = `docker inspect --format '{{json .State}}' ${containerName} 2>&1`;\r\n const r = await sshExec(conn, cmd, proxy);\r\n if (r.exitCode !== 0) return { ok: false, observed: r.stderr.trim().slice(0, 80) || 'inspect failed' };\r\n try {\r\n const state = JSON.parse(r.stdout.trim()) as { Status?: string; Health?: { Status?: string } };\r\n const healthStatus = state.Health?.Status; // 'healthy' | 'unhealthy' | 'starting' | undefined\r\n if (until === 'healthy') {\r\n return { ok: healthStatus === 'healthy', observed: `Status=${state.Status} Health=${healthStatus || 'no-check'}` };\r\n }\r\n return { ok: state.Status === until, observed: `Status=${state.Status}` };\r\n } catch (e) {\r\n return { ok: false, observed: 'parse error: ' + (e instanceof Error ? e.message : String(e)) };\r\n }\r\n }\r\n // file-exists / sftp-exists: same impl, the SFTP backend (R2 bucket\r\n // or SSH server) is selected by which arg is present.\r\n const bucket = typeof a.bucket === 'string' && a.bucket ? a.bucket : '';\r\n const path = String(a.target || a.path || '');\r\n if (!path) return { ok: false, observed: 'no path' };\r\n if (bucket) {\r\n try {\r\n await getR2Client().send(new HeadObjectCommand({ Bucket: bucket, Key: r2Key(path) }));\r\n return { ok: true, observed: `r2://${bucket}/${path} exists` };\r\n } catch {\r\n return { ok: false, observed: `r2://${bucket}/${path} not found` };\r\n }\r\n }\r\n if (!a.serverId) return { ok: false, observed: 'serverId or bucket is required for file-exists' };\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const safe = sanitizePath(path);\r\n const cmd = `test -e ${posixQuote(safe)} && echo OK || echo MISSING`;\r\n const r = await sshExec(conn, cmd, proxy);\r\n const ok = r.stdout.trim() === 'OK';\r\n return { ok, observed: ok ? `${safe} exists` : `${safe} missing` };\r\n };\r\n\r\n let attempts = 0;\r\n let lastObserved = '';\r\n while (Date.now() < deadline) {\r\n attempts++;\r\n const r = await check();\r\n lastObserved = r.observed;\r\n trail.push(`[${attempts}] ${new Date().toISOString().slice(11, 19)} ${r.ok ? 'OK' : '..'} ${r.observed}`);\r\n if (r.ok) {\r\n return { content: [{ type: 'text', text: `Condition met after ${attempts} attempt(s) in ${((Date.now() - (deadline - timeoutSeconds * 1000)) / 1000).toFixed(1)}s.\\nLast observation: ${r.observed}\\n\\n--- trail ---\\n${trail.join('\\n')}` }] };\r\n }\r\n if (Date.now() + intervalSeconds * 1000 >= deadline) break;\r\n await new Promise((res) => setTimeout(res, intervalSeconds * 1000));\r\n }\r\n return { content: [{ type: 'text', text: `Timed out after ${timeoutSeconds}s without seeing condition (${attempts} probe(s)).\\nLast observation: ${lastObserved}\\n\\n--- trail ---\\n${trail.join('\\n')}` }] };\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-query': {\r\n // Engine routing. Default behaviour (mysql + sitePath) is unchanged\r\n // for back-compat. Pass `containerName` to query a DB inside a Docker\r\n // container — engine defaults to postgres in that case (covers the\r\n // self-hosted Supabase / Trigger.dev stacks).\r\n const containerName = typeof a.containerName === 'string' && a.containerName ? a.containerName.replace(/[^a-zA-Z0-9._-]/g, '') : '';\r\n const explicitEngine = a.engine === 'mysql' || a.engine === 'postgres' || a.engine === 'mssql' ? a.engine : null;\r\n const engine: 'mysql' | 'postgres' | 'mssql' = explicitEngine\r\n || (containerName ? 'postgres' : 'mysql');\r\n\r\n // Schema-introspection shortcut. Replaces the old db-describe tool\r\n // and works for all three engines. Sanitises the table identifier\r\n // before string interpolation. \"*\" lists all tables.\r\n const describeArg = typeof a.describe === 'string' ? a.describe.trim() : '';\r\n\r\n // Result-size guardrail + EXPLAIN mode. Both rewrite the query string\r\n // before it hits the engine-specific path below.\r\n const explainMode = a.explain === true;\r\n const maxRowsRaw = a.maxRows === undefined ? 1000 : Number(a.maxRows);\r\n const maxRows = Math.min(Math.max(Number.isFinite(maxRowsRaw) ? maxRowsRaw : 0, 0), 10000);\r\n\r\n let rawQuery: string;\r\n if (describeArg) {\r\n rawQuery = buildDescribeSql(describeArg, engine);\r\n } else {\r\n rawQuery = String(a.query ?? '').trim();\r\n if (!rawQuery) return { content: [{ type: 'text', text: 'Error: query (or describe) is required' }] };\r\n }\r\n assertSafeSql(rawQuery);\r\n\r\n let query = rawQuery.replace(/;\\s*$/, '');\r\n let appliedLimit = false;\r\n\r\n if (explainMode && !describeArg) {\r\n if (engine === 'mssql') {\r\n // mssql has no inline EXPLAIN; prepend SET SHOWPLAN_TEXT ON and\r\n // run the statement so sqlcmd returns the plan instead of rows.\r\n query = `SET SHOWPLAN_TEXT ON;\\n${query}`;\r\n } else {\r\n // postgres + mysql both accept \"EXPLAIN <statement>\".\r\n query = `EXPLAIN ${query}`;\r\n }\r\n } else if (maxRows > 0 && !describeArg) {\r\n // Only auto-LIMIT a single bare SELECT (or WITH ... SELECT) that\r\n // doesn't already have its own LIMIT / TOP. Skip mssql since LIMIT\r\n // syntax differs (TOP / OFFSET FETCH).\r\n const isSelect = /^\\s*(with\\b[\\s\\S]+?\\bselect\\b|select\\b)/i.test(query);\r\n const alreadyLimited = /\\blimit\\s+\\d+\\b/i.test(query) || /\\btop\\s*\\(?\\s*\\d+/i.test(query);\r\n if (isSelect && !alreadyLimited && engine !== 'mssql') {\r\n query = `${query}\\nLIMIT ${maxRows + 1}`; // +1 so we can detect truncation\r\n appliedLimit = true;\r\n }\r\n }\r\n\r\n // Path A: existing MySQL-via-/var/www autodiscover. Always engine=mysql.\r\n if (!containerName && engine === 'mysql') {\r\n if (!a.sitePath) return { content: [{ type: 'text', text: 'Error: sitePath is required for mysql autodiscover (or pass containerName + engine for direct DB queries)' }] };\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n const output = await execSiteMysql(conn, String(a.sitePath), query, proxy);\r\n const footer = formatDbQueryFooter(output, appliedLimit, maxRows, explainMode);\r\n return { content: [{ type: 'text', text: (output || 'Query executed successfully (no output)') + footer }] };\r\n }\r\n\r\n // Path B: docker exec into a container with the appropriate client.\r\n // Query is piped via STDIN to avoid quoting hell with `, $, ; etc.\r\n if (!containerName) {\r\n return { content: [{ type: 'text', text: `Error: engine=${engine} requires containerName (the docker container running the DB server, e.g. \"supabase-db\" or \"trigger-postgres\")` }] };\r\n }\r\n const dbName = typeof a.dbName === 'string' && a.dbName ? a.dbName.replace(/[^a-zA-Z0-9_-]/g, '') : '';\r\n const dbUser = typeof a.dbUser === 'string' && a.dbUser ? a.dbUser.replace(/[^a-zA-Z0-9_-]/g, '') : '';\r\n const { conn, proxy } = await getServerConnection(String(a.serverId));\r\n\r\n let cmd: string;\r\n let stdinPayload: string | undefined;\r\n if (engine === 'postgres') {\r\n // psql: -t (tuples-only) -A (unaligned) is great for parsing; use\r\n // -P expanded=auto for human-friendly default.\r\n const user = dbUser || 'postgres';\r\n const db = dbName || 'postgres';\r\n // Pipe the query in via stdin so we don't need to escape it.\r\n cmd = `docker exec -i ${containerName} psql -U ${user} -d ${db} -P pager=off`;\r\n stdinPayload = query.endsWith(';') ? query : `${query};`;\r\n } else if (engine === 'mssql') {\r\n // sqlcmd path (assumes mssql-tools in container). Caller provides\r\n // dbUser + dbPass (we *only* take dbPass here for mssql since\r\n // it isn't auto-discoverable like Postgres trust).\r\n const user = dbUser || 'sa';\r\n const dbPass = typeof a.dbPass === 'string' ? a.dbPass : '';\r\n if (!dbPass) return { content: [{ type: 'text', text: 'Error: mssql requires dbPass (sqlcmd has no equivalent of pg trust auth)' }] };\r\n const dbArg = dbName ? `-d ${dbName} ` : '';\r\n // Use stdin via -i /dev/stdin pattern; sqlcmd reads from stdin when no -Q given.\r\n cmd = `docker exec -i -e MSSQL_SA_PASSWORD=${posixQuote(dbPass)} ${containerName} /opt/mssql-tools18/bin/sqlcmd -S localhost -U ${user} -P \"$MSSQL_SA_PASSWORD\" -C ${dbArg}-h -1`;\r\n stdinPayload = query.endsWith(';') ? `${query}\\nGO\\n` : `${query};\\nGO\\n`;\r\n } else {\r\n // engine === 'mysql' but with containerName: useful for dockerised\r\n // MySQL outside of /var/www, e.g. a dev stack.\r\n const user = dbUser || 'root';\r\n const db = dbName ? ` ${dbName}` : '';\r\n const dbPass = typeof a.dbPass === 'string' ? a.dbPass : '';\r\n const passArg = dbPass ? `-p${posixQuote(dbPass)} ` : '';\r\n cmd = `docker exec -i ${containerName} mysql -t -u ${user} ${passArg}${db}`;\r\n stdinPayload = query.endsWith(';') ? query : `${query};`;\r\n }\r\n\r\n const result = await sshExec(conn, cmd, proxy, { stdin: stdinPayload });\r\n const output = result.stdout.trim() || result.stderr.trim() || '(no output)';\r\n if (result.exitCode !== 0 && !result.stdout) {\r\n return { content: [{ type: 'text', text: `Error (exit ${result.exitCode}, ${engine}): ${output}` }] };\r\n }\r\n const footer = formatDbQueryFooter(output, appliedLimit, maxRows, explainMode);\r\n return { content: [{ type: 'text', text: output + footer }] };\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 details = a.details === true;\r\n if (!details) {\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 return { content: [{ type: 'text', text: `${domains.length} domain(s):\\n\\n${lines.join('\\n')}` }] };\r\n }\r\n\r\n // details: true → fetch DNS zone per active domain in parallel and\r\n // summarise NS / MX / SPF / DMARC. Inactive domains are skipped so\r\n // we don't burn API quota on records that don't exist.\r\n interface DnsRec { type: string; name: string; value: string; ttl: number; }\r\n const concurrency = Math.min(Math.max(Number(a.concurrency) || 8, 1), 20);\r\n\r\n type Summary = { mx: string[]; hasSpf: boolean; hasDmarc: boolean; error?: string };\r\n const summaries = new Map<string, Summary>();\r\n\r\n const skipStatuses = new Set(['expired', 'redemptionperiod', 'pendingdelete', 'inactive']);\r\n const activeDomains = domains.filter(d => !skipStatuses.has((d.status || '').toLowerCase()));\r\n\r\n async function fetchSummary(domain: string): Promise<Summary> {\r\n try {\r\n const r = await mijnhostFetch<{ records: DnsRec[] }>(\r\n `/domains/${encodeURIComponent(domain)}/dns`,\r\n );\r\n const recs = r.data.records || [];\r\n // mijn.host's /dns endpoint exposes records inside the zone but\r\n // not the zone's own NS delegation, so we deliberately don't\r\n // report nameservers here (was misleading \"(none)\" for every row).\r\n const mx = recs\r\n .filter(x => x.type === 'MX')\r\n .map(x => x.value)\r\n .sort();\r\n const hasSpf = recs.some(x => x.type === 'TXT' && x.value.toLowerCase().includes('v=spf1'));\r\n const hasDmarc = recs.some(x =>\r\n x.type === 'TXT' &&\r\n (x.name.toLowerCase().startsWith('_dmarc') || x.value.toLowerCase().includes('v=dmarc1')),\r\n );\r\n return { mx, hasSpf, hasDmarc };\r\n } catch (err) {\r\n return { mx: [], hasSpf: false, hasDmarc: false, error: err instanceof Error ? err.message : String(err) };\r\n }\r\n }\r\n\r\n // Simple parallel pool — keeps `concurrency` requests in flight.\r\n const queue = [...activeDomains];\r\n async function worker() {\r\n while (queue.length > 0) {\r\n const d = queue.shift();\r\n if (!d) return;\r\n summaries.set(d.domain, await fetchSummary(d.domain));\r\n }\r\n }\r\n await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, worker));\r\n\r\n const lines = domains.map(d => {\r\n const tags = d.tags?.length ? ` [${d.tags.join(', ')}]` : '';\r\n const head = `${d.domain} status=${d.status} expires=${d.renewal_date}${tags}`;\r\n const s = summaries.get(d.domain);\r\n if (!s) return head;\r\n if (s.error) return `${head}\\n dns: error: ${s.error}`;\r\n const mx = s.mx.length ? s.mx.join(', ') : '(none)';\r\n return `${head}\\n mx=${mx} spf=${s.hasSpf ? 'yes' : 'NO'} dmarc=${s.hasDmarc ? 'yes' : 'NO'}`;\r\n });\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `${domains.length} domain(s) (${activeDomains.length} with DNS lookup):\\n\\n${lines.join('\\n')}`,\r\n }],\r\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-record': {\r\n const action = String(a.action);\r\n if (action !== 'create' && action !== 'update' && action !== 'delete') {\r\n throw new Error('action must be one of: create, update, delete');\r\n }\r\n\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 dryRun = a.dryRun === true;\r\n\r\n if (!domain || !type || !dnsName) {\r\n throw new Error('domain, type, and name 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 // Build the next records[] array and the diff descriptor in one pass\r\n // per action. PUT is only called when dryRun is false.\r\n let nextRecords: DnsRecord[];\r\n let diffArgs: { verb: 'create' | 'update' | 'delete'; added?: DnsRecord[]; removed?: DnsRecord[] };\r\n let okMessage: string;\r\n\r\n if (action === 'create') {\r\n const value = typeof a.value === 'string' ? a.value : '';\r\n if (!value) throw new Error('action=\"create\" requires value');\r\n const ttl = Number(a.ttl) || 3600;\r\n const newRecord: DnsRecord = { type, name: dnsName, value, ttl };\r\n nextRecords = [...current.data.records, newRecord];\r\n diffArgs = { verb: 'create', added: [newRecord] };\r\n okMessage = `DNS record created: ${type} ${dnsName} → ${value} (TTL: ${ttl})`;\r\n } else if (action === 'update') {\r\n const oldValue = typeof a.oldValue === 'string' ? a.oldValue : '';\r\n const newValue = typeof a.newValue === 'string' ? a.newValue : '';\r\n if (!oldValue || !newValue) throw new Error('action=\"update\" requires oldValue and newValue');\r\n const ttlArg = a.ttl !== undefined ? Number(a.ttl) : undefined;\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 if (idx === -1) {\r\n throw new Error(\r\n `No matching DNS record found: ${type} ${dnsName} = ${oldValue}\\n` +\r\n describeDnsCandidates(current.data.records, type, dnsName, oldValue),\r\n );\r\n }\r\n\r\n const updated = [...current.data.records];\r\n const before = updated[idx]!;\r\n const after: DnsRecord = {\r\n type,\r\n name: dnsName,\r\n value: newValue,\r\n ttl: ttlArg ?? before.ttl,\r\n };\r\n updated[idx] = after;\r\n nextRecords = updated;\r\n diffArgs = { verb: 'update', removed: [before], added: [after] };\r\n okMessage = `DNS record updated: ${type} ${dnsName} → ${newValue}${ttlArg ? ` (TTL: ${ttlArg})` : ''}`;\r\n } else {\r\n const value = typeof a.value === 'string' ? a.value : '';\r\n if (!value) throw new Error('action=\"delete\" requires value');\r\n\r\n const removed = current.data.records.filter(\r\n (r) => r.type === type && r.name === dnsName && r.value === value,\r\n );\r\n const remaining = current.data.records.filter(\r\n (r) => !(r.type === type && r.name === dnsName && r.value === value),\r\n );\r\n if (removed.length === 0) {\r\n throw new Error(\r\n `No matching DNS record found: ${type} ${dnsName} = ${value}\\n` +\r\n describeDnsCandidates(current.data.records, type, dnsName, value),\r\n );\r\n }\r\n nextRecords = remaining;\r\n diffArgs = { verb: 'delete', removed };\r\n okMessage = `DNS record deleted: ${type} ${dnsName} = ${value} (${remaining.length} records remaining)`;\r\n }\r\n\r\n if (dryRun) {\r\n const diff = formatDnsDiff(domain, current.data.records, nextRecords, diffArgs);\r\n return { content: [{ type: 'text', text: diff }] };\r\n }\r\n\r\n await mijnhostFetch<void>(`/domains/${encodeURIComponent(domain)}/dns`, {\r\n method: 'PUT',\r\n body: JSON.stringify({ records: nextRecords }),\r\n });\r\n\r\n return { content: [{ type: 'text', text: okMessage }] };\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 (VERCEL_TOOL_NAMES.has(name)) {\r\n return handleVercelTool(name, a, { supabase, decrypt });\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 const apiAuthContext = await validateApiKey(apiKey!);\r\n if (!apiAuthContext) {\r\n console.error('API key validation failed');\r\n process.exit(1);\r\n }\r\n\r\n authContext = await validateSshKey(sshKeyPath!, apiAuthContext.apiKeyId);\r\n if (!authContext) {\r\n console.error('SSH-key authentication failed');\r\n process.exit(1);\r\n }\r\n\r\n console.error(`[Security] MCP v${MCP_VERSION} | Key: ${authContext.apiKeyName}`);\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\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"]}
|