UNPKG

ntfy-mcp-server

Version:

An MCP (Model Context Protocol) server designed to interact with the ntfy push notification service. It enables LLMs and AI agents to send notifications to your devices with extensive customization options.

100 lines (99 loc) 3.66 kB
import { ErrorHandler } from "../utils/errorHandler.js"; import { logger } from "../utils/logger.js"; // Create a module-level logger const toolLogger = logger.createChildLogger({ module: 'ToolRegistration' }); /** * Create a tool example * * @param input Example input parameters * @param output Expected output (as a formatted string) * @param description Description of what the example demonstrates * @returns A tool example object */ export function createToolExample(input, output, description) { return { input, output, description }; } /** * Create tool metadata * * @param metadata Tool metadata options * @returns Tool metadata configuration */ export function createToolMetadata(metadata) { return metadata; } /** * Register a tool with the MCP server * * This is a compatibility wrapper for the McpServer.tool() method. * In the current implementation, the tool registration is handled by the McpServer class, * so this function primarily exists to provide a consistent API. * * @param server MCP server instance * @param name Tool name * @param description Tool description * @param inputSchema Schema for validating input * @param handler Handler function for the tool * @param metadata Optional tool metadata */ export function registerTool(server, // Using any to avoid type conflicts name, description, inputSchema, handler, metadata) { return ErrorHandler.tryCatch(async () => { // Log the registration attempt toolLogger.info(`Registering tool: ${name}`, { toolName: name, schemaKeys: Object.keys(inputSchema), hasMetadata: Boolean(metadata), hasExamples: Boolean(metadata?.examples?.length) }); // Some basic validation if (!name) { throw new Error('Tool name is required'); } if (!inputSchema) { throw new Error('Input schema is required'); } if (!handler || typeof handler !== 'function') { throw new Error('Handler must be a function'); } // Convert schema to a more standardized format if needed const schemaDescription = Object.entries(inputSchema).map(([key, schema]) => { const description = schema.description; const isRequired = !schema.isOptional?.(); return `${key}${isRequired ? ' (required)' : ''}: ${description || 'No description'}`; }).join('\n'); toolLogger.debug(`Tool ${name} schema:`, { toolName: name, schema: schemaDescription }); // Actually register the tool with the server // Check if it's an McpServer instance with tool() method if (server.tool && typeof server.tool === 'function') { // Use the McpServer.tool() method directly toolLogger.debug('Using McpServer.tool() method'); server.tool(name, inputSchema, handler, { description, examples: metadata?.examples }); } else { // For other server types or for testing, log a warning toolLogger.warn(`Unable to register tool ${name} with server - missing tool() method`, { toolName: name }); } // Log successful registration toolLogger.info(`Tool ${name} registered successfully`); }, { context: { toolName: name }, operation: "registering tool", errorMapper: (error) => new Error(`Failed to register tool ${name}: ${error instanceof Error ? error.message : String(error)}`), rethrow: true }); }