playwright-mcp
Version:
Playwright integration for ModelContext
125 lines (121 loc) • 3.3 kB
JavaScript
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);
});