基于 SOC 职业分类
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill eva-agent-mcp-development命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
Concevoir et maintenir un watchdog auto-correcteur pour services HTTP — checks de santé, auto-restart, état persistant, rapports et pièges bash.
Serveur de messagerie sécurisé auto-hébergé (Signal-like) avec Flask + WebSocket + AES-256-GCM + pont EVA
ADAM-SENTINEL — Veilleur technologique 24h/24h. Scanne 10 domaines, cree des rapports, met a jour les skills, alerte sur les CVE et breaking changes.
| name | EVA-agent-mcp-development |
| description | Développer des serveurs Model Context Protocol (MCP) personnalisés pour EVA Agent. |
| version | 2.0.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| platforms | ["linux","macos","windows"] |
| metadata | {"EVA":{"tags":["mcp","EVA-agent","model-context-protocol","custom-tools","multi-agent","development","fastmcp","python","json-rpc","stdio"],"related_skills":["EVA-agent","software-development","python-pep8","codex"]}} |
Le Model Context Protocol (MCP) est un protocole standard ouvert qui permet aux modèles de langage (LLM) d'interagir de manière sécurisée avec des sources de données locales, des APIs et des outils système. Développé par la société Anthropic, le MCP définit un contrat d'interface clair entre l'agent (hôte MCP) et les serveurs d'outils.
Cette compétence guide la création de serveurs MCP personnalisés en Python à l'aide de la bibliothèque FastMCP (daskey/fastmcp) ou de la SDK MCP officielle, et explique comment déclarer et configurer ces serveurs dans EVA Agent.
EVA Agent
│
├── Outils natifs (intégrés)
├── Outils skills (locaux)
└── Serveurs MCP externes ←── Vous êtes ici
│
┌─────┴─────┐
│ STDIO │ Communication via entrée/sortie standard (JSON-RPC)
└─────┬─────┘
│
┌─────────▼─────────┐
│ MCP Server (Python)│ ← Votre code : outils, ressources, prompts
│ - Outils (tools) │
│ - Ressources │
│ - Prompts │
└───────────────────┘
À utiliser lorsque l'utilisateur demande de :
cli-config.yaml ou config.yaml de EVA.# Fichier : mcp_server_custom.py
# Installation requise : pip install mcp[cli] ou fastmcp
from mcp.server.fastmcp import FastMCP
import sys
import logging
# Configuration du logging sur stderr (NE PAS polluer stdout !)
logging.basicConfig(level=logging.INFO, stream=sys.stderr,
format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Initialisation du serveur
mcp = FastMCP("EVA Industry Link")
@mcp.tool()
def get_machine_status(machine_id: str) -> str:
"""
Récupère le statut actuel d'une machine de production à partir de son ID.
Args:
machine_id: L'identifiant unique de la machine (ex: 'PLC_01', 'PLC_02').
"""
logger.info(f"Requête get_machine_status pour {machine_id}")
# Simulation d'un appel à une base OT ou API d'usine
statuses = {
"PLC_01": "RUNNING - Vitesse: 1450 rpm - Temp: 62°C",
"PLC_02": "STOPPED - Défaut arrêt d'urgence actif",
}
return statuses.get(machine_id,
f"Machine {machine_id} introuvable ou hors ligne")
@mcp.resource("report://production/today")
def get_daily_report() -> str:
"""Renvoie le rapport textuel de la production du jour (ressource)."""
return "Rapport EVA du jour : OEE global de 82.4%, aucune panne majeure."
if __name__ == "__main__":
mcp.run()
from mcp.server.fastmcp import FastMCP
from pydantic import BaseModel, Field
from typing import Optional
import json
mcp = FastMCP("API Météo Industrielle")
class WeatherQuery(BaseModel):
city: str = Field(..., description="Nom de la ville (ex: Lyon)")
units: Optional[str] = Field("metric", description="metric ou imperial")
@mcp.tool()
def get_weather(query: WeatherQuery) -> str:
"""
Récupère les données météorologiques pour une ville donnée.
Args:
query: Paramètres de la requête (ville et unités).
"""
# Simulation d'appel API météo
data = {
"city": query.city,
"temperature": 22.5 if query.units == "metric" else 72.5,
"humidity": 65,
"conditions": "Partiellement nuageux"
}
return json.dumps(data, indent=2)
@mcp.tool()
def calculate_oee(availability: float, performance: float, quality: float) -> dict:
"""
Calcule le taux de rendement synthétique (OEE/TRS).
Args:
availability: Disponibilité (0.0 - 1.0)
performance: Performance (0.0 - 1.0)
quality: Qualité (0.0 - 1.0)
"""
oee = availability * performance * quality *
{
: (oee, ),
: availability,
: performance,
: quality,
: oee >= (
oee >= oee >=
)
}
Pour enregistrer un serveur MCP personnalisé, ajouter une entrée dans la section mcp_servers du fichier de configuration EVA (~/.EVA/config.yaml ou cli-config.yaml) :
mcp_servers:
EVA-industry-link:
command: "python"
args: ["C:/chemin/absolu/vers/mcp_server_custom.py"]
env:
DB_PASSWORD: "mot_de_passe_secret"
API_ENDPOINT: "https://api.usine.local"
# Optionnel : activer uniquement dans certains contextes
# enabled: true
# timeout: 30
api-meteo:
command: "python"
args: ["/chemin/absolu/vers/meteo_server.py"]
# Vérifier que le serveur est détecté et que ses outils sont chargés
EVA doctor
# Tester un outil MCP via le chat
EVA chat -q "Quel est le statut de la machine PLC_01 ?"
# Voir les logs MCP (sur stderr) :
EVA chat --verbose -q "..."
mon-projet-mcp/
├── server.py # Point d'entrée du serveur MCP
├── tools/
│ ├── __init__.py
│ ├── plc_tools.py # Outils liés aux automates
│ └── quality_tools.py # Outils qualité/OEE
├── resources/
│ ├── __init__.py
│ └── reports.py # Ressources (rapports en lecture seule)
├── models/
│ ├── __init__.py
│ └── schemas.py # Modèles Pydantic pour validation
├── utils/
│ ├── __init__.py
│ ├── db.py # Connexion base de données
│ └── logging_config.py # Configuration logging (stderr)
├── requirements.txt # Dépendances Python
└── README.md # Documentation
Les ressources permettent d'exposer des données structurées (fichiers, rapports, configurations) :
@mcp.resource("config://plc/defaults")
def get_plc_defaults() -> str:
"""Paramètres par défaut pour la configuration des automates."""
return json.dumps({
"watchdog_timeout_ms": 500,
"retry_count": 3,
"default_broker": "mqtt://192.168.1.10:1883"
})
@mcp.resource("docs://api/reference")
def get_api_docs() -> str:
"""Documentation de référence de l'API d'usine."""
with open("/chemin/absolu/vers/api_reference.md", "r") as f:
return f.read()
Les prompts MCP sont des templates de messages qui guident le LLM :
@mcp.prompt()
def diagnose_plc_error(error_code: str) -> str:
"""Génère un prompt de diagnostic pour une erreur automate.
Args:
error_code: Code d'erreur à diagnostiquer.
"""
return f"""
Tu es un expert en diagnostic d'automates industriels.
Analyse le code d'erreur suivant et propose des actions correctives :
Code erreur : {error_code}
Format de réponse :
1. Description de l'erreur
2. Causes possibles
3. Actions correctives immédiates
4. Actions correctives à long terme
"""
import logging
import sys
logging.basicConfig(
level=logging.INFO,
stream=sys.stderr, # CRITIQUE : ne pas utiliser sys.stdout
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s'
)
logger = logging.getLogger(__name__)
from mcp.server.fastmcp import FastMCP
import traceback
mcp = FastMCP("Robust Server")
@mcp.tool()
def read_database(query: str) -> str:
"""Lecture sécurisée d'une base de données."""
try:
# Tentative de connexion et lecture
result = execute_query(query)
return str(result)
except ConnectionError as e:
logger.error(f"Erreur de connexion DB: {e}")
return "ERREUR: Base de données inaccessible. Vérifier la connexion réseau."
except Exception as e:
logger.error(f"Erreur inattendue: {e}\n{traceback.format_exc()}")
return f"ERREUR: {str(e)}"
Pollution du flux de communication STDIO :
print("Début du traitement...") dans le code du serveur. Cela pollue le canal stdout que le protocole MCP utilise pour échanger ses messages JSON-RPC, provoquant le plantage de l'intégration dans EVA.sys.stderr. Exemple : logging.basicConfig(level=logging.INFO, stream=sys.stderr).Types de paramètres non typés ou sans description :
@mcp.tool(), ni fournir de docstring. Le LLM ne saura pas comment ni quand appeler l'outil et l'ignorera.machine_id: str). Ajouter des descriptions Pydantic Field pour les modèles complexes.Absence de chemins absolus dans la configuration :
config.yaml. Si EVA est lancé depuis un autre répertoire, le script ne sera pas trouvé.C:/Users/utilisateur/projet/mcp_server_custom.py.Timeout trop court pour les outils longs :
timeout: 120. Pour les opérations très longues, envisager un mécanisme asynchrone (file d'attente, callback).Décorateur manquant pour les outils :
@mcp.tool(). La fonction existe mais n'est pas exposée comme outil.@mcp.tool(). Vérifier avec EVA doctor que l'outil est bien listé.Dépendances manquantes dans l'environnement EVA :
print() n'écrit sur stdout en dehors de la boucle principale MCP. Les logs écrivent sur stderr.EVA doctor confirme que le serveur est joignable et charge ses outils.Field(description=...)..venv du projet EVA.pip install -r requirements.txt ou les déclarer dans le script lui-même avec un message d'erreur explicite en cas d'import manquant.