Skip to main content
Glama
mcpmessenger

Playwright MCP HTTP Server

by mcpmessenger
server.ts4.2 kB
/** * Express HTTP Server for Playwright MCP */ import express, { Request, Response, ErrorRequestHandler } from "express"; import cors from "cors"; import { config } from "./config"; import { MCPHandler } from "./mcp-handler"; import { JSONRPCRequest } from "./types/mcp"; const app = express(); const mcpHandler = new MCPHandler(); // Middleware app.use(cors({ origin: config.corsOrigin })); app.use(express.json({ limit: "10mb" })); // Request logging middleware app.use((req, res, next) => { const start = Date.now(); res.on("finish", () => { const duration = Date.now() - start; console.log( `[${new Date().toISOString()}] ${req.method} ${req.path} - ${res.statusCode} (${duration}ms)` ); }); next(); }); // Root endpoint - Service information app.get("/", (req: Request, res: Response) => { res.json({ name: "Playwright MCP HTTP Server", version: "1.0.0", protocol: "MCP v0.1", endpoints: { mcp: "/mcp", health: "/health", }, }); }); // Health check endpoint app.get("/health", (req: Request, res: Response) => { const isHealthy = mcpHandler.isReady(); const status = isHealthy ? "healthy" : "starting"; res.status(isHealthy ? 200 : 503).json({ status, version: "1.0.0", uptime: process.uptime(), timestamp: new Date().toISOString(), }); }); // Main MCP protocol endpoint app.post("/mcp", async (req: Request, res: Response) => { try { const request: JSONRPCRequest = req.body; // Validate basic structure if (!request || typeof request !== "object") { return res.status(400).json({ jsonrpc: "2.0", id: null, error: { code: -32600, message: "Invalid Request", }, }); } const response = await mcpHandler.handle(request); res.json(response); } catch (error: any) { console.error("[Server] Error handling request:", error); res.status(500).json({ jsonrpc: "2.0", id: req.body?.id || null, error: { code: -32603, message: "Internal Error", data: error.message, }, }); } }); // Error handling middleware const errorHandler: ErrorRequestHandler = (err, req, res, next) => { console.error("[Server] Unhandled error:", err); res.status(500).json({ jsonrpc: "2.0", id: req.body?.id || null, error: { code: -32603, message: "Internal Error", data: err.message, }, }); }; app.use(errorHandler); // 404 handler app.use((req: Request, res: Response) => { res.status(404).json({ error: "Not Found", path: req.path, }); }); // Start server async function startServer() { try { // Initialize MCP handler console.log("[Server] Initializing MCP handler..."); await mcpHandler.initialize(); // Start HTTP server app.listen(config.port, () => { console.log( `[Server] Playwright MCP HTTP Server running on port ${config.port}` ); console.log(`[Server] Health check: http://localhost:${config.port}/health`); console.log(`[Server] MCP endpoint: http://localhost:${config.port}/mcp`); }); } catch (error) { console.error("[Server] Failed to start:", error); process.exit(1); } } // Graceful shutdown let isShuttingDown = false; async function shutdown() { if (isShuttingDown) return; isShuttingDown = true; console.log("[Server] Shutting down gracefully..."); try { await mcpHandler.cleanup(); console.log("[Server] Cleanup complete"); process.exit(0); } catch (error) { console.error("[Server] Error during shutdown:", error); process.exit(1); } } process.on("SIGTERM", shutdown); process.on("SIGINT", shutdown); // Handle uncaught errors process.on("uncaughtException", (error) => { console.error("[Server] Uncaught exception:", error); shutdown(); }); process.on("unhandledRejection", (reason, promise) => { console.error("[Server] Unhandled rejection at:", promise, "reason:", reason); }); // Start the server startServer();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcpmessenger/playwright-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server