Skip to main content
Glama

Tinder API MCP Server

registry.ts8.14 kB
/** * Schema Registry * * A centralized registry for managing Zod schemas across the application. * Provides functionality to register, retrieve, and validate against schemas. */ import { z } from "zod"; import logger from "../utils/logger"; /** * Schema registry type definitions */ export type SchemaId = string; export type SchemaCategory = "api" | "common" | "internal" | "custom"; /** * Schema registration options */ export interface SchemaRegistrationOptions { /** * Allow overwriting an existing schema * Default: false */ allowOverwrite?: boolean; /** * Schema version */ version?: string; /** * Schema description */ description?: string; } /** * Schema registry entry interface */ export interface SchemaRegistryEntry { id: SchemaId; schema: z.ZodType; category: SchemaCategory; description?: string; version?: string; } /** * Schema registry class */ class SchemaRegistry { private schemas: Map<SchemaId, SchemaRegistryEntry>; private static instance: SchemaRegistry; private constructor() { this.schemas = new Map<SchemaId, SchemaRegistryEntry>(); logger.info("Schema Registry initialized"); } /** * Get the singleton instance of the schema registry */ public static getInstance(): SchemaRegistry { if (!SchemaRegistry.instance) { SchemaRegistry.instance = new SchemaRegistry(); } return SchemaRegistry.instance; } /** * Register a schema with the registry * * @param id - Unique identifier for the schema * @param schema - Zod schema * @param category - Schema category * @param description - Optional description * @param version - Optional version * @returns The registered schema entry */ /** * Validate a schema ID to prevent injection attacks * * @param id - Schema ID to validate * @throws Error if the schema ID is invalid */ private validateSchemaId(id: SchemaId): void { // Schema ID must be a non-empty string if (!id || typeof id !== "string") { throw new Error("Schema ID must be a non-empty string"); } // Schema ID must follow a valid pattern (alphanumeric, dots, underscores, hyphens) const validIdPattern = /^[a-zA-Z0-9._-]+$/; if (!validIdPattern.test(id)) { throw new Error( "Schema ID contains invalid characters (only alphanumeric, dots, underscores, and hyphens are allowed)" ); } // Schema ID must not be too long (prevent DoS attacks) if (id.length > 100) { throw new Error("Schema ID exceeds maximum length (100 characters)"); } } /** * Register a schema with the registry * * @param id - Unique identifier for the schema * @param schema - Zod schema * @param category - Schema category * @param options - Registration options or description (for backward compatibility) * @param version - Optional version (for backward compatibility) * @returns The registered schema entry * @throws Error if schema ID is invalid or if attempting to overwrite without permission */ public register<T extends z.ZodType>( id: SchemaId, schema: T, category: SchemaCategory = "custom", options?: SchemaRegistrationOptions | string, version?: string ): SchemaRegistryEntry { // Validate schema ID this.validateSchemaId(id); // Handle backward compatibility let registrationOptions: SchemaRegistrationOptions = {}; if (typeof options === "string") { registrationOptions = { description: options, version: version, allowOverwrite: false, }; } else if (options) { registrationOptions = options; } // Check if schema already exists if (this.schemas.has(id) && !registrationOptions.allowOverwrite) { const error = new Error( `Schema with ID "${id}" already exists and overwriting is not allowed` ); logger.error(error.message); throw error; } const entry: SchemaRegistryEntry = { id, schema, category, description: typeof options === "string" ? options : registrationOptions.description, version: registrationOptions.version || version, }; this.schemas.set(id, entry); logger.debug(`Registered schema: ${id} (${category})`); return entry; } /** * Get a schema by ID * * @param id - Schema ID * @returns The schema or undefined if not found */ public getSchema(id: SchemaId): z.ZodType | undefined { const entry = this.schemas.get(id); return entry?.schema; } /** * Get a schema entry by ID * * @param id - Schema ID * @returns The schema entry or undefined if not found */ public getSchemaEntry(id: SchemaId): SchemaRegistryEntry | undefined { return this.schemas.get(id); } /** * Check if a schema exists * * @param id - Schema ID * @returns True if the schema exists */ public hasSchema(id: SchemaId): boolean { return this.schemas.has(id); } /** * Remove a schema from the registry * * @param id - Schema ID * @returns True if the schema was removed */ public removeSchema(id: SchemaId): boolean { return this.schemas.delete(id); } /** * Get all schemas in a category * * @param category - Schema category * @returns Array of schema entries in the category */ public getSchemasByCategory(category: SchemaCategory): SchemaRegistryEntry[] { return Array.from(this.schemas.values()).filter( (entry) => entry.category === category ); } /** * Get all schema IDs * * @returns Array of all schema IDs */ public getAllSchemaIds(): SchemaId[] { return Array.from(this.schemas.keys()); } /** * Validate data against a schema * * @param id - Schema ID * @param data - Data to validate * @returns Parsed data or throws an error */ /** * Validate data against a schema * * @param id - Schema ID * @param data - Data to validate * @returns Parsed data or throws an error * @throws Error if schema not found or validation fails */ public validate<T>(id: SchemaId, data: unknown): T { // Validate schema ID this.validateSchemaId(id); const schema = this.getSchema(id); if (!schema) { throw new Error(`Schema with ID "${id}" not found`); } return schema.parse(data) as T; } /** * Safe validate data against a schema * * @param id - Schema ID * @param data - Data to validate * @returns Result object with success flag and parsed data or error */ /** * Safe validate data against a schema * * @param id - Schema ID * @param data - Data to validate * @returns Result object with success flag and parsed data or error */ public safeValidate<T>( id: SchemaId, data: unknown ): { success: boolean; data?: T; error?: z.ZodError; } { try { // Validate schema ID this.validateSchemaId(id); const schema = this.getSchema(id); if (!schema) { return { success: false, error: new z.ZodError([ { code: z.ZodIssueCode.custom, path: [], message: `Schema with ID "${id}" not found`, input: data, }, ]), }; } const result = schema.safeParse(data); if (result.success) { return { success: true, data: result.data as T }; } else { return { success: false, error: result.error }; } } catch (error) { // Handle schema ID validation errors return { success: false, error: new z.ZodError([ { code: z.ZodIssueCode.custom, path: [], message: error instanceof Error ? error.message : "Unknown schema validation error", input: data, }, ]), }; } } } // Export the singleton instance export const schemaRegistry = SchemaRegistry.getInstance(); // Export default for convenience export default schemaRegistry;

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/glassBead-tc/tinder-mcp-server'

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