@juspay/neurolink 9.27.0 → 9.28.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.
Files changed (119) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +59 -9
  3. package/dist/cli/commands/config.d.ts +4 -4
  4. package/dist/cli/commands/mcp.d.ts +87 -0
  5. package/dist/cli/commands/mcp.js +1524 -0
  6. package/dist/cli/loop/optionsSchema.js +4 -0
  7. package/dist/core/modules/ToolsManager.js +29 -2
  8. package/dist/index.d.ts +2 -1
  9. package/dist/index.js +27 -1
  10. package/dist/lib/core/modules/ToolsManager.js +29 -2
  11. package/dist/lib/index.d.ts +2 -1
  12. package/dist/lib/index.js +27 -1
  13. package/dist/lib/mcp/agentExposure.d.ts +228 -0
  14. package/dist/lib/mcp/agentExposure.js +357 -0
  15. package/dist/lib/mcp/batching/index.d.ts +11 -0
  16. package/dist/lib/mcp/batching/index.js +11 -0
  17. package/dist/lib/mcp/batching/requestBatcher.d.ts +202 -0
  18. package/dist/lib/mcp/batching/requestBatcher.js +442 -0
  19. package/dist/lib/mcp/caching/index.d.ts +11 -0
  20. package/dist/lib/mcp/caching/index.js +11 -0
  21. package/dist/lib/mcp/caching/toolCache.d.ts +221 -0
  22. package/dist/lib/mcp/caching/toolCache.js +434 -0
  23. package/dist/lib/mcp/elicitation/elicitationManager.d.ts +169 -0
  24. package/dist/lib/mcp/elicitation/elicitationManager.js +377 -0
  25. package/dist/lib/mcp/elicitation/index.d.ts +11 -0
  26. package/dist/lib/mcp/elicitation/index.js +12 -0
  27. package/dist/lib/mcp/elicitation/types.d.ts +278 -0
  28. package/dist/lib/mcp/elicitation/types.js +11 -0
  29. package/dist/lib/mcp/elicitationProtocol.d.ts +228 -0
  30. package/dist/lib/mcp/elicitationProtocol.js +376 -0
  31. package/dist/lib/mcp/enhancedToolDiscovery.d.ts +205 -0
  32. package/dist/lib/mcp/enhancedToolDiscovery.js +482 -0
  33. package/dist/lib/mcp/index.d.ts +38 -1
  34. package/dist/lib/mcp/index.js +36 -3
  35. package/dist/lib/mcp/mcpRegistryClient.d.ts +332 -0
  36. package/dist/lib/mcp/mcpRegistryClient.js +489 -0
  37. package/dist/lib/mcp/mcpServerBase.d.ts +227 -0
  38. package/dist/lib/mcp/mcpServerBase.js +374 -0
  39. package/dist/lib/mcp/multiServerManager.d.ts +310 -0
  40. package/dist/lib/mcp/multiServerManager.js +580 -0
  41. package/dist/lib/mcp/routing/index.d.ts +11 -0
  42. package/dist/lib/mcp/routing/index.js +11 -0
  43. package/dist/lib/mcp/routing/toolRouter.d.ts +219 -0
  44. package/dist/lib/mcp/routing/toolRouter.js +417 -0
  45. package/dist/lib/mcp/serverCapabilities.d.ts +341 -0
  46. package/dist/lib/mcp/serverCapabilities.js +503 -0
  47. package/dist/lib/mcp/toolAnnotations.d.ts +154 -0
  48. package/dist/lib/mcp/toolAnnotations.js +240 -0
  49. package/dist/lib/mcp/toolConverter.d.ts +178 -0
  50. package/dist/lib/mcp/toolConverter.js +259 -0
  51. package/dist/lib/mcp/toolIntegration.d.ts +136 -0
  52. package/dist/lib/mcp/toolIntegration.js +335 -0
  53. package/dist/lib/neurolink.d.ts +275 -2
  54. package/dist/lib/neurolink.js +596 -56
  55. package/dist/lib/providers/litellm.d.ts +10 -0
  56. package/dist/lib/providers/litellm.js +104 -2
  57. package/dist/lib/types/configTypes.d.ts +56 -0
  58. package/dist/lib/types/generateTypes.d.ts +4 -0
  59. package/dist/lib/types/index.d.ts +1 -1
  60. package/dist/lib/types/modelTypes.d.ts +6 -6
  61. package/dist/lib/types/streamTypes.d.ts +2 -0
  62. package/dist/lib/types/tools.d.ts +2 -0
  63. package/dist/lib/utils/pricing.js +177 -17
  64. package/dist/lib/utils/schemaConversion.d.ts +6 -1
  65. package/dist/lib/utils/schemaConversion.js +50 -28
  66. package/dist/lib/workflow/config.d.ts +16 -16
  67. package/dist/mcp/agentExposure.d.ts +228 -0
  68. package/dist/mcp/agentExposure.js +356 -0
  69. package/dist/mcp/batching/index.d.ts +11 -0
  70. package/dist/mcp/batching/index.js +10 -0
  71. package/dist/mcp/batching/requestBatcher.d.ts +202 -0
  72. package/dist/mcp/batching/requestBatcher.js +441 -0
  73. package/dist/mcp/caching/index.d.ts +11 -0
  74. package/dist/mcp/caching/index.js +10 -0
  75. package/dist/mcp/caching/toolCache.d.ts +221 -0
  76. package/dist/mcp/caching/toolCache.js +433 -0
  77. package/dist/mcp/elicitation/elicitationManager.d.ts +169 -0
  78. package/dist/mcp/elicitation/elicitationManager.js +376 -0
  79. package/dist/mcp/elicitation/index.d.ts +11 -0
  80. package/dist/mcp/elicitation/index.js +11 -0
  81. package/dist/mcp/elicitation/types.d.ts +278 -0
  82. package/dist/mcp/elicitation/types.js +10 -0
  83. package/dist/mcp/elicitationProtocol.d.ts +228 -0
  84. package/dist/mcp/elicitationProtocol.js +375 -0
  85. package/dist/mcp/enhancedToolDiscovery.d.ts +205 -0
  86. package/dist/mcp/enhancedToolDiscovery.js +481 -0
  87. package/dist/mcp/index.d.ts +38 -1
  88. package/dist/mcp/index.js +36 -3
  89. package/dist/mcp/mcpRegistryClient.d.ts +332 -0
  90. package/dist/mcp/mcpRegistryClient.js +488 -0
  91. package/dist/mcp/mcpServerBase.d.ts +227 -0
  92. package/dist/mcp/mcpServerBase.js +373 -0
  93. package/dist/mcp/multiServerManager.d.ts +310 -0
  94. package/dist/mcp/multiServerManager.js +579 -0
  95. package/dist/mcp/routing/index.d.ts +11 -0
  96. package/dist/mcp/routing/index.js +10 -0
  97. package/dist/mcp/routing/toolRouter.d.ts +219 -0
  98. package/dist/mcp/routing/toolRouter.js +416 -0
  99. package/dist/mcp/serverCapabilities.d.ts +341 -0
  100. package/dist/mcp/serverCapabilities.js +502 -0
  101. package/dist/mcp/toolAnnotations.d.ts +154 -0
  102. package/dist/mcp/toolAnnotations.js +239 -0
  103. package/dist/mcp/toolConverter.d.ts +178 -0
  104. package/dist/mcp/toolConverter.js +258 -0
  105. package/dist/mcp/toolIntegration.d.ts +136 -0
  106. package/dist/mcp/toolIntegration.js +334 -0
  107. package/dist/neurolink.d.ts +275 -2
  108. package/dist/neurolink.js +596 -56
  109. package/dist/providers/litellm.d.ts +10 -0
  110. package/dist/providers/litellm.js +104 -2
  111. package/dist/types/configTypes.d.ts +56 -0
  112. package/dist/types/generateTypes.d.ts +4 -0
  113. package/dist/types/index.d.ts +1 -1
  114. package/dist/types/streamTypes.d.ts +2 -0
  115. package/dist/types/tools.d.ts +2 -0
  116. package/dist/utils/pricing.js +177 -17
  117. package/dist/utils/schemaConversion.d.ts +6 -1
  118. package/dist/utils/schemaConversion.js +50 -28
  119. package/package.json +1 -1
