helpingai
Version:
The official JavaScript/TypeScript library for the HelpingAI API - Advanced AI with Emotional Intelligence
188 lines • 6.29 kB
JavaScript
/**
* MCP Client implementation
*/
import { MCPError } from '../errors';
export class MCPClient {
constructor() {
this.connections = new Map();
}
/**
* Initialize MCP server connection
*/
async connect(serverName, config) {
try {
// Check if MCP SDK is available
if (!this.isMCPAvailable()) {
throw new MCPError('MCP SDK not available. Install with: npm install @modelcontextprotocol/sdk', serverName);
}
const connection = {
serverName,
config,
initialized: false,
tools: [],
resources: [],
};
// Initialize connection based on type
if (config.command) {
await this.initializeStdioConnection(connection);
}
else if (config.url) {
await this.initializeHttpConnection(connection);
}
else {
throw new MCPError(`Invalid MCP server configuration for ${serverName}`, serverName);
}
this.connections.set(serverName, connection);
}
catch (error) {
throw new MCPError(`Failed to connect to MCP server ${serverName}: ${error instanceof Error ? error.message : String(error)}`, serverName);
}
}
/**
* Check if MCP SDK is available
*/
isMCPAvailable() {
try {
// Simple check - in a real implementation, this would check for MCP SDK availability
return true; // Mock implementation - always return true for now
}
catch {
return false;
}
}
/**
* Initialize stdio-based MCP connection
*/
async initializeStdioConnection(connection) {
// This would use the actual MCP SDK when available
// For now, we'll create a mock implementation
console.warn(`MCP stdio connection to ${connection.serverName} would be initialized here`);
// Mock initialization
connection.initialized = true;
connection.tools = [
{
name: `${connection.serverName}_tool`,
description: `Tool from ${connection.serverName} server`,
inputSchema: {
type: 'object',
properties: {},
required: [],
},
},
];
}
/**
* Initialize HTTP-based MCP connection
*/
async initializeHttpConnection(connection) {
// This would use the actual MCP SDK when available
console.warn(`MCP HTTP connection to ${connection.serverName} would be initialized here`);
// Mock initialization
connection.initialized = true;
connection.tools = [
{
name: `${connection.serverName}_http_tool`,
description: `HTTP tool from ${connection.serverName} server`,
inputSchema: {
type: 'object',
properties: {},
required: [],
},
},
];
}
/**
* Get all available tools from connected MCP servers
*/
getAvailableTools() {
const tools = [];
for (const connection of this.connections.values()) {
if (connection.initialized) {
tools.push(...connection.tools);
}
}
return tools;
}
/**
* Execute a tool call on an MCP server
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async callTool(toolName, args) {
// Find which server has this tool
let targetConnection;
for (const connection of this.connections.values()) {
if (connection.tools.some(tool => tool.name === toolName)) {
targetConnection = connection;
break;
}
}
if (!targetConnection) {
throw new MCPError(`Tool ${toolName} not found in any connected MCP server`);
}
if (!targetConnection.initialized) {
throw new MCPError(`MCP server ${targetConnection.serverName} not initialized`);
}
try {
// This would use the actual MCP SDK to call the tool
console.log(`Calling MCP tool ${toolName} with args:`, args);
// Mock response
return {
content: [
{
type: 'text',
text: `Mock response from MCP tool ${toolName}`,
},
],
};
}
catch (error) {
throw new MCPError(`Failed to call MCP tool ${toolName}: ${error instanceof Error ? error.message : String(error)}`, targetConnection.serverName);
}
}
/**
* Disconnect from an MCP server
*/
async disconnect(serverName) {
const connection = this.connections.get(serverName);
if (!connection) {
return;
}
try {
// Cleanup connection
this.connections.delete(serverName);
console.log(`Disconnected from MCP server: ${serverName}`);
}
catch (error) {
throw new MCPError(`Failed to disconnect from MCP server ${serverName}: ${error instanceof Error ? error.message : String(error)}`, serverName);
}
}
/**
* Disconnect from all MCP servers
*/
async disconnectAll() {
const serverNames = Array.from(this.connections.keys());
for (const serverName of serverNames) {
await this.disconnect(serverName);
}
}
/**
* Get connection status
*/
getConnectionStatus() {
const status = {};
for (const [serverName, connection] of this.connections) {
status[serverName] = connection.initialized;
}
return status;
}
/**
* List connected servers
*/
getConnectedServers() {
return Array.from(this.connections.keys()).filter(serverName => {
const connection = this.connections.get(serverName);
return connection?.initialized;
});
}
}
//# sourceMappingURL=client.js.map