Skip to content

Latest commit

 

History

History
499 lines (396 loc) · 14 KB

File metadata and controls

499 lines (396 loc) · 14 KB

Intégration MCP Native - Watsonx Orchestrate & Langflow

Ce guide explique comment utiliser le serveur MCP OpenPages directement avec Watsonx Orchestrate et Langflow via le protocole MCP natif, exactement comme avec Claude Desktop.

Vue d'ensemble

Le serveur MCP OpenPages communique via le protocole MCP standard (stdio). Watsonx Orchestrate et Langflow peuvent se connecter directement au serveur MCP sans passer par une API REST.

Architecture MCP Native

┌─────────────────────┐
│  Watsonx Orchestrate│
│     ou Langflow     │
└──────────┬──────────┘
           │ MCP Protocol (stdio)
           │
┌──────────▼──────────┐
│  MCP OpenPages      │
│     Server          │
└──────────┬──────────┘
           │ HTTPS
           │
┌──────────▼──────────┐
│  IBM OpenPages      │
│     REST API        │
└─────────────────────┘

Configuration pour Watsonx Orchestrate

Prérequis

  • Node.js 18+ installé
  • Accès à Watsonx Orchestrate avec support MCP
  • Serveur MCP OpenPages compilé

Étape 1: Préparer le serveur MCP

# Installation
cd /Users/vperrin/Documents/work/MCP_OpenPages
npm install
npm run build

# Vérifier que le serveur fonctionne
export OPENPAGES_BASE_URL="https://votre-serveur.com/opgrc/api"
export OPENPAGES_USERNAME="votre-username"
export OPENPAGES_PASSWORD="votre-password"

node dist/index.js

Étape 2: Configuration MCP dans Watsonx Orchestrate

Si Watsonx Orchestrate supporte le protocole MCP (vérifier la documentation IBM), configurez comme suit:

Fichier de configuration MCP pour Watsonx:

{
  "mcpServers": {
    "openpages": {
      "command": "node",
      "args": ["/chemin/absolu/vers/MCP_OpenPages/dist/index.js"],
      "env": {
        "OPENPAGES_BASE_URL": "https://votre-serveur.com/opgrc/api",
        "OPENPAGES_USERNAME": "votre-username",
        "OPENPAGES_PASSWORD": "votre-password"
      }
    }
  }
}

Emplacement du fichier de configuration:

  • Consultez la documentation Watsonx Orchestrate pour l'emplacement exact
  • Généralement dans le répertoire de configuration de l'application

Étape 3: Utilisation dans Watsonx Orchestrate

Une fois configuré, les 18 outils MCP seront disponibles:

Exemples de commandes dans Watsonx:
- "Récupère l'objet OpenPages avec l'ID 12345"
- "Crée un nouveau SOXIssue nommé 'Problème de sécurité'"
- "Recherche tous les objets contenant 'audit'"
- "Exécute la requête: SELECT [Name] FROM [SOXBusEntity]"

Configuration pour Langflow

Option 1: Intégration MCP Native (Si supporté)

Si Langflow supporte nativement le protocole MCP:

Configuration MCP pour Langflow:

{
  "mcp_servers": {
    "openpages": {
      "command": "node",
      "args": ["/chemin/absolu/vers/MCP_OpenPages/dist/index.js"],
      "env": {
        "OPENPAGES_BASE_URL": "https://votre-serveur.com/opgrc/api",
        "OPENPAGES_USERNAME": "votre-username",
        "OPENPAGES_PASSWORD": "votre-password"
      }
    }
  }
}

Option 2: Client MCP Python pour Langflow

Si Langflow ne supporte pas encore MCP nativement, créez un client MCP en Python:

Créer mcp_client.py:

import subprocess
import json
import sys
from typing import Dict, Any, List

