# Légifrance (unofficial) (mcpb · mcp-legifrance-1.1.0.mcpb)

Unofficial MCP server for French law via the Légifrance API (PISTE): search, read and cite texts.

- Trust score: 54/100 (low)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- mcpb · `mcp-legifrance-1.1.0.mcpb`: 54/100 (this document), [markdown](https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance.md), [page](https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance)
- oci · `ghcr.io/muchiny/mcp-legifrance`: 54/100, [markdown](https://verifymcp.io/servers/muchiny-mcp-legifrance/ghcr-io-muchiny-mcp-legifrance.md), [page](https://verifymcp.io/servers/muchiny-mcp-legifrance/ghcr-io-muchiny-mcp-legifrance)

## Channel facts

- Registry: `mcpb`
- Package: `https://github.com/muchiny/mcp-legifrance/releases/download/v1.1.0/mcp-legifrance-1.1.0.mcpb`
- Version: `1.1.0`
- Transport: `stdio`
- SHA-256: `28e836411326b783b7b566f496d2611602d9d8e03cf3fc8cd0fd78d847b2daab`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 0/100
  - No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.
  - Known CVEs could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none).
  - Install-script risk not yet assessed.
  - Dependency health could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none).
- **Provenance & Transparency**: 100/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to muchiny/mcp-legifrance).
  - Clear OSI-approved license (Apache-2.0).
  - Actively maintained (last published 2 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 75/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4353 tokens (~310/item across 14 items; 13 tools + 1 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 17/100
  - Stability observed for 5 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 13 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 15 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the Légifrance (unofficial) MCP server?

Légifrance (unofficial) ships as an MCPB bundle, a single file you download and open in an MCP host that supports MCPB bundles, such as Claude Desktop. The host reads the launch command from the bundle's own manifest, so there is no command to copy. Before opening it, check the file's SHA-256 matches the one the MCP registry declares for it, 28e836411326b783b7b566f496d2611602d9d8e03cf3fc8cd0fd78d847b2daab; the commands to do that are on this page. If it does not match, do not open it.

- Download bundle: `https://github.com/muchiny/mcp-legifrance/releases/download/v1.1.0/mcp-legifrance-1.1.0.mcpb`
- SHA-256: `28e836411326b783b7b566f496d2611602d9d8e03cf3fc8cd0fd78d847b2daab`

### Verify on macOS / Linux

```bash
echo "28e836411326b783b7b566f496d2611602d9d8e03cf3fc8cd0fd78d847b2daab  mcp-legifrance-1.1.0.mcpb" | shasum -a 256 -c
```

### Verify on Windows (PowerShell)

```powershell
(Get-FileHash -Algorithm SHA256 .\mcp-legifrance-1.1.0.mcpb).Hash -eq "28e836411326b783b7b566f496d2611602d9d8e03cf3fc8cd0fd78d847b2daab"
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 54, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-03 (score 53, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-02 (score 52, 0)

- [functional regression] Schema quality: 273 → 310
- [functional] Package version: 1.0.1 → 1.1.0

### 2026-11-01 (score 52, 0)

- [security regression] Tool safety: pass → unverified
- [security] Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional improvement] Stability: unverified → 0.03
- [functional] Package version: 1.0.0 → 1.0.1

### 2026-10-31 (score 52)

First indexed and scored.

## MCP tools (13)

### `fr_coverage` (~114 tokens)

Coverage and known gaps

Describe what this server covers, how it is sourced and what it does NOT cover. Call it before telling a user that the law "does not contain" something, and whenever a search comes back empty: the gap may be in this server, not in the law. Each gap comes with a fallback. It also reports the PISTE environment (sandbox or production), whether the configuration is complete, the data source and licence with today's consultation date, and the note on ELI identifiers. No arguments, no network call.

Output parameters:

- `as_of_note` (string)
- `attribution` (string)
- `configuration` (object)
- `consulted_on` (string)
- `eli_note` (string)
- `environment` (string)
- `families` (array)
- `gaps` (array)
- `general_tools` (array)
- `source` (string)
- `status` (string)

### `fr_diff_article` (~205 tokens)

Compare article versions

Compare the versions of a code or law article (LEGIARTI) in force on `date_a` and `date_b` (YYYY-MM-DD; `date_b` defaults to today in Paris). Returns both versions with their validity dates and `etat`, and a compact word-level diff: removed and added passages with a little context. `date_fin` is the day the next version (or the repeal) takes effect, absent when there is no end date; `etat` is the Légifrance code (ABROGE_DIFF: still in force, repeal scheduled). `identical` is true when both dates fall in the same version. To read a single version use fr_get_text.

Input parameters:

- `article_id` (string, required): A LEGIARTI... id of any version of the article.
- `date_a` (string, required): First date YYYY-MM-DD.
- `date_b` (string): Second date YYYY-MM-DD (default: today in Paris).

Output parameters:

- `article_id` (string)
- `citation` (string)
- `hunks` (array)
- `identical` (boolean)
- `note` (string)
- `truncated` (boolean)
- `version_a`
- `version_b`

### `fr_get_act` (~252 tokens)

Read a law, decree or code

Read a consolidated law, decree or code by its LEGITEXT id (from fr_search on LODA or CODE): metadata, citation, source_url and a table of contents of sections and articles with their `article_id`. Returns the version in force on `date` (YYYY-MM-DD; default: the version named by a suffixed text_id, else today in Paris); without `date_fin_version` that version has no end date. The table of contents is paged: up to `toc_limit` entries (default 100) from `toc_offset`; continue with `next_toc_offset`. It does not return article text: read an article with fr_get_text. For a collective agreement (KALITEXT) use fr_get_convention.

Input parameters:

- `date` (string): Version date YYYY-MM-DD (default: the version named by a suffixed text_id, else today in Paris).
- `text_id` (string, required): A LEGITEXT... id (from fr_search on LODA or CODE).
- `toc_limit` (integer): Maximum table-of-contents entries (1..500).
- `toc_offset` (integer): First table-of-contents entry (pass next_toc_offset).

Output parameters:

- `aliases` (array)
- `citation` (string)
- `date` (string)
- `date_debut_version` (string)
- `date_fin_version` (string)
- `date_parution` (string)
- `eli` (string)
- `etat` (string): In force: VIGUEUR, VIGUEUR_ETEN, VIGUEUR_NON_ETEN, ABROGE_DIFF. Not yet: VIGUEUR_DIFF. DENONCE may still apply. Every code is classed in the etat of fr_get_text.
- `jo_reference` (string)
- `nature` (string)
- `next_toc_offset` (integer): Pass as toc_offset to read the next page; absent on the last page.
- `nor` (string)
- `note` (string)
- `num_parution` (string)
- `source_url` (string)
- `text_id` (string)
- `title` (string): Omitted when citation already contains it.
- `toc` (array)
- `toc_total` (integer)

### `fr_get_company_agreement` (~120 tokens)

Read a company agreement (metadata)

Read a company-level agreement (accord d'entreprise) by its ACCOTEXT id from fr_search on fond ACCO. Returns METADATA ONLY: company, SIRET, IDCC, APE code, sector, themes, signatory unions, dates, citation and source_url. Légifrance distributes the full text only as a .docx attachment, which this tool does not return: point the user to source_url.

Input parameters:

- `agreement_id` (string, required): An ACCOTEXT... id (from fr_search on fond ACCO).

Output parameters:

- `agreement_id` (string)
- `attachment_note` (string)
- `citation` (string)
- `code_ape` (string)
- `date_depot` (string)
- `date_effet` (string)
- `date_texte` (string)
- `idcc` (string)
- `nature` (string)
- `raison_sociale` (string)
- `secteur` (string)
- `siret` (string)
- `source_url` (string)
- `syndicats` (array)
- `themes` (array)
- `title` (string)

### `fr_get_convention` (~178 tokens)

Read a collective agreement

Read a collective labour agreement text (convention collective, avenant, annexe) by its KALITEXT id from fr_search on fond KALI: title, IDCC, parent convention, status, citation, source_url and a table of contents. Article entries carry KALIARTI ids: read them with fr_get_text. Page the table of contents with `toc_offset`/`toc_limit` (default 100) and `next_toc_offset`. For a company-level agreement use fr_get_company_agreement.

Input parameters:

- `convention_id` (string, required): A KALITEXT... id (from fr_search on fond KALI).
- `toc_limit` (integer): Maximum table-of-contents entries (1..500).
- `toc_offset` (integer): First table-of-contents entry (pass next_toc_offset).

Output parameters:

- `bulletin` (string)
- `citation` (string)
- `container_title` (string)
- `convention_id` (string)
- `date_publication` (string)
- `etat` (string)
- `idcc` (string)
- `next_toc_offset` (integer): Pass as toc_offset to read the next page; absent on the last page.
- `nor` (string)
- `source_url` (string)
- `title` (string): Omitted when citation already contains it.
- `toc` (array)
- `toc_total` (integer)

### `fr_get_decision` (~326 tokens)

Read a court decision

Read a court decision by id: JURITEXT (Cour de cassation, courts of appeal), CONSTEXT (Conseil constitutionnel) or CETATEXT (Conseil d'État, administrative courts), as found by fr_search. Returns court, formation, solution, case numbers, date, the native `ecli` when Légifrance has one (never invented), citation and source_url. By default it adds a short `summary`: the official summary when published, else the operative part or the beginning of the text; a short decision comes back whole in `text`. Use `detail`="full" with `offset`/`max_chars` (default 4,000 characters) to read the text page by page (follow `next_offset`), or `focus` to get the best matching passages (default 3).

Input parameters:

- `decision_id` (string, required): A JURITEXT..., CONSTEXT... or CETATEXT... id (from fr_search on JURI, CONSTIT or CETAT).
- `detail` (string): "summary" (default): metadata and a short summary. "full": the text from offset, up to max_chars.
- `focus` (string): A few words: return the best matching passages instead of the summary or window.
- `max_chars` (integer): Maximum characters of text returned (500 to 40000).
- `offset` (integer): Start position in characters for detail="full"; pass the next_offset of the previous call.
- `passages` (integer): Number of passages returned with focus.

Output parameters:

- `citation` (string)
- `date` (string)
- `decision_id` (string)
- `ecli` (string): Native ECLI only, never derived.
- `formation` (string)
- `juridiction` (string)
- `nature` (string)
- `next_offset` (integer): Pass as offset to read the next window.
- `note` (string)
- `numero_affaire` (array)
- `passages` (array)
- `solution` (string)
- `source_url` (string)
- `summary` (string)
- `summary_source` (string)
- `summary_truncated` (boolean): True when the summary itself is cut short or is only the opening of the text. Absent for an official summary or operative part that is given whole (it may still cover only part of the text).
- `text` (string)
- `text_length` (integer)
- `title` (string): Omitted when citation already contains it.

### `fr_get_deliberation` (~300 tokens)

Read a CNIL deliberation

Read a CNIL deliberation or decision by its CNILTEXT id (from fr_search on fond CNIL): number, nature (e.g. Sanction), status, dates, citation and source_url. By default a text of about 1,200 characters or less comes back whole in `text` and a longer one as a `summary`: the operative part of a sanction or formal notice, else the beginning of the text. `detail`="full" pages through the text with `offset`/`max_chars` (default 4,000 characters) and `next_offset`; `focus` returns the most relevant passages (default 3) and takes precedence over `detail` and `offset`. Personal data is redacted by the CNIL in published texts.

Input parameters:

- `deliberation_id` (string, required): A CNILTEXT... id (from fr_search on fond CNIL).
- `detail` (string): "summary" (default): metadata and a short summary. "full": the text from offset, up to max_chars.
- `focus` (string): A few words: return the best matching passages instead of the summary or window.
- `max_chars` (integer): Maximum characters of text returned (500 to 40000).
- `offset` (integer): Start position in characters for detail="full"; pass the next_offset of the previous call.
- `passages` (integer): Number of passages returned with focus.

Output parameters:

- `citation` (string)
- `date` (string)
- `date_publication` (string)
- `deliberation_id` (string)
- `etat` (string)
- `nature` (string)
- `nature_delib` (string)
- `next_offset` (integer): Pass as offset to read the next window.
- `note` (string)
- `num` (string)
- `passages` (array)
- `source_url` (string)
- `summary` (string)
- `summary_source` (string)
- `summary_truncated` (boolean): True when the summary itself is cut short or is only the opening of the text. Absent for an official summary or operative part that is given whole (it may still cover only part of the text).
- `text` (string)
- `text_length` (integer)
- `title` (string): Omitted when citation already contains it.

### `fr_get_related` (~261 tokens)

Related texts and decisions

List the legal links of an article (LEGIARTI) or a decision (JURITEXT, CONSTEXT, CETATEXT): texts it cites, texts citing it, and case law it refers to. Article links come from Légifrance with their ids; decision links are parsed from the decision's references, have no id and may carry an inexact code: pass one to fr_resolve only if its citation names a code. Each link has a `relation`, a `citation` and, when known, an `id` and `source_url`; `relation` as a parameter keeps one kind of link. At most 100 links are returned: `truncated` is true when there are more, and there is no next page.

Input parameters:

- `id` (string, required): A LEGIARTI... article id or a JURITEXT..., CONSTEXT... or CETATEXT... decision id.
- `relation` (string): Only the links of this relation: cites or cited_by for an article, cites_case_law or applies_text for a decision; the other family is refused. Omit it to get them all. The filter is applied before th…

Output parameters:

- `citation` (string)
- `id` (string)
- `links` (array)
- `note` (string)
- `source_url` (string)
- `total` (integer)
- `truncated` (boolean)

### `fr_get_text` (~397 tokens)

Read an article

Read one article by id: LEGIARTI (from fr_get_act or a CODE search hit) or KALIARTI (from fr_get_convention). Returns its citation (for example "Code civil, art. 9"), source_url, status, validity dates and parent code or text. By default (`detail`="summary") an article of up to 2,000 characters comes back whole and a longer one as a summary of about 1,200 characters (`summary_truncated` is true when the summary stops before the end of the text). A summary is never the whole text: use `detail`="full" before quoting a threshold, amount or rate; it returns up to `max_chars` (default 4,000) from `offset`, and `next_offset` tells where to continue; `focus` returns the most relevant passages instead (default 3). Each LEGIARTI id is one version of the article: `date_debut` and `date_fin` bound its validity; without `date_fin` it has no end date, and without `date_debut` its entry into force is not set yet (see `etat`).

Input parameters:

- `article_id` (string, required): A LEGIARTI... id (from fr_get_act or a CODE hit) or a KALIARTI... id (from fr_get_convention).
- `detail` (string): "summary" (default): metadata and a short summary. "full": the text from offset, up to max_chars.
- `focus` (string): A few words: return the best matching passages instead of the summary or window.
- `max_chars` (integer): Maximum characters of text returned (500 to 40000).
- `offset` (integer): Start position in characters for detail="full"; pass the next_offset of the previous call.
- `passages` (integer): Number of passages returned with focus.

Output parameters:

- `article_id` (string)
- `citation` (string)
- `code_title` (string)
- `date_debut` (string): Omitted when the entry into force is not set yet (see etat).
- `date_fin` (string): Omitted when the article is in force without an end date.
- `eli` (string)
- `etat` (string): In force: VIGUEUR, VIGUEUR_ETEN, VIGUEUR_NON_ETEN, ABROGE_DIFF. Not yet in force: VIGUEUR_DIFF (deferred entry, date_debut may be absent). No longer in force: MODIFIE, ABROGE, PERIME, ANNULE, REMPLAC…
- `next_offset` (integer): Pass as offset to read the next window.
- `nota` (string)
- `note` (string)
- `num` (string)
- `parent_id` (string): LEGITEXT or KALITEXT of the parent text.
- `passages` (array)
- `path` (array)
- `source_url` (string)
- `summary` (string)
- `summary_source` (string)
- `summary_truncated` (boolean): True when the summary itself is cut short or is only the opening of the text. Absent for an official summary or operative part that is given whole (it may still cover only part of the text).
- `text` (string)
- `text_length` (integer)

### `fr_resolve` (~234 tokens)

Resolve a legal citation

Turn one free-text legal citation into Légifrance ids, for example "article 1240 du code civil", "loi n° 78-17 du 6 janvier 1978", "Cass. civ. 1re, 4 juin 2025, n° 24-13.470" or an ECLI. Returns `candidates` (id, kind, citation, source_url, confidence high/medium/low), best first; nothing is guessed or fabricated, and an empty list comes with a `note` saying why. Pass `date` (YYYY-MM-DD, default: today in Paris) for the article version in force on that day. Then open a candidate with the fr_get_* tool for its kind; to check all citations of a text at once use fr_verify_citations.

Input parameters:

- `citation` (string, required): One citation in free text, e.g. "art. L. 1234-5 du code du travail" or an ECLI.
- `date` (string): Date YYYY-MM-DD for the article version (default: today in Paris).

Output parameters:

- `candidates` (array)
- `interpreted_as` (string)
- `note` (string)

### `fr_search` (~539 tokens)

Search Légifrance

Keyword search in one Légifrance fond (default LODA): laws and decrees (LODA), codes (CODE), case law (JURI, CONSTIT, CETAT), CNIL deliberations (CNIL), collective agreements (KALI) or company agreements (ACCO). Returns one page of hits (default 10) with id, title, snippet, citation and source_url; ask for the next `page` while `has_more`. `match` defaults to any word: use `all` for several words, `exact` for a phrase, fr_resolve for one known article. `date_from`/`date_to` filter by date; for KALI, `in_force_only` keeps the texts in force (not their articles' status). LODA and CODE hits are the versions in force on `version_date` (default: today in Paris); a hit `date` is the date Légifrance gives for that fond, not always the act date. Open a hit with the fr_get_* tool for its id prefix (LEGITEXT: fr_get_act, JURITEXT/CONSTEXT/CETATEXT: fr_get_decision, CNILTEXT: fr_get_deliberation, KALITEXT: fr_get_convention, ACCOTEXT: fr_get_company_agreement); CODE hits list `articles`.

Input parameters:

- `date_from` (string): Earliest date YYYY-MM-DD (fond date filter).
- `date_to` (string): Latest date YYYY-MM-DD.
- `fond` (string): Fond to search (case-insensitive).
- `in_force_only` (boolean): KALI only: keep texts in force (VIGUEUR, VIGUEUR_ETEN, VIGUEUR_NON_ETEN), drop DENONCE, MODIFIE, PERIME, REMPLACE, ABROGE. DENONCE excluded, though it may still apply during notice. It filters texts,…
- `match` (string): "any": any word (default); "all": all words; "exact": exact phrase.
- `page` (integer): Page number, from 1.
- `page_size` (integer): Hits per page (1..100).
- `query` (string, required): Free-text query, e.g. "republique numerique". AND/OR/NOT/~/^ are unreliable; a dangling one fails the search. Trailing * is a wildcard.
- `version_date` (string): LODA and CODE only: version in force on this date, YYYY-MM-DD (default today, Paris).

Output parameters:

- `has_more` (boolean): True if a next page exists and is reachable.
- `hits` (array): Résultats, dans l'ordre de l'API ; toujours présents, même vides.
- `note` (string): Hint: no match, window end, articles to page, or content removed.
- `page` (integer): Page servie, à partir de 1.
- `total` (integer): Total results; for CODE, codes; total_articles (if present) counts articles.
- `total_articles` (integer): Nombre total d'articles correspondants (fond `CODE`), à partir de la v0.2.

### `fr_search_all` (~183 tokens)

Search several fonds

Search several Légifrance fonds at once (default LODA, CODE, JURI, CETAT, CONSTIT) and return the top `per_fond` hits of each (default 3, max 10), grouped by fond with their totals. Use it for a first overview when you do not know where the answer is; then refine with fr_search on the relevant fond, which supports paging and filters. A fond that fails yields an error entry without failing the others.

Input parameters:

- `fonds` (array): Fonds to search (default LODA, CODE, JURI, CETAT, CONSTIT).
- `per_fond` (integer): Hits per fond (1..10).
- `query` (string, required): Free-text query. AND/OR/NOT/~/^ are unreliable; a dangling one fails the search. Trailing * is a wildcard.

Output parameters:

- `groups` (array)
- `note` (string): Hint: no match, or content removed.

### `fr_verify_citations` (~274 tokens)

Verify legal citations

Check every legal citation found in a text of up to 20,000 characters, for example a draft answer, against the official Légifrance record. Recognises code articles (a bare number needs article/art.; one prefixed by L, R or D does not), laws and decrees, court decisions, ECLI, CNIL deliberations and collective agreements; found=0 does not prove that a text cites nothing. For each citation returns its `span`, a `status` (verified, not_found, ambiguous, unresolvable or invalid), the official record when found and a `note` explaining any mismatch; `verified` means the article exists, not that it says what the draft claims. A quoted excerpt is compared with the official text (`quote`) only when it is glued to the citation: no `quote` means NOT checked. It checks the first `max_citations` (default 50); if `truncated` is true, call again on the rest of the text. Use it before giving the user an answer that cites law; for a single citation fr_resolve is lighter.

Input parameters:

- `max_citations` (integer): Maximum citations checked, in order of appearance.
- `text` (string, required): The text whose citations must be checked (up to 20000 characters).

Output parameters:

- `checked` (integer)
- `citations` (array)
- `found` (integer)
- `note` (string)
- `truncated` (boolean): True if found > checked.

## Diagnostics

Captured diagnostic sections: Provenance. The full working is on the page: https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance#diagnostics

## Score history

- 2026-11-05: 54
- 2026-11-04: 53
- 2026-11-03: 53
- 2026-11-02: 52
- 2026-11-01: 52
- 2026-10-31: 52

## Common questions

### What is the Légifrance (unofficial) MCP server?

Légifrance (unofficial) is an MCP server listed in the public MCP registry as io.github.muchiny/mcp-legifrance. Unofficial MCP server for French law via the Légifrance API (PISTE): search, read and cite texts. This page covers its MCPB bundle (https://github.com/muchiny/mcp-legifrance/releases/download/v1.1.0/mcp-legifrance-1.1.0.mcpb).

### Is the Légifrance (unofficial) MCP server safe to use?

Légifrance (unofficial) scores 54 out of 100 on VerifyMCP. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Légifrance (unofficial) MCP server expose?

Légifrance (unofficial) exposes 13 tools: fr_coverage, fr_diff_article, fr_get_act, fr_get_company_agreement, fr_get_convention, and 8 more. Their descriptions and schemas cost roughly 3,383 tokens of context every time the server is loaded.

### What licence is the Légifrance (unofficial) MCP server under?

Légifrance (unofficial) declares the Apache-2.0 licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

### What did VerifyMCP test on the Légifrance (unofficial) MCP server?

VerifyMCP ran 12 checks on Légifrance (unofficial), covering Source repository, Provenance, License, Maintenance and 8 more. 4 items could not be completed, a gap on our side rather than a finding about Légifrance (unofficial): Malware scan, Known CVEs, Install scripts and Dependency health. One category scores 0 for that reason, because we only credit what we can confirm. Endpoint Security and Transport & Reachability do not apply to an MCPB bundle, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.

## Links

- Repository: https://github.com/muchiny/mcp-legifrance
- Changelog RSS feed: https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance.xml
- Changelog JSON feed: https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance/changelog.json
- Trust report (JSON): https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance.json
- HTML version of this page: https://verifymcp.io/servers/muchiny-mcp-legifrance/mcp-legifrance
