UNPKG

playwright-mcp

Version:
125 lines (121 loc) 3.3 kB
#!/usr/bin/env node import { server } from "./chunk-VF6I3HOH.js"; import "./chunk-F7R6SO4N.js"; // src/server.ts import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; // src/web-server.ts import http from "http"; import fs from "fs"; import path from "path"; import url, { fileURLToPath } from "url"; import { dirname } from "path"; import net from "net"; var __filename = fileURLToPath(import.meta.url); var __dirname = dirname(__filename); var SERVE_DIR = path.join(__dirname, "ui"); async function isPortInUse(port) { return new Promise((resolve) => { const tester = net.createServer().once("error", () => resolve(true)).once("listening", () => { tester.once("close", () => resolve(false)); tester.close(); }).listen(port); }); } var server2 = http.createServer((req, res) => { const parsedUrl = url.parse(req.url || ""); const pathname = parsedUrl.pathname || "/"; let filePath = path.join(SERVE_DIR, pathname); if (!filePath.startsWith(SERVE_DIR)) { res.writeHead(403, { "Content-Type": "text/plain" }); res.end("403 Forbidden: Access denied"); return; } if (pathname.endsWith("/")) { filePath = path.join(filePath, "index.html"); } fs.stat(filePath, (err, stats) => { if (err) { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("404 Not Found"); return; } if (stats.isDirectory()) { filePath = path.join(filePath, "index.html"); fs.stat(filePath, (err2, stats2) => { if (err2) { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("404 Not Found"); return; } serveFile(filePath, res); }); } else { serveFile(filePath, res); } }); }); function serveFile(filePath, res) { const ext = path.extname(filePath); let contentType = "text/plain"; switch (ext) { case ".html": contentType = "text/html"; break; case ".css": contentType = "text/css"; break; case ".js": contentType = "application/javascript"; break; case ".json": contentType = "application/json"; break; case ".png": contentType = "image/png"; break; case ".jpg": case ".jpeg": contentType = "image/jpeg"; break; case ".gif": contentType = "image/gif"; break; case ".svg": contentType = "image/svg+xml"; break; case ".pdf": contentType = "application/pdf"; break; } fs.readFile(filePath, (err, data) => { if (err) { res.writeHead(500, { "Content-Type": "text/plain" }); res.end("Internal Server Error"); return; } res.writeHead(200, { "Content-Type": contentType }); res.end(data); }); } // src/server.ts async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP Server started"); if (true) { const portInUse = await isPortInUse(5174); if (!portInUse) { server2.listen(5174, () => { console.error("Web server started"); }); } else { console.error("Port 5174 is in use, skipping web server"); } } } main().catch((error) => { console.error("Fatal error in main", error); process.exit(1); });