class MCPOpenPagesClient:
    """Client MCP pour OpenPages utilisable dans Langflow"""
    
    def __init__(self, server_path: str, env: Dict[str, str]):
        """
        Initialise le client MCP
        
        Args:
            server_path: Chemin vers dist/index.js
            env: Variables d'environnement (OPENPAGES_BASE_URL, etc.)
        """
        self.server_path = server_path
        self.env = env
        self.process = None
        
    def start(self):
        """Démarre le serveur MCP"""
        self.process = subprocess.Popen(
            ['node', self.server_path],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            env=self.env,
            text=True
        )
        
    def call_tool(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
        """
        Appelle un outil MCP
        
        Args:
            tool_name: Nom de l'outil (ex: 'openpages_get_object')
            arguments: Arguments de l'outil
            
        Returns:
            Résultat de l'outil
        """
        request = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "tools/call",
            "params": {
                "name": tool_name,
                "arguments": arguments
            }
        }
        
        # Envoyer la requête
        self.process.stdin.write(json.dumps(request) + '\n')
        self.process.stdin.flush()
        
        # Lire la réponse
        response_line = self.process.stdout.readline()
        response = json.loads(response_line)
        
        return response.get('result', {})
    
    def list_tools(self) -> List[Dict[str, Any]]:
        """Liste tous les outils disponibles"""
        request = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "tools/list",
            "params": {}
        }
        
        self.process.stdin.write(json.dumps(request) + '\n')
        self.process.stdin.flush()
        
        response_line = self.process.stdout.readline()
        response = json.loads(response_line)
        
        return response.get('result', {}).get('tools', [])
    
    def stop(self):
        """Arrête le serveur MCP"""
        if self.process:
            self.process.terminate()
            self.process.wait()

# Exemple d'utilisation dans Langflow
def create_openpages_tools():
    """Crée les outils OpenPages pour Langflow"""
    from langchain.tools import Tool
    
    # Configuration
    server_path = "/chemin/vers/MCP_OpenPages/dist/index.js"
    env = {
        "OPENPAGES_BASE_URL": "https://votre-serveur.com/opgrc/api",
        "OPENPAGES_USERNAME": "votre-username",
        "OPENPAGES_PASSWORD": "votre-password"
    }
    
    # Créer le client MCP
    client = MCPOpenPagesClient(server_path, env)
    client.start()
    
    # Créer les outils LangChain
    tools = []
    
    def get_object(object_id: str) -> str:
        """Récupère un objet OpenPages par ID"""
        result = client.call_tool('openpages_get_object', {'id': object_id})
        return json.dumps(result, indent=2)
    
    def query_objects(statement: str) -> str:
        """Requête SQL-like sur OpenPages"""
        result = client.call_tool('openpages_query', {'statement': statement})
        return json.dumps(result, indent=2)
    
    def search_objects(search_term: str) -> str:
        """Recherche dans OpenPages"""
        result = client.call_tool('openpages_search', {'q': search_term})
        return json.dumps(result, indent=2)
    
    def create_object(type_id: str, name: str, description: str = "") -> str:
        """Crée un objet OpenPages"""
        result = client.call_tool('openpages_create_object', {
            'type_definition_id': type_id,
            'name': name,
            'description': description
        })
        return json.dumps(result, indent=2)
    
    tools.extend([
        Tool(
            name="get_openpages_object",
            func=get_object,
            description="Récupère un objet GRC OpenPages par ID"
        ),
        Tool(
            name="query_openpages",
            func=query_objects,
            description="Requête SQL-like sur les objets OpenPages"
        ),
        Tool(
            name="search_openpages",
            func=search_objects,
            description="Recherche dans OpenPages"
        ),
        Tool(
            name="create_openpages_object",
            func=create_object,
            description="Crée un nouvel objet OpenPages"
        )
    ])
    
    return tools, client

# Utilisation dans un flow Langflow
if __name__ == "__main__":
    tools, client = create_openpages_tools()
    
    try:
        # Exemple: Récupérer un objet
        result = tools[0].func("12345")
        print("Objet récupéré:", result)
        
        # Exemple: Recherche
        result = tools[2].func("audit")
        print("Résultats de recherche:", result)
        
    finally:
        client.stop()

Option 3: Composant Langflow Personnalisé avec MCP

Créer langflow_mcp_component.py:

from langflow import CustomComponent
from typing import List
import subprocess
import json

