Skip to main content
Glama

Genkit MCP

Official
by firebase
runtime-detector.ts5.37 kB
/** * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { existsSync } from 'fs'; import { basename, extname } from 'path'; const RUNTIME_NODE = 'node'; const RUNTIME_BUN = 'bun'; const RUNTIME_COMPILED = 'compiled-binary'; const NODE_PATTERNS = ['node', 'nodejs']; const BUN_PATTERNS = ['bun']; const SCRIPT_EXTENSIONS = ['.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx']; /** * CLI runtime types supported by the detector */ export type CLIRuntimeType = 'node' | 'bun' | 'compiled-binary'; /** * Information about the CLI runtime environment */ export interface CLIRuntimeInfo { /** Type of CLI runtime or execution mode */ type: CLIRuntimeType; /** Path to the executable (node, bun, or the compiled binary itself) */ execPath: string; /** Path to the script being executed (undefined for compiled binaries) */ scriptPath?: string; /** Whether this is a compiled binary (e.g., Bun-compiled) */ isCompiledBinary: boolean; /** Platform information */ platform: NodeJS.Platform; } /** * Safely checks if a file exists without throwing errors * @param path - File path to check * @returns true if the file exists, false otherwise */ function safeExistsSync(path: string | undefined): boolean { if (!path) return false; try { return existsSync(path); } catch { return false; } } /** * Checks if the given path has a recognized script file extension * @param path - File path to check * @returns true if the path ends with a known script extension * @internal Kept for potential future use, though not currently used in detection logic */ function isLikelyScriptFile(path: string | undefined): boolean { if (!path) return false; const ext = extname(path).toLowerCase(); return SCRIPT_EXTENSIONS.includes(ext); } /** * Checks if executable name contains any of the given patterns * @param execName - Name of the executable * @param patterns - Array of patterns to match against * @returns true if any pattern is found in the executable name */ function matchesPatterns(execName: string, patterns: string[]): boolean { const lowerExecName = execName.toLowerCase(); return patterns.some((pattern) => lowerExecName.includes(pattern)); } /** * Detects the current CLI runtime environment and execution context. * This helps determine how to properly spawn child processes. * * @returns CLI runtime information including type, paths, and platform * @throws Error if unable to determine CLI runtime executable path */ export function detectCLIRuntime(): CLIRuntimeInfo { const platform = process.platform; const execPath = process.execPath; if (!execPath || execPath.trim() === '') { throw new Error('Unable to determine CLI runtime executable path'); } const argv0 = process.argv[0]; const argv1 = process.argv[1]; const execBasename = basename(execPath); const argv0Basename = argv0 ? basename(argv0) : ''; const hasBunVersion = 'bun' in (process.versions || {}); const hasNodeVersion = 'node' in (process.versions || {}); const execMatchesBun = matchesPatterns(execBasename, BUN_PATTERNS); const execMatchesNode = matchesPatterns(execBasename, NODE_PATTERNS); const argv0MatchesBun = matchesPatterns(argv0Basename, BUN_PATTERNS); const argv0MatchesNode = matchesPatterns(argv0Basename, NODE_PATTERNS); const hasScriptArg = !!argv1; const scriptExists = hasScriptArg && safeExistsSync(argv1); let type: CLIRuntimeType; let scriptPath: string | undefined; let isCompiledBinary: boolean; // Determine runtime type based on most reliable indicators if (hasBunVersion || execMatchesBun || argv0MatchesBun) { // Check if this is a Bun-compiled binary // Bun compiled binaries have virtual paths like /$bunfs/root/... if ( argv1 && (argv1.startsWith('/$bunfs/') || /^[A-Za-z]:[\\/]+~BUN[\\/]+/.test(argv1)) ) { // This is a Bun-compiled binary type = RUNTIME_COMPILED; scriptPath = undefined; isCompiledBinary = true; } else { // Regular Bun runtime type = RUNTIME_BUN; scriptPath = argv1; isCompiledBinary = false; } } else if (hasNodeVersion || execMatchesNode || argv0MatchesNode) { // Definitely Node.js type = RUNTIME_NODE; scriptPath = argv1; isCompiledBinary = false; } else if (!hasScriptArg || !scriptExists) { // No script argument or script doesn't exist - likely compiled binary type = RUNTIME_COMPILED; scriptPath = undefined; isCompiledBinary = true; } else { // Have a script argument that exists but unknown runtime // This handles cases like custom Node.js builds with unusual names type = RUNTIME_NODE; scriptPath = argv1; isCompiledBinary = false; } return { type, execPath, scriptPath, isCompiledBinary, platform, }; }

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/firebase/genkit'

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