@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and
162 lines (161 loc) • 5.29 kB
JavaScript
/**
* NeuroLink MCP Server Factory
* Factory-First Architecture: MCP servers create tools for internal orchestration
* Compatible with MCP patterns for seamless integration
*/
import { z } from "zod";
import { validateMCPTool, ValidationError, createValidationSummary, } from "../utils/parameterValidation.js";
/**
* Input validation schemas
*/
const ServerConfigSchema = z.object({
id: z.string().min(1, "Server ID is required"),
title: z.string().min(1, "Server title is required"),
description: z.string().optional(),
version: z.string().optional(),
category: z
.enum([
"aiProviders",
"frameworks",
"development",
"business",
"content",
"data",
"integrations",
"automation",
"analysis",
"custom",
])
.optional(),
visibility: z.enum(["public", "private", "organization"]).optional(),
metadata: z.record(z.unknown()).optional(),
dependencies: z.array(z.string()).optional(),
capabilities: z.array(z.string()).optional(),
});
/**
* Create MCP Server Factory Function
*
* Core factory function for creating MCP servers.
* Follows Factory-First architecture where tools are internal implementation.
*
* @param config Server configuration with minimal required fields
* @returns Fully configured MCP server ready for tool registration
*
* @example
* ```typescript
* const aiCoreServer = createMCPServer({
* id: 'neurolink-ai-core',
* title: 'NeuroLink AI Core',
* description: 'Core AI provider tools',
* category: 'aiProviders'
* });
*
* aiCoreServer.registerTool({
* name: 'generate',
* description: 'Generate text using AI providers',
* execute: async (params, context) => {
* // Tool implementation
* return { success: true, data: result };
* }
* });
* ```
*/
export function createMCPServer(config) {
// Validate configuration
const validatedConfig = ServerConfigSchema.parse(config);
// Create server with sensible defaults
const server = {
// Required fields
id: validatedConfig.id,
title: validatedConfig.title,
// Optional fields with defaults
description: validatedConfig.description,
version: validatedConfig.version || "1.0.0",
category: validatedConfig.category || "custom",
visibility: validatedConfig.visibility || "private",
// Tool management
tools: {},
// Tool registration method
registerTool(tool) {
// Comprehensive tool validation using centralized utilities
const validation = validateMCPTool(tool);
if (!validation.isValid) {
const summary = createValidationSummary(validation);
throw new ValidationError(`Invalid tool '${tool.name}': ${summary}`, "tool", "VALIDATION_FAILED", validation.suggestions);
}
// Check for duplicate tool names
if (this.tools[tool.name]) {
throw new Error(`Tool '${tool.name}' already exists in server '${this.id}'`);
}
// Register the tool
this.tools[tool.name] = {
...tool,
// Add server metadata to tool
metadata: {
...tool.metadata,
serverId: this.id,
serverCategory: this.category,
registeredAt: Date.now(),
},
};
return this;
},
// Extension points
metadata: validatedConfig.metadata || {},
dependencies: validatedConfig.dependencies || [],
capabilities: validatedConfig.capabilities || [],
};
return server;
}
/**
* Utility function to validate tool interface using centralized validation
* Ensures proper async patterns and type safety
*/
export function validateTool(tool) {
try {
const validation = validateMCPTool(tool);
return validation.isValid;
}
catch (error) {
return false;
}
}
/**
* Utility function to get server info
*/
export function getServerInfo(server) {
return {
id: server.id,
title: server.title,
description: server.description,
category: server.category,
toolCount: Object.keys(server.tools).length,
capabilities: server.capabilities || [],
};
}
/**
* Async utility function to validate all tools in a server
* Ensures all registered tools follow proper async patterns
*/
export async function validateServerTools(server) {
const invalidTools = [];
const errors = [];
for (const [toolName, tool] of Object.entries(server.tools)) {
try {
if (!validateTool(tool)) {
invalidTools.push(toolName);
errors.push(`Tool '${toolName}' does not follow proper async patterns`);
}
}
catch (error) {
invalidTools.push(toolName);
errors.push(`Tool '${toolName}' validation failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
return {
isValid: invalidTools.length === 0,
invalidTools,
errors,
};
}
// Types are already exported above via export interface declarations