<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.dura-lex.org/index.php?action=history&amp;feed=atom&amp;title=MCP%2FTools</id>
	<title>MCP/Tools - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.dura-lex.org/index.php?action=history&amp;feed=atom&amp;title=MCP%2FTools"/>
	<link rel="alternate" type="text/html" href="https://wiki.dura-lex.org/index.php?title=MCP/Tools&amp;action=history"/>
	<updated>2026-04-23T05:37:27Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.dura-lex.org/index.php?title=MCP/Tools&amp;diff=39&amp;oldid=prev</id>
		<title>Nicolas: Create MCP/Tools page from MCP-TOOLS.md (via create-page on MediaWiki MCP Server)</title>
		<link rel="alternate" type="text/html" href="https://wiki.dura-lex.org/index.php?title=MCP/Tools&amp;diff=39&amp;oldid=prev"/>
		<updated>2026-04-23T02:05:18Z</updated>

		<summary type="html">&lt;p&gt;Create MCP/Tools page from MCP-TOOLS.md (via create-page on MediaWiki MCP Server)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= MCP Tools =&lt;br /&gt;
&lt;br /&gt;
Dura Lex exposes 5 MCP tools. All are jurisdiction-agnostic. Jurisdiction plugins provide tag schemas, formatters, and reference resolvers — not tools.&lt;br /&gt;
&lt;br /&gt;
== search ==&lt;br /&gt;
&lt;br /&gt;
Search the corpus with full-text search, tag filters, and faceted discovery.&lt;br /&gt;
ALL filters go in the &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; parameter. Tag values support Overpass QL-inspired&lt;br /&gt;
operators (see Tag filter operators below).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
search(&lt;br /&gt;
    language:               str              # REQUIRED — ISO 639-1 (fr, en, de, ar...)&lt;br /&gt;
    query:                  str | None       # FTS query (websearch syntax: AND, OR, &amp;quot;phrase&amp;quot;, -exclude)&lt;br /&gt;
    tags:                   dict | None      # ALL filters — kind, jurisdiction, source, court, etc.&lt;br /&gt;
    edges:                  dict | None      # Edge filters — key=edge kind, value=target document ID&lt;br /&gt;
    discover:               str | None       # tag key to discover values for, or &amp;quot;*&amp;quot; for available keys&lt;br /&gt;
    at_date:                str | None       # historical date (YYYY-MM-DD) — versions in force at that date&lt;br /&gt;
    date_from:              str | None       # minimum date (YYYY-MM-DD)&lt;br /&gt;
    date_to:                str | None       # maximum date (YYYY-MM-DD)&lt;br /&gt;
    should_expand_synonyms: bool = true      # expand query with legal synonyms&lt;br /&gt;
    limit:                  int = 20         # results per page (max 100)&lt;br /&gt;
    offset:                 int = 0          # pagination offset&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tag filter operators (Overpass QL-inspired) ===&lt;br /&gt;
&lt;br /&gt;
Tag values support these operators:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;value&amp;quot;&amp;lt;/code&amp;gt; — exact match (default)&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;!=value&amp;quot;&amp;lt;/code&amp;gt; — negation: key exists, value differs&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;val1|val2&amp;quot;&amp;lt;/code&amp;gt; — any of (OR)&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;!=val1|val2&amp;quot;&amp;lt;/code&amp;gt; — none of (negated OR)&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;*&amp;quot;&amp;lt;/code&amp;gt; — key exists (any value)&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;!*&amp;quot;&amp;lt;/code&amp;gt; — key absent&lt;br /&gt;
&lt;br /&gt;
=== Virtual tag keys (promoted columns filterable as tags) ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;kind&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;legislation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;record&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;notice&amp;lt;/code&amp;gt;. Operators: &amp;lt;code&amp;gt;&amp;quot;legislation|decision&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;!=record&amp;quot;&amp;lt;/code&amp;gt;. Drives the fan-out UNION ALL query.&lt;br /&gt;
* &amp;lt;code&amp;gt;jurisdiction&amp;lt;/code&amp;gt; (REQUIRED): ISO code. Subdivision-aware: &amp;lt;code&amp;gt;&amp;quot;fr&amp;quot;&amp;lt;/code&amp;gt; matches &amp;lt;code&amp;gt;fr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fr-alsace&amp;lt;/code&amp;gt;. Multi: &amp;lt;code&amp;gt;&amp;quot;eu|fr&amp;quot;&amp;lt;/code&amp;gt;. Wildcard: &amp;lt;code&amp;gt;&amp;quot;*&amp;quot;&amp;lt;/code&amp;gt; (no filter). Negation: &amp;lt;code&amp;gt;&amp;quot;!=eu&amp;quot;&amp;lt;/code&amp;gt;. &amp;#039;&amp;#039;&amp;#039;Omitting &amp;lt;code&amp;gt;tags[&amp;quot;jurisdiction&amp;quot;]&amp;lt;/code&amp;gt; raises a ToolError&amp;#039;&amp;#039;&amp;#039; — the LLM must always be explicit about jurisdiction scope.&lt;br /&gt;
* &amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt;: data source. &amp;lt;code&amp;gt;&amp;quot;legi&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;cass&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;acco&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;kali&amp;quot;&amp;lt;/code&amp;gt;... Exclusion: &amp;lt;code&amp;gt;&amp;quot;!=acco|kali&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;language&amp;lt;/code&amp;gt;: overrides the auto-filter from the &amp;lt;code&amp;gt;language&amp;lt;/code&amp;gt; parameter. &amp;lt;code&amp;gt;&amp;quot;fr|en&amp;quot;&amp;lt;/code&amp;gt; returns French AND English.&lt;br /&gt;
&lt;br /&gt;
=== Primary tag filters (T1) ===&lt;br /&gt;
&lt;br /&gt;
T1 tags (cross-jurisdiction enums, documented in TAG-CONVENTIONS.md) are the intended primary search filters — stable English vocabularies, safe to use regardless of jurisdiction: &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;document_form&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;court_level&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;enforcement_status&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;importance_level&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;formation_solemnity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;content_quality&amp;lt;/code&amp;gt;. For jurisdiction-local precision, fall back to T2/T3 keys (e.g. FR &amp;lt;code&amp;gt;nature&amp;lt;/code&amp;gt;) — see &amp;lt;code&amp;gt;spec/TAG-CONVENTIONS.md&amp;lt;/code&amp;gt; and the per-plugin tag references.&lt;br /&gt;
&lt;br /&gt;
=== Edge filters ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;edges&amp;lt;/code&amp;gt; parameter filters documents by their relationships to other&lt;br /&gt;
documents. Key = edge kind (from EDGE-TYPES.md), value = target document ID.&lt;br /&gt;
Semantics: return documents that have an outgoing edge of this kind to this&lt;br /&gt;
target.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Syntax !! Semantics&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;cites&amp;quot;: &amp;quot;id1&amp;quot;&amp;lt;/code&amp;gt; || cites id1&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;cites&amp;quot;: &amp;quot;id1&amp;amp;#124;id2&amp;quot;&amp;lt;/code&amp;gt; || cites id1 OR id2&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;cites&amp;quot;: &amp;quot;id1&amp;amp;id2&amp;quot;&amp;lt;/code&amp;gt; || cites id1 AND id2&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;cites&amp;quot;: &amp;quot;id1&amp;quot;, &amp;quot;amends&amp;quot;: &amp;quot;id2&amp;quot;&amp;lt;/code&amp;gt; || cites id1 AND amends id2&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;*&amp;quot;: &amp;quot;id1&amp;quot;&amp;lt;/code&amp;gt; || any edge kind to id1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Edge filters compose with all other search parameters (query, tags, dates,&lt;br /&gt;
pagination). The &amp;lt;code&amp;gt;edges&amp;lt;/code&amp;gt; parameter is separate from &amp;lt;code&amp;gt;tags&amp;lt;/code&amp;gt; because edges are&lt;br /&gt;
relationships between documents, not intrinsic properties.&lt;br /&gt;
&lt;br /&gt;
=== Searchable kinds ===&lt;br /&gt;
&lt;br /&gt;
The search tool only accepts &amp;lt;code&amp;gt;legislation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;decision&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;record&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;notice&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;kind&amp;lt;/code&amp;gt; values. &amp;lt;code&amp;gt;section&amp;lt;/code&amp;gt; (navigated via &amp;lt;code&amp;gt;browse_structure&amp;lt;/code&amp;gt;) and &amp;lt;code&amp;gt;chunk&amp;lt;/code&amp;gt; (processing artifact) are valid document kinds in the corpus but are filtered out of search.&lt;br /&gt;
&lt;br /&gt;
=== Modes ===&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Search mode&amp;#039;&amp;#039;&amp;#039; (query and/or tags provided): FTS + tag filters + date range. Returns ranked results with snippets.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Browse mode&amp;#039;&amp;#039;&amp;#039; (tags only, no query): returns documents matching tag filters, ordered by date descending.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Discover mode&amp;#039;&amp;#039;&amp;#039; (discover parameter set): returns distinct values for the given tag key from &amp;lt;code&amp;gt;tag_stats&amp;lt;/code&amp;gt;. Use &amp;lt;code&amp;gt;discover=&amp;quot;*&amp;quot;&amp;lt;/code&amp;gt; to list all available tag keys. Use &amp;lt;code&amp;gt;discover=&amp;quot;edge_kinds&amp;quot;&amp;lt;/code&amp;gt; to list available edge kinds.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
All examples pass &amp;lt;code&amp;gt;tags[&amp;quot;jurisdiction&amp;quot;]&amp;lt;/code&amp;gt; (REQUIRED).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, query=&amp;quot;responsabilite civile&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;, &amp;quot;court&amp;quot;: &amp;quot;cassation&amp;quot;})&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;legislation&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;collective_agreement&amp;quot;, &amp;quot;idcc&amp;quot;: &amp;quot;3239&amp;quot;})&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;legislation&amp;quot;, &amp;quot;source&amp;quot;: &amp;quot;acco&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;collective_agreement&amp;quot;})&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;}, discover=&amp;quot;court&amp;quot;)&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, discover=&amp;quot;*&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;})&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, query=&amp;quot;article 1240&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;legislation&amp;quot;}, at_date=&amp;quot;2015-06-15&amp;quot;)&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;, &amp;quot;importance_level&amp;quot;: &amp;quot;highest_importance&amp;quot;})&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;, &amp;quot;official_grade&amp;quot;: &amp;quot;A&amp;quot;})&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;eu|fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;, &amp;quot;court_level&amp;quot;: &amp;quot;supreme|supranational&amp;quot;})  # apex-court rulings only&lt;br /&gt;
&lt;br /&gt;
# Overpass QL operators&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;legislation&amp;quot;, &amp;quot;source&amp;quot;: &amp;quot;!=acco|kali&amp;quot;})  # exclude conventions&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;eu|fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;legislation|decision&amp;quot;})  # multi-kind, multi-jurisdiction&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;*&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;, &amp;quot;official_grade&amp;quot;: &amp;quot;*&amp;quot;})  # all jurisdictions, only graded decisions&lt;br /&gt;
&lt;br /&gt;
# Edge filters&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;, &amp;quot;kind&amp;quot;: &amp;quot;decision&amp;quot;}, edges={&amp;quot;cites&amp;quot;: &amp;quot;fr.legiarti000032041571&amp;quot;})  # decisions citing article 1240 code civil&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, query=&amp;quot;preuve deloyale&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;}, edges={&amp;quot;cites&amp;quot;: &amp;quot;fr.legiarti000032041571&amp;quot;})  # + FTS&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;}, edges={&amp;quot;cites&amp;quot;: &amp;quot;fr.legiarti000032041571&amp;amp;fr.legiarti000006436298&amp;quot;})  # citing both articles&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;}, edges={&amp;quot;*&amp;quot;: &amp;quot;fr.jorftext000032004539&amp;quot;})  # any relationship to this law&lt;br /&gt;
search(language=&amp;quot;fr&amp;quot;, tags={&amp;quot;jurisdiction&amp;quot;: &amp;quot;fr&amp;quot;}, discover=&amp;quot;edge_kinds&amp;quot;)  # list available edge kinds&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== get_document ==&lt;br /&gt;
&lt;br /&gt;
Retrieve a single document by ID or legal reference.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
get_document(&lt;br /&gt;
    reference:  str               # document ID or natural language reference&lt;br /&gt;
    language:   str               # REQUIRED — ISO 639-1 (fr, en, de...). Disambiguates language variants.&lt;br /&gt;
    highlight:  str | None        # select matching blocks (non-contiguous, ±1 context, capped at 40)&lt;br /&gt;
    blocks:     str | None        # block range for large documents (&amp;quot;30-50&amp;quot;)&lt;br /&gt;
    at_date:    str | None        # historical date (YYYY-MM-DD) — version in force at that date&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reference resolver (jurisdiction-specific) parses the reference into a TagQuery and executes it against the store. Falls back to direct ID lookup. For decisions, the output includes grade and formation display: &amp;lt;code&amp;gt;Grade : A — Publié au Recueil Lebon — highest_importance&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;Formation : Assemblée du contentieux (full_court)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
get_document(reference=&amp;quot;article 1240 du code civil&amp;quot;)&lt;br /&gt;
get_document(reference=&amp;quot;fr.juritext000041701651&amp;quot;, highlight=&amp;quot;preuve deloyale&amp;quot;)&lt;br /&gt;
get_document(reference=&amp;quot;[2024] UKSC 1&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== browse_structure ==&lt;br /&gt;
&lt;br /&gt;
Navigate hierarchical structure (table of contents of codes, conventions, doctrine).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
browse_structure(&lt;br /&gt;
    language:  str             # REQUIRED — filters the tree (not just labels)&lt;br /&gt;
    tags:      dict            # REQUIRED, must contain &amp;quot;jurisdiction&amp;quot;&lt;br /&gt;
    root_id:   str | None      # node ID to start from (NULL = top-level roots)&lt;br /&gt;
    depth:     int | None      # maximum tree depth (capped at 20 internally)&lt;br /&gt;
    limit:     int = 50        # max nodes returned per page&lt;br /&gt;
    offset:    int = 0         # pagination offset&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tags[&amp;quot;jurisdiction&amp;quot;]&amp;lt;/code&amp;gt; is REQUIRED — same syntax as &amp;lt;code&amp;gt;search&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;&amp;quot;fr&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;eu&amp;quot;&amp;lt;/code&amp;gt;,&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot;eu|fr&amp;quot;&amp;lt;/code&amp;gt; (combined), &amp;lt;code&amp;gt;&amp;quot;*&amp;quot;&amp;lt;/code&amp;gt; (all jurisdictions). Other tag filters&lt;br /&gt;
(e.g., &amp;lt;code&amp;gt;&amp;quot;structure_type&amp;quot;: &amp;quot;legislation&amp;quot;&amp;lt;/code&amp;gt;) are passed through as JSONB&lt;br /&gt;
containment filters.&lt;br /&gt;
&lt;br /&gt;
Operates on documents with &amp;lt;code&amp;gt;kind=section&amp;lt;/code&amp;gt;. Uses recursive CTE on &amp;lt;code&amp;gt;parent_id&amp;lt;/code&amp;gt;.&lt;br /&gt;
The jurisdiction and language filters are applied to BOTH the anchor and the&lt;br /&gt;
recursive part of the CTE so a parent&amp;#039;s children inherit the same scope (no&lt;br /&gt;
mixed-jurisdiction or mixed-language trees). Multi-jurisdiction uses&lt;br /&gt;
&amp;lt;code&amp;gt;s.jurisdiction = ANY(%(jurisdictions)s)&amp;lt;/code&amp;gt; in both anchor and recursive WHERE.&lt;br /&gt;
&lt;br /&gt;
== safety_guidelines ==&lt;br /&gt;
&lt;br /&gt;
Retrieve mandatory guidelines for legal research. Two-call workflow: &amp;lt;code&amp;gt;core&amp;lt;/code&amp;gt; once at session start, &amp;lt;code&amp;gt;jurisdiction&amp;lt;/code&amp;gt; per jurisdictional context.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
safety_guidelines(&lt;br /&gt;
    category:     str             # REQUIRED — &amp;quot;core&amp;quot; or &amp;quot;jurisdiction&amp;quot;&lt;br /&gt;
    jurisdiction: str | None      # REQUIRED iff category=&amp;quot;jurisdiction&amp;quot;; ignored (with warning) if category=&amp;quot;core&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Categories ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;core&amp;quot;&amp;lt;/code&amp;gt;: foundational rules (8 non-negotiable, methodology, defensive posture, response format). Independent of jurisdiction. Called ONCE per session. Passing &amp;lt;code&amp;gt;jurisdiction&amp;lt;/code&amp;gt; is non-fatal: the parameter is ignored and a warning is prepended to the returned text instructing the LLM to make a separate &amp;lt;code&amp;gt;category=&amp;quot;jurisdiction&amp;quot;&amp;lt;/code&amp;gt; call.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;jurisdiction&amp;quot;&amp;lt;/code&amp;gt;: jurisdiction-specific rules + corpus provenance filtered by jurisdiction. Called when entering a jurisdictional research context. Supports the same Overpass QL syntax as &amp;lt;code&amp;gt;tags[&amp;quot;jurisdiction&amp;quot;]&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;&amp;quot;fr&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;eu&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;eu|fr&amp;quot;&amp;lt;/code&amp;gt; (concatenated), &amp;lt;code&amp;gt;&amp;quot;*&amp;quot;&amp;lt;/code&amp;gt; (all jurisdictions), &amp;lt;code&amp;gt;&amp;quot;!=eu&amp;quot;&amp;lt;/code&amp;gt; (exclusion). The &amp;lt;code&amp;gt;&amp;quot;!*&amp;quot;&amp;lt;/code&amp;gt; operator is not allowed.&lt;br /&gt;
&lt;br /&gt;
Returns jurisdiction-specific guidance: citation rules, search strategy, authority hierarchy, data freshness, caveats.&lt;br /&gt;
&lt;br /&gt;
The plugin protocol (&amp;lt;code&amp;gt;get_guidelines() -&amp;gt; str&amp;lt;/code&amp;gt;) returns a single jurisdiction-scoped supplement; the core text lives in &amp;lt;code&amp;gt;duralex.mcp/core.md&amp;lt;/code&amp;gt; and is loaded by the MCP server, not by plugins.&lt;br /&gt;
&lt;br /&gt;
== quality_check ==&lt;br /&gt;
&lt;br /&gt;
Mandatory research debrief. Fire-and-forget. Two modes:&lt;br /&gt;
* &amp;lt;code&amp;gt;research&amp;lt;/code&amp;gt; — called ONCE per research sequence, at the END, before presenting the answer to the user. Captures the full research journey.&lt;br /&gt;
* &amp;lt;code&amp;gt;correction&amp;lt;/code&amp;gt; — called immediately when the model detects an error, or when the user signals one.&lt;br /&gt;
&lt;br /&gt;
PRIVACY: ABSOLUTE. Only technical and structural data. Never user facts, names, conversation content, or anything that could identify a party.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
quality_check(&lt;br /&gt;
    mode:               str          # &amp;quot;research&amp;quot; or &amp;quot;correction&amp;quot;&lt;br /&gt;
    model:              str          # LLM model identifier&lt;br /&gt;
    jurisdiction:       str | None   # jurisdiction(s) researched (fr, eu, eu|fr, *) — always include&lt;br /&gt;
&lt;br /&gt;
    # Research-mode fields&lt;br /&gt;
    queries_attempted:  list[str] | None    # legal-concept queries (no user facts)&lt;br /&gt;
    tools_sequence:     list[str] | None    # ordered tool calls (e.g. [&amp;quot;search&amp;quot;,&amp;quot;get_document&amp;quot;])&lt;br /&gt;
    documents_cited:    list[str] | None    # IDs of documents cited in the answer&lt;br /&gt;
    tags_used:          dict | None         # tag filters applied&lt;br /&gt;
    satisfaction:       str | None          # sufficient | partial | insufficient&lt;br /&gt;
    confidence:         str | None          # high | moderate | low&lt;br /&gt;
    gaps:               list[str] | None    # coverage gaps identified&lt;br /&gt;
    difficulties:       list[str] | None    # technical issues encountered&lt;br /&gt;
    concept:            str | None          # legal concept label for synonym groups&lt;br /&gt;
&lt;br /&gt;
    # Correction-mode fields&lt;br /&gt;
    error_type:         str | None          # fabricated_citation | wrong_jurisdiction&lt;br /&gt;
                                            # | repealed_law | misattribution&lt;br /&gt;
                                            # | temporal_error | wrong_article&lt;br /&gt;
                                            # | user_correction&lt;br /&gt;
    document_ids:       list[str] | None    # documents involved in the error&lt;br /&gt;
    detail:             str | None          # technical description (no user facts)&lt;br /&gt;
    severity:           str | None          # critical | important | minor&lt;br /&gt;
&lt;br /&gt;
    # Self-audit checklist (11 booleans, all default False)&lt;br /&gt;
    # Pure presence-of-string checks on the pending response / visible context.&lt;br /&gt;
    # Declared-true values trigger adaptive alerts tiered STOP / DANGER /&lt;br /&gt;
    # DRIFT / ATTENTION; the tool returns a structured block the model must&lt;br /&gt;
    # translate-and-relay to the user before emitting.&lt;br /&gt;
    context_contains_compaction_marker:                     bool&lt;br /&gt;
    response_self_references_previous_turn:                 bool&lt;br /&gt;
    response_contains_flattery:                             bool&lt;br /&gt;
    response_contains_prescriptive_legal_advice:            bool&lt;br /&gt;
    response_contains_outcome_prediction:                   bool&lt;br /&gt;
    response_contains_legal_assertion_verb:                 bool&lt;br /&gt;
    response_contains_hedge_marker:                         bool&lt;br /&gt;
    response_cites_document_without_verbatim_or_locator:    bool&lt;br /&gt;
    response_cites_document_without_permanent_link:         bool&lt;br /&gt;
    response_claims_settled_case_law:                       bool&lt;br /&gt;
    response_asserts_legal_absence_as_inexistence:          bool&lt;br /&gt;
    safety_guidelines_not_fully_loaded:                     bool&lt;br /&gt;
    safety_guidelines_distant_or_unclear:                   bool&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The feedback server is schema-agnostic; the tool adds &amp;lt;code&amp;gt;&amp;quot;tool_name&amp;quot;: &amp;quot;quality_check&amp;quot;&amp;lt;/code&amp;gt; automatically so downstream JSONL analysis can distinguish quality_check payloads from older &amp;lt;code&amp;gt;report&amp;lt;/code&amp;gt; payloads.&lt;br /&gt;
&lt;br /&gt;
The 11 self-audit booleans and the computed &amp;lt;code&amp;gt;highest_alert_severity&amp;lt;/code&amp;gt; are persisted in the payload for forensic analysis of declaration rates per boolean. See ADR &amp;lt;code&amp;gt;2026-04-15-quality-check-self-audit-checklist&amp;lt;/code&amp;gt; for the full rationale and the alert-severity tiering.&lt;br /&gt;
&lt;br /&gt;
[[Category:MCP]]&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>
	</entry>
</feed>