Intégration Python - OpenLegi MCP
🎯 Recommandation importante
Pour une intégration simple et robuste, nous recommandons d'utiliser les librairies officielles MCP :
- MCP Python SDK : SDK officiel avec support complet du protocole
- Claude Desktop : Intégration native dans l'interface Claude
La classe OpenLegiClient ci-dessous est fournie à titre éducatif et pour les cas d'usage avancés nécessitant un contrôle fin du protocole.
Installation
pip install requests
Configuration
URLs de base
| Environnement | URL |
|---|---|
| Production | https://mcp.openlegi.fr |
| Local | http://localhost:3000 |
Services disponibles
| Service | Endpoint | Description |
|---|---|---|
| Légifrance | /legifrance/mcp |
Codes, jurisprudences, JORF, textes légaux |
| INPI | /inpi/mcp |
Registre du commerce et des sociétés |
| EUR-Lex | /eurlex/mcp |
Droit européen |
Authentification
Trois méthodes supportées :
1. Header Authorization (recommandé)
session.headers.update({
"Authorization": "Bearer VOTRE_TOKEN_ICI"
})
2. Query Parameter
url = f"https://mcp.openlegi.fr/legifrance/mcp?token=VOTRE_TOKEN"
3. Path Token
url = "https://mcp.openlegi.fr/legifrance/mcp/token/VOTRE_TOKEN"
Client Python OpenLegiClient
Classe complète
import requests
import json
class OpenLegiClient:
"""Client Python pour l'API OpenLegi MCP.
Gère le protocole MCP avec support du format SSE (Server-Sent Events).
"""
def __init__(
self,
token: str,
service: str = "legifrance",
base_url: str = "https://mcp.openlegi.fr"
):
"""Initialise le client MCP.
Args:
token: Token d'authentification OpenLegi
service: Service à utiliser ('legifrance', 'inpi', 'eurlex')
base_url: URL de base du serveur MCP
"""
self.base_url = base_url
self.service = service
self.endpoint = f"{base_url}/{service}/mcp"
self.session = requests.Session()
# Headers requis par le protocole MCP
self.session.headers.update({
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream", # Les deux types sont requis
"Authorization": f"Bearer {token}"
})
# Initialiser la session MCP
self._initialize()
def _initialize(self):
"""Initialise la session MCP et récupère le session ID."""
payload = {
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "OpenLegiClient",
"version": "1.0.0"
}
}
}
response = self.session.post(self.endpoint, json=payload)
response.raise_for_status()
# Récupérer le session ID du header
session_id = response.headers.get('mcp-session-id')
if session_id:
self.session.headers.update({"mcp-session-id": session_id})
@staticmethod
def _parse_sse_response(text: str) -> dict:
"""Parse une réponse SSE et extrait le JSON de la ligne data:.
Le serveur MCP renvoie les réponses au format SSE :
event: message
data: {"jsonrpc":"2.0","id":1,"result":{...}}
Args:
text: Texte brut de la réponse HTTP
Returns:
Dictionnaire JSON extrait de la ligne 'data:'
Raises:
ValueError: Si aucune ligne 'data:' n'est trouvée
"""
lines = text.strip().split('\n')
for line in lines:
if line.startswith('data: '):
return json.loads(line[6:]) # Retire 'data: ' et parse le JSON
raise ValueError("Aucune ligne 'data:' trouvée dans la réponse SSE")
def call_tool(self, tool_name: str, arguments: dict) -> dict:
"""Appelle un tool MCP avec les arguments fournis.
Args:
tool_name: Nom du tool à appeler (ex: 'rechercher_code')
arguments: Dictionnaire des arguments du tool
Returns:
Résultat du tool (contenu du champ 'result')
Raises:
requests.HTTPError: Si la requête HTTP échoue
Exception: Si le serveur renvoie une erreur JSON-RPC
"""
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": tool_name,
"arguments": arguments
}
}
response = self.session.post(self.endpoint, json=payload)
response.raise_for_status()
# Parser la réponse SSE
result = self._parse_sse_response(response.text)
if "error" in result:
raise Exception(f"Erreur MCP: {result['error']}")
return result["result"]
def list_tools(self) -> list[dict]:
"""Liste tous les tools disponibles sur le serveur.
Returns:
Liste des tools avec leurs métadonnées (name, description, inputSchema)
Raises:
requests.HTTPError: Si la requête HTTP échoue
"""
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
response = self.session.post(self.endpoint, json=payload)
response.raise_for_status()
# Parser la réponse SSE
result = self._parse_sse_response(response.text)
return result["result"]["tools"]
def close(self):
"""Ferme la session HTTP."""
self.session.close()
def __enter__(self):
"""Support du context manager (with statement)."""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Fermeture automatique de la session."""
self.close()
Exemples d'utilisation
1. Lister les tools disponibles
from openlegi_client import OpenLegiClient
# Créer le client avec votre token
token = "votre_token_ici"
with OpenLegiClient(token=token) as client:
# Récupérer la liste des tools
tools = client.list_tools()
print(f"📋 {len(tools)} tools disponibles:\n")
for tool in tools:
print(f"🔧 {tool['name']}")
print(f" {tool['description'][:100]}...")
print()
Sortie attendue :
📋 12 tools disponibles:
🔧 rechercher_dans_texte_legal
Recherche dans les textes légaux consolidés depuis légifrance...
🔧 rechercher_code
Recherche des articles juridiques dans les codes juridiques français...
🔧 rechercher_jurisprudence_judiciaire
Recherche des jurisprudences judiciaires avec validation MCP...
🔧 rechercher_jurisprudence_administrative
Recherche dans la jurisprudence administrative (Conseil d'État...
🔧 rechercher_decisions_cnil
Recherche dans les délibérations et décisions de la CNIL...
🔧 rechercher_conventions_collectives
Recherche dans les conventions collectives (KALI)...
🔧 rechercher_decisions_constitutionnelles
Recherche dans les décisions du Conseil constitutionnel...
🔧 recherche_journal_officiel
Recherche dans le Journal Officiel français...
🔧 dernier_journal_officiel
Récupère le(s) dernier(s) Journal(aux) Officiel(s) publiés...
🔧 lister_codes_juridiques
Liste tous les codes juridiques disponibles sur Legifrance...
🔧 lister_emetteurs_jorf
Liste tous les émetteurs/autorités disponibles pour les recherches JORF...
🔧 lister_natures_textes_jorf
Liste toutes les natures de textes disponibles pour les recherches JORF...
2. Rechercher un article dans un code
from openlegi_client import OpenLegiClient
token = "votre_token_ici"
with OpenLegiClient(token=token) as client:
# Rechercher l'article 9 du Code civil
result = client.call_tool(
tool_name="rechercher_code",
arguments={
"search": "9",
"code_name": "Code civil",
"champ": "NUM_ARTICLE"
}
)
print("📖 Résultat de la recherche:\n")
print(result)
3. Rechercher dans la jurisprudence
from openlegi_client import OpenLegiClient
token = "votre_token_ici"
with OpenLegiClient(token=token) as client:
# Rechercher des décisions sur la responsabilité civile
result = client.call_tool(
tool_name="rechercher_jurisprudence_judiciaire",
arguments={
"search": "responsabilité civile",
"juridiction_judiciaire": ["Cour de cassation"],
"publication_bulletin": ["T"],
"sort": "DATE_DESC",
"page_size": 5
}
)
print("⚖️ Jurisprudences trouvées:\n")
print(result)
4. Consulter le dernier Journal Officiel
from openlegi_client import OpenLegiClient
token = "votre_token_ici"
with OpenLegiClient(token=token) as client:
# Récupérer les 3 derniers JO
result = client.call_tool(
tool_name="dernier_journal_officiel",
arguments={
"nb_jo": 3
}
)
print("📰 Derniers Journaux Officiels:\n")
print(result)
5. Rechercher dans les conventions collectives
from openlegi_client import OpenLegiClient
token = "votre_token_ici"
with OpenLegiClient(token=token) as client:
# Rechercher des conventions sur le télétravail
result = client.call_tool(
tool_name="rechercher_conventions_collectives",
arguments={
"search": "télétravail",
"panorama": True, # Vue d'ensemble sans texte intégral
"page_size": 10
}
)
print("📄 Conventions collectives:\n")
print(result)
6. Lister les codes juridiques disponibles
from openlegi_client import OpenLegiClient
token = "votre_token_ici"
with OpenLegiClient(token=token) as client:
# Lister tous les codes disponibles
result = client.call_tool(
tool_name="lister_codes_juridiques",
arguments={}
)
print("📚 Codes juridiques disponibles:\n")
for code in result:
print(f" • {code}")
Gestion des erreurs
Erreurs HTTP
from openlegi_client import OpenLegiClient
import requests
token = "votre_token_ici"
try:
with OpenLegiClient(token=token) as client:
result = client.call_tool("rechercher_code", {"search": "test"})
except requests.HTTPError as e:
print(f"❌ Erreur HTTP: {e}")
print(f"Status: {e.response.status_code}")
print(f"Détails: {e.response.text}")
Erreurs JSON-RPC
from openlegi_client import OpenLegiClient
token = "votre_token_ici"
try:
with OpenLegiClient(token=token) as client:
# Tool inexistant
result = client.call_tool("tool_qui_nexiste_pas", {})
except Exception as e:
print(f"❌ Erreur MCP: {e}")
Notes importantes
Format SSE (Server-Sent Events)
Le serveur MCP renvoie les réponses au format SSE, même pour les requêtes JSON-RPC simples :
event: message
data: {"jsonrpc":"2.0","id":1,"result":{...}}
C'est pourquoi :
1. Le header Accept doit inclure text/event-stream
2. La réponse doit être parsée ligne par ligne
3. On ne peut pas utiliser directement response.json()
Performance
- Toujours utiliser
requests.Session()pour réutiliser la connexion HTTP - Le context manager (
withstatement) garantit la fermeture de la session - Les credentials PISTE personnels éliminent les limitations de rate limiting
Authentification
- Le token est obligatoire pour tous les endpoints
- Format recommandé : Header
Authorization: Bearer <token> - Testez votre token avec
list_tools()avant d'appeler des tools complexes
Alternatives recommandées
Pour une intégration production, considérez :
- MCP Python SDK - SDK officiel avec :
- Support complet du protocole MCP
- Gestion automatique des sessions
- Streaming SSE natif
-
Types Python stricts
-
Claude Desktop - Pour une utilisation interactive :
- Configuration via
claude_desktop_config.json - Interface graphique native
-
Pas de code nécessaire
-
Claude Code CLI - Pour l'automatisation :
- Intégration Git
- Exécution de tâches complexes
- Support natif des serveurs MCP
Support
- 📧 Contact : support@openlegi.fr
- 📖 Documentation complète : https://auth.openlegi.fr/documentation
- 🐛 Issues : GitHub Issues
Licence
Ce code est fourni sous licence MIT à titre d'exemple éducatif.