Introduction : Ce que vous allez apprendre

Dans ce tutoriel technique, je vais vous guider pas à pas dans la création d'un serveur MCP (Model Context Protocol) fonctionnant sur Debian 12. Que vous soyez développeur cherchant à étendre les capacités de Claude Desktop ou administrateur système souhaitant déployer une infrastructure IA locale, ce guide vous fournira toutes les étapes nécessaires, depuis l'installation des dépendances jusqu'à la configuration finale. L'objectif est simple : faire fonctionner un serveur MCP robuste qui communique avec l'API Claude d'Anthropic, en utilisant les SDK officiels et une configuration réseau optimisée pour Debian 12.

Prérequis système

Avant de commencer, mettons à jour votre système et installons les dépendances essentielles :
# Mise à jour du système Debian 12
sudo apt update && sudo apt upgrade -y

Installation des dépendances essentielles

sudo apt install -y python3 python3-pip python3-venv git curl build-essential

Installation de Node.js 20 LTS via NodeSource

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs

Vérification des versions installées

python3 --version # Devrait afficher Python 3.11.x ou supérieur node --version # Devrait afficher v20.x.x npm --version # Devrait afficher 10.x.x

Architecture d'un serveur MCP

Le Model Context Protocol est un protocole standardisé permettant aux applications d'interagir avec des modèles de langage. Un serveur MCP typique se compose de trois éléments principaux :

Installation paso a paso

Étape 1 : Création de l'environnement projet

# Création du répertoire de projet
mkdir ~/mcp-claude-server && cd ~/mcp-claude-server

Initialisation d'un environnement Python virtuel

python3 -m venv venv source venv/bin/activate

Installation des dépendances Python

pip install --upgrade pip pip install anthropic httpx uvicorn fastapi pydantic python-dotenv

Étape 2 : Configuration de la clé API

Créez un fichier .env pour stocker vos identifiants de manière sécurisée :
# Création du fichier de configuration
cat > .env << 'EOF'

Clé API Anthropic - obtenez-la sur console.anthropic.com

ANTHROPIC_API_KEY=sk-ant-xxxxx-votre-clé-api-ici

Configuration du serveur

SERVER_HOST=0.0.0.0 SERVER_PORT=8080 LOG_LEVEL=INFO EOF

Protection du fichier contenant la clé API

chmod 600 .env

Étape 3 : Implémentation du serveur MCP

Voici le code complet du serveur MCP utilisant le SDK officiel Anthropic :
"""
Serveur MCP (Model Context Protocol) pour Claude Desktop
Implémentation avec le SDK Anthropic officiel
"""

import os
import json
import asyncio
from typing import Optional, List, Dict, Any
from contextlib import asynccontextmanager

from fastapi import FastAPI, HTTPException, BackgroundTasks
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
from anthropic import Anthropic
from dotenv import load_dotenv
import uvicorn
import logging

Chargement des variables d'environnement

load_dotenv()

Configuration du logging

logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__)

Initialisation du client Anthropic

anthropic = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))

Modèles Pydantic pour les requêtes

