Skip to content

MCP Integration

Haveapp1 edited this page Aug 22, 2025 · 1 revision

MCP Integration

Complete guide to Model Context Protocol integration in Agentwise.

Overview

The Model Context Protocol (MCP) integration is a core feature of Agentwise that enables seamless connection with 61+ MCP servers, extending functionality and enabling specialized capabilities for agents.

MCP Architecture

Protocol Basics

MCP enables standardized communication between Agentwise and external tools and services:

{
  "mcp_components": {
    "servers": "External services providing tools and resources",
    "clients": "Agentwise agents that consume MCP services", 
    "protocol": "Standardized JSON-RPC communication",
    "transports": "stdio, HTTP, WebSocket connections"
  }
}

Integration Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Agentwise      β”‚    β”‚  MCP Protocol   β”‚    β”‚  MCP Servers    β”‚
β”‚  Agent          │◄──►│  Layer          │◄──►│  (61+ servers)  β”‚
β”‚                 β”‚    β”‚                 β”‚    β”‚                 β”‚
β”‚ β€’ Task Request  β”‚    β”‚ β€’ Tool Discoveryβ”‚    β”‚ β€’ File System   β”‚
β”‚ β€’ Tool Usage    β”‚    β”‚ β€’ Resource Mgmt β”‚    β”‚ β€’ GitHub API    β”‚
β”‚ β€’ Result Proc.  β”‚    β”‚ β€’ Communication β”‚    β”‚ β€’ Database      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Server Discovery and Configuration

Automatic Discovery

Agentwise automatically discovers MCP servers through multiple methods:

// Auto-discovery process
class MCPDiscovery {
  async discoverServers() {
    const sources = await Promise.all([
      this.scanConfigFile(),
      this.scanServerDirectory(),
      this.scanEnvironmentVariables(),
      this.queryRegistry()
    ]);
    
    return this.mergeAndValidateServers(sources);
  }
  
  async scanConfigFile() {
    const configPath = path.join(os.homedir(), '.claude', 'claude_desktop_config.json');
    
    if (await fs.exists(configPath)) {
      const config = await fs.readJSON(configPath);
      return config.mcpServers || {};
    }
    
    return {};
  }
}

Manual Configuration

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"],
      "description": "File system access server"
    },
    "github": {
      "command": "npx", 
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      },
      "description": "GitHub repository management"
    },
    "database": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-sqlite", "--db-path", "./project.db"],
      "description": "SQLite database operations"
    }
  }
}

Available MCP Servers

Core Servers

{
  "core_servers": {
    "filesystem": {
      "capabilities": ["file_read", "file_write", "directory_list", "file_search"],
      "use_cases": ["Project file management", "Code generation", "Asset handling"],
      "agents": ["all"]
    },
    "github": {
      "capabilities": ["repo_access", "issue_management", "pr_creation", "file_operations"],
      "use_cases": ["Repository operations", "CI/CD integration", "Issue tracking"],
      "agents": ["devops", "backend", "frontend"]
    },
    "database": {
      "capabilities": ["query_execution", "schema_management", "data_operations"],
      "use_cases": ["Database design", "Data migration", "Query optimization"],
      "agents": ["database", "backend"]
    }
  }
}

Specialized Servers

{
  "specialized_servers": {
    "web_search": {
      "server": "@modelcontextprotocol/server-brave-search",
      "capabilities": ["search", "web_scraping", "content_analysis"],
      "agents": ["research", "frontend", "backend"]
    },
    "email": {
      "server": "@modelcontextprotocol/server-gmail",
      "capabilities": ["send_email", "read_email", "manage_threads"],
      "agents": ["devops", "research"]
    },
    "cloud_services": {
      "aws": "@modelcontextprotocol/server-aws",
      "gcp": "@modelcontextprotocol/server-gcp", 
      "azure": "@modelcontextprotocol/server-azure",
      "agents": ["devops", "backend"]
    },
    "development_tools": {
      "docker": "@modelcontextprotocol/server-docker",
      "kubernetes": "@modelcontextprotocol/server-kubernetes",
      "terraform": "@modelcontextprotocol/server-terraform",
      "agents": ["devops"]
    }
  }
}

Agent-Server Integration

Tool Registration

class AgentMCPIntegration {
  constructor(agent) {
    this.agent = agent;
    this.mcpClients = new Map();
    this.availableTools = new Map();
  }
  
  async initializeMCPIntegration() {
    const servers = await this.discoverRelevantServers();
    
    for (const [serverName, serverConfig] of servers) {
      try {
        const client = await this.connectToServer(serverName, serverConfig);
        const tools = await client.listTools();
        
        this.mcpClients.set(serverName, client);
        this.registerTools(serverName, tools);
        
        console.log(`Connected to MCP server: ${serverName}`);
      } catch (error) {
        console.warn(`Failed to connect to ${serverName}:`, error.message);
      }
    }\n  }\n  \n  registerTools(serverName, tools) {\n    tools.forEach(tool => {\n      const toolKey = `${serverName}:${tool.name}`;\n      this.availableTools.set(toolKey, {\n        server: serverName,\n        tool: tool,\n        client: this.mcpClients.get(serverName)\n      });\n    });\n  }\n}

