# OpenLegi - Documentation Complete > Serveur MCP pour l'acces aux sources juridiques francaises officielles ## Presentation OpenLegi est un serveur MCP (Model Context Protocol) qui permet aux LLMs d'acceder directement aux bases de donnees juridiques francaises : Legifrance, RNE (Registre National des Entreprises) et EUR-Lex. ## Configuration rapide ### Claude Desktop ```json { "mcpServers": { "Legifrance": { "type": "streamable-http", "url": "https://mcp.openlegi.fr/legifrance/mcp", "headers": { "Authorization": "Bearer VOTRE_TOKEN" } } } } ``` ## Liens - Documentation web : https://auth.openlegi.fr/documentation/ - Dashboard (obtenir token) : https://auth.openlegi.fr/users/dashboard/ - Contact : https://auth.openlegi.fr/contact/ - Endpoint MCP : https://mcp.openlegi.fr/legifrance/mcp --- ## legal ### Mentions légales # Mentions légales ## 1. Éditeur du Site Le site openlegi.fr est édité par : **Me Raphaël d'Assignies** Avocat inscrit au barreau de Paris 12, cours Albert 1er -- 75008 Paris SIREN : 485 393 334 Contact : [Formulaire de contact](https://auth.openlegi.fr/contact/) Directeur de la publication : Me Raphaël d'Assignies ## 2. Hébergeur Le Site est hébergé par : **Clever Cloud SAS** 4, rue Voltaire -- 44000 Nantes, France Site web : ### Politique de confidentialité – openlegi.fr ## 1. Objet et champ d'application La présente politique de confidentialité a pour objet d'informer les utilisateurs du service openlegi.fr (ci‑après le « Service ») des conditions dans lesquelles leurs données à caractère personnel sont collectées, traitées et protégées, conformément au règlement (UE) 2016/679 du 27 avril 2016 (RGPD) et à la loi n° 78‑17 du 6 janvier 1978 modifiée. L'utilisation du Service implique la mise en œuvre de traitements de données à caractère personnel au sens de ces textes. ## 2. Responsable du traitement Le responsable de traitement est l'éditeur du Service openlegi.fr, dont les coordonnées complètes figurent dans les mentions légales accessibles sur le site. ## 3. Catégories de données traitées Dans le cadre du Service, l'éditeur est susceptible de traiter notamment les catégories de données suivantes : ### 3.1. Données d'identification et de compte Nom, prénom, adresse électronique professionnelle, identifiant de compte, mot de passe (stocké sous forme hachée), organisation de rattachement le cas échéant. ### 3.2. Données de configuration du compte Paramètres d'utilisation du Service, préférences techniques, historique de requêtes adressées aux API publiques via le Service (métadonnées). ### 3.3. Données relatives aux clés d'API Clés d'API fournies par l'utilisateur pour accéder aux API juridiques publiques, stockées sous forme chiffrée et non lisible en clair par l'éditeur en dehors des opérations techniques strictement nécessaires au fonctionnement du Service. ### 3.4. Logs techniques et de sécurité Journaux de connexion et d'usage (adresses IP, horodatages, identifiants techniques, codes de réponse, événements de sécurité), nécessaires au bon fonctionnement, à la sécurité et à la traçabilité du Service. ### 3.5. Données relatives aux demandes d'exercice de droits Contenu des demandes adressées via le système de tickets intégré au Service ou via le formulaire de contact, ainsi que les échanges intervenus à cette occasion. Les données juridiques publiques consultées via le Service (textes législatifs et réglementaires, décisions de justice, informations issues de registres publics, etc.) ne sont pas produites par l'éditeur et relèvent des régimes propres à chaque producteur de données (Légifrance, INPI, etc.), qui mettent en œuvre leur propre politique de confidentialité. ## 4. Finalités des traitements Les données personnelles sont traitées pour les finalités suivantes : ### 4.1. Gestion des comptes utilisateurs et fourniture du Service Création, gestion et suppression des comptes, configuration des accès, gestion des clés d'API, exécution des requêtes vers les API publiques, mise en forme et restitution des résultats. ### 4.2. Sécurisation et amélioration du Service Gestion de la sécurité des accès et des échanges, prévention et détection des incidents de sécurité ou d'abus, production de journaux techniques, amélioration des performances et de la qualité du Service. ### 4.3. Support utilisateur et gestion des demandes Gestion des demandes d'assistance, des réclamations et des demandes d'exercice de droits, via le système de tickets ou le formulaire de contact. ### 4.4. Respect des obligations légales Conservation de certaines données pour répondre aux obligations légales ou réglementaires applicables, ainsi qu'aux demandes des autorités compétentes. ## 5. Bases légales des traitements Les traitements reposent, selon les cas, sur les bases légales suivantes : ### 5.1. Exécution du contrat (article 6, § 1, b) RGPD) pour les traitements nécessaires à la fourniture du Service et à la gestion du compte utilisateur (gestion du compte, gestion des clés d'API, exécution des requêtes, support). ### 5.2. Intérêt légitime (article 6, § 1, f) RGPD) pour la gestion des demandes transmises via le formulaire de contact, la sécurisation du Service, la prévention des abus, la production de logs techniques, ainsi que l'amélioration et l'optimisation du Service, sous réserve de ne pas porter atteinte aux droits et libertés des personnes concernées. ### 5.3. Respect d'obligations légales (article 6, § 1, c) RGPD) pour la conservation de certaines données, notamment dans le cadre des demandes d'exercice de droits, afin de répondre aux obligations légales, réglementaires ou aux demandes des autorités. ## 6. Durées de conservation Les données personnelles sont conservées pour des durées limitées, proportionnées aux finalités poursuivies, puis supprimées ou anonymisées. - **Données de compte** : pendant toute la durée d'activation du compte, puis pendant une durée maximale de cinq (5) ans à compter de la clôture du compte, à des fins de preuve et de gestion des litiges. - **Clés d'API chiffrées** : pendant la durée d'activation du compte ou jusqu'à leur révocation par l'utilisateur, puis suppression ou anonymisation sans possibilité de restauration. - **Logs techniques** : pendant une durée maximale de douze (12) mois à compter de leur enregistrement, aux seules fins de sécurité, de traçabilité et d'amélioration du Service. - **Données relatives aux demandes d'exercice de droits** : pendant le temps nécessaire au traitement de la demande, puis archivage pendant une durée maximale de cinq (5) ans à des fins de preuve du respect des obligations issues du RGPD. L'éditeur s'engage à limiter les durées de conservation conformément aux principes de minimisation et de limitation de la conservation prévus à l'article 5 du RGPD. ## 7. Destinataires des données et sous‑traitants Les données personnelles sont destinées aux seules équipes habilitées de l'éditeur, dans la limite de leurs attributions respectives. L'éditeur peut faire appel à des prestataires techniques agissant en qualité de sous‑traitants au sens de l'article 28 du RGPD (hébergement, maintenance, support, etc.), lesquels ne peuvent traiter les données que sur instruction documentée de l'éditeur et dans le cadre de contrats écrits comportant les clauses exigées par le RGPD. **Liste des sous‑traitants** - CleverCloud SAS, 4 rue Voltaire – 44000 Nantes (France) Les données peuvent, le cas échéant, être communiquées à des autorités administratives ou judiciaires, sur requête et dans la limite de ce qui est requis par les textes applicables. ## 8. Transferts de données hors de l'Union européenne Les données personnelles sont hébergées et traitées au sein de l'Union européenne. Si certains sous‑traitants ou prestataires techniques sont situés dans des pays tiers au sens du chapitre V du RGPD, l'éditeur s'assure de la mise en place de garanties appropriées (décisions d'adéquation, clauses contractuelles types, règles d'entreprise contraignantes ou tout autre mécanisme prévu aux articles 44 et suivants du RGPD). En tout état de cause, les transferts éventuels sont encadrés de manière à garantir un niveau de protection des données personnelles substantiellement équivalent à celui applicable au sein de l'Union européenne. ## 9. Sécurité des données L'éditeur met en œuvre des mesures techniques et organisationnelles appropriées pour assurer un niveau de sécurité adapté aux risques, notamment : chiffrement des clés d'API, hachage des mots de passe, journalisation des accès, contrôle des habilitations, procédures de sauvegarde et de restauration et, le cas échéant, pseudonymisation de certaines données. L'utilisateur est toutefois informé qu'aucun système n'est totalement sécurisé et qu'il lui appartient de mettre en œuvre des mesures appropriées pour protéger ses propres systèmes, identifiants et clés d'API. ## 10. Droits des personnes concernées et modalités d'exercice Conformément aux articles 15 à 22 du RGPD, toute personne concernée dispose, dans les conditions prévues par ces textes, des droits suivants : droit d'accès, de rectification, d'effacement, de limitation du traitement, d'opposition et, le cas échéant, droit à la portabilité. Ces droits peuvent être exercés : - via le système de tickets intégré à l'interface du Service pour les utilisateurs disposant d'un compte ; - via le formulaire de contact mis à disposition sur le site pour les personnes ne disposant pas de compte ou ne pouvant y accéder. L'éditeur s'efforce de répondre aux demandes dans les meilleurs délais et au plus tard dans le délai d'un (1) mois à compter de leur réception, prorogeable dans les cas prévus par l'article 12 du RGPD. En cas de doute raisonnable sur l'identité du demandeur, l'éditeur peut solliciter la fourniture d'informations complémentaires nécessaires pour confirmer cette identité. Les personnes concernées disposent également du droit d'introduire une réclamation auprès de la Commission nationale de l'informatique et des libertés (CNIL). ## 11. Absence de profilage et caractère gratuit du Service Le Service est fourni à titre gratuit. Aucun profilage à des fins de prospection commerciale n'est réalisé sur la base des données personnelles collectées dans le cadre du Service. Les traitements de données mis en œuvre sont strictement limités aux finalités techniques, de sécurité, de support et de respect des obligations légales décrites dans la présente politique. ## 12. Cookies et traceurs ### 12.1. Cadre juridique applicable L'utilisation de cookies et autres traceurs par le Service est encadrée par l'article 82 de la loi n° 78‑17 du 6 janvier 1978 modifiée, qui transpose l'article 5, paragraphe 3, de la directive 2002/58/CE dite « ePrivacy », telle que modifiée. ### 12.2. Cookies utilisés par le Service Le Service utilise exclusivement des cookies de session et autres traceurs strictement nécessaires à son fonctionnement technique, notamment : - cookies nécessaires à l'authentification et au maintien de la session utilisateur ; - cookies nécessaires à la sécurité des échanges, notamment pour la protection contre les attaques de type « cross‑site request forgery » (CSRF) ou similaires ; - le cas échéant, cookies nécessaires à la mémorisation de certains choix techniques indispensables au fonctionnement du Service. Aucun cookie de mesure d'audience, de suivi publicitaire ou de traçage à des fins marketing n'est déposé ou lu par l'éditeur dans le terminal de l'utilisateur. #### Cookies utilisés | Cookie | Finalité | Durée | HttpOnly | Secure (HTTPS) | |--------|----------|-------|----------|----------------| | `sessionid` | Maintien de la session utilisateur authentifié | Durée de la session navigateur | Oui | Oui | | `csrftoken` | Protection contre les attaques CSRF sur les formulaires | Durée de la session | Non | Oui | | `messages` | Affichage des messages de notification (confirmations, erreurs) | Une seule requête | Non | Non | ### Cookies liés à l'authentification | Cookie | Finalité | Durée | Contexte d'utilisation | |--------|----------|-------|------------------------| | `account_verified_email` | Suivi de la vérification de l'adresse email lors de l'inscription | Durée de la session | Processus d'inscription uniquement | | `socialaccount_state` | Paramètre de sécurité OAuth2 pour la connexion Microsoft | Durée de la session | Connexion via Microsoft Azure AD uniquement | ### 12.3. Consentement de l'utilisateur Conformément à l'article 82 de la loi Informatique et libertés et à la doctrine de la CNIL, les cookies strictement nécessaires à la fourniture d'un service de communication en ligne expressément demandé par l'utilisateur ne requièrent pas le recueil préalable de son consentement. Dès lors que le Service ne recourt qu'à de tels cookies strictement nécessaires, aucun mécanisme de recueil de consentement aux cookies (bandeau, bouton « accepter/refuser ») n'est mis en œuvre. L'utilisateur est informé de l'usage de ces cookies par la présente politique de confidentialité accessible sur le site. ### Conditions Générales d'Utilisation -OpenLegi ## 1. Objet et champ d'application Les présentes conditions générales d'utilisation ont pour objet de définir les conditions dans lesquelles le site Internet openlegi.fr accessible à partir de l'adresse URL suivante : (ci-après le « Site »), édité par Me Raphaël d'Assignies, avocat inscrit au barreau de Paris, dont le cabinet est sis 12 cours Albert 1er, numéro de SIREN 485 393 334 (ci-après l'Éditeur), met à disposition des utilisateurs un service en ligne de passerelle technique permettant d'accéder à des sources de données juridiques publiques françaises, notamment celles mises à disposition via les plateformes Légifrance PISTE et INPI. Le service s'adresse exclusivement à des utilisateurs professionnels agissant dans le cadre de leur activité. ## 2. Définitions **CGU** : désigne les présentes Conditions Générales d'Utilisation ; **Donnée(s) Personnelle(s)** : désigne(nt) les données à caractère personnel de l'Utilisateur collectées et traitées par l'Éditeur dans le cadre de la consultation du Site et des Services et ce, dans les conditions et modalités telles que définies dans la Politique de Confidentialité ; **Politique de Confidentialité** : désigne la politique de confidentialité et de protection des Données Personnelles des Utilisateurs mise en œuvre par l'Éditeur et accessible en cliquant sur le lien suivant : , laquelle fait partie intégrante des présentes CGU ; **Services** : désigne les services proposés par l'Éditeur sur le Site et décrits à l'article 3 des présentes CGU ; **Site** : désigne le site Internet édité par l'Éditeur accessible notamment via l'adresse www.openlegi.fr ; **Utilisateurs** : désigne l'ensemble des utilisateurs, visiteurs du Site. ## 3. Description des services Le service permet à l'Utilisateur de : - configurer et gérer ses propres clés API délivrées par les fournisseurs de données publics (par exemple Légifrance PISTE, INPI) ; - effectuer, via un serveur intermédiaire, des requêtes vers ces API, selon les paramètres qu'il définit ; - recevoir en retour les données juridiques correspondantes, sans modification de leur substance par openlegi.fr. Openlegi ne fournit aucune interprétation juridique, aucun conseil personnalisé et ne modifie pas le contenu des données juridiques reçues des sources publiques, en dehors d'éventuels traitements techniques de formatage ou de mise en cache. ## 4. Conditions d'accès ### 4.1. Public visé par le Service Le Service est principalement conçu pour un usage par des utilisateurs professionnels, c'est-à-dire des personnes physiques ou morales agissant, y compris par l'intermédiaire d'une autre personne agissant en leur nom ou pour leur compte, à des fins entrant dans le cadre de leur activité commerciale, industrielle, artisanale, libérale ou de toute autre activité professionnelle. À ce titre, le Service est notamment destiné aux entreprises, cabinets d'avocats, professionnels du droit, éditeurs, prestataires de services numériques, administrations ou organismes assimilés. ### 4.2. Absence de vérification systématique de la qualité de professionnel L'Éditeur n'est pas en mesure de vérifier de manière systématique et exhaustive la qualité de professionnel de chaque Utilisateur lors de l'inscription ou de l'utilisation du Service. En conséquence, il appartient à chaque Utilisateur de s'assurer qu'il agit à des fins professionnelles lorsqu'il recourt au Service, et d'indiquer des informations exactes lors de son inscription. ### 4.3. Qualification fonctionnelle du professionnel Pour l'application des présentes, la qualité de professionnel s'apprécie de manière fonctionnelle, au regard de la finalité poursuivie par l'Utilisateur dans le cadre du recours au Service, et non de sa seule forme juridique ou de son but lucratif. ### 4.4. Adresse email valide L'Utilisateur doit fournir une adresse email professionnelle valide et pérenne lors de son inscription. L'Éditeur se réserve le droit de refuser ou de révoquer toute inscription effectuée avec une adresse email temporaire, jetable ou ne permettant pas une identification fiable de l'Utilisateur. ## 5. Clés API, sécurité et confidentialité Pour utiliser le service, l'Utilisateur doit fournir ses propres clés API ou identifiants délivrés par les fournisseurs de données publics. Ces clés restent la propriété de l'Utilisateur, qui demeure seul responsable de leur création, de leur renouvellement et de leur révocation auprès des fournisseurs concernés. Lorsque l'Utilisateur renseigne dans le Service une clé d'API personnelle délivrée par une API tierce (notamment une clé PISTE / Légifrance), il confère à Openlegi un mandat strictement limité consistant à utiliser cette clé pour exécuter, via ses serveurs, les requêtes techniques que l'Utilisateur initie au moyen du Service, et ce exclusivement pour son compte et dans le cadre de son organisation. Openlegi s'engage à n'utiliser la clé d'API de l'Utilisateur que pour les besoins de l'exécution de ces requêtes, à l'exclusion de toute autre finalité, notamment de tout usage pour d'autres clients, de toute mutualisation non autorisée ou de toute exploitation à des fins propres. Openlegi met en œuvre des mesures techniques et organisationnelles appropriées pour assurer la sécurité des clés API et des données associées, notamment par leur chiffrement en base de données, la limitation des accès aux seules personnes habilitées et la journalisation des accès. L'Utilisateur s'engage à : - ne pas communiquer ses identifiants de connexion au service à des tiers non autorisés ; - informer sans délai openlegi.fr de toute compromission suspectée de ses clés ou identifiants. ## 6. Sources de données, licences et réutilisation Les données accessibles via le service proviennent de sources publiques, notamment : - les bases juridiques diffusées sur Légifrance et accessibles via la plateforme PISTE, dans le cadre de la Licence Ouverte / Etalab 2.0 () ou de toute autre licence publique applicable ; - et, le cas échéant, d'autres bases publiques comme le BOFIP ou le BODACC explicitement mentionnées sur le site. L'utilisation de ces données est régie par les licences propres à chaque producteur de données publiques. L'Utilisateur s'engage à respecter ces licences, notamment en ce qui concerne : - la mention de la source et de la date de dernière mise à jour ; - le respect de l'intégrité des données ; - le respect des éventuels droits de propriété intellectuelle de tiers. ## 7. Statut d'intermédiaire technique et responsabilité ### 7.1. Nature du Service et absence de maîtrise des contenus juridiques Openlegi fournit un service d'intermédiation technique permettant à l'Utilisateur d'adresser des requêtes techniques à certaines API juridiques publiques au moyen d'interfaces et de serveurs opérés par Openlegi. L'Utilisateur demeure seul titulaire des droits d'accès aux API tierces (notamment PISTE / Légifrance) et seul responsable de la souscription et du respect des conditions générales applicables à ces API. Openlegi n'acquiert aucun droit autonome sur ces accès et agit exclusivement en qualité de prestataire technique pour le compte de l'Utilisateur. L'Éditeur ne produit pas les données juridiques accessibles via le Service et n'en maîtrise ni le contenu, ni l'exhaustivité, ni la mise à jour, lesquels relèvent de la responsabilité exclusive des producteurs de données concernés. Le Service se borne à opérer des traitements techniques de mise en forme, de conversion ou d'agrégation, sans altérer la substance des données juridiques sous-jacentes. ### 7.2. Statut d'intermédiaire technique Conformément à la loi n° 2004-575 du 21 juin 2004 pour la confiance dans l'économie numérique (LCEN) et à la directive 2000/31/CE dite « e-commerce », l'Éditeur agit, pour les contenus juridiques et informations transitant par le Service, en qualité d'intermédiaire technique de type hébergeur ou assimilé, dont la responsabilité est limitée aux conditions prévues par ces textes. À ce titre, l'Éditeur ne peut voir sa responsabilité civile ou pénale engagée du fait des contenus juridiques ou informations transmis ou mis à disposition via le Service que s'il avait effectivement connaissance de leur caractère manifestement illicite ou de faits et circonstances faisant apparaître ce caractère, et s'il n'a pas agi promptement pour retirer ces données ou en rendre l'accès impossible. L'Éditeur n'est soumis à aucune obligation générale de surveillance des informations qu'il transmet ou stocke, ni à une obligation générale de rechercher des faits ou circonstances révélant des activités illicites, sous réserve des obligations particulières prévues par la loi. ### 7.3. Absence de garantie de service -- absence de SLA Le Service est fourni à titre gratuit, sans garantie contractuelle de disponibilité, de performance ou de temps de rétablissement, et sans service level agreement (SLA). L'accès aux différents fonds, sources de données et fonctionnalités proposés via le Service est géré de manière entièrement discrétionnaire par Openlegi, qui se réserve le droit, à tout moment, de limiter, restreindre, suspendre, interrompre, supprimer ou modifier tout ou partie de l'accès au Service, à certains comptes, à certaines clés API, à certains fonds ou fonctionnalités, sans préavis, sans justification et sans indemnité, pour quelque motif que ce soit, y compris pour des raisons techniques, de sécurité, de conformité légale ou d'évolution du Service. L'Éditeur s'efforce de maintenir un niveau raisonnable de disponibilité du Service, mais ne saurait être tenu à une obligation de résultat à ce titre. Le Service peut être temporairement interrompu pour des raisons techniques (maintenance, mise à jour, incident, surcharge, indisponibilité ou dysfonctionnement des API tierces, etc.) ou pour des motifs de sécurité, sans que ces interruptions n'ouvrent droit à indemnisation. L'Utilisateur reconnaît qu'il ne bénéficie d'aucun droit acquis au maintien du Service, de ses fonctionnalités, de ses performances, ni du périmètre des données ou API accessibles, et qu'il lui appartient d'organiser ses propres sauvegardes, redondances et solutions alternatives adaptées à ses besoins professionnels. ### 7.4. Limitations de responsabilité Dans les limites permises par le droit français, l'Éditeur ne pourra être tenu responsable : - des dommages résultant de l'utilisation, de l'interprétation ou de l'exploitation des données juridiques obtenues via le Service, lesquelles sont fournies par des tiers et peuvent comporter des erreurs, omissions, retards de mise à jour ou incohérences ; - des préjudices indirects, tels que perte de chance, perte de chiffre d'affaires, de bénéfice, d'image, ou toute autre perte financière, subis par l'Utilisateur du fait de l'utilisation ou de l'impossibilité d'utiliser le Service ; - des conséquences résultant de l'indisponibilité totale ou partielle du Service, y compris en cas d'indisponibilité des API tierces ou des infrastructures techniques sous-jacentes ; - des dommages résultant d'une utilisation du Service non conforme aux CGU, aux lois et règlements applicables, ou aux conditions contractuelles imposées par les fournisseurs d'API publiques (notamment conditions d'utilisation de Légifrance, INPI, etc.). En tout état de cause, lorsque l'Utilisateur agit à des fins professionnelles, toute réparation susceptible d'être mise à la charge de l'Éditeur en cas de faute prouvée sera strictement limitée, toutes causes confondues, au montant d'un plafond forfaitaire défini dans les CGU, sans préjudice des dispositions d'ordre public applicables. ### 7.5. Obligations de l'Utilisateur En accédant au Site et aux Services, l'Utilisateur déclare, garantit et s'engage à : - accéder et utiliser le Site et/ou des Services en toute bonne foi, de manière raisonnable, non contraire aux termes des présentes CGU ; - ne pas utiliser de dispositifs ou logiciels autres que ceux fournis par l'Éditeur destinés à i) affecter ou tenter d'affecter le bon fonctionnement du Site et/ou des Services ii) d'extraire, modifier, consulter, même en mémoire tampon ou temporaire, ou encore pour une utilisation individualisée, tout ou partie du Site et/ou des Services ; - ne pas accéder et/ou utiliser le Site et/ou des Services à des fins illicites et/ou dans le but de causer un préjudice à la réputation et/ou à l'image de l'Éditeur et/ou des Utilisateurs, ou plus généralement à porter atteinte aux droits, notamment de propriété intellectuelle, de l'Éditeur et/ou de tiers, en ce compris les Utilisateurs ; - ne pas commercialiser directement ou indirectement l'accès au Site et/ou aux Services ; - ne pas réutiliser, ni exploiter tout ou partie du Site et/ou des Services qu'il contient, en particulier à des fins commerciales et/ou collectives et/ou à des fins personnelles sous une forme et/ou un média non autorisé par l'Éditeur et/ou les Utilisateurs ; - ne pas reproduire, représenter tout ou partie du Site et/ou des Services à des fins privées au-delà des exceptions légales prévues, en particulier par le Code de la propriété intellectuelle, ou en vue d'une commercialisation directe ou indirecte notamment auprès de tiers ; - ne pas limiter l'accès et l'utilisation du Site et/ou des Services ; - s'assurer que l'utilisation du Site et/ou des Services n'affecte, ni ne compromette la stabilité, la sécurité et la qualité du Site, des réseaux, de la bande passante, ou des infrastructures de l'Éditeur, des autres Utilisateurs et/ou des tiers ; - ne pas contrevenir aux dispositions des articles 323-1 à 323-7 du Code pénal réprimant les pratiques de piratage. En cas de manquement à l'une ou l'autre de ces obligations, sans que cette liste ne soit limitative, l'Utilisateur est informé que l'Éditeur aura la faculté de lui refuser ou lui suspendre, unilatéralement et sans notification préalable, l'accès à tout ou partie du Site et/ou des Services. L'Utilisateur demeure seul responsable : - de l'usage qu'il fait du Service et des données juridiques obtenues, ainsi que des décisions ou analyses qu'il fonde sur ces données ; - du respect des conditions d'utilisation applicables aux API et bases de données tierces qu'il interroge via le Service ; - de la protection, de la confidentialité et de l'usage de ses identifiants de connexion et de ses clés d'API, qu'il s'engage à ne pas communiquer à des tiers non autorisés ; - de la conformité de ses propres traitements de données (notamment vis-à-vis de ses clients finaux) aux textes applicables, en particulier au RGPD et à la loi Informatique et libertés, lorsqu'il agit lui-même en qualité de responsable de traitement. L'Utilisateur s'engage à notifier sans délai à l'Éditeur toute utilisation non autorisée de ses identifiants ou de ses clés d'API, ainsi que tout incident de sécurité susceptible d'affecter le Service. ## 8. Force majeure La responsabilité de l'Éditeur ne pourra pas être recherchée si l'exécution de l'une de ses obligations est empêchée ou retardée en raison d'un cas de force majeure telle que définie par la jurisprudence des Tribunaux français et l'article 1218 du Code civil, et notamment les catastrophes naturelles, incendies, dysfonctionnement ou interruption du réseau de télécommunications ou du réseau électrique. ## 9. Propriété intellectuelle ### 9.1. Droits d'auteur sur le Site et son contenu L'Éditeur est titulaire ou concessionnaire des droits de propriété intellectuelle tant de la structure générale du Site que son contenu (textes, images, vidéos, photos, programmes et autres contenus). Dès lors, toute représentation, reproduction, modification, dénaturation et/ou exploitation totale ou partielle du Site et/ou des Services, par quelque procédé que ce soit et sur quelque support que ce soit, sans l'autorisation expresse et préalable de l'Éditeur, est prohibée et constitue des actes de contrefaçon de droits d'auteur. De même, toute exploitation non autorisée du Site et/ou des Services engage la responsabilité pénale et civile de l'Utilisateur sur le fondement de la contrefaçon de droits d'auteur. L'Utilisateur reconnaît et accepte que l'accès au Site et/ou aux Services mis à disposition par l'Éditeur ne saurait emporter quelconque cession ou concession des droits de propriété intellectuelle (droits d'auteurs notamment) et autres droits de la personnalité (droit à l'image, au respect de la vie privée) au bénéfice de l'Utilisateur. L'accès au Site et aux Services est exclusivement limité à l'usage privé et personnel de l'Utilisateur dans les conditions et limites définies dans les présentes CGU. ### 9.2. Signes distinctifs Les logos, la dénomination sociale, les sigles, noms commerciaux, enseignes et/ou nom de domaine d'Openlegi et/ou de ses partenaires commerciaux mentionnés sur le Site, mis à disposition par l'Éditeur sur le Site, constituent des signes distinctifs insusceptibles d'utilisation sans l'autorisation expresse et préalable de leur titulaire. Toute représentation et/ou reproduction et/ou exploitation partielle ou totale de ces signes distinctifs est donc prohibée et constitutive de contrefaçon de marque, d'usurpation de dénomination sociale, de nom commercial et de nom de domaine engageant la responsabilité civile délictuelle de son auteur. ### 9.3. Liens hypertextes Les liens hypertextes accessibles sur le Site et/ou dans le cadre des Services, en direction d'autres sites Internet et d'une manière générale vers toutes ressources existantes sur Internet ne sauraient engager la responsabilité de l'Éditeur. L'Utilisateur ne pourra en aucun cas mettre en place de liens hypertextes à destination de pages profondes du Site, permettant l'accès aux pages des Services et ce, par quelconque procédé technique destiné à passer outre le champ d'identification de l'Utilisateur ou à procéder à l'aspiration de tout ou partie du contenu des pages du Site. La technique du "framing" est interdite, sauf autorisation expresse et préalable de l'Éditeur. ### 9.4. Bases de données L'Utilisateur reconnaît irrévocablement que le Site et les Services sont constitués d'une ou plusieurs bases de données mises à la disposition des Utilisateurs par l'Éditeur en qualité de producteur desdites bases de données au sens des dispositions des articles L.341-1 et suivants du Code de la propriété intellectuelle. Dès lors, conformément aux dispositions de l'article L.342-1 du même Code, l'Utilisateur s'interdit de procéder à : - l'extraction par transfert permanent ou temporaire de la totalité ou d'une partie qualitativement ou quantitativement substantielle du contenu d'une ou plusieurs des bases de données accessibles sur le Site, sur un autre support, par tout moyen et sous toute forme que ce soit, en ce compris à des fins d'utilisation ou de consultation par un média et/ou un procédé(s) non autorisé(s) par l'Éditeur ; - la réutilisation, par la mise à la disposition du public de la totalité ou d'une partie qualitativement ou quantitativement substantielle du contenu d'une ou plusieurs des bases de données accessibles sur le Site et/ou les Services quelle qu'en soit la forme, y compris par un lien hypertexte, un média et/ou un procédé(s) non autorisé(s) par l'Éditeur ; - la constitution, l'édition, la maintenance, la mise à jour, l'importation, l'exportation, la mise à disposition de tiers, à titre gracieux ou onéreux, et la participation aux actes précités, d'une base de données concurrente issue de tout ou partie d'une ou plusieurs des bases de données de l'Éditeur ; - la visualisation sur un écran par un autre procédé ou média que ceux par lesquels l'Éditeur entend divulguer le Site et/ou les Services ; - d'une manière générale, toute extraction, utilisation, stockage, reproduction, représentation ou conservation, directe ou indirecte, partielle ou totale, y compris en mémoire tampon ou temporaire, qualitativement ou quantitativement substantielle du contenu d'une ou plusieurs des bases de données de l'Éditeur, commise par l'un des procédés visés ci-dessus est strictement prohibée, y compris par un média non autorisé par l'Éditeur. ## 10. Dispositions diverses ### 10.1. Correspondance -- Preuve Sauf disposition particulière des présentes CGU, les correspondances échangées entre l'Éditeur et l'Utilisateur sont principalement assurées par courrier électronique. En application des articles 1366 et suivants du Code civil, l'Utilisateur reconnaît et accepte que les informations délivrées par l'Éditeur par courrier électronique et/ou par le Site fassent foi entre lui et l'Éditeur. Les éléments tels que le moment de la réception ou de l'émission, ainsi que la qualité des données reçues feront foi par priorité telles que figurant sur les supports précités, ou telles qu'authentifiées par les procédures informatisées de l'Éditeur, sauf à en apporter la preuve écrite et contraire par l'Utilisateur. La portée de la preuve des informations délivrées par le Site est celle accordée à un original au sens d'un document écrit papier, signé de manière manuscrite. ### 10.2. Intégralité des CGU Les présentes CGU expriment l'intégralité des obligations de l'Éditeur et de l'Utilisateur relatives à leur objet. Le fait pour l'une des parties de ne pas se prévaloir d'un manquement par l'autre partie, à l'une quelconque des obligations visées dans les présentes, ne saurait être interprété pour l'avenir comme une renonciation à l'obligation en cause. ### 10.3. Non-validité partielle Dans l'hypothèse où une ou plusieurs stipulations des présentes CGU seraient considérées comme nulles, réputées non écrites ou déclarées comme telles en application d'une loi, d'un règlement ou à la suite d'une décision d'une juridiction compétente ayant autorité de la chose jugée en dernier ressort, les autres stipulations garderont toute leur force et leur portée et resteront pleinement applicables, sauf si la ou les stipulations non valides présentaient un caractère substantiel et que leur disparition remettait en cause l'équilibre contractuel. ### 10.4. Titres En cas de difficultés d'interprétation entre l'un des titres figurant en tête des clauses des présentes CGU, et l'une des clauses, les titres seront déclarés inexistants. ## 11. Modification des CGU L'Éditeur se réserve la faculté de modifier les présentes CGU afin de tenir compte des évolutions du service ou de la réglementation applicable. L'Utilisateur sera informé de toute modification substantielle par tout moyen approprié au moins quinze (15) jours avant leur entrée en vigueur. En cas de désaccord avec les nouvelles CGU, l'Utilisateur pourra résilier le service avant cette date. L'utilisation du service après l'entrée en vigueur des nouvelles CGU vaut acceptation de celles-ci. ## 12. Droit applicable, règlement des litiges et médiation Les présentes CGU sont soumises au droit français. En cas de litige entre l'Éditeur et un Utilisateur professionnel, les tribunaux du ressort du siège social de l'Éditeur seront seuls compétents, sous réserve d'une attribution de compétence spécifique découlant d'un texte particulier. ## Demarrage rapide Configurer OpenLegi MCP en quelques minutes ### Clés API personnelles ## Clés API personnelles (PISTE Legifrance) Par défaut, OpenLegi utilise des **clés API partagées** avec des limites de débit. Pour un usage intensif ou professionnel, vous pouvez configurer vos propres credentials PISTE. ### Avantages des clés personnelles - **Aucune limite de débit** — Pas de quota partagé avec d'autres utilisateurs - **Mode illimité** — Vos requêtes ne sont plus comptabilisées - **Stockage sécurisé** — Vos credentials sont chiffrés ### Obtenir vos credentials PISTE 1. Rendez-vous sur [https://piste.gouv.fr](https://piste.gouv.fr) (portail PISTE) 2. Créez un compte ou connectez-vous 3. Créez une **application** et souscrivez à l'**API Legifrance** 4. Attendez l'**approbation** de votre application (peut prendre quelques jours) 5. Une fois approuvée, accédez à votre application en environnement **Production** 6. Récupérez votre **identifiant OAuth (pas API Keys)** (= Client ID) et votre **Consumer Secret** (= Client Secret) ### Configurer dans OpenLegi 1. Connectez-vous sur [auth.openlegi.fr](https://auth.openlegi.fr) 2. Accédez à votre [Dashboard](https://auth.openlegi.fr/users/dashboard/) 3. Onglet **Clés OAuth** → cliquez sur **Ajouter une clé** 4. Renseignez un nom, votre Client ID et Client Secret 5. La validation automatique teste vos credentials (jusqu'à 30 secondes) 6. Si la validation réussit, votre clé passe en statut **Active** ### Statuts possibles | Statut | Signification | Action | |--------|--------------|--------| | **Active** | Credentials valides, prêts à l'emploi | Rien à faire | | **En attente** | La validation n'a pas pu aboutir (timeout) | Cliquez sur **Tester** pour relancer | | **Invalide** | Credentials rejetés par l'API PISTE | Vérifiez vos credentials (voir erreurs courantes) | ### Erreurs courantes **"Client ID ou Client Secret invalide"** (erreur invalid_client) - Vérifiez que vous utilisez les credentials de l'environnement **Production** (pas Sandbox) - Vérifiez que votre application PISTE est bien **approuvée** (statut "Approved") - Attention aux **espaces invisibles** lors du copier-coller - Le Consumer Key et le Consumer Secret sont différents du login/mot de passe PISTE **"Timeout de connexion"** - Le serveur de validation n'a pas répondu à temps - Cela peut indiquer des credentials invalides (le serveur retente plusieurs fois avant d'échouer) - Vérifiez d'abord vos credentials, puis cliquez sur **Tester** **"Accès interdit"** (erreur 403) - Votre application PISTE n'a probablement pas souscrit à l'API Legifrance - Connectez-vous sur le portail PISTE et vérifiez vos souscriptions ### Gestion des clés - **Une seule clé active par provider** — Supprimez l'ancienne avant d'en créer une nouvelle - **Bouton Tester** — Relance la validation à tout moment - **Bouton Supprimer** — Supprime la clé et repasse automatiquement en clés partagées - **Toggle "Clés personnelles"** — Active/désactive l'utilisation de vos clés (nécessite une clé active) ### Liste des services compatibles ## Compatibilité avec les Assistants IA | Plateforme | Support MCP | Méthode d'intégration | Notes | |------------|-------------|----------------------|-------| | **Claude Desktop** | ✅ Support complet | Configuration native dans `claude_desktop_config.json` | Recommandé | | **Claude (Web)** | ✅ Support complet | Support MCP natif sur claude.ai via interface web | Interface web | | **Perplexity** | ⚠️ Support partiel | Client lourd uniquement (application desktop) | Desktop uniquement | | **Mistral Le Chat** | ✅ Support complet | Via "Connecteurs" dans la rubrique "Intelligence" | Interface web | | **Microsoft Copilot** | ✅ Support complet | Via Copilot Studio (configuration serveur MCP) | Entreprise | | **ChatGPT** | ❌ Non compatible | Pas de support MCP natif | - | | **Google Gemini** | ❌ Non compatible | Pas de support MCP natif | - | | **VSCode / Cursor** | ✅ Support complet | Extensions MCP disponibles (Continue, Cline, etc.) | IDE | | **JetBrains IDEs** | ⚠️ Support partiel | Support partiel via plugins tiers | En développement | ### Légende - ✅ **Support complet** : Intégration MCP native et fonctionnelle - ⚠️ **Support partiel** : Intégration limitée ou en cours de développement - ❌ **Non compatible** : Pas de support MCP disponible ### Configuration Claude Desktop Pour utiliser OpenLegi MCP avec Claude Desktop, ajoutez cette configuration dans votre fichier `claude_desktop_config.json` : ### Claude Desktop Ajoutez cette configuration dans `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) ou `%APPDATA%\Claude\claude_desktop_config.json` (Windows) : ```json { "mcpServers": { "MCP Legifrance": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "https://mcp.openlegi.fr/legifrance/mcp?token=YOUR_TOKEN_HERE" ] } } } ``` ## Outils disponibles Reference des outils MCP pour acceder aux donnees juridiques ### Liste des outils ### Service Légifrance (Droit français) | Outil | Description | |-------|-------------| | `rechercher_code` | Recherche dans les codes juridiques français | | `rechercher_jurisprudence_judiciaire` | Recherche de jurisprudence judiciaire (JURI) | | `rechercher_jurisprudence_administrative` | Recherche de jurisprudence administrative (CETAT) | | `rechercher_decisions_cnil` | Recherche dans les décisions CNIL | | `rechercher_decisions_constitutionnelles` | Recherche dans les décisions du Conseil constitutionnel | | `rechercher_conventions_collectives` | Recherche dans les conventions collectives (KALI) | | `rechercher_dans_texte_legal` | Recherche dans les textes légaux consolidés (LODA) | | `recherche_journal_officiel` | Recherche dans le Journal Officiel (JORF) | | `dernier_journal_officiel` | Récupère les derniers JO publiés | | `lister_codes_juridiques` | Liste tous les codes juridiques disponibles | | `lister_emetteurs_jorf` | Liste les émetteurs du Journal Officiel | | `lister_natures_textes_jorf` | Liste les types de textes publiés au JORF | ### Service RNE (Registre National des Entreprises) | Outil | Description | |-------|-------------| | `rne_search_companies` | Recherche d'entreprises françaises | | `rne_get_company_data` | Données complètes d'une entreprise | | `rne_get_bodacc` | Annonces légales BODACC | | `rne_download_acte` | Télécharge un acte PDF (URL SAS temporaire) | | `rne_download_bilan` | Télécharge un bilan PDF | | `rne_download_extrait_rne` | Télécharge l'extrait RNE (KBIS) | | `rne_list_temp_files` | Liste les fichiers temporaires | | `rne_delete_temp_file` | Supprime un fichier temporaire | | `rne_cleanup_temp_files` | Nettoie les fichiers temporaires | ### Service EUR-Lex (Droit européen) | Outil | Description | |-------|-------------| | `eurlex_search_by_title` | Recherche par titre de document | | `eurlex_search_by_number` | Recherche par numéro CELEX | | `eurlex_fetch_article` | Récupère un article spécifique | | `eurlex_fetch_recital` | Récupère un considérant | | `eurlex_list_articles` | Liste tous les articles d'un document | | `eurlex_list_recitals` | Liste tous les considérants | | `eurlex_search_in_document` | Recherche dans le texte d'un document | | `eurlex_get_metadata` | Récupère les métadonnées d'un document | | `eurlex_fetch_text` | Récupère le texte intégral d'un document | ### Mode d'affichage - pagination et panorama ## Pagination La plupart des outils supportent la pagination : ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: # Page 1 result_page1 = client.call_tool( "rechercher_code", { "search": "responsabilité", "code_name": "Code civil", "page_number": 1, "page_size": 20 } ) # Page 2 result_page2 = client.call_tool( "rechercher_code", { "search": "responsabilité", "code_name": "Code civil", "page_number": 2, "page_size": 20 } ) ``` ## Mode Panorama Pour éviter de récupérer des textes intégraux volumineux, utilisez le mode `panorama=True` qui retourne uniquement les métadonnées et résumés : ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: result = client.call_tool( "rechercher_jurisprudence_judiciaire", { "search": "contrat de travail", "panorama": True, # Vue d'ensemble uniquement "page_size": 50 } ) ``` ### Codes juridiques ## rechercher_code Recherche dans les codes juridiques francais (Code civil, Code penal, Code du travail, etc.) ### Parametres | Parametre | Type | Description | |-----------|------|-------------| | `search` | string | Termes de recherche (obligatoire) | | `code_name` | string | Nom du code juridique (obligatoire) | | `max_results` | integer | Nombre de resultats (defaut: 10, max: 100) | | `champ` | string | Champ de recherche: ALL, TITLE, NUM_ARTICLE, ARTICLE | | `sort` | string | Tri: PERTINENCE, DATE_ASC, DATE_DESC | ### Exemple ```python { "name": "rechercher_code", "arguments": { "search": "contrat de travail", "code_name": "Code du travail", "max_results": 5 } } ``` ### Codes disponibles Utilisez l'outil `lister_codes_juridiques` pour obtenir la liste complete des codes disponibles. Exemples courants: - Code civil - Code penal - Code du travail - Code de commerce - Code de procedure civile - Code de procedure penale - Code general des impots ### Jurisprudence judiciaire ## rechercher_jurisprudence_judiciaire Recherche dans la jurisprudence judiciaire (Cour de cassation, cours d'appel, tribunaux) ### Parametres | Parametre | Type | Description | |-----------|------|-------------| | `search` | string | Termes ou numeros d'affaires (obligatoire) | | `max_results` | integer | Nombre de resultats (defaut: 10, max: 100) | | `juridiction_judiciaire` | array | Juridictions a inclure | | `publication_bulletin` | array | ['T'] pour publiees au bulletin | | `sort` | string | Tri: PERTINENCE, DATE_ASC, DATE_DESC | | `champ` | string | Champ: ALL, TITLE, ABSTRACTS, TEXTE, NUM_AFFAIRE | ### Exemple ```python { "name": "rechercher_jurisprudence_judiciaire", "arguments": { "search": "responsabilite civile", "juridiction_judiciaire": ["Cour de cassation"], "publication_bulletin": ["T"], "max_results": 10 } } ``` ### Juridictions disponibles - `Cour de cassation` - `Juridictions d'appel` - `Juridictions du premier degre` ### Journal Officiel (JORF) ## recherche_journal_officiel Recherche dans le Journal Officiel francais (decrets, arretes, nominations, etc.) ### Parametres | Parametre | Type | Description | |-----------|------|-------------| | `search` | string | Mots-cles a rechercher (obligatoire) | | `max_results` | integer | Nombre de resultats (defaut: 5, max: 100) | | `ministeres` | array | Filtrer par ministeres | | `text_types` | array | Types de textes (LOI, DECRET, ARRETE, etc.) | | `sort` | string | Tri: PERTINENCE, PUBLI_DATE_ASC, PUBLI_DATE_DESC | | `date_publication` | array | Plage de dates [debut, fin] au format YYYY-MM-DD | ### Exemple ```python { "name": "recherche_journal_officiel", "arguments": { "search": "nomination ambassadeur", "text_types": ["DECRET"], "max_results": 10 } } ``` ### Types de textes disponibles - `LOI` - Lois - `DECRET` - Decrets - `ARRETE` - Arretes - `ORDONNANCE` - Ordonnances - `DECISION` - Decisions - `AVIS` - Avis ### Textes consolides (LODA) ## rechercher_dans_texte_legal Recherche dans les textes legaux historiques avec validation MCP (lois, ordonnances, decrets, arretes) ### Parametres | Parametre | Type | Description | |-----------|------|-------------| | `search` | string | Mots-cles ou numero d'article (obligatoire) | | `text_id` | string | Numero du texte (format AAAA-NUMERO, optionnel) | | `champ` | string | Champ: ALL, TITLE, TABLE, NUM_ARTICLE, ARTICLE | | `max_results` | integer | Nombre de resultats (defaut: 10, max: 100) | | `sort` | string | Tri: PERTINENCE, PUBLICATION_DATE_ASC, PUBLICATION_DATE_DESC | | `type_recherche` | string | TOUS_LES_MOTS_DANS_UN_CHAMP, EXACTE, UN_DES_MOT | ### Exemples Recherche d'un article specifique dans une loi: ```python { "name": "rechercher_dans_texte_legal", "arguments": { "search": "7", "text_id": "78-17", "champ": "NUM_ARTICLE" } } ``` Recherche generale: ```python { "name": "rechercher_dans_texte_legal", "arguments": { "search": "signature electronique validite conditions", "max_results": 10 } } ``` ## Modes d'integration Differentes facons d'utiliser OpenLegi MCP ### Integration Python - Installation # 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](https://github.com/modelcontextprotocol/python-sdk)** : SDK officiel avec support complet du protocole - **[Claude Desktop](https://claude.ai/download)** : 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 ```bash 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é) ```python session.headers.update({ "Authorization": "Bearer VOTRE_TOKEN_ICI" }) ``` ### 2. Query Parameter ```python url = f"https://mcp.openlegi.fr/legifrance/mcp?token=VOTRE_TOKEN" ``` ### 3. Path Token ```python url = "https://mcp.openlegi.fr/legifrance/mcp/token/VOTRE_TOKEN" ``` --- ## Client Python OpenLegiClient ### Classe complète ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 (`with` statement) 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 ` - Testez votre token avec `list_tools()` avant d'appeler des tools complexes --- ## Alternatives recommandées Pour une intégration production, considérez : 1. **[MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)** - SDK officiel avec : - Support complet du protocole MCP - Gestion automatique des sessions - Streaming SSE natif - Types Python stricts 2. **[Claude Desktop](https://claude.ai/download)** - Pour une utilisation interactive : - Configuration via `claude_desktop_config.json` - Interface graphique native - Pas de code nécessaire 3. **[Claude Code CLI](https://github.com/anthropics/claude-code)** - Pour l'automatisation : - Intégration Git - Exécution de tâches complexes - Support natif des serveurs MCP --- ## Support - 📧 Contact : [support@openlegi.fr](mailto:support@openlegi.fr) - 📖 Documentation complète : [https://auth.openlegi.fr/documentation](https://auth.openlegi.fr/documentation) - 🐛 Issues : [GitHub Issues](https://github.com/legalchain/legal-mcp/issues) --- ## Licence Ce code est fourni sous licence MIT à titre d'exemple éducatif. ### Integration Python - Utilisation ## Exemples d'utilisation ### Lister les outils disponibles ```python # Service Légifrance with OpenLegiClient(token="VOTRE_TOKEN", service="legifrance") as client: tools = client.list_tools() print(f"🔧 {len(tools)} outils Légifrance disponibles") for tool in tools: print(f"- {tool['name']}: {tool['description']}") # Service RNE (Entreprises) with OpenLegiClient(token="VOTRE_TOKEN", service="rne") as client: tools = client.list_tools() print(f"\n🏢 {len(tools)} outils RNE disponibles") # Service EUR-Lex (Droit européen) with OpenLegiClient(token="VOTRE_TOKEN", service="eurlex") as client: tools = client.list_tools() print(f"\n🇪🇺 {len(tools)} outils EUR-Lex disponibles") ``` ### Rechercher dans le Journal Officiel ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: result = client.call_tool( "recherche_journal_officiel", { "search": "dechet industriel recyclage", "max_results": 5, "sort": "SIGNATURE_DATE_DESC" } ) # Le résultat est dans result["content"][0]["text"] print(result["content"][0]["text"]) ``` ### Rechercher dans un code juridique ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: result = client.call_tool( "rechercher_code", { "search": "mariage", "code_name": "Code civil", "page_size": 10 } ) print(result["content"][0]["text"]) ``` ### Rechercher de la jurisprudence ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: result = client.call_tool( "rechercher_jurisprudence_judiciaire", { "search": "licenciement abusif", "sort": "DATE_DESC", "panorama": True, # Vue d'ensemble (métadonnées uniquement) "page_size": 10 } ) print(result["content"][0]["text"]) ``` ### Rechercher dans un texte légal (LODA) ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: result = client.call_tool( "rechercher_dans_texte_legal", { "search": "signature électronique", "champ": "ALL", "page_size": 5 } ) print(result["content"][0]["text"]) ``` ### Lister les codes juridiques disponibles ```python with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: result = client.call_tool("lister_codes_juridiques", {}) print(result["content"][0]["text"]) ``` ## Gestion des erreurs ```python import requests from requests.exceptions import RequestException, HTTPError with OpenLegiClient(token="VOTRE_TOKEN_ICI") as client: try: result = client.call_tool( "recherche_journal_officiel", {"search": "urbanisme"} ) print(result["content"][0]["text"]) except HTTPError as e: if e.response.status_code == 401: print("❌ Erreur d'authentification: token invalide ou expiré") elif e.response.status_code == 403: print("❌ Accès interdit: vérifiez vos permissions") elif e.response.status_code == 404: print("❌ Endpoint non trouvé") else: print(f"❌ Erreur HTTP {e.response.status_code}: {e}") except RequestException as e: print(f"❌ Erreur de connexion: {e}") except Exception as e: print(f"❌ Erreur: {e}") ``` ### Rechercher des décisions CNIL ```python with OpenLegiClient(token="VOTRE_TOKEN", service="legifrance") as client: result = client.call_tool( "rechercher_decisions_cnil", { "search": "RGPD", "nature_delib": ["Sanction"], "sort": "DATE_DECISION_DESC", "page_size": 10 } ) print(result["content"][0]["text"]) ``` ### Rechercher des décisions du Conseil constitutionnel ```python with OpenLegiClient(token="VOTRE_TOKEN", service="legifrance") as client: result = client.call_tool( "rechercher_decisions_constitutionnelles", { "search": "liberté expression", "panorama": True, "page_size": 10 } ) print(result["content"][0]["text"]) ``` ### Rechercher des conventions collectives ```python with OpenLegiClient(token="VOTRE_TOKEN", service="legifrance") as client: result = client.call_tool( "rechercher_conventions_collectives", { "search": "métallurgie", "page_size": 10 } ) print(result["content"][0]["text"]) ``` ### Rechercher une entreprise (RNE) ```python with OpenLegiClient(token="VOTRE_TOKEN", service="rne") as client: result = client.call_tool( "rne_search_companies", { "query": "Google France", "page": 1, "per_page": 10 } ) print(result["content"][0]["text"]) ``` ### Rechercher dans EUR-Lex ```python with OpenLegiClient(token="VOTRE_TOKEN", service="eurlex") as client: result = client.call_tool( "eurlex_search_by_title", { "title": "RGPD", "max_results": 5 } ) print(result["content"][0]["text"]) ``` ### Optimisation des performances ## Optimisation des performances ### Réutilisation de session ```python # ❌ Mauvaise pratique : nouvelle connexion à chaque appel import requests def mauvais_appel(search: str): response = requests.post( "https://mcp.openlegi.fr/legifrance/mcp", json={"jsonrpc": "2.0", "method": "tools/call", ...}, headers={"Authorization": "Bearer TOKEN"} ) return response.json() # ✅ Bonne pratique : réutilisation de session with OpenLegiClient(token="TOKEN") as client: for search_term in ["mariage", "divorce", "succession"]: result = client.call_tool("rechercher_code", {"search": search_term}) # Traitement... ``` ### Connexion persistante ```python # Pour un script long avec de nombreux appels client = OpenLegiClient(token="VOTRE_TOKEN_ICI") try: for i in range(100): result = client.call_tool("recherche_journal_officiel", {"search": f"terme{i}"}) # Traitement... finally: client.close() # Fermeture propre ``` ### Depannage - codes erreur ### Erreur 400 Bad Request - Vérifiez qu'il n'y a pas de slash final avant le `?` dans l'URL - Vérifiez le format JSON de votre payload ### Erreur 401 Unauthorized - Vérifiez que votre token est valide - Vérifiez que le token est bien préfixé par `Bearer ` dans le header ### Erreur 403 Forbidden - Vérifiez que votre token a les permissions nécessaires (scopes) - Contactez l'administrateur pour vérifier vos droits d'accès ### Erreur de connexion - Vérifiez que le serveur est accessible - En local : vérifiez que le serveur est démarré (`./scripts/run_dev.sh`) - Vérifiez votre connexion réseau ### Protocole MCP et API Rest # SSE vs REST : Comprendre le protocole MCP ## 🤔 Le malentendu fréquent **Ce que les gens pensent :** > "C'est une API REST classique, je fais une requête POST et je reçois du JSON" **La réalité :** > "C'est un serveur MCP qui utilise SSE (Server-Sent Events) même pour les requêtes simples" --- ## 📊 Comparaison visuelle ### API REST classique ```http POST /api/search HTTP/1.1 Content-Type: application/json Accept: application/json {"query": "test"} ``` **Réponse REST classique :** ```http HTTP/1.1 200 OK Content-Type: application/json {"results": [...], "count": 42} ``` ### MCP avec SSE ```http POST /legifrance/mcp HTTP/1.1 Content-Type: application/json Accept: application/json, text/event-stream {"jsonrpc": "2.0", "method": "tools/list", "params": {}} ``` **Réponse MCP (format SSE) :** ```http HTTP/1.1 200 OK Content-Type: text/event-stream event: message data: {"jsonrpc":"2.0","id":1,"result":{...}} ``` --- ## 🔍 Différence clé | Aspect | REST classique | MCP avec SSE | |--------|----------------|--------------| | **Content-Type** | `application/json` | `text/event-stream` | | **Format réponse** | JSON brut | `event: ...\ndata: {...}` | | **Parsing** | `response.json()` | Parser ligne par ligne | | **Header Accept** | `application/json` | `application/json, text/event-stream` | | **Streaming** | Non (buffer complet) | Oui (événements progressifs) | --- ## 🧩 Pourquoi MCP utilise SSE ? ### 1. **Protocole unifié pour tous les cas d'usage** MCP supporte deux modes de communication : #### Mode 1 : Requête/Réponse simple (votre cas) ```python # Vous envoyez une requête {"jsonrpc": "2.0", "method": "tools/list", "params": {}} # Vous recevez UNE réponse event: message data: {"jsonrpc":"2.0","result":{...}} ``` #### Mode 2 : Notifications asynchrones ```python # Le serveur peut envoyer des notifications à tout moment event: notification data: {"method": "tools/list_changed"} event: notification data: {"method": "resources/updated", "params": {...}} ``` **Le SSE permet au serveur d'envoyer des événements au client SANS que le client n'ait fait de requête.** ### 2. **Support du streaming de contenu** Pour les outils qui génèrent beaucoup de données : ```python # Réponse progressive (streaming) event: message data: {"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"Début..."}]}} event: progress data: {"progress": 50, "total": 100} event: message data: {"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"...Suite..."}]}} ``` ### 3. **Maintien de la connexion** Avec SSE, la connexion HTTP reste ouverte : - Le serveur peut pousser des mises à jour - Pas besoin de polling (requêtes répétées) - Plus efficace pour les sessions longues --- ## 🎯 "Streamable" vs "Streaming" ### Streamable (capacité) ```python # Le header indique QUE LE CLIENT SUPPORTE le streaming headers = { "Accept": "application/json, text/event-stream" } ``` **Signification :** "Je suis capable de recevoir à la fois du JSON simple ET du streaming SSE" ### Streaming (action) ```python # Le serveur CHOISIT de streamer la réponse for chunk in long_computation(): send_sse_event("progress", {"chunk": chunk}) ``` **En pratique pour MCP :** - Toutes les réponses sont au format SSE (même si elles ne "streament" pas) - C'est le format d'enveloppe du protocole - Même une réponse instantanée utilise `event: message\ndata: {...}` --- ## 💡 Analogie simple ### REST classique = Lettre postale - Vous envoyez une lettre - Vous recevez UNE réponse complète - La boîte aux lettres se ferme après ### MCP avec SSE = Canal téléphonique - Vous appelez et la ligne reste ouverte - Vous posez une question (requête) - Vous recevez la réponse (event: message) - MAIS la ligne reste ouverte - Le serveur peut vous rappeler plus tard (notifications) - Vous pouvez poser d'autres questions sur la même ligne --- ## 🛠️ Implémentation pratique ### Code REST classique (NE MARCHE PAS avec MCP) ```python import requests # ❌ Ceci échoue avec MCP response = requests.post( "https://mcp.openlegi.fr/legifrance/mcp", json={"jsonrpc": "2.0", "method": "tools/list"}, headers={"Authorization": "Bearer TOKEN"} ) # ❌ JSONDecodeError: Expecting value data = response.json() ``` **Pourquoi ça échoue ?** ```python >>> response.text 'event: message\ndata: {"jsonrpc":"2.0",...}\n\n' >>> response.json() # Erreur : "event: message" n'est pas du JSON valide ! ``` ### Code MCP correct (avec parser SSE) ```python import requests import json def parse_sse(text): """Extrait le JSON de la ligne 'data:' """ for line in text.split('\n'): if line.startswith('data: '): return json.loads(line[6:]) # Retire 'data: ' raise ValueError("Pas de ligne data: trouvée") # ✅ Ceci fonctionne response = requests.post( "https://mcp.openlegi.fr/legifrance/mcp", json={"jsonrpc": "2.0", "method": "tools/list"}, headers={ "Authorization": "Bearer TOKEN", "Accept": "application/json, text/event-stream" # Important ! } ) # ✅ Parser le SSE data = parse_sse(response.text) print(data) # {"jsonrpc":"2.0","result":{...}} ``` --- ## 📋 Format SSE en détail ### Structure complète ``` event: message id: 123 data: {"jsonrpc":"2.0","id":1,"result":{...}} ``` | Champ | Description | Exemple | |-------|-------------|---------| | `event:` | Type d'événement | `message`, `notification`, `progress` | | `id:` | Identifiant unique (optionnel) | `123` | | `data:` | Payload JSON | `{"jsonrpc":"2.0",...}` | | Ligne vide | Fin de l'événement | `\n\n` | ### Événements multiples ``` event: message data: {"result": "partie 1"} event: progress data: {"percent": 50} event: message data: {"result": "partie 2"} ``` **Chaque bloc est séparé par une ligne vide.** --- ## ⚠️ Erreurs courantes ### Erreur 1 : Header Accept manquant ```python # ❌ ERREUR 406 Not Acceptable headers = {"Accept": "application/json"} # ✅ CORRECT headers = {"Accept": "application/json, text/event-stream"} ``` **Message d'erreur :** ```json { "error": { "code": -32600, "message": "Not Acceptable: Client must accept both application/json and text/event-stream" } } ``` ### Erreur 2 : Utiliser response.json() directement ```python # ❌ JSONDecodeError data = response.json() # ✅ Parser le SSE d'abord data = parse_sse(response.text) ``` ### Erreur 3 : Oublier l'initialisation de session ```python # ❌ 400 Bad Request (pas de session ID) response = session.post(url, json={"method": "tools/list"}) # ✅ Initialiser d'abord init_response = session.post(url, json={"method": "initialize"}) session_id = init_response.headers.get('mcp-session-id') session.headers.update({"mcp-session-id": session_id}) ``` --- ## 🚀 Avantages du SSE pour MCP ### 1. **Bidirectionnel (serveur → client)** ```python # Le serveur peut notifier le client event: notification data: {"method": "tools/list_changed"} ``` ### 2. **Reconnexion automatique** ```javascript // Côté JavaScript const eventSource = new EventSource('/mcp'); eventSource.addEventListener('message', (e) => { console.log(JSON.parse(e.data)); }); // Se reconnecte automatiquement si déconnecté ``` ### 3. **HTTP standard** - Pas besoin de WebSocket - Passe les proxies/firewalls - Compatible avec HTTP/1.1 et HTTP/2 ### 4. **Streaming progressif** ```python # Pour les longues réponses for i in range(100): send_event("progress", {"step": i, "total": 100}) send_event("message", {"result": final_data}) ``` --- ## 📚 Spécification SSE ### Format officiel W3C ``` stream = [ bom ] *event event = *( comment / field ) end-of-line comment = colon *any-char end-of-line field = 1*name-char [ colon [ space ] *any-char ] end-of-line end-of-line = ( cr lf / cr / lf ) ``` ### Champs standards | Champ | Signification | |-------|---------------| | `event:` | Type d'événement (défaut: "message") | | `data:` | Données de l'événement (peut être multi-lignes) | | `id:` | Identifiant de l'événement (pour reconnexion) | | `retry:` | Délai de reconnexion en ms | ### Exemple multi-lignes ``` event: message data: { data: "long": "json", data: "with": "multiple", data: "lines": true data: } ``` **Le client doit joindre toutes les lignes `data:`** --- ## 🔧 Debugging ### Voir le format brut avec curl ```bash curl -N \ -H "Authorization: Bearer TOKEN" \ -H "Accept: application/json, text/event-stream" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"tools/list","params":{}}' \ https://mcp.openlegi.fr/legifrance/mcp ``` **Sortie :** ``` event: message data: {"jsonrpc":"2.0","id":null,"result":{"tools":[...]}} ``` ### Voir avec Python requests ```python import requests response = requests.post( "https://mcp.openlegi.fr/legifrance/mcp", json={"jsonrpc": "2.0", "method": "tools/list"}, headers={ "Authorization": "Bearer TOKEN", "Accept": "application/json, text/event-stream" } ) print("=== RAW RESPONSE ===") print(response.text) print("=== CONTENT-TYPE ===") print(response.headers.get('Content-Type')) ``` --- ## 📖 Ressources ### Spécifications - **SSE (W3C)** : https://html.spec.whatwg.org/multipage/server-sent-events.html - **MCP Protocol** : https://spec.modelcontextprotocol.io/ - **JSON-RPC 2.0** : https://www.jsonrpc.org/specification ### Librairies Python - **requests** : HTTP classique (ce que vous utilisez) - **httpx** : HTTP avec support async et streaming - **sseclient-py** : Parser SSE dédié - **mcp SDK** : SDK officiel MCP --- ## 🎓 Résumé pour expliquer à quelqu'un > "Le serveur MCP n'est PAS une API REST classique. Il utilise le protocole MCP qui encapsule toutes les réponses au format SSE (Server-Sent Events), même pour les requêtes simples. > > C'est pourquoi vous devez : > 1. Ajouter `text/event-stream` dans le header `Accept` > 2. Parser la réponse ligne par ligne pour extraire le JSON de la ligne `data:` > 3. Ne pas utiliser `response.json()` directement > > Le SSE permet au serveur d'envoyer des notifications asynchrones et de streamer les réponses progressivement, même si pour l'instant vous n'utilisez que le mode requête/réponse simple. > > C'est comme si vous demandiez une lettre postale mais que vous receviez un télégramme : le contenu est le même, mais le format d'enveloppe est différent." --- ## ✅ Checklist de migration REST → MCP - [ ] Ajouter `text/event-stream` au header `Accept` - [ ] Implémenter un parser SSE (`parse_sse_response()`) - [ ] Remplacer `response.json()` par `parse_sse(response.text)` - [ ] Ajouter l'initialisation de session (`initialize` avec `mcp-session-id`) - [ ] Gérer les notifications asynchrones (optionnel) - [ ] Tester avec différents tools - [ ] Documenter le changement pour l'équipe --- ## 📞 Questions fréquentes ### Q: Pourquoi pas du JSON simple ? **R:** MCP a besoin de supporter les notifications serveur et le streaming. SSE est le standard HTTP pour ça. ### Q: Est-ce que je peux forcer du JSON pur ? **R:** Non, c'est le protocole MCP. Utilisez les SDK officiels si vous voulez abstraire ça. ### Q: Ça consomme plus de ressources ? **R:** Négligeable. Le surcoût est juste quelques lignes de parsing. ### Q: Et WebSocket alors ? **R:** SSE est plus simple (HTTP standard) et suffisant pour MCP. WebSocket serait overkill. ### Q: Ça marche avec tous les clients HTTP ? **R:** Oui, mais vous devez parser manuellement. Les SDK MCP le font pour vous. --- ## 🎯 Conclusion **MCP avec SSE ≠ API REST classique** Même si vous faites des requêtes POST et recevez des données, le format est différent. C'est une architecture événementielle (event-driven) qui se trouve être synchrone pour vos cas d'usage actuels. **Solution recommandée :** Utilisez un SDK MCP officiel ou la classe `OpenLegiClient` fournie qui gère tout ça pour vous. ## Architecture ### Vue d'ensemble ## Architecture OpenLegi MCP ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ LLM/Client │ ←→ │ Serveur MCP │ ←→ │ API Legifrance │ │ │ │ │ │ │ │ Claude Desktop │ │ Protocole MCP │ │ Donnees │ │ Applications │ │ JSON-RPC │ │ Juridiques │ └─────────────────┘ └─────────────────┘ └─────────────────┘ ``` ### Composants 1. **Client LLM** - Claude Desktop, Cursor, ou votre application 2. **Serveur MCP** - Gere l'authentification et les requetes 3. **API Legifrance** - Source officielle des donnees juridiques ### Flux de donnees 1. Le client envoie une requete JSON-RPC au serveur MCP 2. Le serveur valide le token et verifie les quotas 3. La requete est traduite en appel API Legifrance 4. Les resultats sont formates et renvoyes au client ### Sécurité ## Securite ### Authentification - **Token Bearer** - Authentification par token unique - **OAuth2 Microsoft** - Connexion via compte Microsoft - **Chiffrement** - Toutes les communications en HTTPS ### Protection des donnees - **Rate limiting** - Limitation du nombre de requetes - **Logs d'acces** - Tracabilite des appels - **Cles API chiffrees** - Stockage securise des credentials ### Bonnes pratiques 1. **Ne partagez jamais votre token** - Il est personnel 2. **Regenerez-le regulierement** - Via votre Dashboard 3. **Utilisez des variables d'environnement** - Ne codez pas le token en dur ### En cas de compromission Si vous pensez que votre token a ete compromis: 1. Connectez-vous a votre [Dashboard](https://auth.openlegi.fr/users/dashboard/) 2. Cliquez sur "Regenerer le token" 3. Mettez a jour vos configurations ### Performance ## Performance ### Optimisations - **Formatage optimise** - Reponses adaptees aux LLM - **Transport HTTP streamable** - Pour les grandes reponses - **Pagination intelligente** - Gestion efficace des volumes ### Conseils d'utilisation 1. **Limitez max_results** - Ne demandez que ce dont vous avez besoin 2. **Utilisez les filtres** - Affinez vos recherches (ministeres, dates, etc.) 3. **Preferez les recherches specifiques** - Plutot que des termes trop generaux ### Temps de reponse typiques | Operation | Temps moyen | |-----------|-------------| | Liste des outils | < 100ms | | Recherche simple | 200-500ms | | Recherche complexe | 500ms-2s | ### Gestion des erreurs En cas de timeout ou d'erreur, le serveur renvoie un message explicite. Attendez quelques secondes avant de reessayer.