UNPKG

rnr-mcp-server

Version:

A Model Context Protocol (MCP) server for React Native Reusables components, providing AI assistants with access to component source code, demos, and metadata for React Native development.

138 lines (137 loc) 4.87 kB
import Joi from 'joi'; /** * Validation schemas for different request types */ export const validationSchemas = { // Component-related schemas componentName: Joi.object({ componentName: Joi.string().required().min(1).max(100) .description('Name of the shadcn/ui component') }), // Search schemas searchQuery: Joi.object({ query: Joi.string().required().min(1).max(500) .description('Search query string') }), // Optional query schemas optionalQuery: Joi.object({ query: Joi.string().optional().max(500) .description('Optional query string') }), // Block schemas blockQuery: Joi.object({ query: Joi.string().optional().max(500) .description('Optional search query'), category: Joi.string().optional().max(100) .description('Optional category filter') }), // Directory structure schemas directoryStructure: Joi.object({ path: Joi.string().optional().max(500) .description('Path within the repository'), owner: Joi.string().optional().max(100) .description('Repository owner'), repo: Joi.string().optional().max(100) .description('Repository name'), branch: Joi.string().optional().max(100) .description('Branch name') }), // Block schemas blockRequest: Joi.object({ blockName: Joi.string().required().min(1).max(200) .description('Name of the block'), includeComponents: Joi.boolean().optional() .description('Whether to include component files') }), // Resource schemas resourceRequest: Joi.object({ uri: Joi.string().required().min(1).max(1000) .description('Resource URI') }), // Prompt schemas promptRequest: Joi.object({ name: Joi.string().required().min(1).max(200) .description('Prompt name'), arguments: Joi.object().optional() .description('Prompt arguments') }), // Tool schemas toolRequest: Joi.object({ name: Joi.string().required().min(1).max(200) .description('Tool name'), arguments: Joi.object().optional() .description('Tool arguments') }) }; /** * Validate request parameters against a schema * @param schema Joi schema to validate against * @param params Parameters to validate * @returns Validated parameters * @throws ValidationError if validation fails */ export function validateRequest(schema, params) { try { const { error, value } = schema.validate(params, { abortEarly: false, stripUnknown: true, allowUnknown: false }); if (error) { const errorMessages = error.details.map(detail => `${detail.path.join('.')}: ${detail.message}`).join(', '); throw new Error(`Validation failed: ${errorMessages}`); } return value; } catch (error) { if (error instanceof Error) { throw error; } throw new Error(`Unexpected validation error: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get validation schema for a specific method * @param method Method name * @returns Joi schema or undefined */ export function getValidationSchema(method) { const schemaMap = { // Component methods 'get_component': validationSchemas.componentName, 'get_component_demo': validationSchemas.componentName, 'get_component_metadata': validationSchemas.componentName, 'get_component_details': validationSchemas.componentName, 'get_examples': validationSchemas.componentName, 'get_usage': validationSchemas.componentName, // Search methods 'search_components': validationSchemas.searchQuery, 'get_themes': validationSchemas.optionalQuery, 'get_blocks': validationSchemas.blockQuery, // Directory methods 'get_directory_structure': validationSchemas.directoryStructure, // Block methods 'get_block': validationSchemas.blockRequest, // Resource methods 'read_resource': validationSchemas.resourceRequest, // Prompt methods 'get_prompt': validationSchemas.promptRequest, // Tool methods 'call_tool': validationSchemas.toolRequest }; return schemaMap[method]; } /** * Validate and sanitize input parameters * @param method Method name * @param params Parameters to validate * @returns Validated and sanitized parameters */ export function validateAndSanitizeParams(method, params) { const schema = getValidationSchema(method); if (!schema) { // If no specific schema found, return params as-is return params; } return validateRequest(schema, params); }