class OpenPagesMCPComponent(CustomComponent):
    display_name = "OpenPages MCP"
    description = "Connecteur MCP natif pour IBM OpenPages"
    
    def build_config(self):
        return {
            "server_path": {
                "display_name": "Chemin du serveur MCP",
                "info": "Chemin vers dist/index.js",
            },
            "base_url": {
                "display_name": "URL OpenPages",
                "info": "URL de base de l'API OpenPages",
            },
            "username": {
                "display_name": "Nom d'utilisateur",
                "password": True,
            },
            "password": {
                "display_name": "Mot de passe",
                "password": True,
            },
            "operation": {
                "display_name": "Opération",
                "options": [
                    "get_object",
                    "create_object",
                    "query",
                    "search",
                    "get_workflows"
                ],
            },
        }
    
    def build(self, server_path: str, base_url: str, username: str, 
              password: str, operation: str):
        
        # Démarrer le serveur MCP
        env = {
            "OPENPAGES_BASE_URL": base_url,
            "OPENPAGES_USERNAME": username,
            "OPENPAGES_PASSWORD": password
        }
        
        process = subprocess.Popen(
            ['node', server_path],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            env=env,
            text=True
        )
        
        # Fonction pour appeler le serveur MCP
        def call_mcp(tool_name: str, args: dict) -> str:
            request = {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "tools/call",
                "params": {
                    "name": f"openpages_{tool_name}",
                    "arguments": args
                }
            }
            
            process.stdin.write(json.dumps(request) + '\n')
            process.stdin.flush()
            
            response_line = process.stdout.readline()
            response = json.loads(response_line)
            
            return json.dumps(response.get('result', {}), indent=2)
        
        return call_mcp

Comparaison des Approches

Approche Avantages Inconvénients
MCP Natif - Protocole standard
- Pas de couche intermédiaire
- Performance optimale
- Support plateforme requis
Client Python - Flexible
- Contrôle total
- Fonctionne partout
- Code supplémentaire
- Maintenance
REST Wrapper - Simple
- Compatible HTTP
- Facile à déboguer
- Couche supplémentaire
- Latence

Vérification du Support MCP

Pour Watsonx Orchestrate

Vérifiez si Watsonx supporte MCP:

# Consultez la documentation IBM Watsonx Orchestrate
# Recherchez "Model Context Protocol" ou "MCP"
# Contactez le support IBM si nécessaire

Pour Langflow

Vérifiez si Langflow supporte MCP:

# Consultez la documentation Langflow
# Recherchez dans les issues GitHub: https://github.com/logspace-ai/langflow
# Vérifiez les composants disponibles

Configuration Recommandée

Si MCP est supporté nativement:

✅ Utilisez la configuration MCP native (comme Claude)

Si MCP n'est pas encore supporté:

  1. Court terme: Utilisez le client Python MCP
  2. Moyen terme: Contribuez au support MCP dans le projet
  3. Alternative: Utilisez le REST wrapper (rest-wrapper.js)

Exemples d'Utilisation

Watsonx Orchestrate avec MCP

Workflow Watsonx:
1. Trigger: "Analyser les risques"
2. Tool: openpages_query
   - Statement: "SELECT [Name], [Status] FROM [SOXRisk] WHERE [Status] = 'Open'"
3. Tool: openpages_get_workflows
4. Action: Générer rapport

Langflow avec MCP

# Flow Langflow avec MCP
from langflow import Flow

# Créer le flow
flow = Flow()

# Ajouter le composant MCP OpenPages
openpages = flow.add_component(OpenPagesMCPComponent, {
    "server_path": "/path/to/dist/index.js",
    "base_url": "https://server.com/opgrc/api",
    "username": "user",
    "password": "pass"
})

# Connecter à un LLM
llm = flow.add_component(ChatOpenAI)
flow.connect(openpages, llm)

# Exécuter
result = flow.run("Récupère l'objet 12345 d'OpenPages")

Dépannage

Le serveur MCP ne démarre pas

# Vérifier Node.js
node --version  # Doit être >= 18

# Vérifier la compilation
npm run build

# Tester manuellement
node dist/index.js

Erreurs de connexion

# Vérifier les variables d'environnement
echo $OPENPAGES_BASE_URL
echo $OPENPAGES_USERNAME

# Tester la connexion
npm test

Problèmes de communication MCP

# Activer les logs de débogage
export DEBUG=mcp:*
node dist/index.js

Support et Documentation

Conclusion

Le serveur MCP OpenPages est conçu pour fonctionner avec le protocole MCP standard. Si Watsonx Orchestrate ou Langflow supportent MCP nativement, l'intégration sera identique à Claude Desktop. Sinon, utilisez le client Python fourni pour une intégration transparente.

Pour toute question, consultez la documentation ou ouvrez une issue sur GitHub.