Skip to main content
Glama

Spec Workflow MCP

utils.ts3.49 kB
import { createServer } from 'net'; // Dashboard constants export const DASHBOARD_TEST_MESSAGE = 'MCP Workflow Dashboard Online!'; async function isPortAvailable(port: number): Promise<boolean> { return new Promise((resolve) => { const server = createServer(); server.listen(port, '0.0.0.0', () => { server.once('close', () => { resolve(true); }); server.close(); }); server.on('error', () => { resolve(false); }); }); } export async function findAvailablePort(): Promise<number> { // Use industry standard ephemeral port range (49152-65535) const ephemeralStart = 49152; const ephemeralEnd = 65535; // Generate a random starting point to avoid always using the same ports const randomStart = ephemeralStart + Math.floor(Math.random() * 1000); for (let port = randomStart; port <= ephemeralEnd; port++) { if (await isPortAvailable(port)) { return port; } } // If we didn't find one from random start to end, try from beginning to random start for (let port = ephemeralStart; port < randomStart; port++) { if (await isPortAvailable(port)) { return port; } } throw new Error(`No available ephemeral port found in range ${ephemeralStart}-${ephemeralEnd}`); } /** * Check if a specific port is available for use * @param port The port number to check * @returns Promise<boolean> true if port is available, false otherwise */ export async function isSpecificPortAvailable(port: number): Promise<boolean> { return isPortAvailable(port); } /** * Check if an existing dashboard is running on the specified port * @param port The port number to check * @returns Promise<boolean> true if a dashboard is running, false otherwise */ export async function checkExistingDashboard(port: number): Promise<boolean> { try { const response = await fetch(`http://localhost:${port}/api/test`, { method: 'GET', signal: AbortSignal.timeout(1000) // 1 second timeout }); if (response.ok) { const data = await response.json() as { message?: string }; // Check if it's actually our dashboard return data.message === DASHBOARD_TEST_MESSAGE; } return false; } catch { // Connection failed or timeout - no dashboard running return false; } } /** * Validate a port number and check if it's available * @param port The port number to validate and check * @param skipDashboardCheck Optional flag to skip checking for existing dashboard * @returns Promise<void> throws error if invalid or unavailable */ export async function validateAndCheckPort(port: number, skipDashboardCheck: boolean = false): Promise<void> { // Validate port range first if (port < 1024 || port > 65535) { throw new Error(`Port ${port} is out of range. Port must be between 1024 and 65535.`); } // Check if it's our dashboard first (more efficient when dashboard exists) if (!skipDashboardCheck) { const isDashboard = await checkExistingDashboard(port); if (isDashboard) { // Let caller handle existing dashboard scenario throw new Error(`Port ${port} is already in use by an existing dashboard instance.`); } } // Only check general port availability if it's not our dashboard const available = await isSpecificPortAvailable(port); if (!available) { throw new Error(`Port ${port} is already in use. Please choose a different port or omit --port to use an ephemeral port.`); } }

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/Pimzino/spec-workflow-mcp'

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