adk-typescript
Version:
TypeScript port of Google's Agent Development Kit (ADK)
115 lines (114 loc) • 4.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MCPTool = void 0;
const BaseTool_1 = require("../BaseTool");
/**
* Turns a MCP Tool into a Vertex Agent Framework Tool.
*
* Internally, the tool initializes from a MCP Tool, and uses the MCP Session to
* call the tool.
*/
class MCPTool extends BaseTool_1.BaseTool {
/**
* Initializes a MCPTool.
*
* This tool wraps a MCP Tool interface and an active MCP Session. It invokes
* the MCP Tool through executing the tool from remote MCP Session.
*
* @param options Configuration options for the MCPTool
* @param options.mcpTool The MCP tool to wrap
* @param options.mcpSession The MCP session to use to call the tool
* @param options.mcpSessionManager The session manager to reinitialize sessions if needed
* @param options.authScheme Optional authentication scheme to use
* @param options.authCredential Optional authentication credential to use
*
* @throws Error If mcpTool or mcpSession is null/undefined
*/
constructor({ mcpTool, mcpSession, mcpSessionManager, authScheme, authCredential, }) {
if (!mcpTool) {
throw new Error('mcpTool cannot be null or undefined');
}
if (!mcpSession) {
throw new Error('mcpSession cannot be null or undefined');
}
// Initialize the BaseTool with the name and description from the MCP tool
super({
name: mcpTool.name,
description: mcpTool.description || '',
});
this.mcpTool = mcpTool;
this.mcpSession = mcpSession;
this.mcpSessionManager = mcpSessionManager;
this.authScheme = authScheme;
this.authCredential = authCredential;
}
/**
* Private method to reinitialize the MCP session if it's closed
*/
async _reinitializeSession() {
this.mcpSession = await this.mcpSessionManager.createSession();
}
/**
* Get the function declaration for the tool
* @returns The function declaration object
*/
_getDeclaration() {
// Convert the MCP tool's input schema to a Gemini function declaration
// This is a placeholder implementation - in a real implementation, this would
// convert from JSON Schema to Gemini's schema format
const schema = this.mcpTool.inputSchema;
return {
name: this.name,
description: this.description,
parameters: schema
};
}
/**
* Execute the tool asynchronously
* @param args Arguments to pass to the tool
* @param toolContext The tool context
* @returns The result of executing the tool
*/
async execute(args, toolContext) {
try {
// Wrap execution with retry logic instead of using a decorator
return await this.executeWithRetry(args);
}
catch (error) {
console.error('Error executing MCP tool:', error);
throw error;
}
}
/**
* Execute with retry logic if the session is closed
* @param args Arguments to pass to the tool
* @returns The result of executing the tool
*/
async executeWithRetry(args) {
try {
// Use the correct method from the MCP SDK to call a tool
return await this.mcpSession.callTool({
name: this.name,
arguments: args
});
}
catch (error) {
// Check if error is a ClosedResourceError
if (error instanceof Error && (error.name === 'ClosedResourceError' || error.message.includes('closed'))) {
try {
await this._reinitializeSession();
}
catch (reinitError) {
throw new Error(`Error reinitializing session: ${reinitError}`);
}
// Retry once after reinitializing with the correct method call
return await this.mcpSession.callTool({
name: this.name,
arguments: args
});
}
throw error;
}
}
}
exports.MCPTool = MCPTool;