Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
RECHT_MCP_BASE_URLNoBase 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

CapabilityDetails
tools
{
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
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 normalised_from / normalised_to, never silently, and disambiguated_by says when it was YOUR court or date that picked the decision out. Where the court you named writes a suffix your citation dropped ('4 U 120/24 e'), the answer carries docket_completed with the full Aktenzeichen — cite that one.

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 not_in_corpus (we hold nothing and know of nothing), attested / known_missing (the decision provably EXISTS — decisions we do hold cite it by Aktenzeichen, and they are listed as the evidence — but we do not have its text), ambiguous (with candidates) or unparseable. attested is not a failure: you may state that the decision exists, cite it, and say the text was not available to you. What you must not do is treat it as not_in_corpus.

A resolved norm carries fundstelle: the gazette citation of the authentic text, which is the citation a court accepts. Our own URL is a reading copy, and for Land law the gazette citation is the only source reference there is. Prefer it in anything you publish.

text on a resolved norm is a 300-character stub unless you pass include: ["text"], and text_truncated says which it is. Never verify a quotation against the stub: it is the head of the provision, not the Absatz you cited.

When you supply a date or a court that does not match the decision the docket resolves to, the result carries date_mismatch / court_mismatch with the actual value. That is the hallucinated-citation case this tool exists for: cite what is actually there, not what you held — and a court_mismatch usually means this is not the decision you meant at all.

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 by_jurisdiction roll-up. Ask 'Videoüberwachung öffentlich zugänglicher Räume' and you get BDSG § 4 next to the Land data-protection and police provisions. Full text is held for Bayern, Brandenburg, Nordrhein-Westfalen and Sachsen.

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 doknr — the key listCasePassages, listCitedAuthorities and listCitingDecisions take, so you can go straight from a search hit to that decision's passages or its authorities without resolving anything first. Query in German; write raw umlauts, they are handled.

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.

law is the abbreviation as a citation writes it ('BGB', 'DSGVO', 'BDSG 2018', 'RVG'); ref is the bare number, with any letter suffix and no § or Art. ('622', '823', '3a', '83'). Aliases resolve, and CASE IS READ: 'LwG' is the federal Landwirtschaftsgesetz while 'LWG' is a Land statute (Bayern's Landeswahlgesetz, NRW's Landeswassergesetz), so write the abbreviation the way your citation writes it. A spelling that matches no law exactly still resolves case-insensitively, and a miss lists the other laws the abbreviation names under other_laws, each with a law_key you can call again with.

POINT IN TIME: as_of=YYYY-MM-DD returns the version stored for that date. Read version_coverage on every answer — the version archive begins 2019-06-10, and a date before that answers outside_coverage with the law's amendment register attached. That is a limit of our archive and says nothing about whether the provision existed.

Every answer carries first_observed, valid_to, date_precision and amendment_note. first_observed is the day we first saw the text, NOT the legal Inkrafttreten — do not compute a deadline from it without reading date_precision (day / week / launch; 'launch' means the date is a floor).

TRUST: fundstelle is the gazette citation of the authentic text — the citation a court accepts. authoritative_source names what our copy is (a consolidated, non-official reading version) and where the binding text lives. Quote the provision from markdown; the reader page at url carries per-Absatz anchors (#abs-N) if you want to deep-link a single Absatz.

listNormVersionsA

Every stored version of one provision, newest first, so you can find out which dates getNorm(as_of=…) can actually answer before you ask.

Each entry carries first_observed (the day the text was first seen here — NOT the Inkrafttreten), valid_to, date_precision and the law-level amendment_note. at_archive_floor: true marks the version that was current when mirroring began: its date is a floor, not an amendment, and earlier amendments exist that are named in the law's Änderungsverlauf (linked as amendment_history_url) but whose text is not held.

There is no diff tool: fetch two versions with getNorm(as_of=…) and diff them yourself — a diff we computed would hide which side of it came from a floor date.

listCitingDecisionsA

Incoming citation edges. Give EITHER law + ref (which decisions apply this statute provision) OR case (which decisions cite this decision) — exactly one of the two.

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 total exceeds what you read, page on with offset (pagination.next_offset) before concluding anything about national case law.

NEWEST FIRST: pass sort: "recent" when the question is about current case law ('fünf aktuelle Entscheidungen zu …'). Paging works the same way. This ordering is bounded — for a handful of procedural giants (§ 154 VwGO, § 708 ZPO) it cannot be computed inside the query budget, and then the answer comes back in WEIGHT order and says so in sort_applied and sort_note. Check sort_applied before you describe a list as the most recent decisions.

For a decision, each citer carries citing_rn: the Randnummer of the CITING decision's own text that holds the citation, as that court numbered it, and the URL is anchored to it.

COVERAGE: the graph is built over federal case law. A Land provision can answer total: 0 because it is not indexed, not because no court has cited it — coverage.complete_for_this_norm tells you which, and for a Land provision you should fall back to search on the provision's wording.

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.

treatment is null on every edge and stays null. Classifying an edge as gefolgt / abgegrenzt / aufgegeben is unbuilt work, and a wrong 'aufgegeben' in a brief is worse than no label at all. Read the citing passage yourself with listCasePassages.

A decision we can prove exists but do not hold answers known_missing, with the decisions that attest it — not a 404.

listCasePassagesA

The full text of one decision, split into its paragraphs, each with a permalink you can cite.

rn is the Randnummer the COURT printed, read out of the decision's own markup. It is never inferred from position: where a document prints no numbers, rn is null and stays null. anchor_basis is derived per decision — only 'native_numbering' means our anchor and the printed number provably coincide, so pin-cite a Randnummer only when you see that value.

amtliche_seite is null everywhere: our texts carry no page breaks, so a BVerfGE-style page pin cannot be produced honestly.

SIZE. Long decisions run to several hundred paragraphs, so the default page is 30. Three ways to move: offset pages, limit widens (max 400 — enough for a whole decision when you really want it), and around jumps. pagination appears whenever there is more than the page you were handed.

around: 51 returns a window of limit passages CENTRED on Randnummer 51 — the right call when listCitingDecisions gave you a citing_rn, when a search hit came back anchored at …#rd_51, or when you want the passage around a pin cite and not the whole judgment. It takes the number the court printed, not a position, and a decision that prints no such number answers not_in_corpus rather than silently handing you a different passage. around and offset address the same list two different ways; give one.

getChangesA

Which provisions got a new text recently, newest first — the freshness feed, as JSON. Poll it with since set to the newest observed you have already processed.

observed is the day the new text was FIRST SEEN here, which is not necessarily the day it came into force. Say so if you report a date. The window is the last 120 days; the law's own Änderungsverlauf goes further back.

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 limits: the version-archive floor, the federal scope of the citation graph, what a version date actually means, and why source windows differ.

Use it to tell outside_coverage from not_in_corpus. They are different answers and this API never collapses them.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.5/5.0

Scored across 9 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness5/5

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).

Maintenance

ActivityMaintained
ResponsivenessNo issues