Tool Invocation

async invokeTool(toolName, parameters) {
  const toolEntry = this.availableTools.get(toolName);
  
  if (!toolEntry) {
    throw new Error(`Tool not found: ${toolName}`);\n  }\n  \n  try {\n    const result = await toolEntry.client.callTool(\n      toolEntry.tool.name,\n      parameters\n    );\n    \n    return this.processToolResult(result);\n  } catch (error) {\n    throw new MCPToolError(`Tool invocation failed: ${error.message}`);\n  }\n}

async processToolResult(result) {
  // Process and validate tool result
  return {\n    success: true,\n    data: result.content,\n    metadata: {\n      timestamp: Date.now(),\n      tokens_used: this.estimateTokenUsage(result)\n    }\n  };\n}

Server-Specific Integrations

File System Operations

// Frontend agent using filesystem MCP server
class FrontendAgentWithMCP extends FrontendSpecialist {
  async createComponent(task, context) {
    const componentCode = await this.generateComponentCode(task);
    
    // Use filesystem MCP server to write files
    await this.invokeTool('filesystem:write_file', {
      path: `src/components/${task.componentName}.jsx`,
      content: componentCode,
      encoding: 'utf-8'
    });
    
    // Create accompanying test file
    const testCode = await this.generateTestCode(task, componentCode);
    
    await this.invokeTool('filesystem:write_file', {
      path: `src/components/__tests__/${task.componentName}.test.jsx`,
      content: testCode,
      encoding: 'utf-8'
    });
    
    return {
      status: 'success',
      files_created: 2,
      component_name: task.componentName
    };
  }
}

GitHub Integration

// DevOps agent using GitHub MCP server
class DevOpsAgentWithMCP extends DevOpsSpecialist {
  async setupCICD(task, context) {
    // Create GitHub Actions workflow
    const workflowContent = await this.generateWorkflow(task);
    
    await this.invokeTool('github:create_file', {
      repo: context.repository,
      path: '.github/workflows/ci.yml',
      content: workflowContent,
      message: 'Add CI/CD workflow',
      branch: 'main'
    });
    
    // Create pull request for review
    const prResult = await this.invokeTool('github:create_pull_request', {
      repo: context.repository,
      title: 'Add CI/CD Pipeline',
      body: 'Automated CI/CD setup with testing and deployment',
      head: 'feature/cicd-setup',
      base: 'main'
    });
    
    return {\n      status: 'success',\n      workflow_created: true,\n      pull_request: prResult.data.html_url\n    };\n  }\n}

Database Operations

// Database agent using database MCP server
class DatabaseAgentWithMCP extends DatabaseSpecialist {
  async createSchema(task, context) {
    const schemaSQL = await this.generateSchema(task);
    
    // Execute schema creation
    const result = await this.invokeTool('database:execute_query', {
      query: schemaSQL,
      params: []
    });
    
    // Create indexes for optimization
    const indexes = await this.generateIndexes(task);
    
    for (const index of indexes) {
      await this.invokeTool('database:execute_query', {
        query: index.sql,
        params: []
      });
    }
    
    // Generate and run seed data
    const seedData = await this.generateSeedData(task);
    
    await this.invokeTool('database:execute_query', {
      query: seedData.sql,
      params: seedData.params
    });
    
    return {
      status: 'success',
      tables_created: task.tables.length,
      indexes_created: indexes.length,
      records_seeded: seedData.recordCount
    };
  }
}

Custom MCP Server Development

Creating Custom Servers

// Example custom MCP server for Agentwise
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

class AgentWiseCustomServer {
  constructor() {
    this.server = new Server(
      {
        name: 'agentwise-custom',
        version: '1.0.0'
      },
      {
        capabilities: {
          tools: {},
          resources: {}
        }
      }
    );
    
    this.setupTools();
  }
  
  setupTools() {
    // Custom tool for project analysis
    this.server.setRequestHandler('tools/list', async () => ({
      tools: [
        {
          name: 'analyze_project_structure',
          description: 'Analyze project structure and provide recommendations',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: { type: 'string' },
              analysisType: { type: 'string', enum: ['structure', 'dependencies', 'security'] }
            },
            required: ['projectPath']
          }
        }
      ]
    }));
    
    this.server.setRequestHandler('tools/call', async (request) => {
      const { name, arguments: args } = request.params;
      
      switch (name) {
        case 'analyze_project_structure':
          return await this.analyzeProjectStructure(args);
        default:
          throw new Error(`Unknown tool: ${name}`);
      }
    });
  }
  
  async analyzeProjectStructure({ projectPath, analysisType = 'structure' }) {
    // Implementation of project analysis
    const analysis = await this.performAnalysis(projectPath, analysisType);
    
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(analysis, null, 2)
        }
      ]
    };
  }
  
  async start() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
  }
}

// Start the server
const server = new AgentWiseCustomServer();
server.start().catch(console.error);

