Skip to main content
Glama

MCP YAML API

by molavec
parser.ts4.94 kB
import { z } from "zod"; import type { ApiBodyProperty } from "../types/api.js"; import { describe } from "node:test"; /** * Helper function to replace environment variables in a string * * @param str - String containing environment variables in format ${VAR_NAME} * @returns String with environment variables replaced with their values */ const replaceEnvVars = (str: string): string => { return str.replace(/\${([^}]+)}/g, (_, varName) => process.env[varName] || ""); } /** * Extracts path and query parameters from a URL template * * @param url - URL template with parameters in format {paramName} and query params * @returns Object with parameter names as keys * * @example * // URL with path parameter * getUrlParametersAndQuerys("/users/{id}") * // Returns { id: string | number } * * @example * // URL with query parameters * getUrlParametersAndQuerys("/users?page={page}&limit={limit}") * // Returns { page: string | number, limit: string | number } * * @example * // URL with both path and query parameters * getUrlParametersAndQuerys("/users/{id}?page={page}&limit={limit}") * // Returns { id: string | number, page: string | number, limit: string | number } */ const getUrlParametersAndQuerys = (url: string): Record<string, any> => { const params: Record<string, any> = {}; // Split URL into path and query const [path, query] = url.split('?'); // Extract path parameters const pathMatches = path.match(/{([^}]+)}/g) || []; pathMatches.forEach(match => { const param = match.slice(1, -1); // Remove { and } params[param] = {type: "string"}; }); // Extract query parameters if (query) { const queryMatches = query.match(/{([^}]+)}/g) || []; queryMatches.forEach(match => { const param = match.slice(1, -1); // Remove { and } params[param] = {type: "string"}; }); } return params; }; /** * Replaces dynamic parameters in a URL template with their corresponding values * * @param url - URL template containing parameters in format {paramName} * @param params - Object containing the values to replace in the URL * @returns URL with all parameters replaced with their values * * @example * // Basic usage * const url = "/api/users/{userId}"; * const params = { userId: "123" }; * replaceUrlParams(url, params); // Returns "/api/users/123" * * @example * // Multiple parameters * const url = "/api/users/{userId}/posts/{postId}"; * const params = { userId: "123", postId: "456" }; * replaceUrlParams(url, params); // Returns "/api/users/123/posts/456" * * @example * // Missing parameters * const url = "/api/users/{userId}"; * const params = {}; * replaceUrlParams(url, params); // Returns "/api/users/" */ const replaceUrlParams = (url: string, params: Record<string, string>): string => { return url.replace(/{([^}]+)}/g, (_, param) => params[param] || ""); } const getBodyProperties = (bodyDef: ApiBodyProperty[] | undefined) => { if (!bodyDef || !Array.isArray(bodyDef)) return {}; const schema: Record<string, any> = {}; for (const prop of bodyDef) { schema[prop.name] = { type: prop.type, describe: prop.description, } } return schema; } // Function to create a Zod schema based on the body definition const createBodySchema = (bodyDef: ApiBodyProperty[] | undefined) => { if (!bodyDef || !Array.isArray(bodyDef)) return z.object({}).optional(); const schema: Record<string, any> = {}; for (const prop of bodyDef) { let zodType; switch (prop.type.toLowerCase()) { case 'string': zodType = z.string(); break; case 'number': case 'integer': zodType = z.number(); break; case 'boolean': zodType = z.boolean(); break; default: zodType = z.any(); } // If required is true, the field is mandatory and the description message is added if (prop.required) { schema[prop.name] = zodType.describe(prop.description || ''); } else { schema[prop.name] = zodType.optional(); } // if default exists, the default value is added if (prop.default) { schema[prop.name] = schema[prop.name].default(prop.default); } } return schema; } const getPropertiesFromSchema = (schema: z.ZodTypeAny) => { if (schema instanceof z.ZodObject) { return schema.shape; } if (schema instanceof z.ZodOptional && schema._def.innerType instanceof z.ZodObject) { return schema._def.innerType.shape; } return {}; }; export { replaceEnvVars, getUrlParametersAndQuerys, replaceUrlParams, getBodyProperties, createBodySchema, getPropertiesFromSchema, }

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/molavec/mcp-yaml-api'

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