@juspay/neurolink 7.12.0 → 7.14.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 (65) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +90 -25
  3. package/dist/config/conversationMemoryConfig.js +2 -1
  4. package/dist/context/ContextManager.d.ts +28 -0
  5. package/dist/context/ContextManager.js +113 -0
  6. package/dist/context/config.d.ts +5 -0
  7. package/dist/context/config.js +42 -0
  8. package/dist/context/types.d.ts +20 -0
  9. package/dist/context/types.js +1 -0
  10. package/dist/context/utils.d.ts +7 -0
  11. package/dist/context/utils.js +8 -0
  12. package/dist/core/baseProvider.d.ts +16 -1
  13. package/dist/core/baseProvider.js +208 -9
  14. package/dist/core/conversationMemoryManager.js +3 -2
  15. package/dist/core/factory.js +13 -2
  16. package/dist/factories/providerFactory.js +5 -11
  17. package/dist/factories/providerRegistry.js +2 -2
  18. package/dist/lib/config/conversationMemoryConfig.js +2 -1
  19. package/dist/lib/context/ContextManager.d.ts +28 -0
  20. package/dist/lib/context/ContextManager.js +113 -0
  21. package/dist/lib/context/config.d.ts +5 -0
  22. package/dist/lib/context/config.js +42 -0
  23. package/dist/lib/context/types.d.ts +20 -0
  24. package/dist/lib/context/types.js +1 -0
  25. package/dist/lib/context/utils.d.ts +7 -0
  26. package/dist/lib/context/utils.js +8 -0
  27. package/dist/lib/core/baseProvider.d.ts +16 -1
  28. package/dist/lib/core/baseProvider.js +208 -9
  29. package/dist/lib/core/conversationMemoryManager.js +3 -2
  30. package/dist/lib/core/factory.js +13 -2
  31. package/dist/lib/factories/providerFactory.js +5 -11
  32. package/dist/lib/factories/providerRegistry.js +2 -2
  33. package/dist/lib/mcp/externalServerManager.d.ts +115 -0
  34. package/dist/lib/mcp/externalServerManager.js +677 -0
  35. package/dist/lib/mcp/mcpCircuitBreaker.d.ts +184 -0
  36. package/dist/lib/mcp/mcpCircuitBreaker.js +338 -0
  37. package/dist/lib/mcp/mcpClientFactory.d.ts +104 -0
  38. package/dist/lib/mcp/mcpClientFactory.js +416 -0
  39. package/dist/lib/mcp/toolDiscoveryService.d.ts +192 -0
  40. package/dist/lib/mcp/toolDiscoveryService.js +578 -0
  41. package/dist/lib/neurolink.d.ts +128 -16
  42. package/dist/lib/neurolink.js +555 -49
  43. package/dist/lib/providers/googleVertex.d.ts +1 -1
  44. package/dist/lib/providers/googleVertex.js +23 -7
  45. package/dist/lib/types/externalMcp.d.ts +282 -0
  46. package/dist/lib/types/externalMcp.js +6 -0
  47. package/dist/lib/types/generateTypes.d.ts +0 -1
  48. package/dist/lib/types/index.d.ts +1 -0
  49. package/dist/mcp/externalServerManager.d.ts +115 -0
  50. package/dist/mcp/externalServerManager.js +677 -0
  51. package/dist/mcp/mcpCircuitBreaker.d.ts +184 -0
  52. package/dist/mcp/mcpCircuitBreaker.js +338 -0
  53. package/dist/mcp/mcpClientFactory.d.ts +104 -0
  54. package/dist/mcp/mcpClientFactory.js +416 -0
  55. package/dist/mcp/toolDiscoveryService.d.ts +192 -0
  56. package/dist/mcp/toolDiscoveryService.js +578 -0
  57. package/dist/neurolink.d.ts +128 -16
  58. package/dist/neurolink.js +555 -49
  59. package/dist/providers/googleVertex.d.ts +1 -1
  60. package/dist/providers/googleVertex.js +23 -7
  61. package/dist/types/externalMcp.d.ts +282 -0
  62. package/dist/types/externalMcp.js +6 -0
  63. package/dist/types/generateTypes.d.ts +0 -1
  64. package/dist/types/index.d.ts +1 -0
  65. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [7.14.0](https://github.com/juspay/neurolink/compare/v7.13.0...v7.14.0) (2025-08-14)
2
+
3
+ ### Features
4
+
5
+ - **(external-mcp):** add external MCP server integration support ([c03dee8](https://github.com/juspay/neurolink/commit/c03dee8dd7a2e06e78bc743d7b3a5cff858395de))
6
+
7
+ ## [7.13.0](https://github.com/juspay/neurolink/compare/v7.12.0...v7.13.0) (2025-08-14)
8
+
9
+ ### Features
10
+
11
+ - **(SDK):** Add context summarizer for conversation BZ-43204 ([38231c4](https://github.com/juspay/neurolink/commit/38231c475b7546c16db741010173794251a7dbaa))
12
+
1
13
  ## [7.12.0](https://github.com/juspay/neurolink/compare/v7.11.1...v7.12.0) (2025-08-14)
2
14
 
3
15
  ### Features
package/README.md CHANGED
@@ -69,7 +69,7 @@ npx @juspay/neurolink sagemaker benchmark my-endpoint # Performance testing
69
69
  - **🛡️ Error Recovery** - Graceful failures with provider fallback and retry logic
70
70
  - **📊 Analytics & Evaluation** - Built-in usage tracking and AI-powered quality assessment
71
71
  - **🎯 Real-time Event Monitoring** - EventEmitter integration for progress tracking and debugging
72
- - **🔧 MCP Integration** - Model Context Protocol with 6 built-in tools and 58+ discoverable servers
72
+ - **🔧 External MCP Integration** - Model Context Protocol with 6 built-in tools + full external MCP server support
73
73
  - **🚀 Lighthouse Integration** - Unified tool registration API supporting both object and array formats for seamless Lighthouse tool import
74
74
 
75
75
  ---
@@ -118,6 +118,28 @@ npx @juspay/neurolink status # Check all providers
118
118
  ```bash
119
119
  # SDK Installation for using in your typescript projects
120
120
  npm install @juspay/neurolink
121
+
122
+ # 🆕 NEW: External MCP Server Integration Quick Test
123
+ node -e "
124
+ const { NeuroLink } = require('@juspay/neurolink');
125
+ (async () => {
126
+ const neurolink = new NeuroLink();
127
+
128
+ // Add external filesystem MCP server
129
+ await neurolink.addExternalMCPServer('filesystem', {
130
+ command: 'npx',
131
+ args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
132
+ transport: 'stdio'
133
+ });
134
+
135
+ // External tools automatically available in generate()
136
+ const result = await neurolink.generate({
137
+ input: { text: 'List files in the current directory' }
138
+ });
139
+ console.log('🎉 External MCP integration working!');
140
+ console.log(result.content);
141
+ })();
142
+ "
121
143
  ```
122
144
 
123
145
  ### Basic Usage
@@ -327,40 +349,56 @@ console.log(productData.name, productData.price, productData.features);
327
349
  - ⚡ **Automatic Fallback** - Never fail when providers are down, intelligent provider switching
328
350
  - 🖥️ **CLI + SDK** - Use from command line or integrate programmatically with TypeScript support
329
351
  - 🛡️ **Production Ready** - Enterprise-grade error handling, performance optimization, extracted from production
330
- - ✅ **MCP Integration** - Model Context Protocol with working built-in tools and 58+ discoverable external servers
352
+ - ✅ **External MCP Integration** - Model Context Protocol with built-in tools + full external MCP server support
331
353
  - 🔍 **Smart Model Resolution** - Fuzzy matching, aliases, and capability-based search across all providers
332
354
  - 🏠 **Local AI Support** - Run completely offline with Ollama or through LiteLLM proxy
333
355
  - 🌍 **Universal Model Access** - Direct providers + 100,000+ models via Hugging Face + 100+ models via LiteLLM
356
+ - 🧠 **Automatic Context Summarization** - Stateful, long-running conversations with automatic history summarization.
334
357
  - 📊 **Analytics & Evaluation** - Built-in usage tracking and AI-powered quality assessment
335
358
 
336
- ## 🛠️ MCP Integration Status ✅ **BUILT-IN TOOLS WORKING**
359
+ ## 🛠️ External MCP Integration Status ✅ **PRODUCTION READY**
337
360
 
338
- | Component | Status | Description |
339
- | ------------------- | ------------------ | -------------------------------------------------------- |
340
- | Built-in Tools | ✅ **Working** | 6 core tools fully functional across all providers |
341
- | SDK Custom Tools | ✅ **Working** | Register custom tools programmatically |
342
- | External Discovery | 🔍 **Discovery** | 58+ MCP servers discovered from AI tools ecosystem |
343
- | Tool Execution | ✅ **Working** | Real-time AI tool calling with built-in tools |
344
- | **External Tools** | 🚧 **Development** | Manual config needs one-line fix, activation in progress |
345
- | **CLI Integration** | ✅ **READY** | **Production-ready with built-in tools** |
346
- | External Activation | 🔧 **Development** | Discovery complete, activation protocol in progress |
361
+ | Component | Status | Description |
362
+ | ---------------------- | -------------- | ---------------------------------------------------------------- |
363
+ | Built-in Tools | ✅ **Working** | 6 core tools fully functional across all providers |
364
+ | SDK Custom Tools | ✅ **Working** | Register custom tools programmatically |
365
+ | **External MCP Tools** | **Working** | **Full external MCP server support with dynamic tool discovery** |
366
+ | Tool Execution | ✅ **Working** | Real-time AI tool calling with all tool types |
367
+ | **Streaming Support** | **Working** | **External MCP tools work with streaming generation** |
368
+ | **Multi-Provider** | ✅ **Working** | **External tools work across all AI providers** |
369
+ | **CLI Integration** | **READY** | **Production-ready with external MCP support** |
347
370
 
348
- ### ✅ Quick MCP Test (v1.7.1)
371
+ ### ✅ External MCP Integration Demo
349
372
 
350
373
  ```bash
351
374
  # Test built-in tools (works immediately)
352
375
  npx @juspay/neurolink generate "What time is it?" --debug
353
376
 
354
- # Disable tools for pure text generation
355
- npx @juspay/neurolink generate "Write a poem" --disable-tools
377
+ # 🆕 NEW: External MCP server integration (SDK)
378
+ import { NeuroLink } from '@juspay/neurolink';
379
+
380
+ const neurolink = new NeuroLink();
381
+
382
+ // Add external MCP server (e.g., Bitbucket)
383
+ await neurolink.addExternalMCPServer('bitbucket', {
384
+ command: 'npx',
385
+ args: ['-y', '@nexus2520/bitbucket-mcp-server'],
386
+ transport: 'stdio',
387
+ env: {
388
+ BITBUCKET_USERNAME: process.env.BITBUCKET_USERNAME,
389
+ BITBUCKET_TOKEN: process.env.BITBUCKET_TOKEN,
390
+ BITBUCKET_BASE_URL: 'https://bitbucket.example.com'
391
+ }
392
+ });
393
+
394
+ // Use external MCP tools in generation
395
+ const result = await neurolink.generate({
396
+ input: { text: 'Get pull request #123 details from the main repository' },
397
+ disableTools: false // External MCP tools automatically available
398
+ });
356
399
 
357
400
  # Discover available MCP servers
358
401
  npx @juspay/neurolink mcp discover --format table
359
-
360
- # Install popular MCP servers (NEW: Bitbucket support added!)
361
- npx @juspay/neurolink mcp install filesystem
362
- npx @juspay/neurolink mcp install github
363
- npx @juspay/neurolink mcp install bitbucket # 🆕 NEW
364
402
  ```
365
403
 
366
404
  ### 🔧 SDK Custom Tool Registration (NEW!)
@@ -662,16 +700,43 @@ npx @juspay/neurolink generate "Hello!" --provider openai-compatible
662
700
  - **Extensibility**: Connect external tools and services via MCP protocol
663
701
  - **🆕 Dynamic Server Management**: Programmatically add MCP servers at runtime
664
702
 
665
- ### 🔧 Programmatic MCP Server Management [Coming Soon]
703
+ ### 🔧 External MCP Server Management **AVAILABLE NOW**
666
704
 
667
- **Note**: External MCP server activation is in development. Currently available:
705
+ **External MCP integration is now production-ready:**
668
706
 
669
707
  - ✅ 6 built-in tools working across all providers
670
708
  - ✅ SDK custom tool registration
671
- - 🔍 MCP server discovery (58+ servers found)
672
- - 🚧 External server activation (one-line fix pending)
709
+ - **External MCP server management** (add, remove, list, test servers)
710
+ - **Dynamic tool discovery** (automatic tool registration from external servers)
711
+ - ✅ **Multi-provider support** (external tools work with all AI providers)
712
+ - ✅ **Streaming integration** (external tools work with real-time streaming)
713
+ - ✅ **Enhanced tool tracking** (proper parameter extraction and execution logging)
673
714
 
674
- Manual MCP configuration (`.mcp-config.json`) support coming soon.
715
+ ```typescript
716
+ // Complete external MCP server API
717
+ const neurolink = new NeuroLink();
718
+
719
+ // Server management
720
+ await neurolink.addExternalMCPServer(serverId, config);
721
+ await neurolink.removeExternalMCPServer(serverId);
722
+ const servers = neurolink.listExternalMCPServers();
723
+ const server = neurolink.getExternalMCPServer(serverId);
724
+
725
+ // Tool management
726
+ const tools = neurolink.getExternalMCPTools();
727
+ const serverTools = neurolink.getExternalMCPServerTools(serverId);
728
+
729
+ // Direct tool execution
730
+ const result = await neurolink.executeExternalMCPTool(
731
+ serverId,
732
+ toolName,
733
+ params,
734
+ );
735
+
736
+ // Statistics and monitoring
737
+ const stats = neurolink.getExternalMCPStatistics();
738
+ await neurolink.shutdownExternalMCPServers();
739
+ ```
675
740
 
676
741
  ## 🤝 Contributing
677
742
 
@@ -34,6 +34,7 @@ export function getConversationMemoryDefaults() {
34
34
  return {
35
35
  enabled: process.env.NEUROLINK_MEMORY_ENABLED === "true",
36
36
  maxSessions: Number(process.env.NEUROLINK_MEMORY_MAX_SESSIONS) || DEFAULT_MAX_SESSIONS,
37
- maxTurnsPerSession: Number(process.env.NEUROLINK_MEMORY_MAX_TURNS_PER_SESSION) || DEFAULT_MAX_TURNS_PER_SESSION,
37
+ maxTurnsPerSession: Number(process.env.NEUROLINK_MEMORY_MAX_TURNS_PER_SESSION) ||
38
+ DEFAULT_MAX_TURNS_PER_SESSION,
38
39
  };
39
40
  }
@@ -0,0 +1,28 @@
1
+ import type { TextGenerationOptions, TextGenerationResult } from "../core/types.js";
2
+ import type { ContextManagerConfig } from "./types.js";
3
+ type InternalGenerator = (options: TextGenerationOptions) => Promise<TextGenerationResult>;
4
+ /**
5
+ * Manages conversation context, automatically summarizing it when it
6
+ * exceeds a specified word count limit.
7
+ */
8
+ export declare class ContextManager {
9
+ private static readonly SUMMARIZATION_FAILED_WARNING;
10
+ private static readonly SUMMARIZATION_EMPTY_WARNING;
11
+ private history;
12
+ private wordCount;
13
+ private readonly internalGenerator;
14
+ private readonly config;
15
+ constructor(generatorFunction: InternalGenerator, config: ContextManagerConfig, initialContext?: string);
16
+ addTurn(role: "user" | "assistant", message: string): Promise<void>;
17
+ /**
18
+ * Formats the history including the latest user turn for the prompt, without modifying the permanent history.
19
+ */
20
+ getContextForPrompt(role: "user", message: string): string;
21
+ getCurrentContext(): string;
22
+ private _summarize;
23
+ /**
24
+ * Truncates the history to a specific word count, preserving the most recent messages.
25
+ */
26
+ private _truncateHistory;
27
+ }
28
+ export {};
@@ -0,0 +1,113 @@
1
+ import { logger } from "../utils/logger.js";
2
+ import { formatHistoryToString } from "./utils.js";
3
+ /**
4
+ * Manages conversation context, automatically summarizing it when it
5
+ * exceeds a specified word count limit.
6
+ */
7
+ export class ContextManager {
8
+ static SUMMARIZATION_FAILED_WARNING = "[System Warning: Context summarization failed. Conversation history has been truncated.]";
9
+ static SUMMARIZATION_EMPTY_WARNING = "[System Warning: Context summarization failed to return valid content. Conversation history has been truncated.]";
10
+ history;
11
+ wordCount;
12
+ internalGenerator;
13
+ config;
14
+ constructor(generatorFunction, config, initialContext = "This is the start of the conversation.") {
15
+ this.internalGenerator = generatorFunction;
16
+ this.config = config;
17
+ const initialMessage = {
18
+ role: "system",
19
+ content: initialContext,
20
+ };
21
+ initialMessage.wordCount = this.config.estimateWordCount([initialMessage]);
22
+ this.history = [initialMessage];
23
+ this.wordCount = initialMessage.wordCount;
24
+ }
25
+ async addTurn(role, message) {
26
+ const newMessage = { role, content: message };
27
+ newMessage.wordCount = this.config.estimateWordCount([newMessage]);
28
+ this.history.push(newMessage);
29
+ this.wordCount += newMessage.wordCount;
30
+ logger.info(`[ContextManager] Current word count: ${this.wordCount} / ${this.config.highWaterMarkWords}`);
31
+ if (this.wordCount > this.config.highWaterMarkWords) {
32
+ await this._summarize();
33
+ }
34
+ }
35
+ /**
36
+ * Formats the history including the latest user turn for the prompt, without modifying the permanent history.
37
+ */
38
+ getContextForPrompt(role, message) {
39
+ const tempHistory = [...this.history, { role, content: message }];
40
+ return formatHistoryToString(tempHistory);
41
+ }
42
+ getCurrentContext() {
43
+ // Format the history into a single string for the provider prompt
44
+ return formatHistoryToString(this.history);
45
+ }
46
+ async _summarize() {
47
+ try {
48
+ const prompt = this.config.getSummarizationPrompt(this.history, this.config.lowWaterMarkWords);
49
+ // Construct options for the internal method, bypassing the main 'generate' entry point
50
+ const textOptions = {
51
+ prompt,
52
+ provider: this.config.summarizationProvider,
53
+ model: this.config.summarizationModel,
54
+ // Ensure summarization does not trigger more context management or tools
55
+ disableTools: true,
56
+ };
57
+ // Call the internal generation function directly to avoid recursion
58
+ const result = await this.internalGenerator(textOptions);
59
+ if (typeof result.content === "string" && result.content.length > 0) {
60
+ // Replace the history with a single system message containing the summary
61
+ const newHistory = [
62
+ { role: "system", content: result.content },
63
+ ];
64
+ this.history = newHistory;
65
+ this.wordCount = this.config.estimateWordCount(this.history);
66
+ logger.info(`[ContextManager] Summarization complete. New history length: ${this.wordCount} words.`);
67
+ }
68
+ else {
69
+ logger.warn("[ContextManager] Summarization returned empty or non-string content; truncating history as a fallback.");
70
+ this._truncateHistory(this.config.lowWaterMarkWords);
71
+ this.history.unshift({
72
+ role: "system",
73
+ content: ContextManager.SUMMARIZATION_EMPTY_WARNING,
74
+ });
75
+ this.wordCount = this.config.estimateWordCount(this.history);
76
+ }
77
+ logger.debug(`[ContextManager] New history: ${JSON.stringify(this.history)}`);
78
+ }
79
+ catch (error) {
80
+ logger.error("Context summarization failed:", { error });
81
+ // Fallback strategy: truncate the history to the target word count.
82
+ this._truncateHistory(this.config.lowWaterMarkWords);
83
+ this.history.unshift({
84
+ role: "system",
85
+ content: ContextManager.SUMMARIZATION_FAILED_WARNING,
86
+ });
87
+ this.wordCount = this.config.estimateWordCount(this.history);
88
+ }
89
+ }
90
+ /**
91
+ * Truncates the history to a specific word count, preserving the most recent messages.
92
+ */
93
+ _truncateHistory(wordLimit) {
94
+ if (this.wordCount <= wordLimit) {
95
+ return;
96
+ }
97
+ let runningCount = 0;
98
+ let sliceIndex = this.history.length;
99
+ for (let i = this.history.length - 1; i >= 0; i--) {
100
+ let wordCount = this.history[i].wordCount;
101
+ if (wordCount === undefined) {
102
+ logger.warn(`[ContextManager] Word count cache missing for message at index ${i}. Recalculating.`);
103
+ wordCount = this.config.estimateWordCount([this.history[i]]);
104
+ }
105
+ runningCount += wordCount;
106
+ if (runningCount > wordLimit) {
107
+ sliceIndex = i + 1;
108
+ break;
109
+ }
110
+ }
111
+ this.history = this.history.slice(sliceIndex);
112
+ }
113
+ }
@@ -0,0 +1,5 @@
1
+ import type { ContextManagerConfig } from "./types.js";
2
+ /**
3
+ * Default configuration for the ContextManager.
4
+ */
5
+ export declare const defaultContextConfig: ContextManagerConfig;
@@ -0,0 +1,42 @@
1
+ import { formatHistoryToString } from "./utils.js";
2
+ /**
3
+ * Estimates the word count of a conversation history.
4
+ */
5
+ function estimateWordCount(history) {
6
+ if (!history || history.length === 0) {
7
+ return 0;
8
+ }
9
+ return history.reduce((acc, msg) => acc +
10
+ (msg.content
11
+ .trim()
12
+ .split(/\s+/)
13
+ .filter((word) => word.length > 0).length || 0), 0);
14
+ }
15
+ /**
16
+ * Generates the default prompt for summarization.
17
+ */
18
+ function getDefaultSummarizationPrompt(history, wordLimit) {
19
+ const formattedHistory = formatHistoryToString(history);
20
+ return `
21
+ You are a context summarization AI. Your task is to condense the following conversation history for another AI assistant.
22
+ The summary must be a concise, third-person narrative that retains all critical information. Pay special attention to retaining key entities, technical details, decisions made, and any specific dates or times mentioned.
23
+ Ensure the summary flows logically and is ready to be used as context for the next turn in the conversation.
24
+ Please keep the summary under ${wordLimit} words.
25
+
26
+ Conversation History to Summarize:
27
+ ---
28
+ ${formattedHistory}
29
+ ---
30
+ `.trim();
31
+ }
32
+ /**
33
+ * Default configuration for the ContextManager.
34
+ */
35
+ export const defaultContextConfig = {
36
+ highWaterMarkWords: 3000,
37
+ lowWaterMarkWords: 800,
38
+ summarizationModel: "gemini-2.5-flash",
39
+ summarizationProvider: "googlevertex",
40
+ getSummarizationPrompt: getDefaultSummarizationPrompt,
41
+ estimateWordCount: estimateWordCount,
42
+ };
@@ -0,0 +1,20 @@
1
+ export interface ChatMessage {
2
+ /** Role of the message sender */
3
+ role: "user" | "assistant" | "system";
4
+ /** Content of the message */
5
+ content: string;
6
+ /** Cached word count for performance */
7
+ wordCount?: number;
8
+ }
9
+ /**
10
+ * Defines the configuration for the ContextManager.
11
+ * This allows for easy customization of the summarization behavior.
12
+ */
13
+ export interface ContextManagerConfig {
14
+ highWaterMarkWords: number;
15
+ lowWaterMarkWords: number;
16
+ summarizationModel: string;
17
+ summarizationProvider: string;
18
+ getSummarizationPrompt: (history: ChatMessage[], wordLimit: number) => string;
19
+ estimateWordCount: (history: ChatMessage[]) => number;
20
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { ChatMessage } from "./types.js";
2
+ /**
3
+ * Formats a chat history array into a single string for use in a prompt.
4
+ * @param history The array of ChatMessage objects.
5
+ * @returns A formatted string representing the conversation.
6
+ */
7
+ export declare function formatHistoryToString(history: ChatMessage[]): string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Formats a chat history array into a single string for use in a prompt.
3
+ * @param history The array of ChatMessage objects.
4
+ * @returns A formatted string representing the conversation.
5
+ */
6
+ export function formatHistoryToString(history) {
7
+ return history.map((msg) => `${msg.role}: ${msg.content}`).join("\n\n");
8
+ }
@@ -6,7 +6,7 @@ import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
6
6
  import type { JsonValue, UnknownRecord } from "../types/common.js";
7
7
  import type { ToolResult } from "../types/tools.js";
8
8
  /**
9
- * Interface for SDK with in-memory MCP servers
9
+ * Interface for SDK with in-memory MCP servers and external MCP support
10
10
  */
11
11
  export interface NeuroLinkSDK {
12
12
  getInMemoryServers?: () => Map<string, {
@@ -18,6 +18,16 @@ export interface NeuroLinkSDK {
18
18
  category?: string;
19
19
  metadata?: UnknownRecord;
20
20
  }>;
21
+ externalServerManager?: {
22
+ getAllTools: () => Array<{
23
+ name: string;
24
+ description: string;
25
+ serverId: string;
26
+ isAvailable: boolean;
27
+ inputSchema?: Record<string, unknown>;
28
+ }>;
29
+ executeTool: (serverId: string, toolName: string, params: any) => Promise<any>;
30
+ };
21
31
  }
22
32
  /**
23
33
  * Interface for tool information in MCP servers
@@ -86,6 +96,11 @@ export declare abstract class BaseProvider implements AIProvider {
86
96
  * MCP tools are added when available (without blocking)
87
97
  */
88
98
  protected getAllTools(): Promise<Record<string, Tool>>;
99
+ /**
100
+ * Convert MCP JSON Schema to Zod schema for AI SDK tools
101
+ * Handles common MCP schema patterns safely
102
+ */
103
+ private convertMCPSchemaToZod;
89
104
  /**
90
105
  * Set session context for MCP tools
91
106
  */