@@ -6,7 +6,6 @@ import type { StructuredToolInterface, ToolInterface } from '@langchain/core/too
66import type { AgentFinish , AgentStep } from 'langchain/agents'
77import type { MCPClient } from '../client.js'
88import type { BaseConnector } from '../connectors/base.js'
9- import type { ServerManager } from '../managers/server_manager.js'
109import type { MCPSession } from '../session.js'
1110import {
1211 AIMessage ,
@@ -24,6 +23,7 @@ import {
2423} from 'langchain/agents'
2524import { LangChainAdapter } from '../adapters/langchain_adapter.js'
2625import { logger } from '../logging.js'
26+ import { ServerManager } from '../managers/server_manager.js'
2727import { createSystemMessage } from './prompts/system_prompt_builder.js'
2828import { DEFAULT_SYSTEM_PROMPT_TEMPLATE , SERVER_MANAGER_SYSTEM_PROMPT_TEMPLATE } from './prompts/templates.js'
2929
@@ -35,6 +35,7 @@ export class MCPAgent {
3535 private autoInitialize : boolean
3636 private memoryEnabled : boolean
3737 private disallowedTools : string [ ]
38+ private additionalTools : StructuredToolInterface [ ]
3839 private useServerManager : boolean
3940 private verbose : boolean
4041 private systemPrompt ?: string | null
@@ -61,10 +62,10 @@ export class MCPAgent {
6162 systemPromptTemplate ?: string | null
6263 additionalInstructions ?: string | null
6364 disallowedTools ?: string [ ]
65+ additionalTools ?: StructuredToolInterface [ ]
6466 useServerManager ?: boolean
6567 verbose ?: boolean
6668 adapter ?: LangChainAdapter
67- serverManagerFactory ?: ( client : MCPClient ) => ServerManager
6869 } ) {
6970 this . llm = options . llm
7071
@@ -77,6 +78,7 @@ export class MCPAgent {
7778 this . systemPromptTemplateOverride = options . systemPromptTemplate ?? null
7879 this . additionalInstructions = options . additionalInstructions ?? null
7980 this . disallowedTools = options . disallowedTools ?? [ ]
81+ this . additionalTools = options . additionalTools ?? [ ]
8082 this . useServerManager = options . useServerManager ?? false
8183 this . verbose = options . verbose ?? false
8284
@@ -88,15 +90,13 @@ export class MCPAgent {
8890 if ( ! this . client ) {
8991 throw new Error ( '\'client\' must be provided when \'useServerManager\' is true.' )
9092 }
91- if ( options . serverManagerFactory ) {
92- this . serverManager = options . serverManagerFactory ( this . client )
93- }
94- else {
95- throw new Error ( 'No serverManagerFactory passed to MCPAgent constructor.' )
96- }
93+ this . adapter = options . adapter ?? new LangChainAdapter ( this . disallowedTools )
94+ this . serverManager = new ServerManager ( this . client , this . adapter )
9795 }
9896 // Let consumers swap allowed tools dynamically
99- this . adapter = options . adapter ?? new LangChainAdapter ( this . disallowedTools )
97+ else {
98+ this . adapter = options . adapter ?? new LangChainAdapter ( this . disallowedTools )
99+ }
100100 }
101101
102102 public async initialize ( ) : Promise < void > {
@@ -109,6 +109,7 @@ export class MCPAgent {
109109 // Get server management tools
110110 const managementTools = this . serverManager . tools
111111 this . tools = managementTools
112+ this . tools . push ( ...this . additionalTools )
112113 logger . info (
113114 `🔧 Server manager mode active with ${ managementTools . length } management tools` ,
114115 )
@@ -132,6 +133,7 @@ export class MCPAgent {
132133
133134 // Create LangChain tools directly from the client using the adapter
134135 this . tools = await LangChainAdapter . createTools ( this . client )
136+ this . tools . push ( ...this . additionalTools )
135137 logger . info ( `🛠️ Created ${ this . tools . length } LangChain tools from client` )
136138 }
137139 else {
@@ -145,6 +147,7 @@ export class MCPAgent {
145147
146148 // Create LangChain tools using the adapter with connectors
147149 this . tools = await this . adapter . createToolsFromConnectors ( this . connectors )
150+ this . tools . push ( ...this . additionalTools )
148151 logger . info ( `🛠️ Created ${ this . tools . length } LangChain tools from connectors` )
149152 }
150153
@@ -251,12 +254,47 @@ export class MCPAgent {
251254 return this . disallowedTools
252255 }
253256
257+ private async _consumeAndReturn (
258+ generator : AsyncGenerator < AgentStep , string , void > ,
259+ ) : Promise < string > {
260+ // Manually iterate through the generator to consume the steps.
261+ // The for-await-of loop is not used because it discards the generator's
262+ // final return value. We need to capture that value when `done` is true.
263+ while ( true ) {
264+ const { done, value } = await generator . next ( )
265+ if ( done ) {
266+ return value
267+ }
268+ }
269+ }
270+
271+ /**
272+ * Runs the agent and returns a promise for the final result.
273+ */
254274 public async run (
255275 query : string ,
256276 maxSteps ?: number ,
257- manageConnector = true ,
277+ manageConnector ?: boolean ,
258278 externalHistory ?: BaseMessage [ ] ,
259279 ) : Promise < string > {
280+ const generator = this . stream (
281+ query ,
282+ maxSteps ,
283+ manageConnector ,
284+ externalHistory ,
285+ )
286+ return this . _consumeAndReturn ( generator )
287+ }
288+
289+ /**
290+ * Runs the agent and yields intermediate steps as an async generator.
291+ */
292+ public async * stream (
293+ query : string ,
294+ maxSteps ?: number ,
295+ manageConnector = true ,
296+ externalHistory ?: BaseMessage [ ] ,
297+ ) : AsyncGenerator < AgentStep , string , void > {
260298 let result = ''
261299 let initializedHere = false
262300
@@ -315,6 +353,7 @@ export class MCPAgent {
315353 `🔄 Tools changed before step ${ stepNum + 1 } , updating agent. New tools: ${ [ ...currentToolNames ] . join ( ', ' ) } ` ,
316354 )
317355 this . tools = currentTools
356+ this . tools . push ( ...this . additionalTools )
318357 await this . createSystemMessageFromTools ( this . tools )
319358 this . agentExecutor = this . createAgent ( )
320359 this . agentExecutor . maxIterations = steps
@@ -342,6 +381,7 @@ export class MCPAgent {
342381 intermediateSteps . push ( ...stepArray )
343382
344383 for ( const step of stepArray ) {
384+ yield step
345385 const { action, observation } = step
346386 const toolName = action . tool
347387 let toolInputStr = String ( action . toolInput )
0 commit comments