Spaces:
Runtime error
Runtime error
| import { spawn } from "node:child_process"; | |
| import { existsSync } from "node:fs"; | |
| import { dirname, join } from "node:path"; | |
| import { fileURLToPath } from "node:url"; | |
| const __filename = fileURLToPath(import.meta.url); | |
| const __dirname = dirname(__filename); | |
| const ROOT = join(__dirname, ".."); | |
| /** | |
| * @param {string} [rootDir] - project root directory (defaults to package root) | |
| * @param {(path: string) => boolean} [existsSyncFn] - injectable fs.existsSync | |
| * for testing; defaults to the real existsSync | |
| * @returns {string|null} resolved absolute path to the MCP server entry, or null | |
| */ | |
| export function resolveMcpEntry(rootDir = ROOT, existsSyncFn = existsSync) { | |
| const candidates = [ | |
| // Preferred distributable JS entry (npm publish artifact, built by prepublish.ts) | |
| join(rootDir, "dist", "open-sse", "mcp-server", "server.js"), | |
| // Local workspace TypeScript source fallback | |
| join(rootDir, "open-sse", "mcp-server", "server.ts"), | |
| ]; | |
| for (const entry of candidates) { | |
| if (existsSyncFn(entry)) return entry; | |
| } | |
| return null; | |
| } | |
| function formatSpawnError(exitCode, signal) { | |
| if (signal) return `MCP server exited by signal ${signal}`; | |
| return `MCP server exited with code ${exitCode ?? 1}`; | |
| } | |
| export async function startMcpCli(rootDir = ROOT) { | |
| const mcpEntry = resolveMcpEntry(rootDir); | |
| if (!mcpEntry) { | |
| throw new Error( | |
| "MCP server entrypoint not found. Expected dist/open-sse/mcp-server/server.js or open-sse/mcp-server/server.ts." | |
| ); | |
| } | |
| // `tsx` loader is only required for local `.ts` fallback; JS entry works without it. | |
| const loaderArgs = mcpEntry.endsWith(".ts") ? ["--import", "tsx"] : []; | |
| await new Promise((resolve, reject) => { | |
| const child = spawn(process.execPath, [...loaderArgs, mcpEntry], { | |
| cwd: rootDir, | |
| env: process.env, | |
| stdio: "inherit", | |
| }); | |
| child.once("error", reject); | |
| child.once("exit", (code, signal) => { | |
| if ((code ?? 0) === 0 && !signal) { | |
| resolve(undefined); | |
| return; | |
| } | |
| reject(new Error(formatSpawnError(code, signal))); | |
| }); | |
| }); | |
| } | |
| if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) { | |
| startMcpCli().catch((err) => { | |
| console.error("\x1b[31m✖ Failed to start MCP server:\x1b[0m", err?.message || err); | |
| process.exit(1); | |
| }); | |
| } | |