Skip to main content
Glama

mcp-github-project-manager

ToolValidator.ts3.43 kB
import { z } from "zod"; import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"; import { MCPResponseFormatter } from "../mcp/MCPResponseFormatter.js"; import { MCPErrorCode } from "../../domain/mcp-types.js"; import { ParameterCoercion } from "./ParameterCoercion.js"; export type ToolSchema<T> = z.ZodType<T>; export interface ToolDefinition<T> { name: string; description: string; schema: ToolSchema<T>; examples?: Array<{ name: string; description: string; args: T; }>; } export class ToolValidator { /** * Validate tool arguments against the schema */ static validate<T>(toolName: string, args: unknown, schema: ToolSchema<T>): T { try { // Apply parameter coercion before validation const coercedArgs = ParameterCoercion.coerceParameters(args as Record<string, any>, schema); return schema.parse(coercedArgs); } catch (error) { if (error instanceof z.ZodError) { // Format Zod validation errors const details = error.errors.map(err => ({ path: err.path.join('.'), message: err.message, code: err.code })); throw new McpError( ErrorCode.InvalidParams, `Invalid parameters for tool ${toolName}: ${error.errors.map(e => e.message).join(", ")}`, { details } ); } // Generic validation error throw new McpError( ErrorCode.InvalidParams, `Invalid parameters for tool ${toolName}`, { cause: String(error) } ); } } /** * Transform MCP SDK errors to our custom error format */ static handleToolError(error: unknown, toolName: string): ReturnType<typeof MCPResponseFormatter.error> { // Use stderr to avoid interfering with MCP protocol on stdout process.stderr.write(`[${toolName}] Error: ${error}\n`); // Handle MCP SDK errors if (error instanceof McpError) { return MCPResponseFormatter.error( this.mapErrorCode(error.code), error.message, // Safely handle potentially unknown error.data error.data && typeof error.data === 'object' ? error.data as Record<string, unknown> : undefined ); } // Handle regular errors if (error instanceof Error) { return MCPResponseFormatter.error( MCPErrorCode.INTERNAL_ERROR, `Error executing tool ${toolName}: ${error.message}`, { stack: error.stack } ); } // Handle unknown errors return MCPResponseFormatter.error( MCPErrorCode.INTERNAL_ERROR, `Unknown error executing tool ${toolName}`, { error: String(error) } ); } /** * Map MCP SDK error codes to our custom error codes */ private static mapErrorCode(mcpErrorCode: ErrorCode): MCPErrorCode { switch (mcpErrorCode) { case ErrorCode.InvalidParams: return MCPErrorCode.VALIDATION_ERROR; case ErrorCode.MethodNotFound: return MCPErrorCode.RESOURCE_NOT_FOUND; case ErrorCode.InternalError: return MCPErrorCode.INTERNAL_ERROR; // Replace non-existent enum values with valid ones case ErrorCode.InvalidRequest: // Instead of Unauthorized return MCPErrorCode.UNAUTHORIZED; case ErrorCode.ParseError: // Instead of RateLimited return MCPErrorCode.RATE_LIMITED; default: return MCPErrorCode.INTERNAL_ERROR; } } }

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/kunwarVivek/mcp-github-project-manager'

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