MCP server for the French Legifrance API via PISTE (legifrance.gouv.fr) — search legislation (LODA, codes) and case law (JURI, Conseil constitutionnel, administrative courts) with verifiable citations and native ECLI.
Strong domain-specific tool design with clear naming (verb_noun pattern: fr_search, fr_get_*), comprehensive parameter descriptions, and well-documented schemas. All 8 tools have explicit input schemas with type definitions and parameter descriptions. Tool descriptions are detailed (100-300 chars) and explain the call order and constraints. However, output schemas are not formally documented in the code, responses are inferred from model classes. Error handling is described in prose (INSTRUCTIONS) but not enforced in visible tool definitions. Security is well-considered (credentials via env, read-only operations, audit logging). Composition is excellent: tools chain naturally (search → get_act → get_text). Minor gaps: no pagination parameters visible for search results, no explicit error recovery guidance in tool schemas.
Declare what this connector covers, how it is sourced, and what it does not cover.
Consult a LODA law/decree by its text_id (a LEGITEXT... id). Returns metadata, citation and a table of contents (articles with their article_id + num).
A company-level agreement by its ACCOTEXT... id (from fr_search on fond ACCO). Returns METADATA ONLY (company, SIRET, IDCC, sector, themes, unions, dates) - Legifrance distributes the full text of ACCO agreements only as a .docx attachment; cite source_url.
A collective labour agreement text by its KALITEXT... id (from fr_search on fond KALI). Returns metadata and a table of contents whose KALIARTI... ids resolve via fr_get_text.
A court decision by decision_id (a JURITEXT..., CONSTEXT... or CETATEXT... id, from fr_search on fond JURI, CONSTIT or CETAT). Returns the native ecli, court, formation, solution and the decision text.
Output schemas not formally documented in tool definitions. Responses are inferred from Pydantic models (Act, Decision, etc.) but not exposed as JSON Schema in the tool registration. LLMs cannot see what fields to expect without reading implementation code.
fr_search lacks explicit pagination parameters (page, limit, offset). Description mentions 'page_size' with default 10 and range 1..100, but no 'page' or 'offset' parameter visible to navigate large result sets. Agents cannot iterate through all results.
Error handling guidance exists in INSTRUCTIONS prose but is not enforced in tool schemas. Tools return structured errors with [code] prefixes (invalid_arg, not_found, upstream_error, config_error) but these error types are not declared in the tool definitions, so LLMs cannot plan recovery without reading documentation.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
A CNIL deliberation by its CNILTEXT... id (from fr_search on fond CNIL). Returns the verbatim deliberation text.
The verbatim text of a single article by article_id (a LEGIARTI... id from legislation/codes, or a KALIARTI... id from a collective agreement's table of contents).
Keyword-search French legislation or case law on Legifrance.
Tool annotations present (toolAnnotations=true) but only readOnlyHint is used. All 8 tools are read-only, which is correct, but no idempotentHint or destructiveHint declarations visible in source. Annotations should be explicit in tool registration.
No batch or multi-item variants. If an agent needs to fetch 10 articles, it must call fr_get_text 10 times sequentially. A batch_get_texts(article_ids: []) would reduce latency and token overhead.