@@ -0,0 +1,488 @@
1
+ /**
2
+ * MCP Registry Client
3
+ *
4
+ * Client for discovering MCP servers from centralized registries.
5
+ * Supports multiple registry sources including:
6
+ * - Official MCP Registry
7
+ * - NPM packages
8
+ * - GitHub repositories
9
+ * - Custom registries
10
+ *
11
+ * @module mcp/mcpRegistryClient
12
+ * @since 8.39.0
13
+ */
14
+ import { EventEmitter } from "events";
15
+ /**
16
+ * Well-known MCP servers catalog
17
+ */
18
+ const WELL_KNOWN_SERVERS = [
19
+ {
20
+ id: "filesystem",
21
+ name: "Filesystem",
22
+ description: "File system operations - read, write, create, list directories",
23
+ version: "1.0.0",
24
+ npmPackage: "@modelcontextprotocol/server-filesystem",
25
+ command: "npx",
26
+ args: ["-y", "@modelcontextprotocol/server-filesystem"],
27
+ transports: ["stdio"],
28
+ categories: ["file-system"],
29
+ tags: ["files", "directories", "read", "write"],
30
+ tools: ["read_file", "write_file", "list_directory", "create_directory"],
31
+ verified: true,
32
+ },
33
+ {
34
+ id: "github",
35
+ name: "GitHub",
36
+ description: "GitHub repository management and file operations",
37
+ version: "1.0.0",
38
+ npmPackage: "@modelcontextprotocol/server-github",
39
+ command: "npx",
40
+ args: ["-y", "@modelcontextprotocol/server-github"],
41
+ requiredEnvVars: ["GITHUB_PERSONAL_ACCESS_TOKEN"],
42
+ transports: ["stdio"],
43
+ categories: ["version-control", "api"],
44
+ tags: ["github", "git", "repositories", "issues", "pull-requests"],
45
+ tools: [
46
+ "create_repository",
47
+ "list_commits",
48
+ "create_issue",
49
+ "create_pull_request",
50
+ ],
51
+ verified: true,
52
+ },
53
+ {
54
+ id: "postgres",
55
+ name: "PostgreSQL",
56
+ description: "PostgreSQL database query and management",
57
+ version: "1.0.0",
58
+ npmPackage: "@modelcontextprotocol/server-postgres",
59
+ command: "npx",
60
+ args: ["-y", "@modelcontextprotocol/server-postgres"],
61
+ requiredEnvVars: ["DATABASE_URL"],
62
+ transports: ["stdio"],
63
+ categories: ["database"],
64
+ tags: ["postgres", "postgresql", "sql", "database", "query"],
65
+ tools: ["query", "list_tables", "describe_table"],
66
+ verified: true,
67
+ },
68
+ {
69
+ id: "sqlite",
70
+ name: "SQLite",
71
+ description: "SQLite database operations and queries",
72
+ version: "1.0.0",
73
+ npmPackage: "@modelcontextprotocol/server-sqlite",
74
+ command: "npx",
75
+ args: ["-y", "@modelcontextprotocol/server-sqlite"],
76
+ transports: ["stdio"],
77
+ categories: ["database"],
78
+ tags: ["sqlite", "sql", "database", "local"],
79
+ tools: ["query", "list_tables", "describe_table"],
80
+ verified: true,
81
+ },
82
+ {
83
+ id: "brave-search",
84
+ name: "Brave Search",
85
+ description: "Web search using Brave Search API",
86
+ version: "1.0.0",
87
+ npmPackage: "@modelcontextprotocol/server-brave-search",
88
+ command: "npx",
89
+ args: ["-y", "@modelcontextprotocol/server-brave-search"],
90
+ requiredEnvVars: ["BRAVE_API_KEY"],
91
+ transports: ["stdio"],
92
+ categories: ["search", "api"],
93
+ tags: ["search", "web", "brave", "internet"],
94
+ tools: ["web_search", "local_search"],
95
+ verified: true,
96
+ },
97
+ {
98
+ id: "puppeteer",
99
+ name: "Puppeteer",
100
+ description: "Web scraping and browser automation",
101
+ version: "1.0.0",
102
+ npmPackage: "@modelcontextprotocol/server-puppeteer",
103
+ command: "npx",
104
+ args: ["-y", "@modelcontextprotocol/server-puppeteer"],
105
+ transports: ["stdio"],
106
+ categories: ["automation", "web"],
107
+ tags: ["browser", "scraping", "automation", "puppeteer"],
108
+ tools: ["navigate", "screenshot", "click", "type", "get_content"],
109
+ verified: true,
110
+ },
111
+ {
112
+ id: "git",
113
+ name: "Git",
114
+ description: "Git repository operations and version control",
115
+ version: "1.0.0",
116
+ npmPackage: "@modelcontextprotocol/server-git",
117
+ command: "npx",
118
+ args: ["-y", "@modelcontextprotocol/server-git"],
119
+ transports: ["stdio"],
120
+ categories: ["version-control"],
121
+ tags: ["git", "vcs", "commits", "branches"],
122
+ tools: ["git_status", "git_log", "git_diff", "git_commit"],
123
+ verified: true,
124
+ },
125
+ {
126
+ id: "memory",
127
+ name: "Memory",
128
+ description: "Persistent memory and knowledge storage",
129
+ version: "1.0.0",
130
+ npmPackage: "@modelcontextprotocol/server-memory",
131
+ command: "npx",
132
+ args: ["-y", "@modelcontextprotocol/server-memory"],
133
+ transports: ["stdio"],
134
+ categories: ["memory", "storage"],
135
+ tags: ["memory", "knowledge", "storage", "persistent"],
136
+ tools: ["store", "retrieve", "search", "delete"],
137
+ verified: true,
138
+ },
139
+ {
140
+ id: "slack",
141
+ name: "Slack",
142
+ description: "Slack workspace integration",
143
+ version: "1.0.0",
144
+ npmPackage: "@modelcontextprotocol/server-slack",
145
+ command: "npx",
146
+ args: ["-y", "@modelcontextprotocol/server-slack"],
147
+ requiredEnvVars: ["SLACK_BOT_TOKEN"],
148
+ transports: ["stdio"],
149
+ categories: ["communication", "api"],
150
+ tags: ["slack", "messaging", "chat", "team"],
151
+ tools: ["send_message", "list_channels", "get_channel_history"],
152
+ verified: true,
153
+ },
154
+ {
155
+ id: "google-drive",
156
+ name: "Google Drive",
157
+ description: "Google Drive file management",
158
+ version: "1.0.0",
159
+ npmPackage: "@modelcontextprotocol/server-gdrive",
160
+ command: "npx",
161
+ args: ["-y", "@modelcontextprotocol/server-gdrive"],
162
+ transports: ["stdio"],
163
+ categories: ["file-system", "api"],
164
+ tags: ["google", "drive", "files", "cloud"],
165
+ tools: ["list_files", "read_file", "create_file", "search_files"],
166
+ verified: true,
167
+ },
168
+ ];
169
+ /**
170
+ * MCP Registry Client
171
+ *
172
+ * Provides methods to discover and install MCP servers from registries.
173
+ *
174
+ * @example
175
+ * ```typescript
176
+ * const client = new MCPRegistryClient();
177
+ *
178
+ * // Search for servers
179
+ * const results = await client.search({ query: "database" });
180
+ *
181
+ * // Get server details
182
+ * const entry = await client.getEntry("postgres");
183
+ *
184
+ * // Convert to MCPServerInfo
185
+ * const serverInfo = client.toServerInfo(entry);
186
+ * ```
187
+ */
188
+ export class MCPRegistryClient extends EventEmitter {
189
+ config;
190
+ cache = new Map();
191
+ customEntries = new Map();
192
+ constructor(config = {}) {
193
+ super();
194
+ this.config = {
195
+ registries: config.registries ?? [
196
+ { type: "official", enableCache: true },
197
+ ],
198
+ enableCache: config.enableCache ?? true,
199
+ defaultCacheTTL: config.defaultCacheTTL ?? 3600000, // 1 hour
200
+ timeout: config.timeout ?? 10000,
201
+ userAgent: config.userAgent ?? "NeuroLink-MCP-Registry-Client/1.0",
202
+ };
203
+ }
204
+ /**
205
+ * Search the registry
206
+ */
207
+ async search(options = {}) {
208
+ const { query, categories, tags, transport, verifiedOnly = false, sortBy = "downloads", sortDirection = "desc", limit: rawLimit = 25, offset: rawOffset = 0, } = options;
209
+ const limit = Math.max(1, rawLimit);
210
+ const offset = Math.max(0, rawOffset);
211
+ // Get all entries (from cache or fetch)
212
+ let entries = await this.getAllEntries();
213
+ // Apply filters
214
+ if (query) {
215
+ const searchLower = query.toLowerCase();
216
+ entries = entries.filter((e) => e.name.toLowerCase().includes(searchLower) ||
217
+ e.description.toLowerCase().includes(searchLower) ||
218
+ e.tags?.some((t) => t.toLowerCase().includes(searchLower)));
219
+ }
220
+ if (categories?.length) {
221
+ entries = entries.filter((e) => e.categories?.some((c) => categories.includes(c)));
222
+ }
223
+ if (tags?.length) {
224
+ entries = entries.filter((e) => e.tags?.some((t) => tags.includes(t)));
225
+ }
226
+ if (transport) {
227
+ entries = entries.filter((e) => e.transports?.includes(transport));
228
+ }
229
+ if (verifiedOnly) {
230
+ entries = entries.filter((e) => e.verified);
231
+ }
232
+ // Sort
233
+ entries.sort((a, b) => {
234
+ let comparison = 0;
235
+ switch (sortBy) {
236
+ case "name":
237
+ comparison = a.name.localeCompare(b.name);
238
+ break;
239
+ case "downloads":
240
+ comparison = (a.downloads ?? 0) - (b.downloads ?? 0);
241
+ break;
242
+ case "stars":
243
+ comparison = (a.stars ?? 0) - (b.stars ?? 0);
244
+ break;
245
+ case "lastUpdated":
246
+ comparison = (a.lastUpdated ?? "").localeCompare(b.lastUpdated ?? "");
247
+ break;
248
+ }
249
+ return sortDirection === "desc" ? -comparison : comparison;
250
+ });
251
+ const totalCount = entries.length;
252
+ // Apply pagination
253
+ entries = entries.slice(offset, offset + limit);
254
+ return {
255
+ entries,
256
+ totalCount,
257
+ page: Math.floor(offset / limit) + 1,
258
+ pageSize: limit,
259
+ hasMore: offset + entries.length < totalCount,
260
+ };
261
+ }
262
+ /**
263
+ * Get a specific entry by ID
264
+ */
265
+ async getEntry(id) {
266
+ // Check custom entries first
267
+ if (this.customEntries.has(id)) {
268
+ return this.customEntries.get(id);
269
+ }
270
+ // Check well-known servers
271
+ const wellKnown = WELL_KNOWN_SERVERS.find((s) => s.id === id);
272
+ if (wellKnown) {
273
+ return wellKnown;
274
+ }
275
+ // TODO: Fetch from remote registry
276
+ return undefined;
277
+ }
278
+ /**
279
+ * Get all available entries
280
+ */
281
+ async getAllEntries() {
282
+ const cacheKey = "all-entries";
283
+ // Check cache
284
+ if (this.config.enableCache) {
285
+ const cached = this.cache.get(cacheKey);
286
+ if (cached &&
287
+ Date.now() - cached.timestamp < this.config.defaultCacheTTL) {
288
+ return cached.data;
289
+ }
290
+ }
291
+ // Combine well-known servers and custom entries, deduplicating by ID.
292
+ // Custom entries take precedence over well-known servers.
293
+ const customIds = new Set(this.customEntries.keys());
294
+ const allEntries = [
295
+ ...WELL_KNOWN_SERVERS.filter((entry) => !customIds.has(entry.id)),
296
+ ...Array.from(this.customEntries.values()),
297
+ ];
298
+ // Cache the result
299
+ if (this.config.enableCache) {
300
+ this.cache.set(cacheKey, { data: allEntries, timestamp: Date.now() });
301
+ }
302
+ return allEntries;
303
+ }
304
+ /**
305
+ * Get entries by category
306
+ */
307
+ async getByCategory(category) {
308
+ const entries = await this.getAllEntries();
309
+ return entries.filter((e) => e.categories?.includes(category));
310
+ }
311
+ /**
312
+ * Get entries by tag
313
+ */
314
+ async getByTag(tag) {
315
+ const entries = await this.getAllEntries();
316
+ return entries.filter((e) => e.tags?.includes(tag));
317
+ }
318
+ /**
319
+ * Get all categories
320
+ */
321
+ async getCategories() {
322
+ const entries = await this.getAllEntries();
323
+ const categories = new Set();
324
+ for (const entry of entries) {
325
+ for (const category of entry.categories ?? []) {
326
+ categories.add(category);
327
+ }
328
+ }
329
+ return Array.from(categories).sort();
330
+ }
331
+ /**
332
+ * Get all tags
333
+ */
334
+ async getTags() {
335
+ const entries = await this.getAllEntries();
336
+ const tags = new Set();
337
+ for (const entry of entries) {
338
+ for (const tag of entry.tags ?? []) {
339
+ tags.add(tag);
340
+ }
341
+ }
342
+ return Array.from(tags).sort();
343
+ }
344
+ /**
345
+ * Convert registry entry to MCPServerInfo
346
+ */
347
+ toServerInfo(entry) {
348
+ return {
349
+ id: entry.id,
350
+ name: entry.name,
351
+ description: entry.description,
352
+ command: entry.command,
353
+ args: entry.args,
354
+ transport: entry.transports?.[0] ?? "stdio",
355
+ status: "stopped",
356
+ tools: entry.tools?.map((name) => ({
357
+ name,
358
+ description: `Tool: ${name}`,
359
+ })) ?? [],
360
+ metadata: {
361
+ ...entry.metadata,
362
+ version: entry.version,
363
+ author: entry.author,
364
+ license: entry.license,
365
+ homepage: entry.homepage,
366
+ repository: entry.repository,
367
+ npmPackage: entry.npmPackage,
368
+ requiredEnvVars: entry.requiredEnvVars,
369
+ categories: entry.categories,
370
+ tags: entry.tags,
371
+ verified: entry.verified,
372
+ },
373
+ };
374
+ }
375
+ /**
376
+ * Add a custom registry entry
377
+ */
378
+ addCustomEntry(entry) {
379
+ this.customEntries.set(entry.id, entry);
380
+ this.clearCache();
381
+ this.emit("entryAdded", { entry });
382
+ }
383
+ /**
384
+ * Remove a custom registry entry
385
+ */
386
+ removeCustomEntry(id) {
387
+ const removed = this.customEntries.delete(id);
388
+ if (removed) {
389
+ this.clearCache();
390
+ this.emit("entryRemoved", { id });
391
+ }
392
+ return removed;
393
+ }
394
+ /**
395
+ * Add a registry configuration
396
+ */
397
+ addRegistry(config) {
398
+ this.config.registries.push(config);
399
+ this.clearCache();
400
+ const { authToken: _, ...safeConfig } = config;
401
+ this.emit("registryAdded", { config: safeConfig });
402
+ }
403
+ /**
404
+ * Clear the cache
405
+ */
406
+ clearCache() {
407
+ this.cache.clear();
408
+ this.emit("cacheCleared");
409
+ }
410
+ /**
411
+ * Check if required environment variables are set
412
+ */
413
+ checkRequiredEnvVars(entry) {
414
+ const missing = [];
415
+ for (const envVar of entry.requiredEnvVars ?? []) {
416
+ if (!process.env[envVar]) {
417
+ missing.push(envVar);
418
+ }
419
+ }
420
+ return {
421
+ ready: missing.length === 0,
422
+ missing,
423
+ };
424
+ }
425
+ /**
426
+ * Get installation command for an entry
427
+ */
428
+ getInstallCommand(entry) {
429
+ if (entry.installCommand) {
430
+ return entry.installCommand;
431
+ }
432
+ if (entry.npmPackage) {
433
+ return `npx -y ${entry.npmPackage}`;
434
+ }
435
+ return undefined;
436
+ }
437
+ /**
438
+ * Get popular servers
439
+ */
440
+ async getPopularServers(limit = 10) {
441
+ const result = await this.search({
442
+ sortBy: "downloads",
443
+ sortDirection: "desc",
444
+ limit,
445
+ });
446
+ return result.entries;
447
+ }
448
+ /**
449
+ * Get verified servers
450
+ */
451
+ async getVerifiedServers() {
452
+ const result = await this.search({
453
+ verifiedOnly: true,
454
+ });
455
+ return result.entries;
456
+ }
457
+ /**
458
+ * Get statistics
459
+ */
460
+ async getStatistics() {
461
+ const entries = await this.getAllEntries();
462
+ const categories = await this.getCategories();
463
+ const tags = await this.getTags();
464
+ return {
465
+ totalEntries: entries.length,
466
+ verifiedEntries: entries.filter((e) => e.verified).length,
467
+ categories: categories.length,
468
+ tags: tags.length,
469
+ customEntries: this.customEntries.size,
470
+ };
471
+ }
472
+ }
473
+ /**
474
+ * Global MCP registry client instance
475
+ */
476
+ export const globalMCPRegistryClient = new MCPRegistryClient();
477
+ /**
478
+ * Quick lookup function for well-known servers
479
+ */
480
+ export function getWellKnownServer(id) {
481
+ return WELL_KNOWN_SERVERS.find((s) => s.id === id);
482
+ }
483
+ /**
484
+ * Get all well-known servers
485
+ */
486
+ export function getAllWellKnownServers() {
487
+ return [...WELL_KNOWN_SERVERS];
488
+ }
@@ -0,0 +1,227 @@
1
+ /**
2
+ * MCP Server Base Class
3
+ *
4
+ * Abstract base class for creating custom MCP servers with consistent patterns
5
+ * for tool registration, execution, and lifecycle management.
6
+ *
7
+ * Implements Mastra-style MCPServerBase features including:
8
+ * - Tool annotation support (readOnlyHint, destructiveHint, idempotentHint)
9
+ * - Lifecycle hooks (onInit, onStart, onStop)
10
+ * - Event emission for tool operations
11
+ * - Conversion to MCPServerInfo format
12
+ *
13
+ * @module mcp/mcpServerBase
14
+ * @since 8.39.0
15
+ */
16
+ import { EventEmitter } from "events";
17
+ import type { JsonValue } from "../types/common.js";
18
+ import type { MCPServerInfo, MCPTransportType, MCPServerCategory, NeuroLinkExecutionContext, ToolResult } from "../types/mcpTypes.js";
19
+ import type { MCPToolAnnotations, MCPServerTool } from "./toolAnnotations.js";
20
+ /**
21
+ * MCPServerBase configuration
22
+ */
23
+ export type MCPServerBaseConfig = {
24
+ /**
25
+ * Unique server identifier
26
+ */
27
+ id: string;
28
+ /**
29
+ * Human-readable server name
30
+ */
31
+ name: string;
32
+ /**
33
+ * Server description
34
+ */
35
+ description?: string;
36
+ /**
37
+ * Server version
38
+ */
39
+ version?: string;
40
+ /**
41
+ * Server category for organization
42
+ */
43
+ category?: MCPServerCategory;
44
+ /**
45
+ * Transport protocol preference
46
+ */
47
+ transport?: MCPTransportType;
48
+ /**
49
+ * Custom metadata
50
+ */
51
+ metadata?: Record<string, JsonValue>;
52
+ /**
53
+ * Default timeout for tool execution in milliseconds (default: 30000)
54
+ */
55
+ defaultTimeoutMs?: number;
56
+ /**
57
+ * Global tool annotations applied to all tools
58
+ */
59
+ defaultAnnotations?: MCPToolAnnotations;
60
+ };
61
+ /**
62
+ * Server lifecycle events
63
+ */
64
+ export type MCPServerEvents = {
65
+ toolRegistered: {
66
+ toolName: string;
67
+ tool: MCPServerTool;
68
+ };
69
+ toolExecuted: {
70
+ toolName: string;
71
+ duration: number;
72
+ success: boolean;
73
+ };
74
+ toolError: {
75
+ toolName: string;
76
+ error: Error;
77
+ };
78
+ serverReady: {
79
+ tools: string[];
80
+ };
81
+ serverStopped: {
82
+ reason?: string;
83
+ };
84
+ };
85
+ /**
86
+ * Abstract base class for MCP servers
87
+ *
88
+ * Provides a foundation for creating custom MCP servers with consistent
89
+ * patterns for tool registration, execution, and lifecycle management.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * class MyCustomServer extends MCPServerBase {
94
+ * constructor() {
95
+ * super({
96
+ * id: "my-custom-server",
97
+ * name: "My Custom Server",
98
+ * description: "Provides custom functionality",
99
+ * category: "custom",
100
+ * });
101
+ *
102
+ * // Register tools in constructor or init
103
+ * this.registerTool({
104
+ * name: "myTool",
105
+ * description: "Does something useful",
106
+ * annotations: {
107
+ * readOnlyHint: true,
108
+ * idempotentHint: true,
109
+ * },
110
+ * execute: async (params, context) => {
111
+ * return { success: true, data: "result" };
112
+ * },
113
+ * });
114
+ * }
115
+ * }
116
+ * ```
117
+ */
118
+ export declare abstract class MCPServerBase extends EventEmitter {
119
+ protected readonly config: Required<MCPServerBaseConfig>;
120
+ protected readonly tools: Map<string, MCPServerTool>;
121
+ protected isInitialized: boolean;
122
+ protected isRunning: boolean;
123
+ constructor(config: MCPServerBaseConfig);
124
+ /**
125
+ * Initialize the server
126
+ * Override in subclasses for async initialization
127
+ */
128
+ init(): Promise<void>;
129
+ /**
130
+ * Hook for subclass initialization
131
+ * Override to perform async setup
132
+ */
133
+ protected onInit(): Promise<void>;
134
+ /**
135
+ * Start the server
136
+ */
137
+ start(): Promise<void>;
138
+ /**
139
+ * Hook for subclass start logic
140
+ */
141
+ protected onStart(): Promise<void>;
142
+ /**
143
+ * Stop the server
144
+ */
145
+ stop(reason?: string): Promise<void>;
146
+ /**
147
+ * Hook for subclass stop logic
148
+ */
149
+ protected onStop(): Promise<void>;
150
+ /**
151
+ * Register a tool with the server
152
+ */
153
+ registerTool(tool: MCPServerTool): this;
154
+ /**
155
+ * Register multiple tools at once
156
+ */
157
+ registerTools(tools: MCPServerTool[]): this;
158
+ /**
159
+ * Validate tool configuration
160
+ */
161
+ protected validateTool(tool: MCPServerTool): void;
162
+ /**
163
+ * Execute a tool by name
164
+ */
165
+ executeTool(toolName: string, params: unknown, context?: NeuroLinkExecutionContext): Promise<ToolResult>;
166
+ /**
167
+ * Type guard to check if result is a ToolResult
168
+ */
169
+ private isToolResult;
170
+ /**
171
+ * Get all registered tools
172
+ */
173
+ getTools(): MCPServerTool[];
174
+ /**
175
+ * Get a specific tool by name
176
+ */
177
+ getTool(name: string): MCPServerTool | undefined;
178
+ /**
179
+ * Check if a tool exists
180
+ */
181
+ hasTool(name: string): boolean;
182
+ /**
183
+ * Remove a tool
184
+ */
185
+ removeTool(name: string): boolean;
186
+ /**
187
+ * Get server info in MCPServerInfo format
188
+ */
189
+ toServerInfo(): MCPServerInfo;
190
+ /**
191
+ * Get tools filtered by annotations
192
+ */
193
+ getToolsByAnnotation(annotation: keyof MCPToolAnnotations, value: boolean | string | number | string[]): MCPServerTool[];
194
+ /**
195
+ * Get read-only tools
196
+ */
197
+ getReadOnlyTools(): MCPServerTool[];
198
+ /**
199
+ * Get destructive tools
200
+ */
201
+ getDestructiveTools(): MCPServerTool[];
202
+ /**
203
+ * Get idempotent tools
204
+ */
205
+ getIdempotentTools(): MCPServerTool[];
206
+ /**
207
+ * Get tools that require confirmation
208
+ */
209
+ getToolsRequiringConfirmation(): MCPServerTool[];
210
+ /**
211
+ * Server identification
212
+ */
213
+ get id(): string;
214
+ get name(): string;
215
+ get description(): string;
216
+ get version(): string;
217
+ get category(): MCPServerCategory;
218
+ /**
219
+ * Check if server is initialized
220
+ */
221
+ get initialized(): boolean;
222
+ /**
223
+ * Check if server is running
224
+ */
225
+ get running(): boolean;
226
+ }
227
+ export type { MCPToolAnnotations, MCPServerTool } from "./toolAnnotations.js";