Skip to main content
Glama

@pulumi/mcp-server

Official
by pulumi
cors.ts3.52 kB
import express from 'express'; import { logger } from '../../logging/logging.js'; /** * CORS configuration for MCP HTTP transport. * - strict: Only allows explicitly configured origins * - development: Allows localhost + explicitly configured origins * - disabled: Allows all origins (not recommended for production) */ export interface CORSConfig { mode: 'strict' | 'development' | 'disabled'; allowedOrigins: string[]; } // Pattern to match localhost origins (IPv4, IPv6, and named localhost) const LOCALHOST_PATTERN = /^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])(:\d+)?$/; /** * Loads CORS configuration from environment variables. * Uses MCP_CORS_MODE and MCP_ALLOWED_ORIGINS environment variables. */ export function loadCORSConfig(): CORSConfig { const validModes = ['strict', 'development', 'disabled']; const givenMode = (process.env.MCP_CORS_MODE || 'strict').toLowerCase(); const mode = validModes.includes(givenMode) ? givenMode : 'strict'; if (!validModes.includes(givenMode)) { logger.warn(`Invalid CORS mode '${givenMode}'. Defaulting to 'strict'.`); } const allowedOrigins = parseCommaSeparatedEnv(process.env.MCP_ALLOWED_ORIGINS); return { mode: mode as CORSConfig['mode'], allowedOrigins }; } /** * Sets standard CORS headers for MCP HTTP responses. * Includes session ID header for MCP protocol communication. */ export function setCORSHeaders(res: express.Response, origin?: string): void { res.header('Access-Control-Max-Age', '3600'); res.header('Access-Control-Allow-Origin', origin || '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Mcp-Session-Id'); } /** * Checks if an origin is allowed based on CORS configuration. * In development mode, localhost origins are automatically allowed. */ export function isOriginAllowed(origin: string, config: CORSConfig): boolean { // Check explicit allowlist if (config.allowedOrigins.includes(origin)) return true; // In development mode, allow localhost origins if (config.mode === 'development' && LOCALHOST_PATTERN.test(origin)) return true; return false; } /** * Creates Express middleware for CORS validation and header setting. * Handles preflight OPTIONS requests and origin validation. */ export function createCORSMiddleware() { return (req: express.Request, res: express.Response, next: express.NextFunction) => { const origin = req.headers.origin; const corsConfig = loadCORSConfig(); // If CORS is disabled, allow all origins if (corsConfig.mode === 'disabled') { setCORSHeaders(res); if (req.method === 'OPTIONS') { res.status(200).end(); return; } return next(); } // Allow requests without origin header (same-origin requests) if (!origin) { return next(); } // Check if the origin is allowed if (!isOriginAllowed(origin, corsConfig)) { res.status(403).send('Origin not allowed'); return; } setCORSHeaders(res, origin); // Handle preflight OPTIONS requests if (req.method === 'OPTIONS') { res.status(200).end(); return; } next(); }; } /** * Parses a comma-separated environment variable into a trimmed array. * Filters out empty values after trimming. */ function parseCommaSeparatedEnv(envValue: string | undefined): string[] { return ( envValue ?.split(',') .map((item) => item.trim()) .filter(Boolean) || [] ); }

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/pulumi/mcp-server'

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