class MessageRequest(BaseModel): messages: List[Dict[str, str]] model: str = "claude-sonnet-4-20250514" max_tokens: int = Field(default=1024, ge=1, le=8192) temperature: float = Field(default=1.0, ge=0, le=2) system_prompt: Optional[str] = None class ToolDefinition(BaseModel): name: str description: str input_schema: Dict[str, Any] class MCPServer: """Classe principale du serveur MCP""" def __init__(self): self.tools: Dict[str, ToolDefinition] = {} self.app = FastAPI(title="Claude MCP Server") self._setup_middleware() self._setup_routes() def _setup_middleware(self): """Configuration des middlewares FastAPI""" self.app.add_middleware( CORSMiddleware, allow_origins=["*"], # À restreindre en production allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) def _setup_routes(self): """Définition des routes API""" @self.app.get("/health") async def health_check(): return {"status": "healthy", "service": "mcp-claude-server"} @self.app.post("/v1/messages") async def create_message(request: MessageRequest): """Endpoint principal pour envoyer des messages à Claude""" try: # Construction du contexte système system = request.system_prompt or "Vous êtes un assistant IA helpful." # Ajout du contexte MCP si des tools sont enregistrés if self.tools: tools_prompt = self._build_tools_prompt() system = f"{system}\n\n{tools_prompt}" # Appel à l'API Anthropic response = anthropic.messages.create( model=request.model, max_tokens=request.max_tokens, temperature=request.temperature, system=system, messages=request.messages ) return { "id": response.id, "model": response.model, "content": response.content[0].text, "usage": { "input_tokens": response.usage.input_tokens, "output_tokens": response.usage.output_tokens } } except Exception as e: logger.error(f"Erreur lors de l'appel API : {str(e)}") raise HTTPException(status_code=500, detail=str(e)) @self.app.post("/v1/tools") async def register_tool(tool: ToolDefinition): """Enregistrement d'un nouvel outil MCP""" self.tools[tool.name] = tool logger.info(f"Outil enregistré : {tool.name}") return {"status": "registered", "tool": tool.name} @self.app.get("/v1/tools") async def list_tools(): """Liste des outils disponibles""" return {"tools": list(self.tools.values())} @self.app.delete("/v1/tools/{tool_name}") async def unregister_tool(tool_name: str): """Suppression d'un outil""" if tool_name in self.tools: del self.tools[tool_name] return {"status": "unregistered"} raise HTTPException(status_code=404, detail="Outil non trouvé") def _build_tools_prompt(self) -> str: """Construit le prompt décrivant les outils disponibles""" if not self.tools: return "" tools_description = "\n## Outils disponibles\n\n" for name, tool in self.tools.items(): tools_description += f"- **{name}** : {tool.description}\n" tools_description += "\nVous pouvez utiliser ces outils en indiquant leur nom dans votre réponse." return tools_description def run(self, host: str = "0.0.0.0", port: int = 8080): """Démarrage du serveur""" uvicorn.run(self.app, host=host, port=port)

Point d'entrée

if __name__ == "__main__": server = MCPServer() server.run( host=os.getenv("SERVER_HOST", "0.0.0.0"), port=int(os.getenv("SERVER_PORT", 8080)) )

Étape 4 : Configuration de Claude Desktop

Pour connecter Claude Desktop à votre serveur MCP local, vous devez créer un fichier de configuration. Sur Debian, le fichier de configuration se trouve généralement dans ~/.config/Claude/:
# Création du répertoire de configuration Claude
mkdir -p ~/.config/Claude

Création du fichier de configuration MCP

cat > ~/.config/Claude/claude_desktop_config.json << 'EOF' { "mcpServers": { "local-llm": { "command": "uvicorn", "args": [ "--host", "127.0.0.1", "--port", "8080", "mcp_server:app", "--reload" ], "env": { "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}" } } } } EOF echo "Configuration Claude Desktop créée avec succès"

Étape 5 : Démarrage et test du serveur

# Activation de l'environnement virtuel
source ~/mcp-claude-server/venv/bin/activate

Export de la clé API (remplacez par votre vraie clé)

export ANTHROPIC_API_KEY="sk-ant-xxxxx-votre-clé-api-ici"

Démarrage du serveur en arrière-plan

cd ~/mcp-claude-server nohup python3 mcp_server.py > server.log 2>&1 &

Vérification du démarrage

sleep 3 curl -s http://localhost:8080/health

Test de l'endpoint de messages

curl -s -X POST http://localhost:8080/v1/messages \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "Bonjour, peux-tu te présenter?"}], "max_tokens": 200 }'

Comparaison des providers d'API IA

Le choix du provider API influence directement vos coûts et performances. Voici un tableau comparatif des principales options disponibles en 2026 :
Provider Prix approx. (USD/MTok) Latence moyenne Moyens de paiement Modèles disponibles Profil recommandé
HolySheep AI $0.42 - $15 <50ms WeChat, Alipay, Cartes GPT-4.1, Claude Sonnet, Gemini 2.5, DeepSeek V3.2 Développeurs en Asie, budget limité
Anthropic (officiel) $3 - $18 800-1500ms Carte bancaire, virement Claude 3.5, Claude 3 Opus Usage professionnel, qualité maximale
OpenAI (officiel) $2.5 - $60 600-1200ms Carte bancaire GPT-4o, GPT-4 Turbo, o-series Applications d'entreprise
Groq Gratuit - $0.10 20-100ms Carte bancaire Llama 3, Mixtral Prototypage rapide, faible latence

Remarque : Les prix indiqués sont approximatifs et susceptibles de changer. Consultez les grilles tarifaires officielles pour les informations les plus récentes.

Pour les développeurs situés en Asie ou cherchant à optimiser leurs coûts, s'inscrire ici peut offrir des avantages significatifs avec des options de paiement locales et des tarifs compétitifs.

Commandes utiles pour la gestion du serveur

# Voir les logs du serveur en temps réel
tail -f ~/mcp-claude-server/server.log

Arrêter le serveur

pkill -f "python3 mcp_server.py"

Redémarrer le serveur

cd ~/mcp-claude-server && python3 mcp_server.py &

Vérifier que le processus est actif

ps aux | grep mcp_server

Vérifier les ports en écoute

ss -tlnp | grep 8080

Tests automatisés

Créez un fichier de tests pour valider le bon fonctionnement de votre serveur :
"""
Tests unitaires pour le serveur MCP
Exécution : pytest test_mcp_server.py -v
"""

import pytest
from fastapi.testclient import TestClient
from mcp_server import MCPServer

@pytest.fixture
def client():
    """Fixture créant un client de test"""
    # Note: Ces tests nécessitent une clé API valide
    # Définissez ANTHROPIC_API_KEY dans votre environnement
    server = MCPServer()
    return TestClient(server.app)

def test_health_endpoint(client):
    """Test de l'endpoint de santé"""
    response = client.get("/health")
    assert response.status_code == 200
    assert response.json()["status"] == "healthy"

def test_list_tools(client):
    """Test de la liste des outils"""
    response = client.get("/v1/tools")
    assert response.status_code == 200
    assert "tools" in response.json()

def test_register_tool(client):
    """Test de l'enregistrement d'un outil"""
    tool_data = {
        "name": "calculator",
        "description": "Effectue des calculs mathématiques",
        "input_schema": {
            "type": "object",
            "properties": {
                "expression": {"type": "string"}
            }
        }
    }
    response = client.post("/v1/tools", json=tool_data)
    assert response.status_code == 200
    assert response.json()["status"] == "registered"

def test_message_creation(client):
    """Test de création de message (nécessite ANTHROPIC_API_KEY)"""
    message_data = {
        "messages": [
            {"role": "user", "content": "Dis 'test réussi' si tu comprends"}
        ],
        "max_tokens": 50
    }
    response = client.post("/v1/messages", json=message_data)
    # Ce test échouera sans clé API valide
    if response.status_code == 200:
        assert "content" in response.json()

Intégration avec des outils externes

Pour étendre les capacités de votre serveur MCP, vous pouvez intégrer des bibliothèques tierces. Par exemple, pour ajouter un outil de recherche web :
# Ajout d'un tool de recherche web avec DuckDuckGo
pip install duckduckgo-search

Modification dans mcp_server.py

from duckduckgo_search import DDGS class WebSearchTool: """Outil de recherche web via DuckDuckGo""" def __init__(self): self.ddgs = DDGS() def search(self, query: str, max_results: int = 5): """Effectue une recherche web""" results = list(self.ddgs.text(query, max_results=max_results)) return [ { "title": r["title"], "url": r["href"], "snippet": r["body"] } for r in results ]

Enregistrement automatique des tools au démarrage

def register_default_tools(server: MCPServer): """Enregistre les tools par défaut""" server.tools["web_search"] = ToolDefinition( name="web_search", description="Recherche des informations sur le web", input_schema={ "type": "object", "properties": { "query": {"type": "string", "description": "Terme de recherche"}, "max_results": {"type": "integer", "default": 5} }, "required": ["query"] } )

Considérations de sécurité

Pour sécuriser l'accès au serveur en production, utilisez Nginx comme reverse proxy avec SSL :
# /etc/nginx/sites-available/mcp-server
server {
    listen 443 ssl;
    server_name mcp.votredomaine.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Dépannage et erreurs courantes

Erreur 1 : "ModuleNotFoundError: No module named 'anthropic'"

Symptôme : Le serveur refuse de démarrer et affiche une erreur d'import. Solution :
# Activez l'environnement virtuel et réinstallez les dépendances
source ~/mcp-claude-server/venv/bin/activate
pip install anthropic httpx uvicorn fastapi pydantic python-dotenv

Vérification de l'installation

python3 -c "import anthropic; print('OK')"

Erreur 2 : "AuthenticationError: Invalid API key"

Symptôme : L'API retourne une erreur 401 lors des appels. Solution :
# Vérifiez que la clé API est correctement définie
echo $ANTHROPIC_API_KEY

Si vide, rechargez depuis le fichier .env

source ~/mcp-claude-server/.env

Ou exportez manuellement (remplacez par votre vraie clé)

export ANTHROPIC_API_KEY="sk-ant-xxxxx-votre-clé-api"

Redémarrez le serveur

pkill -f "python3 mcp_server.py" cd ~/mcp-claude-server && python3 mcp_server.py &

Erreur 3 : "Connection refused" sur localhost:8080

Symptôme : Le serveur ne répond pas aux requêtes curl. Solution :
# Vérifiez que le processus est en cours d'exécution
ps aux | grep mcp_server

Vérifiez les ports en écoute

ss -tlnp | grep 8080

Consultez les logs d'erreur

cat ~/mcp-claude-server/server.log

Si le port est déjà utilisé, kill le processus ou changez le port

sudo lsof -i :8080

Puis kill le PID offending si nécessaire

Erreur 4 : Timeout lors des appels API

Symptôme : Les requêtes timeout après 30 secondes. Solution :
# Modifiez la configuration du client Anthropic dans mcp_server.py

Ajoutez un timeout plus long

anthropic = Anthropic( api_key=os.getenv("ANTHROPIC_API_KEY"), timeout=120 # Timeout de 120 secondes )

Ou via variable d'environnement

ANTHROPIC_TIMEOUT=120

Mon retour d'expérience

Après avoir déployé plusieurs serveurs MCP en production pour des projets d'entreprise, je peux vous dire que la configuration sur Debian 12 offre une stabilité remarquable. La combination de FastAPI pour le serveur HTTP et du SDK Anthropic pour les appels API constitue une architecture éprouvée qui gère facilement des centaines de requêtes par minute sur un serveur modeste. La partie la plus délicate reste selon mon expérience la gestion des времениouts et des connexions persistantes. J'ai rencontré des problèmes de sessions bloquantes lorsque le modèle mettait trop de temps à répondre, résolus en implémentant un système de queue asynchrone avec Celery. Pour ceux qui cherchent à optimiser leurs coûts, explorer des providers alternatifs peut s'avérer judicieux. J'ai récemment testé HolySheep AI pour des projets personnels et leur intégration avec la structure MCP existante s'est faite sans friction particulière.

Conclusion

Vous disposez maintenant d'un serveur MCP fonctionnel sur Debian 12, prêt à être intégré avec Claude Desktop ou d'autres clients compatibles. Les étapes clés à retenir : Pour approfondir vos connaissances, consultez la documentation officielle du Model Context Protocol et les guides Anthropic sur l'utilisation optimale de leurs modèles. 👉 Inscrivez-vous sur HolySheep AI — crédits offerts