@juspay/neurolink 1.2.4 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +108 -0
- package/README.md +72 -19
- package/dist/cli/commands/config.d.ts +373 -0
- package/dist/cli/commands/config.js +532 -0
- package/dist/cli/commands/mcp.d.ts +7 -0
- package/dist/cli/commands/mcp.js +434 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +5 -0
- package/dist/mcp/context-manager.d.ts +164 -0
- package/dist/mcp/context-manager.js +273 -0
- package/dist/mcp/factory.d.ts +144 -0
- package/dist/mcp/factory.js +141 -0
- package/dist/mcp/orchestrator.d.ts +170 -0
- package/dist/mcp/orchestrator.js +372 -0
- package/dist/mcp/registry.d.ts +188 -0
- package/dist/mcp/registry.js +373 -0
- package/dist/mcp/servers/ai-providers/ai-core-server.d.ts +10 -0
- package/dist/mcp/servers/ai-providers/ai-core-server.js +280 -0
- package/dist/utils/providerUtils.js +8 -2
- package/package.json +76 -6
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NeuroLink MCP Tool Registry System
|
|
3
|
+
* Central registry for managing MCP servers and tools with execution capabilities
|
|
4
|
+
* Supports tool discovery, registration, and orchestrated execution
|
|
5
|
+
*/
|
|
6
|
+
import type { NeuroLinkMCPServer, NeuroLinkMCPTool, NeuroLinkExecutionContext, ToolResult } from './factory.js';
|
|
7
|
+
import { ContextManager } from './context-manager.js';
|
|
8
|
+
/**
|
|
9
|
+
* Tool registration information
|
|
10
|
+
*/
|
|
11
|
+
export interface ToolRegistration {
|
|
12
|
+
tool: NeuroLinkMCPTool;
|
|
13
|
+
serverId: string;
|
|
14
|
+
serverTitle: string;
|
|
15
|
+
serverCategory?: string;
|
|
16
|
+
qualifiedName: string;
|
|
17
|
+
simpleName: string;
|
|
18
|
+
registeredAt: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Tool execution options
|
|
22
|
+
*/
|
|
23
|
+
export interface ToolExecutionOptions {
|
|
24
|
+
validateInput?: boolean;
|
|
25
|
+
validatePermissions?: boolean;
|
|
26
|
+
trackMetrics?: boolean;
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Tool search criteria
|
|
31
|
+
*/
|
|
32
|
+
export interface ToolSearchCriteria {
|
|
33
|
+
name?: string;
|
|
34
|
+
category?: string;
|
|
35
|
+
serverId?: string;
|
|
36
|
+
serverCategory?: string;
|
|
37
|
+
permissions?: string[];
|
|
38
|
+
implemented?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Registry statistics
|
|
42
|
+
*/
|
|
43
|
+
export interface RegistryStats {
|
|
44
|
+
totalServers: number;
|
|
45
|
+
totalTools: number;
|
|
46
|
+
toolsByCategory: Record<string, number>;
|
|
47
|
+
serversByCategory: Record<string, number>;
|
|
48
|
+
executionCount: number;
|
|
49
|
+
averageExecutionTime: number;
|
|
50
|
+
errorRate: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Central MCP Tool Registry
|
|
54
|
+
* Manages all MCP servers and their tools with advanced execution capabilities
|
|
55
|
+
*/
|
|
56
|
+
export declare class MCPToolRegistry {
|
|
57
|
+
private servers;
|
|
58
|
+
private tools;
|
|
59
|
+
private contextManager;
|
|
60
|
+
private executionCount;
|
|
61
|
+
private totalExecutionTime;
|
|
62
|
+
private errorCount;
|
|
63
|
+
constructor(contextManager?: ContextManager);
|
|
64
|
+
/**
|
|
65
|
+
* Register an MCP server and all its tools
|
|
66
|
+
*
|
|
67
|
+
* @param server MCP server to register
|
|
68
|
+
* @throws Error if server ID already exists
|
|
69
|
+
*/
|
|
70
|
+
registerServer(server: NeuroLinkMCPServer): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Register a single tool from a server
|
|
73
|
+
*
|
|
74
|
+
* @param server Source server
|
|
75
|
+
* @param toolName Tool name
|
|
76
|
+
* @param tool Tool implementation
|
|
77
|
+
*/
|
|
78
|
+
private registerToolFromServer;
|
|
79
|
+
/**
|
|
80
|
+
* Execute a tool with comprehensive error handling and context tracking
|
|
81
|
+
*
|
|
82
|
+
* @param toolName Tool name (simple or qualified)
|
|
83
|
+
* @param params Tool parameters
|
|
84
|
+
* @param context Execution context
|
|
85
|
+
* @param options Execution options
|
|
86
|
+
* @returns Tool execution result
|
|
87
|
+
*/
|
|
88
|
+
executeTool(toolName: string, params: any, context: NeuroLinkExecutionContext, options?: ToolExecutionOptions): Promise<ToolResult>;
|
|
89
|
+
/**
|
|
90
|
+
* List all available tools with optional filtering
|
|
91
|
+
*
|
|
92
|
+
* @param criteria Search criteria for filtering tools
|
|
93
|
+
* @returns Array of tool information
|
|
94
|
+
*/
|
|
95
|
+
listTools(criteria?: ToolSearchCriteria): {
|
|
96
|
+
name: string;
|
|
97
|
+
qualifiedName: string;
|
|
98
|
+
description: string;
|
|
99
|
+
server: string;
|
|
100
|
+
serverTitle: string;
|
|
101
|
+
category?: string;
|
|
102
|
+
serverCategory?: string;
|
|
103
|
+
permissions?: string[];
|
|
104
|
+
isImplemented?: boolean;
|
|
105
|
+
}[];
|
|
106
|
+
/**
|
|
107
|
+
* Get detailed information about a specific tool
|
|
108
|
+
*
|
|
109
|
+
* @param toolName Tool name (simple or qualified)
|
|
110
|
+
* @returns Detailed tool information or undefined if not found
|
|
111
|
+
*/
|
|
112
|
+
getToolInfo(toolName: string): {
|
|
113
|
+
tool: NeuroLinkMCPTool;
|
|
114
|
+
server: NeuroLinkMCPServer;
|
|
115
|
+
registration: ToolRegistration;
|
|
116
|
+
} | undefined;
|
|
117
|
+
/**
|
|
118
|
+
* Get registry statistics
|
|
119
|
+
*
|
|
120
|
+
* @returns Comprehensive registry statistics
|
|
121
|
+
*/
|
|
122
|
+
getStats(): RegistryStats;
|
|
123
|
+
/**
|
|
124
|
+
* Unregister a server and all its tools
|
|
125
|
+
*
|
|
126
|
+
* @param serverId Server ID to unregister
|
|
127
|
+
* @returns Whether server was found and removed
|
|
128
|
+
*/
|
|
129
|
+
unregisterServer(serverId: string): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Clear all servers and tools
|
|
132
|
+
*/
|
|
133
|
+
clear(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Create timeout promise wrapper
|
|
136
|
+
*
|
|
137
|
+
* @param promise Promise to wrap
|
|
138
|
+
* @param timeoutMs Timeout in milliseconds
|
|
139
|
+
* @param timeoutMessage Error message for timeout
|
|
140
|
+
* @returns Promise that rejects on timeout
|
|
141
|
+
*/
|
|
142
|
+
private createTimeoutPromise;
|
|
143
|
+
/**
|
|
144
|
+
* Update execution metrics
|
|
145
|
+
*
|
|
146
|
+
* @param executionTime Execution time in milliseconds
|
|
147
|
+
* @param success Whether execution was successful
|
|
148
|
+
*/
|
|
149
|
+
private updateExecutionMetrics;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Default registry instance
|
|
153
|
+
* Can be used across the application for consistent tool management
|
|
154
|
+
*/
|
|
155
|
+
export declare const defaultToolRegistry: MCPToolRegistry;
|
|
156
|
+
/**
|
|
157
|
+
* Utility function to register server with default registry
|
|
158
|
+
*
|
|
159
|
+
* @param server MCP server to register
|
|
160
|
+
*/
|
|
161
|
+
export declare function registerServer(server: NeuroLinkMCPServer): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Utility function to execute tool with default registry
|
|
164
|
+
*
|
|
165
|
+
* @param toolName Tool name to execute
|
|
166
|
+
* @param params Tool parameters
|
|
167
|
+
* @param context Execution context
|
|
168
|
+
* @param options Execution options
|
|
169
|
+
* @returns Tool execution result
|
|
170
|
+
*/
|
|
171
|
+
export declare function executeTool(toolName: string, params: any, context: NeuroLinkExecutionContext, options?: ToolExecutionOptions): Promise<ToolResult>;
|
|
172
|
+
/**
|
|
173
|
+
* Utility function to list tools with default registry
|
|
174
|
+
*
|
|
175
|
+
* @param criteria Search criteria
|
|
176
|
+
* @returns Array of tool information
|
|
177
|
+
*/
|
|
178
|
+
export declare function listTools(criteria?: ToolSearchCriteria): {
|
|
179
|
+
name: string;
|
|
180
|
+
qualifiedName: string;
|
|
181
|
+
description: string;
|
|
182
|
+
server: string;
|
|
183
|
+
serverTitle: string;
|
|
184
|
+
category?: string;
|
|
185
|
+
serverCategory?: string;
|
|
186
|
+
permissions?: string[];
|
|
187
|
+
isImplemented?: boolean;
|
|
188
|
+
}[];
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NeuroLink MCP Tool Registry System
|
|
3
|
+
* Central registry for managing MCP servers and tools with execution capabilities
|
|
4
|
+
* Supports tool discovery, registration, and orchestrated execution
|
|
5
|
+
*/
|
|
6
|
+
import { ContextManager, ContextValidator } from './context-manager.js';
|
|
7
|
+
/**
|
|
8
|
+
* Central MCP Tool Registry
|
|
9
|
+
* Manages all MCP servers and their tools with advanced execution capabilities
|
|
10
|
+
*/
|
|
11
|
+
export class MCPToolRegistry {
|
|
12
|
+
servers = new Map();
|
|
13
|
+
tools = new Map();
|
|
14
|
+
contextManager;
|
|
15
|
+
// Execution tracking
|
|
16
|
+
executionCount = 0;
|
|
17
|
+
totalExecutionTime = 0;
|
|
18
|
+
errorCount = 0;
|
|
19
|
+
constructor(contextManager) {
|
|
20
|
+
this.contextManager = contextManager || new ContextManager();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register an MCP server and all its tools
|
|
24
|
+
*
|
|
25
|
+
* @param server MCP server to register
|
|
26
|
+
* @throws Error if server ID already exists
|
|
27
|
+
*/
|
|
28
|
+
async registerServer(server) {
|
|
29
|
+
// Check for duplicate server ID
|
|
30
|
+
if (this.servers.has(server.id)) {
|
|
31
|
+
throw new Error(`Server with ID '${server.id}' is already registered`);
|
|
32
|
+
}
|
|
33
|
+
// Register the server
|
|
34
|
+
this.servers.set(server.id, server);
|
|
35
|
+
// Register all tools from the server
|
|
36
|
+
for (const [toolName, tool] of Object.entries(server.tools)) {
|
|
37
|
+
await this.registerToolFromServer(server, toolName, tool);
|
|
38
|
+
}
|
|
39
|
+
console.log(`[MCPRegistry] Registered server '${server.id}' with ${Object.keys(server.tools).length} tools`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register a single tool from a server
|
|
43
|
+
*
|
|
44
|
+
* @param server Source server
|
|
45
|
+
* @param toolName Tool name
|
|
46
|
+
* @param tool Tool implementation
|
|
47
|
+
*/
|
|
48
|
+
async registerToolFromServer(server, toolName, tool) {
|
|
49
|
+
const qualifiedName = `${server.id}.${toolName}`;
|
|
50
|
+
const simpleName = toolName;
|
|
51
|
+
const registration = {
|
|
52
|
+
tool,
|
|
53
|
+
serverId: server.id,
|
|
54
|
+
serverTitle: server.title,
|
|
55
|
+
serverCategory: server.category,
|
|
56
|
+
qualifiedName,
|
|
57
|
+
simpleName,
|
|
58
|
+
registeredAt: Date.now()
|
|
59
|
+
};
|
|
60
|
+
// Register with both qualified and simple names
|
|
61
|
+
this.tools.set(qualifiedName, registration);
|
|
62
|
+
// Only register simple name if it doesn't conflict
|
|
63
|
+
if (!this.tools.has(simpleName)) {
|
|
64
|
+
this.tools.set(simpleName, registration);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.warn(`[MCPRegistry] Tool name conflict: '${simpleName}' already exists, use qualified name '${qualifiedName}'`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Execute a tool with comprehensive error handling and context tracking
|
|
72
|
+
*
|
|
73
|
+
* @param toolName Tool name (simple or qualified)
|
|
74
|
+
* @param params Tool parameters
|
|
75
|
+
* @param context Execution context
|
|
76
|
+
* @param options Execution options
|
|
77
|
+
* @returns Tool execution result
|
|
78
|
+
*/
|
|
79
|
+
async executeTool(toolName, params, context, options = {}) {
|
|
80
|
+
const startTime = Date.now();
|
|
81
|
+
const { validateInput = true, validatePermissions = true, trackMetrics = true, timeoutMs = 30000 } = options;
|
|
82
|
+
try {
|
|
83
|
+
// Find the tool
|
|
84
|
+
const registration = this.tools.get(toolName);
|
|
85
|
+
if (!registration) {
|
|
86
|
+
throw new Error(`Tool not found: ${toolName}`);
|
|
87
|
+
}
|
|
88
|
+
const { tool, serverId, serverTitle } = registration;
|
|
89
|
+
// Validate context
|
|
90
|
+
if (validatePermissions) {
|
|
91
|
+
const contextValidation = ContextValidator.validateContext(context);
|
|
92
|
+
if (!contextValidation.isValid) {
|
|
93
|
+
throw new Error(`Context validation failed: ${contextValidation.errors.join(', ')}`);
|
|
94
|
+
}
|
|
95
|
+
// Check tool permissions
|
|
96
|
+
if (tool.permissions && !ContextValidator.hasPermissions(context, tool.permissions)) {
|
|
97
|
+
throw new Error(`Insufficient permissions for tool '${toolName}'. Required: ${tool.permissions.join(', ')}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Validate input parameters if schema provided
|
|
101
|
+
if (validateInput && tool.inputSchema) {
|
|
102
|
+
try {
|
|
103
|
+
tool.inputSchema.parse(params);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
107
|
+
throw new Error(`Input validation failed for tool '${toolName}': ${errorMessage}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Add tool to execution chain
|
|
111
|
+
this.contextManager.addToToolChain(context, toolName);
|
|
112
|
+
// Execute tool with timeout
|
|
113
|
+
const executeWithTimeout = this.createTimeoutPromise(tool.execute(params, context), timeoutMs, `Tool '${toolName}' execution timeout`);
|
|
114
|
+
const result = await executeWithTimeout;
|
|
115
|
+
// Add execution metadata
|
|
116
|
+
const executionTime = Date.now() - startTime;
|
|
117
|
+
const enhancedResult = {
|
|
118
|
+
...result,
|
|
119
|
+
metadata: {
|
|
120
|
+
...result.metadata,
|
|
121
|
+
toolName,
|
|
122
|
+
serverId,
|
|
123
|
+
serverTitle,
|
|
124
|
+
sessionId: context.sessionId,
|
|
125
|
+
timestamp: Date.now(),
|
|
126
|
+
executionTime
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
// Track metrics
|
|
130
|
+
if (trackMetrics) {
|
|
131
|
+
this.updateExecutionMetrics(executionTime, result.success);
|
|
132
|
+
}
|
|
133
|
+
// Validate output if schema provided
|
|
134
|
+
if (tool.outputSchema && result.success) {
|
|
135
|
+
try {
|
|
136
|
+
tool.outputSchema.parse(result.data);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
140
|
+
console.warn(`[MCPRegistry] Output validation warning for tool '${toolName}': ${errorMessage}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
console.log(`[MCPRegistry] Executed tool '${toolName}' in ${executionTime}ms - ${result.success ? 'SUCCESS' : 'FAILED'}`);
|
|
144
|
+
return enhancedResult;
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
const executionTime = Date.now() - startTime;
|
|
148
|
+
// Track error metrics
|
|
149
|
+
if (trackMetrics) {
|
|
150
|
+
this.updateExecutionMetrics(executionTime, false);
|
|
151
|
+
}
|
|
152
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
153
|
+
const errorResult = {
|
|
154
|
+
success: false,
|
|
155
|
+
error: errorMessage,
|
|
156
|
+
metadata: {
|
|
157
|
+
toolName,
|
|
158
|
+
sessionId: context.sessionId,
|
|
159
|
+
timestamp: Date.now(),
|
|
160
|
+
executionTime
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
console.error(`[MCPRegistry] Tool execution failed '${toolName}': ${errorMessage}`);
|
|
164
|
+
return errorResult;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* List all available tools with optional filtering
|
|
169
|
+
*
|
|
170
|
+
* @param criteria Search criteria for filtering tools
|
|
171
|
+
* @returns Array of tool information
|
|
172
|
+
*/
|
|
173
|
+
listTools(criteria = {}) {
|
|
174
|
+
const tools = [];
|
|
175
|
+
// Get unique tools (prefer qualified names over simple names)
|
|
176
|
+
const uniqueTools = new Map();
|
|
177
|
+
for (const [name, registration] of this.tools) {
|
|
178
|
+
if (name.includes('.')) { // Qualified name
|
|
179
|
+
uniqueTools.set(registration.qualifiedName, registration);
|
|
180
|
+
}
|
|
181
|
+
else if (!uniqueTools.has(registration.qualifiedName)) {
|
|
182
|
+
uniqueTools.set(registration.qualifiedName, registration);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
for (const registration of uniqueTools.values()) {
|
|
186
|
+
const { tool, serverId, serverTitle, serverCategory, qualifiedName, simpleName } = registration;
|
|
187
|
+
// Apply filters
|
|
188
|
+
if (criteria.name && !simpleName.toLowerCase().includes(criteria.name.toLowerCase())) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (criteria.category && tool.category !== criteria.category) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (criteria.serverId && serverId !== criteria.serverId) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (criteria.serverCategory && serverCategory !== criteria.serverCategory) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (criteria.implemented !== undefined && tool.isImplemented !== criteria.implemented) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (criteria.permissions && criteria.permissions.length > 0) {
|
|
204
|
+
const toolPermissions = tool.permissions || [];
|
|
205
|
+
const hasAllPermissions = criteria.permissions.every(p => toolPermissions.includes(p));
|
|
206
|
+
if (!hasAllPermissions) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
tools.push({
|
|
211
|
+
name: simpleName,
|
|
212
|
+
qualifiedName,
|
|
213
|
+
description: tool.description,
|
|
214
|
+
server: serverId,
|
|
215
|
+
serverTitle,
|
|
216
|
+
category: tool.category,
|
|
217
|
+
serverCategory,
|
|
218
|
+
permissions: tool.permissions,
|
|
219
|
+
isImplemented: tool.isImplemented
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return tools.sort((a, b) => a.qualifiedName.localeCompare(b.qualifiedName));
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Get detailed information about a specific tool
|
|
226
|
+
*
|
|
227
|
+
* @param toolName Tool name (simple or qualified)
|
|
228
|
+
* @returns Detailed tool information or undefined if not found
|
|
229
|
+
*/
|
|
230
|
+
getToolInfo(toolName) {
|
|
231
|
+
const registration = this.tools.get(toolName);
|
|
232
|
+
if (!registration) {
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
const server = this.servers.get(registration.serverId);
|
|
236
|
+
if (!server) {
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
tool: registration.tool,
|
|
241
|
+
server,
|
|
242
|
+
registration
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get registry statistics
|
|
247
|
+
*
|
|
248
|
+
* @returns Comprehensive registry statistics
|
|
249
|
+
*/
|
|
250
|
+
getStats() {
|
|
251
|
+
const toolsByCategory = {};
|
|
252
|
+
const serversByCategory = {};
|
|
253
|
+
// Count tools by category
|
|
254
|
+
for (const registration of this.tools.values()) {
|
|
255
|
+
const category = registration.tool.category || 'uncategorized';
|
|
256
|
+
toolsByCategory[category] = (toolsByCategory[category] || 0) + 1;
|
|
257
|
+
}
|
|
258
|
+
// Count servers by category
|
|
259
|
+
for (const server of this.servers.values()) {
|
|
260
|
+
const category = server.category || 'uncategorized';
|
|
261
|
+
serversByCategory[category] = (serversByCategory[category] || 0) + 1;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
totalServers: this.servers.size,
|
|
265
|
+
totalTools: new Set(Array.from(this.tools.values()).map(r => r.qualifiedName)).size,
|
|
266
|
+
toolsByCategory,
|
|
267
|
+
serversByCategory,
|
|
268
|
+
executionCount: this.executionCount,
|
|
269
|
+
averageExecutionTime: this.executionCount > 0 ? this.totalExecutionTime / this.executionCount : 0,
|
|
270
|
+
errorRate: this.executionCount > 0 ? this.errorCount / this.executionCount : 0
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Unregister a server and all its tools
|
|
275
|
+
*
|
|
276
|
+
* @param serverId Server ID to unregister
|
|
277
|
+
* @returns Whether server was found and removed
|
|
278
|
+
*/
|
|
279
|
+
unregisterServer(serverId) {
|
|
280
|
+
const server = this.servers.get(serverId);
|
|
281
|
+
if (!server) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
// Remove all tools from this server
|
|
285
|
+
const toolsToRemove = [];
|
|
286
|
+
for (const [name, registration] of this.tools) {
|
|
287
|
+
if (registration.serverId === serverId) {
|
|
288
|
+
toolsToRemove.push(name);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
for (const toolName of toolsToRemove) {
|
|
292
|
+
this.tools.delete(toolName);
|
|
293
|
+
}
|
|
294
|
+
// Remove the server
|
|
295
|
+
this.servers.delete(serverId);
|
|
296
|
+
console.log(`[MCPRegistry] Unregistered server '${serverId}' and ${toolsToRemove.length} tools`);
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Clear all servers and tools
|
|
301
|
+
*/
|
|
302
|
+
clear() {
|
|
303
|
+
this.servers.clear();
|
|
304
|
+
this.tools.clear();
|
|
305
|
+
this.executionCount = 0;
|
|
306
|
+
this.totalExecutionTime = 0;
|
|
307
|
+
this.errorCount = 0;
|
|
308
|
+
console.log('[MCPRegistry] Cleared all servers and tools');
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Create timeout promise wrapper
|
|
312
|
+
*
|
|
313
|
+
* @param promise Promise to wrap
|
|
314
|
+
* @param timeoutMs Timeout in milliseconds
|
|
315
|
+
* @param timeoutMessage Error message for timeout
|
|
316
|
+
* @returns Promise that rejects on timeout
|
|
317
|
+
*/
|
|
318
|
+
createTimeoutPromise(promise, timeoutMs, timeoutMessage) {
|
|
319
|
+
return Promise.race([
|
|
320
|
+
promise,
|
|
321
|
+
new Promise((_, reject) => {
|
|
322
|
+
setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
323
|
+
})
|
|
324
|
+
]);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Update execution metrics
|
|
328
|
+
*
|
|
329
|
+
* @param executionTime Execution time in milliseconds
|
|
330
|
+
* @param success Whether execution was successful
|
|
331
|
+
*/
|
|
332
|
+
updateExecutionMetrics(executionTime, success) {
|
|
333
|
+
this.executionCount++;
|
|
334
|
+
this.totalExecutionTime += executionTime;
|
|
335
|
+
if (!success) {
|
|
336
|
+
this.errorCount++;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Default registry instance
|
|
342
|
+
* Can be used across the application for consistent tool management
|
|
343
|
+
*/
|
|
344
|
+
export const defaultToolRegistry = new MCPToolRegistry();
|
|
345
|
+
/**
|
|
346
|
+
* Utility function to register server with default registry
|
|
347
|
+
*
|
|
348
|
+
* @param server MCP server to register
|
|
349
|
+
*/
|
|
350
|
+
export async function registerServer(server) {
|
|
351
|
+
return defaultToolRegistry.registerServer(server);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Utility function to execute tool with default registry
|
|
355
|
+
*
|
|
356
|
+
* @param toolName Tool name to execute
|
|
357
|
+
* @param params Tool parameters
|
|
358
|
+
* @param context Execution context
|
|
359
|
+
* @param options Execution options
|
|
360
|
+
* @returns Tool execution result
|
|
361
|
+
*/
|
|
362
|
+
export async function executeTool(toolName, params, context, options) {
|
|
363
|
+
return defaultToolRegistry.executeTool(toolName, params, context, options);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Utility function to list tools with default registry
|
|
367
|
+
*
|
|
368
|
+
* @param criteria Search criteria
|
|
369
|
+
* @returns Array of tool information
|
|
370
|
+
*/
|
|
371
|
+
export function listTools(criteria) {
|
|
372
|
+
return defaultToolRegistry.listTools(criteria);
|
|
373
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NeuroLink AI Core Server
|
|
3
|
+
* Wraps existing AI provider functionality as MCP tools for orchestration
|
|
4
|
+
* Integrates AIProviderFactory with Factory-First MCP architecture
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* AI Core Server - Central hub for AI provider tools
|
|
8
|
+
* Provides text generation, provider selection, and AI capabilities
|
|
9
|
+
*/
|
|
10
|
+
export declare const aiCoreServer: import("../../factory.js").NeuroLinkMCPServer;
|