Configuration Management

Server Configuration Validation

class MCPConfigValidator {
  validate(config) {
    const errors = [];
    
    for (const [serverName, serverConfig] of Object.entries(config.mcpServers || {})) {
      // Validate required fields
      if (!serverConfig.command) {
        errors.push(`Server ${serverName}: missing required 'command' field`);
      }
      
      // Validate command existence
      if (!this.commandExists(serverConfig.command)) {
        errors.push(`Server ${serverName}: command '${serverConfig.command}' not found`);
      }
      
      // Validate environment variables
      if (serverConfig.env) {
        for (const [envVar, value] of Object.entries(serverConfig.env)) {
          if (value.startsWith('${') && value.endsWith('}')) {
            const actualVar = value.slice(2, -1);
            if (!process.env[actualVar]) {
              errors.push(`Server ${serverName}: environment variable '${actualVar}' not set`);
            }
          }
        }
      }
    }
    
    return {
      valid: errors.length === 0,
      errors
    };
  }
}

Dynamic Server Management

class DynamicMCPManager {
  constructor() {
    this.activeServers = new Map();
    this.serverHealth = new Map();
    this.reconnectAttempts = new Map();
  }
  
  async addServer(serverName, config) {
    try {
      const client = await this.connectToServer(serverName, config);
      this.activeServers.set(serverName, client);
      this.serverHealth.set(serverName, 'healthy');
      
      // Start health monitoring
      this.startHealthMonitoring(serverName);
      
      return { success: true, serverName };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }
  
  async removeServer(serverName) {
    const client = this.activeServers.get(serverName);
    if (client) {
      await client.close();
      this.activeServers.delete(serverName);
      this.serverHealth.delete(serverName);
      this.reconnectAttempts.delete(serverName);
    }
  }
  
  async healthCheck(serverName) {
    const client = this.activeServers.get(serverName);
    if (!client) return false;
    
    try {
      await client.ping();
      this.serverHealth.set(serverName, 'healthy');
      return true;
    } catch (error) {
      this.serverHealth.set(serverName, 'unhealthy');
      this.attemptReconnection(serverName);
      return false;
    }
  }
}

Performance Optimization

Connection Pooling

class MCPConnectionPool {
  constructor(maxConnections = 10) {
    this.maxConnections = maxConnections;
    this.connections = new Map();
    this.available = new Set();
    this.waitQueue = [];
  }
  
  async getConnection(serverName) {
    const poolKey = `pool:${serverName}`;
    
    if (this.available.has(poolKey)) {
      const connection = this.connections.get(poolKey);
      this.available.delete(poolKey);
      return connection;
    }
    
    if (this.connections.size < this.maxConnections) {
      const connection = await this.createConnection(serverName);
      this.connections.set(poolKey, connection);
      return connection;
    }
    
    // Wait for available connection
    return new Promise((resolve) => {
      this.waitQueue.push({ serverName, resolve });
    });
  }
  
  releaseConnection(serverName, connection) {
    const poolKey = `pool:${serverName}`;
    this.available.add(poolKey);
    
    // Serve waiting requests
    if (this.waitQueue.length > 0) {
      const { resolve } = this.waitQueue.shift();
      this.available.delete(poolKey);
      resolve(connection);
    }
  }
}

Error Handling and Resilience

Retry Logic

class MCPResilienceManager {
  constructor() {
    this.retryConfig = {\n      maxRetries: 3,\n      baseDelay: 1000,\n      maxDelay: 10000,\n      backoffFactor: 2\n    };\n  }\n  \n  async callWithRetry(operation, context = {}) {\n    let attempt = 0;\n    let lastError;\n    \n    while (attempt <= this.retryConfig.maxRetries) {\n      try {\n        return await operation();\n      } catch (error) {\n        lastError = error;\n        attempt++;\n        \n        if (attempt > this.retryConfig.maxRetries) {\n          break;\n        }\n        \n        if (!this.isRetryableError(error)) {\n          throw error;\n        }\n        \n        const delay = this.calculateDelay(attempt);\n        await this.sleep(delay);\n      }\n    }\n    \n    throw new MCPRetryExhaustedError(\n      `Operation failed after ${this.retryConfig.maxRetries} retries`,\n      lastError\n    );\n  }\n}

Troubleshooting MCP Integration

Common Issues

Diagnostic Commands

bash\n# MCP server diagnostics\nnpm run mcp:list # List discovered servers\nnpm run mcp:test <server> # Test specific server\nnpm run mcp:health # Check server health\nnpm run mcp:logs <server> # View server logs\nnpm run mcp:validate-config # Validate MCP configuration\n\n\n---\n\nFor more information, see Configuration, Agent System, or API Reference.

Navigation

πŸš€ Getting Started

πŸ“š Documentation

πŸ› οΈ Development

🎯 Advanced Topics

πŸ“– Resources

βš–οΈ Legal

πŸ”— Quick Links


Support

  • Discord: @vibecodingwithphil
  • GitHub: @VibeCodingWithPhil
Clone this wiki locally