Intégration de FastMCP avec le code Claude
Intégration de FastMCP avec Claude Code
Claude Code est l'outil CLI officiel d'Anthropic qui prend en charge les serveurs MCP, vous permettant d'étendre les capacités de Claude avec vos serveurs FastMCP personnalisés. Cette intégration permet des flux de travail de développement puissants où Claude peut accéder à vos outils, ressources et fonctionnalités spécifiques à votre domaine.
Pourquoi intégrer avec Claude Code ?
L'intégration de Claude Code offre plusieurs avantages convaincants :
- Flux de travail de développement amélioré : Accédez à vos outils personnalisés directement depuis Claude.
- Assistance contextuelle : Claude peut lire les ressources et la configuration de votre projet.
- Tâches automatisées : Exécutez des opérations complexes via vos outils MCP.
- Support local et à distance : Connectez-vous aussi bien aux serveurs de développement locaux qu'aux services déployés.
- Interaction en temps réel : Découverte et exécution dynamiques des outils.
Configuration de votre serveur FastMCP
Création d'un serveur de développement
Créons un serveur FastMCP complet, conçu pour les flux de travail de développement :
# dev_server.py
import os
import subprocess
import json
from pathlib import Path
from datetime import datetime
from fastmcp import FastMCP, Context
mcp = FastMCP(
name="Assistant au développement",
instructions="""
Ce serveur fournit des outils de développement, notamment :
- Analyse de projet et opérations sur les fichiers
- Opérations Git et gestion de dépôt
- Vérifications de la qualité du code et tests
- Gestion de l'environnement et des dépendances
"""
)
@mcp.tool
def run_command(command: str, cwd: str = ".") -> dict:
"""Exécute une commande shell et renvoie le résultat."""
try:
result = subprocess.run(
command.split(),
cwd=cwd,
capture_output=True,
text=True,
timeout=30
)
return {
"command": command,
"returncode": result.returncode,
"stdout": result.stdout,
"stderr": result.stderr,
"success": result.returncode == 0
}
except subprocess.TimeoutExpired:
return {"error": "La commande a expiré après 30 secondes"}
except Exception as e:
return {"error": str(e)}
@mcp.tool
def analyze_project_structure(path: str = ".") -> dict:
"""Analyse la structure d'un répertoire de projet."""
project_path = Path(path)
if not project_path.exists():
return {"error": f"Le chemin {path} n'existe pas"}
structure = {
"root": str(project_path.absolute()),
"files": [],
"directories": [],
"python_files": [],
"config_files": [],
"total_size": 0
}
config_extensions = {".json", ".yaml", ".yml", ".toml", ".ini", ".cfg"}
for item in project_path.rglob("*"):
if item.is_file():
size = item.stat().st_size
structure["total_size"] += size
file_info = {
"path": str(item.relative_to(project_path)),
"size": size,
"modified": datetime.fromtimestamp(item.stat().st_mtime).isoformat()
}
structure["files"].append(file_info)
if item.suffix == ".py":
structure["python_files"].append(file_info)
elif item.suffix in config_extensions:
structure["config_files"].append(file_info)
elif item.is_dir():
structure["directories"].append(str(item.relative_to(project_path)))
return structure
@mcp.tool
async def check_code_quality(file_path: str, ctx: Context) -> dict:
"""Vérifie la qualité du code à l'aide de divers outils de linting."""
await ctx.info(f"Vérification de la qualité du code pour {file_path}...")
if not os.path.exists(file_path):
return {"error": f"Le fichier {file_path} est introuvable"}
results = {"file": file_path, "checks": {}}
# Vérifier avec différents outils
tools = {
"flake8": ["flake8", file_path],
"pylint": ["pylint", file_path, "--output-format=json"],
"mypy": ["mypy", file_path]
}
for tool, command in tools.items():
try:
result = subprocess.run(
command,
capture_output=True,
text=True,
timeout=15
)
results["checks"][tool] = {
"returncode": result.returncode,
"output": result.stdout,
"errors": result.stderr
}
except (subprocess.TimeoutExpired, FileNotFoundError):
results["checks"][tool] = {"error": f"{tool} non disponible ou a expiré"}
return results
@mcp.resource("project://config")
def get_project_config() -> dict:
"""Obtient la configuration du projet à partir de divers fichiers de configuration."""
config = {"found_files": [], "configurations": {}}
config_files = [
"pyproject.toml", "setup.py", "requirements.txt",
"package.json", "Dockerfile", ".env", "config.yaml"
]
for config_file in config_files:
if os.path.exists(config_file):
config["found_files"].append(config_file)
try:
with open(config_file, 'r') as f:
content = f.read()
config["configurations"][config_file] = {
"content": content[:1000] + ("..." if len(content) > 1000 else ""),
"size": len(content)
}
except Exception as e:
config["configurations"][config_file] = {"error": str(e)}
return config
@mcp.resource("git://status")
def get_git_status() -> dict:
"""Obtient l'état actuel du dépôt Git."""
try:
# Vérifier si nous sommes dans un dépôt git
subprocess.run(["git", "rev-parse", "--git-dir"],
check=True, capture_output=True)
# Obtenir diverses informations git
commands = {
"branch": ["git", "branch", "--show-current"],
"status": ["git", "status", "--porcelain"],
"last_commit": ["git", "log", "-1", "--pretty=format:%H|%an|%ad|%s"],
"remote": ["git", "remote", "-v"]
}
result = {}
for key, command in commands.items():
try:
output = subprocess.run(
command, capture_output=True, text=True, check=True
).stdout.strip()
result[key] = output
except subprocess.CalledProcessError:
result[key] = "non disponible"
return result
except subprocess.CalledProcessError:
return {"error": "Pas un dépôt git"}
if __name__ == "__main__":
mcp.run(transport="http", host="127.0.0.1", port=8000)
Connexion à Claude Code
Démarrer votre serveur
Tout d'abord, démarrez votre serveur FastMCP :
# Démarrez le serveur en mode HTTP
python dev_server.py
Votre serveur sera accessible à http://127.0.0.1:8000/mcp/
Ajout du serveur à Claude Code
Utilisez les commandes de gestion MCP de Claude Code pour ajouter votre serveur :
# Ajoutez votre serveur FastMCP
claude mcp add dev-assistant --transport http http://localhost:8000/mcp/
# Vérifiez que le serveur est connecté
claude mcp list
Alternative : Transport STDIO
Pour le développement local, vous pourriez préférer le transport STDIO :
# dev_server_stdio.py
# ... (même code de serveur que ci-dessus)
if __name__ == "__main__":
mcp.run() # Utilise STDIO par défaut
Ajoutez-le à Claude Code :
claude mcp add dev-assistant --transport stdio "python dev_server_stdio.py"
Utilisation de votre serveur avec Claude Code
Une fois connecté, vous pouvez interagir avec votre serveur MCP via Claude Code :
Utilisation de base des outils
# Claude découvrira et utilisera automatiquement vos outils
claude "Analyse la structure de mon projet actuel"
# Claude appellera votre outil analyze_project_structure
# La réponse inclura le nombre de fichiers, les tailles et l'organisation
Accès aux ressources
Claude peut accéder aux ressources de votre serveur en utilisant les méta-données @
:
# Accéder à la configuration du projet
claude "Quels fichiers de configuration ce projet contient-il ? Utilise @dev-assistant:project://config"
# Vérifier l'état de Git
claude "Quel est l'état actuel de Git ? Utilise @dev-assistant:git://status"
Flux de travail complexes
Combinez plusieurs outils pour des opérations sophistiquées :
claude "Vérifiez la qualité du code de tous les fichiers Python dans le répertoire src/ et résumez les problèmes"
# Claude fera :
# 1. Utiliser analyze_project_structure pour trouver les fichiers Python
# 2. Utiliser check_code_quality sur chaque fichier
# 3. Résumer les résultats
Exemples de configuration avancée
Serveur de développement avec outils de base de données
# db_server.py
import sqlite3
from fastmcp import FastMCP
mcp = FastMCP("Outils de base de données")
@mcp.tool
def query_database(query: str, db_path: str = "app.db") -> dict:
"""Exécute une requête SQL sur la base de données."""
try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute(query)
if query.strip().upper().startswith("SELECT"):
results = cursor.fetchall()
columns = [description[0] for description in cursor.description]
return {
"columns": columns,
"rows": results,
"count": len(results)
}
else:
conn.commit()
return {"affected_rows": cursor.rowcount}
except Exception as e:
return {"error": str(e)}
finally:
conn.close()
@mcp.resource("db://schema")
def get_database_schema() -> dict:
"""Obtient les informations sur le schéma de la base de données."""
# Implémentation pour lire le schéma de la base de données
pass
if __name__ == "__main__":
mcp.run(transport="http", port=8001)
API Testing Server
# api_server.py
import requests
from fastmcp import FastMCP, Context
mcp = FastMCP("Outils de test d'API")
@mcp.tool
async def test_api_endpoint(url: str, method: str = "GET",
headers: dict = None, data: dict = None,
ctx: Context = None) -> dict:
"""Teste un point de terminaison d'API et renvoie des résultats détaillés."""
await ctx.info(f"Test de {method} {url}...")
try:
response = requests.request(
method=method.upper(),
url=url,
headers=headers or {},
json=data,
timeout=10
)
return {
"url": url,
"method": method.upper(),
"status_code": response.status_code,
"headers": dict(response.headers),
"response_time": response.elapsed.total_seconds(),
"body": response.text[:1000] if response.text else None,
"success": 200 <= response.status_code < 300
}
except Exception as e:
return {
"url": url,
"method": method.upper(),
"error": str(e),
"success": False
}
if __name__ == "__main__":
mcp.run(transport="http", port=8002)
Configuration de serveurs multiples
Vous pouvez connecter plusieurs serveurs FastMCP à Claude Code :
# Ajoutez plusieurs serveurs
claude mcp add dev-tools --transport http http://localhost:8000/mcp/
claude mcp add db-tools --transport http http://localhost:8001/mcp/
claude mcp add api-tools --transport http http://localhost:8002/mcp/
# Claude peut maintenant accéder à tous les serveurs
claude "Vérifiez la structure du projet, puis testez les points de terminaison de l'API définis dans la configuration"
Dépannage des problèmes courants
Le serveur ne répond pas
# Vérifiez si le serveur est en cours d'exécution
curl http://localhost:8000/mcp/
# Supprimez et ré-ajoutez le serveur
claude mcp remove dev-assistant
claude mcp add dev-assistant --transport http http://localhost:8000/mcp/
Outil introuvable
Assurez-vous que votre serveur est correctement enregistré et que les outils sont décorés :
# Assurez-vous que les outils sont correctement décorés
@mcp.tool # Ce décorateur est requis
def my_tool():
pass
Problèmes d'accès aux ressources
Vérifiez le format des URI de ressources :
# Bon format
claude "Utilisez @server-name:resource://uri"
# Pas @server-name/resource://uri
Bonnes pratiques pour l'intégration de Claude Code
- Noms d'outils clairs : Utilisez des noms d'outils descriptifs et explicites.
- Bonne documentation : Incluez des docstrings complètes.
- Gestion des erreurs : Fournissez des messages d'erreur significatifs.
- Organisation des ressources : Utilisez des schémas d'URI logiques pour les ressources.
- Performance : Maintenez des temps d'exécution raisonnables pour les outils.
- Sécurité : Validez les entrées et limitez les opérations dangereuses.
Prochaines étapes
Une fois votre serveur FastMCP intégré à Claude Code, vous pouvez :
- Construire des assistants de développement spécifiques à votre domaine.
- Automatiser des tâches complexes de gestion de projet.
- Créer des outils personnalisés d'analyse et de contrôle qualité du code.
- Développer des flux de travail spécialisés pour les tests et le déploiement.
Dans la dernière section, nous explorerons des modèles avancés, le déploiement en production et les stratégies de mise à l'échelle pour vos serveurs FastMCP.