recht-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| RECHT_MCP_BASE_URL | No | Base URL for the public REST API. Can also be set with the --base-url option. | https://recht.nulegal.eu |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| resolveIdentifiersA | Ground a batch of German legal citations against the corpus. Call this BEFORE stating any citation you did not read here. Takes the citation in the form you already hold it — including the court name, the dispositive word and the date a model normally writes around a docket. KEEP THEM IN: the court and the date are used to disambiguate. An Aktenzeichen is unique per court, not nationwide, and 21,021 dockets in this corpus are held by more than one decision, so 'OLG Bamberg, 4 U 120/24' resolves to Bamberg's decision where the bare '4 U 120/24' is ambiguous or lands on another court's. Where the string has to be rewritten to be read, the rewrite is reported back under Accepted kinds: norm citations ('§ 823 Abs. 1 BGB', '§§ 305-310 BGB', 'Art. 83 DSGVO'), Aktenzeichen ('2 C 9.22', '8 AZR 26/18'), ECLI ('ECLI:DE:BGH:2019:180619UVIIIZR247.18.0') and Fundstellen ('BVerfGE 65, 1'). Full prose citations work: 'BVerwG, Urteil vom 24.10.2023 - 2 C 9.22'. It never returns a near match. A miss comes back as A resolved norm carries
When you supply a date or a court that does not match the decision the docket resolves to, the result carries |
| searchA | One query over BOTH corpora: federal and Land statutes (lexical, with concept pinning) and court decisions (semantic — natural-language questions work well here and are the better shape for case law). Search both unless you have a reason not to. A term of art often does not appear in the statute that governs it: 'Verzugspauschale' matches no provision (§ 288 BGB says 'Pauschale in Höhe von 40 Euro') while 184 decisions use the word. scope='norms' alone will read as 'nothing here' in exactly those cases. CROSS-LAND COMPARISON: a single query returns the parallel provisions of the Bund and of every covered Land side by side, each row jurisdiction-labelled, plus a Decision hits come back already anchored at the best-matching Randnummer (…#rd_51), so you can quote a paragraph rather than a document, AND carry |
| getNormA | The text of one provision, by default as clean Markdown — about a tenth the size of the reader page for the same provision, with no navigation, no scripts and no boilerplate.
POINT IN TIME: Every answer carries TRUST: |
| listNormVersionsA | Every stored version of one provision, newest first, so you can find out which dates Each entry carries There is no diff tool: fetch two versions with |
| listCitingDecisionsA | Incoming citation edges. Give EITHER Results are ranked by citation weight, then court tier, then recency. Read the ranking honestly: for a provision with many EU decisions the first ten can be almost all CJEU, and the German courts appear only further down. If NEWEST FIRST: pass For a decision, each citer carries COVERAGE: the graph is built over federal case law. A Land provision can answer |
| listCitedAuthoritiesA | Outgoing citation edges of one decision: the statute provisions it cites (with how often it cites each — that is the Normenkette, weighted) and the decisions it relies on.
A decision we can prove exists but do not hold answers |
| listCasePassagesA | The full text of one decision, split into its paragraphs, each with a permalink you can cite.
SIZE. Long decisions run to several hundred paragraphs, so the default page is 30. Three ways to move:
|
| getChangesA | Which provisions got a new text recently, newest first — the freshness feed, as JSON. Poll it with
|
| getCoverageA | Corpus scope with its holes stated. Call this once when your answer depends on whether an absence is real. Returns totals (laws, provisions, versions, decisions, courts, citation edges), the per-source windows, the count of Aktenzeichen we can prove exist and do not hold, and Use it to tell |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 9 tools
The tools are largely distinct: resolveIdentifiers handles citation grounding, search handles discovery, getNorm/listNormVersions handle statute text, listCitingDecisions/listCitedAuthorities/listCasePassages handle citation graph and case text, getChanges/getCoverage handle freshness and scope. Minor overlap exists between search and getNorm (both can retrieve norm text) and between listCitingDecisions and listCitedAuthorities (both expose citation edges), but the descriptions clearly delineate their roles.
Most tools follow a consistent verb_noun pattern: resolveIdentifiers, getNorm, listNormVersions, listCitingDecisions, listCitedAuthorities, listCasePassages, getChanges, getCoverage. The outlier is 'search', which is a bare verb rather than verb_noun, but it is a common and recognizable convention. Overall the pattern is predictable and readable.
Nine tools is well within the ideal 3-15 range and each tool serves a distinct, necessary function for a legal research server: citation resolution, search, norm retrieval, version history, citation graph (in/out), case text, change feed, and coverage metadata. No tool feels redundant or superfluous.
The surface covers the full research workflow: discover (search), resolve (resolveIdentifiers), read (getNorm, listCasePassages), trace (listCitingDecisions, listCitedAuthorities), track versions (listNormVersions, getChanges), and verify scope (getCoverage). The only minor gap is the absence of a diff tool, but the descriptions explicitly acknowledge this and provide a workaround (fetch two versions and diff manually).