UNPKG

@mseep/mcp-codex-keeper

Version:

An intelligent MCP server that serves as a guardian of development knowledge, providing AI assistants with curated access to latest documentation and best practices

124 lines 3.76 kB
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'; import { InvalidDocUrlError, } from '../types/index.js'; /** * Validates if a value is a valid DocCategory * @param category - Value to check * @returns Type guard for DocCategory */ export function isValidCategory(category) { return (typeof category === 'string' && [ 'Languages', 'Frameworks', 'Libraries', 'Tools', 'APIs', 'Guides', 'Reference', 'Standards', 'Other', ].includes(category)); } /** * Validates a URL string * @param url - URL to validate * @throws {InvalidDocUrlError} If URL is invalid */ function validateUrl(url) { try { new URL(url); } catch { throw new InvalidDocUrlError(url); } } /** * Validates tags array * @param tags - Array of tags to validate * @returns Cleaned and validated tags array */ function validateTags(tags) { if (!Array.isArray(tags)) { return []; } return tags .filter((tag) => typeof tag === 'string') .map(tag => tag.trim()) .filter(tag => tag.length > 0); } /** * Validates version string * @param version - Version to validate * @returns Cleaned version string or undefined */ function validateVersion(version) { if (typeof version !== 'string') { return undefined; } const cleaned = version.trim(); return cleaned.length > 0 ? cleaned : undefined; } /** * Validates arguments for adding documentation * @param args - Arguments to validate * @throws {McpError} If validation fails * @returns Validated AddDocArgs */ export function validateAddDocArgs(args) { // Check required fields if (typeof args.name !== 'string' || typeof args.url !== 'string' || !isValidCategory(args.category)) { throw new McpError(ErrorCode.InvalidParams, 'Invalid parameters: name (string), url (string), and category (valid category) are required'); } // Validate URL format validateUrl(args.url); // Validate description if (args.description !== undefined && typeof args.description !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Description must be a string if provided'); } return { name: args.name.trim(), url: args.url.trim(), description: args.description?.trim() || '', category: args.category, tags: validateTags(args.tags), version: validateVersion(args.version), }; } /** * Validates arguments for updating documentation * @param args - Arguments to validate * @throws {McpError} If validation fails * @returns Validated UpdateDocArgs */ export function validateUpdateDocArgs(args) { if (typeof args.name !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Invalid parameters: name (string) is required'); } return { name: args.name.trim(), force: args.force === true, }; } /** * Validates arguments for searching documentation * @param args - Arguments to validate * @throws {McpError} If validation fails * @returns Validated SearchDocArgs */ export function validateSearchDocArgs(args) { if (typeof args.query !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Invalid parameters: query (string) is required'); } const category = args.category; if (category !== undefined && !isValidCategory(category)) { throw new McpError(ErrorCode.InvalidParams, 'Invalid category'); } return { query: args.query.trim(), category: category, tag: typeof args.tag === 'string' ? args.tag.trim() : undefined, }; } //# sourceMappingURL=index.js.map