Compare commits
1 Commits
d25937fc73
...
mcp-migrat
| Author | SHA1 | Date | |
|---|---|---|---|
| 7449bbf10c |
58
__env
58
__env
@@ -1,58 +0,0 @@
|
||||
LOG_LEVEL=debug
|
||||
# Modèles à utiliser
|
||||
MODEL_NAME=gpt-alex
|
||||
#MULTIMODAL_MODEL=minicpm-v-2_6
|
||||
#IMAGE_MODEL=sd-1.5-ggml
|
||||
#EMBEDDING_MODEL=granite-embedding-107m-multilingual
|
||||
|
||||
STT_ENGINE=STT_ENGINE=whisper
|
||||
|
||||
# For Fast Whisper (GPU recommended)
|
||||
STT_ENGINE=whisper-alex-fast
|
||||
|
||||
CUDA_VISIBLE_DEVICES=0
|
||||
GGML_CUDA_FORCE_MMQ=0
|
||||
GGML_CUDA_FORCE_CUBLAS=1
|
||||
|
||||
# Home Assistant Configuration
|
||||
HASS_HOST=https://jarvis.carriere.cloud
|
||||
HASS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjYjYzMTQwZjc4Njk0ZTdhODFiYTY2OGI4YzM1NWQzMSIsImlhdCI6MTc0OTM4ODkzMCwiZXhwIjoyMDY0NzQ4OTMwfQ.y6zC6fOk_d7COngm4QG-WatC8lQCYfltuvrJSDbZtk8
|
||||
HASS_SOCKET_URL=ws://jarvis.carriere.cloud/api/websocket
|
||||
|
||||
# Server Configuration
|
||||
PORT=3000
|
||||
NODE_ENV=production
|
||||
DEBUG=false
|
||||
# URLs des services
|
||||
LOCALAGI_LLM_API_URL=http://localai:8080
|
||||
LOCALAGI_LOCALRAG_URL=http://localrecall:8080
|
||||
|
||||
# Configuration générale
|
||||
LOCALAGI_TIMEOUT=5m
|
||||
LOCALAGI_MCP_TIMEOUT=5m
|
||||
LOCALAGI_STATE_DIR=/pool
|
||||
LOCALAGI_ENABLE_CONVERSATIONS_LOGGING=false
|
||||
|
||||
# Configuration LocalAI (basée sur votre instance Unraid)
|
||||
DEBUG=true
|
||||
MODELS_PATH=/models
|
||||
THREADS=4
|
||||
COQUI_TOS_AGREED=1
|
||||
GALLERIES=[{"name":"localai","url":"github:mudler/LocalAI/gallery/index.yaml@master"}]
|
||||
SINGLE_ACTIVE_BACKEND=false
|
||||
LOCALAI_SINGLE_ACTIVE_BACKEND=false
|
||||
PYTHON_GRPC_MAX_WORKERS=12
|
||||
LLAMACPP_PARALLEL=6
|
||||
PARALLEL_REQUESTS=true
|
||||
WATCHDOG_IDLE=true
|
||||
WATCHDOG_BUSY=true
|
||||
WATCHDOG_IDLE_TIMEOUT=60m
|
||||
WATCHDOG_BUSY_TIMEOUT=5m
|
||||
LOCALAI_UPLOAD_LIMIT=256
|
||||
DISABLE_AUTODETECT=true
|
||||
LOW_VRAM=true
|
||||
MMAP=true
|
||||
CONTEXT_SIZE=32768
|
||||
LOCALAI_P2P=true
|
||||
LOCALAI_FEDERATED=true
|
||||
LOCALAI_P2P_LOGLEVEL=info
|
||||
@@ -1,474 +0,0 @@
|
||||
# Plan de migration détaillé : metoro-io/mcp-golang vers mark3labs/mcp-go
|
||||
|
||||
Ce document présente un plan de migration détaillé pour remplacer la bibliothèque metoro-io/mcp-golang par mark3labs/mcp-go dans le projet LocalAGI. Le plan est divisé en phases avec des exemples de code concrets pour chaque étape critique.
|
||||
|
||||
## Phase 1 : Préparation et analyse
|
||||
|
||||
### Étape 1.1 : Audit du code existant
|
||||
|
||||
```bash
|
||||
# Identifier tous les fichiers qui utilisent la bibliothèque metoro-io/mcp-golang
|
||||
grep -r "github.com/metoro-io/mcp-golang" --include="*.go" .
|
||||
|
||||
# Identifier les fonctionnalités spécifiques utilisées
|
||||
grep -r "mcp\.Client" --include="*.go" .
|
||||
grep -r "transport/http" --include="*.go" .
|
||||
grep -r "transport/stdio" --include="*.go" .
|
||||
```
|
||||
|
||||
### Étape 1.2 : Création d'un environnement de test
|
||||
|
||||
```bash
|
||||
# Créer une branche pour la migration
|
||||
git checkout -b mcp-migration
|
||||
|
||||
# Installer la nouvelle bibliothèque
|
||||
go get github.com/mark3labs/mcp-go
|
||||
```
|
||||
|
||||
## Phase 2 : Modification des importations et structures
|
||||
|
||||
### Étape 2.1 : Mise à jour des importations
|
||||
|
||||
```go
|
||||
// Avant
|
||||
import (
|
||||
mcp "github.com/metoro-io/mcp-golang"
|
||||
"github.com/metoro-io/mcp-golang/transport/http"
|
||||
stdioTransport "github.com/metoro-io/mcp-golang/transport/stdio"
|
||||
)
|
||||
|
||||
// Après
|
||||
import (
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
"github.com/mark3labs/mcp-go/server"
|
||||
)
|
||||
```
|
||||
|
||||
### Étape 2.2 : Adaptation des structures
|
||||
|
||||
```go
|
||||
// Avant
|
||||
type mcpAction struct {
|
||||
mcpClient *mcp.Client
|
||||
inputSchema ToolInputSchema
|
||||
toolName string
|
||||
toolDescription string
|
||||
}
|
||||
|
||||
// Après
|
||||
type mcpAction struct {
|
||||
// Nous devrons déterminer la structure équivalente dans mark3labs/mcp-go
|
||||
// Basé sur la documentation, cela pourrait ressembler à:
|
||||
mcpClient *mcp.Client // ou une structure équivalente
|
||||
toolDefinition *mcp.Tool
|
||||
toolName string
|
||||
toolDescription string
|
||||
}
|
||||
|
||||
// Avant
|
||||
type ToolInputSchema struct {
|
||||
Type string `json:"type"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
Required []string `json:"required,omitempty"`
|
||||
}
|
||||
|
||||
// Après
|
||||
// Nous utiliserons directement les structures de schéma fournies par mark3labs/mcp-go
|
||||
```
|
||||
|
||||
## Phase 3 : Migration des clients et transports
|
||||
|
||||
### Étape 3.1 : Clients HTTP
|
||||
|
||||
```go
|
||||
// Avant
|
||||
transport := http.NewHTTPClientTransport("/mcp")
|
||||
transport.WithBaseURL(mcpServer.URL)
|
||||
if mcpServer.Token != "" {
|
||||
transport.WithHeader("Authorization", "Bearer "+mcpServer.Token)
|
||||
}
|
||||
client := mcp.NewClient(transport)
|
||||
|
||||
// Après
|
||||
// Basé sur les exemples disponibles, nous pourrions avoir besoin de créer un client HTTP personnalisé
|
||||
// Voici une approche possible:
|
||||
httpClient := &http.Client{}
|
||||
// Configurer un client HTTP pour se connecter au serveur MCP
|
||||
// Note: L'API exacte dépendra de la façon dont mark3labs/mcp-go implémente les clients
|
||||
```
|
||||
|
||||
### Étape 3.2 : Clients STDIO
|
||||
|
||||
```go
|
||||
// Avant
|
||||
client := stdio.NewClient(a.options.mcpBoxURL)
|
||||
p, err := client.CreateProcess(a.context,
|
||||
mcpStdioServer.Cmd,
|
||||
mcpStdioServer.Args,
|
||||
mcpStdioServer.Env,
|
||||
a.Character.Name)
|
||||
read, writer, err := client.GetProcessIO(p.ID)
|
||||
transport := stdioTransport.NewStdioServerTransportWithIO(read, writer)
|
||||
mcpClient := mcp.NewClient(transport)
|
||||
|
||||
// Après
|
||||
// Basé sur les exemples, mark3labs/mcp-go utilise une approche différente pour STDIO
|
||||
// Nous devrons adapter notre code pour utiliser l'API de mark3labs/mcp-go
|
||||
// Exemple possible:
|
||||
cmd := exec.Command(mcpStdioServer.Cmd, mcpStdioServer.Args...)
|
||||
cmd.Env = append(os.Environ(), mcpStdioServer.Env...)
|
||||
// Configurer les pipes stdin/stdout
|
||||
// Créer un client qui utilise ces pipes
|
||||
```
|
||||
|
||||
## Phase 4 : Migration des outils et actions
|
||||
|
||||
### Étape 4.1 : Définition des outils
|
||||
|
||||
```go
|
||||
// Avant
|
||||
// Les outils sont définis implicitement via les réponses du serveur MCP
|
||||
var inputSchema ToolInputSchema
|
||||
err = json.Unmarshal(dat, &inputSchema)
|
||||
generatedActions = append(generatedActions, &mcpAction{
|
||||
mcpClient: client,
|
||||
toolName: t.Name,
|
||||
inputSchema: inputSchema,
|
||||
toolDescription: desc,
|
||||
})
|
||||
|
||||
// Après
|
||||
// Avec mark3labs/mcp-go, nous pouvons définir les outils plus explicitement
|
||||
// Exemple basé sur la documentation:
|
||||
calculatorTool := mcp.NewTool("calculate",
|
||||
mcp.WithDescription("Perform basic arithmetic operations"),
|
||||
mcp.WithString("operation",
|
||||
mcp.Required(),
|
||||
mcp.Description("The operation to perform"),
|
||||
mcp.Enum("add", "subtract", "multiply", "divide"),
|
||||
),
|
||||
mcp.WithNumber("x",
|
||||
mcp.Required(),
|
||||
mcp.Description("First number"),
|
||||
),
|
||||
mcp.WithNumber("y",
|
||||
mcp.Required(),
|
||||
mcp.Description("Second number"),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### Étape 4.2 : Appel des outils
|
||||
|
||||
```go
|
||||
// Avant
|
||||
func (m *mcpAction) Run(ctx context.Context, sharedState *types.AgentSharedState, params types.ActionParams) (types.ActionResult, error) {
|
||||
resp, err := m.mcpClient.CallTool(ctx, m.toolName, params)
|
||||
if err != nil {
|
||||
return types.ActionResult{}, err
|
||||
}
|
||||
|
||||
textResult := ""
|
||||
for _, c := range resp.Content {
|
||||
switch c.Type {
|
||||
case mcp.ContentTypeText:
|
||||
textResult += c.TextContent.Text + "\n"
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
return types.ActionResult{
|
||||
Result: textResult,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Après
|
||||
// Basé sur la documentation, l'appel d'outil pourrait ressembler à:
|
||||
func (m *mcpAction) Run(ctx context.Context, sharedState *types.AgentSharedState, params types.ActionParams) (types.ActionResult, error) {
|
||||
// Convertir params en format attendu par mark3labs/mcp-go
|
||||
args := make(map[string]interface{})
|
||||
if err := params.Unmarshal(&args); err != nil {
|
||||
return types.ActionResult{}, err
|
||||
}
|
||||
|
||||
// Créer une requête d'appel d'outil
|
||||
request := mcp.CallToolRequest{
|
||||
Params: mcp.CallToolParams{
|
||||
Name: m.toolName,
|
||||
Arguments: args,
|
||||
},
|
||||
}
|
||||
|
||||
// Appeler l'outil
|
||||
// Note: L'API exacte dépendra de la façon dont mark3labs/mcp-go implémente les appels d'outils
|
||||
result, err := m.mcpClient.CallTool(ctx, request)
|
||||
if err != nil {
|
||||
return types.ActionResult{}, err
|
||||
}
|
||||
|
||||
// Traiter le résultat
|
||||
textResult := ""
|
||||
// Extraire le texte du résultat selon le format de mark3labs/mcp-go
|
||||
|
||||
return types.ActionResult{
|
||||
Result: textResult,
|
||||
}, nil
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 5 : Gestion des résultats
|
||||
|
||||
```go
|
||||
// Avant
|
||||
textResult := ""
|
||||
for _, c := range resp.Content {
|
||||
switch c.Type {
|
||||
case mcp.ContentTypeText:
|
||||
textResult += c.TextContent.Text + "\n"
|
||||
case mcp.ContentTypeImage:
|
||||
xlog.Error("Image content not supported yet")
|
||||
case mcp.ContentTypeEmbeddedResource:
|
||||
xlog.Error("Embedded resource content not supported yet")
|
||||
}
|
||||
}
|
||||
|
||||
// Après
|
||||
// Basé sur la documentation, le traitement des résultats pourrait ressembler à:
|
||||
textResult := ""
|
||||
// Supposons que result est de type *mcp.CallToolResult
|
||||
if result.Error != nil {
|
||||
return types.ActionResult{}, fmt.Errorf("tool error: %s", result.Error)
|
||||
}
|
||||
|
||||
// Traiter les différents types de contenu
|
||||
for _, content := range result.Content {
|
||||
switch content.Type {
|
||||
case "text":
|
||||
textContent, ok := content.Content.(mcp.TextContent)
|
||||
if ok {
|
||||
textResult += textContent.Text + "\n"
|
||||
}
|
||||
case "image":
|
||||
xlog.Error("Image content not supported yet")
|
||||
case "embedded_resource":
|
||||
xlog.Error("Embedded resource content not supported yet")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 6 : Gestion des sessions
|
||||
|
||||
```go
|
||||
// Avant
|
||||
// La gestion des sessions est limitée dans la bibliothèque actuelle
|
||||
|
||||
// Après
|
||||
// Implémentation d'une gestion de session plus avancée avec mark3labs/mcp-go
|
||||
type MCPSession struct {
|
||||
id string
|
||||
notifChannel chan mcp.JSONRPCNotification
|
||||
isInitialized bool
|
||||
}
|
||||
|
||||
// Implémenter l'interface ClientSession
|
||||
func (s *MCPSession) SessionID() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *MCPSession) NotificationChannel() chan<- mcp.JSONRPCNotification {
|
||||
return s.notifChannel
|
||||
}
|
||||
|
||||
func (s *MCPSession) Initialize() {
|
||||
s.isInitialized = true
|
||||
}
|
||||
|
||||
func (s *MCPSession) Initialized() bool {
|
||||
return s.isInitialized
|
||||
}
|
||||
|
||||
// Utilisation dans le code
|
||||
session := &MCPSession{
|
||||
id: mcpServer.SessionId,
|
||||
notifChannel: make(chan mcp.JSONRPCNotification, 10),
|
||||
}
|
||||
if err := mcpServer.RegisterSession(context.Background(), session); err != nil {
|
||||
xlog.Error("Failed to register session", "error", err.Error())
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 7 : Adaptation de la fonction initMCPActions
|
||||
|
||||
```go
|
||||
// Avant
|
||||
func (a *Agent) initMCPActions() error {
|
||||
a.mcpActions = nil
|
||||
var err error
|
||||
generatedActions := types.Actions{}
|
||||
|
||||
// MCP HTTP Servers
|
||||
for _, mcpServer := range a.options.mcpServers {
|
||||
transport := http.NewHTTPClientTransport("/mcp")
|
||||
transport.WithBaseURL(mcpServer.URL)
|
||||
if mcpServer.Token != "" {
|
||||
transport.WithHeader("Authorization", "Bearer "+mcpServer.Token)
|
||||
}
|
||||
|
||||
client := mcp.NewClient(transport)
|
||||
actions, err := a.addTools(client)
|
||||
if err != nil {
|
||||
xlog.Error("Failed to add tools for MCP server", "error", err.Error())
|
||||
}
|
||||
generatedActions = append(generatedActions, actions...)
|
||||
}
|
||||
|
||||
// MCP STDIO Servers
|
||||
// ...
|
||||
|
||||
a.mcpActions = generatedActions
|
||||
return err
|
||||
}
|
||||
|
||||
// Après
|
||||
func (a *Agent) initMCPActions() error {
|
||||
a.mcpActions = nil
|
||||
var err error
|
||||
generatedActions := types.Actions{}
|
||||
|
||||
// MCP HTTP Servers
|
||||
for _, mcpServer := range a.options.mcpServers {
|
||||
// Créer un client HTTP pour se connecter au serveur MCP
|
||||
// Note: L'implémentation exacte dépendra de l'API de mark3labs/mcp-go
|
||||
httpClient := &http.Client{}
|
||||
// Configurer les headers, l'URL, etc.
|
||||
|
||||
// Initialiser le client
|
||||
// ...
|
||||
|
||||
// Lister et ajouter les outils
|
||||
actions, err := a.addTools(client, &mcpServer)
|
||||
if err != nil {
|
||||
xlog.Error("Failed to add tools for MCP server", "error", err.Error())
|
||||
}
|
||||
generatedActions = append(generatedActions, actions...)
|
||||
}
|
||||
|
||||
// MCP STDIO Servers
|
||||
// Adapter pour utiliser l'API STDIO de mark3labs/mcp-go
|
||||
// ...
|
||||
|
||||
a.mcpActions = generatedActions
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 8 : Tests et validation
|
||||
|
||||
### Étape 8.1 : Tests unitaires
|
||||
|
||||
```go
|
||||
// Créer des tests unitaires pour chaque composant migré
|
||||
func TestMCPClientInitialization(t *testing.T) {
|
||||
// Tester l'initialisation du client avec mark3labs/mcp-go
|
||||
}
|
||||
|
||||
func TestToolDefinition(t *testing.T) {
|
||||
// Tester la définition des outils avec mark3labs/mcp-go
|
||||
}
|
||||
|
||||
func TestToolExecution(t *testing.T) {
|
||||
// Tester l'exécution des outils avec mark3labs/mcp-go
|
||||
}
|
||||
```
|
||||
|
||||
### Étape 8.2 : Tests d'intégration
|
||||
|
||||
```go
|
||||
// Créer des tests d'intégration pour vérifier que tout fonctionne ensemble
|
||||
func TestMCPServerIntegration(t *testing.T) {
|
||||
// Tester l'intégration complète avec un serveur MCP
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 9 : Déploiement progressif
|
||||
|
||||
### Étape 9.1 : Déploiement en environnement de test
|
||||
|
||||
```bash
|
||||
# Déployer la version migrée en environnement de test
|
||||
docker build -t localagi-mcp-migration:test .
|
||||
docker run -d --name localagi-test localagi-mcp-migration:test
|
||||
```
|
||||
|
||||
### Étape 9.2 : Surveillance et correction
|
||||
|
||||
```bash
|
||||
# Surveiller les logs pour détecter d'éventuels problèmes
|
||||
docker logs -f localagi-test
|
||||
|
||||
# Corriger les problèmes identifiés
|
||||
# ...
|
||||
|
||||
# Redéployer
|
||||
docker build -t localagi-mcp-migration:test-v2 .
|
||||
docker run -d --name localagi-test-v2 localagi-mcp-migration:test-v2
|
||||
```
|
||||
|
||||
### Étape 9.3 : Déploiement en production
|
||||
|
||||
```bash
|
||||
# Une fois les tests validés, déployer en production
|
||||
docker build -t localagi:latest .
|
||||
# Déployer selon votre processus habituel
|
||||
```
|
||||
|
||||
## Considérations supplémentaires
|
||||
|
||||
### Compatibilité avec les serveurs MCP existants
|
||||
|
||||
Il est important de vérifier que mark3labs/mcp-go est compatible avec les serveurs MCP existants auxquels votre application se connecte. Si des différences de protocole existent, des adaptations supplémentaires pourraient être nécessaires.
|
||||
|
||||
### Documentation
|
||||
|
||||
Documenter tous les changements effectués et les différences de comportement entre les deux bibliothèques. Cela facilitera la maintenance future et aidera les développeurs à comprendre les choix de migration.
|
||||
|
||||
### Formation
|
||||
|
||||
Prévoir une session de formation pour les développeurs afin de les familiariser avec la nouvelle bibliothèque et ses particularités.
|
||||
|
||||
## Diagramme de séquence de la migration
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Dev as Développeur
|
||||
participant Git as Système de contrôle de version
|
||||
participant Test as Environnement de test
|
||||
participant Prod as Production
|
||||
|
||||
Dev->>Git: Créer branche de migration
|
||||
Dev->>Git: Modifier importations
|
||||
Dev->>Git: Adapter structures
|
||||
Dev->>Git: Migrer clients HTTP
|
||||
Dev->>Git: Migrer clients STDIO
|
||||
Dev->>Git: Migrer définition des outils
|
||||
Dev->>Git: Migrer appel des outils
|
||||
Dev->>Git: Migrer gestion des résultats
|
||||
Dev->>Git: Migrer gestion des sessions
|
||||
Dev->>Git: Écrire tests unitaires
|
||||
Dev->>Git: Écrire tests d'intégration
|
||||
Git->>Test: Déployer en test
|
||||
Test->>Dev: Retour d'erreurs
|
||||
Dev->>Git: Corrections
|
||||
Git->>Test: Redéployer en test
|
||||
Test->>Dev: Validation
|
||||
Git->>Prod: Déployer en production
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Ce plan de migration détaillé devrait vous guider efficacement à travers le processus de remplacement de metoro-io/mcp-golang par mark3labs/mcp-go. La migration nécessitera des modifications significatives du code existant, mais les avantages potentiels en termes de maintenance, de fonctionnalités et de robustesse justifient cet effort.
|
||||
|
||||
Les principales difficultés résident dans les différences d'API et la façon dont les transports et les outils sont configurés et utilisés. Une approche progressive, avec des tests approfondis à chaque étape, est recommandée pour minimiser les risques.
|
||||
|
||||
N'hésitez pas à adapter ce plan en fonction des spécificités de votre projet et des découvertes faites pendant la migration.
|
||||
Reference in New Issue
Block a user