nu:legal Deutsches Recht
REMOTE · RECHT.NULEGAL.EU · SCANNED SEP 27
German federal and Land statutes plus court decisions for agents. Keyless, read-only, CC BY 4.0.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security80
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one. See how to fix → View diagnostics → Partial
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability61
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 3420 tokens (~380/item across 9 items; 9 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management13
- Stability observed for 4 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage88
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 64% of tool parameters carry a description.Partial
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 9 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 10 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the nu:legal Deutsches Recht MCP server?
nu:legal Deutsches Recht is a hosted endpoint at https://recht.nulegal.eu/v1/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · recht.nulegal.eu
claude mcp add --transport http eu-nulegal-recht 'https://recht.nulegal.eu/v1/mcp'
{
"mcpServers": {
"eu-nulegal-recht": {
"url": "https://recht.nulegal.eu/v1/mcp"
}
}
} {
"servers": {
"eu-nulegal-recht": {
"type": "http",
"url": "https://recht.nulegal.eu/v1/mcp"
}
}
} [mcp_servers.eu-nulegal-recht] url = "https://recht.nulegal.eu/v1/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"eu-nulegal-recht": {
"type": "remote",
"url": "https://recht.nulegal.eu/v1/mcp",
"enabled": true
}
}
} openclaw mcp add eu-nulegal-recht --url 'https://recht.nulegal.eu/v1/mcp' --transport streamable-http
mcp_servers:
eu-nulegal-recht:
url: "https://recht.nulegal.eu/v1/mcp" {
"McpServers": {
"eu-nulegal-recht": {
"Transport": "http",
"Url": "https://recht.nulegal.eu/v1/mcp"
}
}
} assistant mcp add eu-nulegal-recht -t streamable-http -u 'https://recht.nulegal.eu/v1/mcp'
{
"mcpServers": {
"eu-nulegal-recht": {
"type": "http",
"url": "https://recht.nulegal.eu/v1/mcp"
}
}
} The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 27 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.
- 25 Sept 26 +1
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 24 Sept 26 +1
- Tool “getNorm” rewrote its description, which is the text the model reads security
- Tool “listCasePassages” rewrote its description, which is the text the model reads security
- Tool “listCitingDecisions” rewrote its description, which is the text the model reads security
- Tool “resolveIdentifiers” rewrote its description, which is the text the model reads security
- Tool “search” rewrote its description, which is the text the model reads security
- Schema quality: 301 → 380 ▼ functional
- Stability: unverified → 0.03 ▲ functional
- MCP protocol: fail → pass ▲ functional
- MCP protocol version: 2025-06-18 → 2025-11-25 functional
- Server version: 1.0.0 → 1.0.1 functional
- “listCasePassages” added an optional parameter “around” cosmetic
- “listCitingDecisions” added an optional parameter “sort” cosmetic
- Tool “getChanges” changed its title: Recently changed provisions → Recent changes cosmetic
- Tool “getCoverage” changed its title: What the corpus holds, and what it does not → Corpus coverage cosmetic
- Tool “getNorm” changed its title: Statute text, as Markdown → Get statute text cosmetic
- Tool “listCasePassages” changed its title: A decision as numbered passages → List case passages cosmetic
- Tool “listCitedAuthorities” changed its title: What a decision cites → List cited authorities cosmetic
- Tool “listCitingDecisions” changed its title: Decisions citing a provision or a decision → List citing decisions cosmetic
- Tool “listNormVersions” changed its title: Observed versions of a provision → List statute versions cosmetic
- Tool “resolveIdentifiers” changed its title: Resolve German legal citations → Resolve legal citations cosmetic
- Tool “search” changed its title: Search statutes and case law → Search German law cosmetic
- 23 Sept 26 69
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 27 Sept 2026 · Probed https://recht.nulegal.eu/v1/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=nulegal.eu | CN=YE1,O=Let's Encrypt,C=US | 21 Sept 2026 | 20 Dec 2026 | ECDSA 256 | ECDSA-SHA384 | 619c0ce5b63f18d2f34ef2a803fa393aa50 |
| SANs: *.nulegal.eu, nulegal.eu | ||||||
| CN=YE1,O=Let's Encrypt,C=US (CA) | CN=Root YE,O=ISRG,C=US | 3 Sept 2025 | 2 Sept 2028 | ECDSA 384 | ECDSA-SHA384 | 5ddd70dd31f801c85c186a7a04b80afe |
| CN=Root YE,O=ISRG,C=US (CA) | CN=ISRG Root X2,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | ECDSA-SHA384 | 872165fc34b6e5fba8add5b3705fb53a |
| CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) | CN=ISRG Root X1,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | SHA256-RSA | 6c8f1dc727c7117f7baf853ac980f9cd |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of recht.nulegal.eu. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| eu. | present | 35926 | 8 | Verified |
| nulegal.eu. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication No authorisation required
The endpoint answered without asking for a token. Anyone who knows the URL can reach it.
| Result | No authorisation required |
|---|---|
| HTTP status | 200 |
| Header | Value |
|---|---|
| strict-transport-security | max-age=31536000; includeSubDomains |
| content-security-policy | default-src 'self'; script-src 'self' 'unsafe-inline' https://eu.i.posthog.com https://eu-assets.i.posthog.com; connect-src 'self' https://eu.i.posthog.com https://eu-assets.i.posthog.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; object-src 'none' |
| x-content-type-options | nosniff |
| x-frame-options | SAMEORIGIN |
| referrer-policy | strict-origin-when-cross-origin |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://recht.nulegal.eu/v1/mcp | Verified | 200 | |
| http (plaintext) | http://recht.nulegal.eu/v1/mcp | HTTPS enforced | 301 | https://recht.nulegal.eu/v1/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
getChanges Recent changes ~122
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.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | – |
| since | string | – | Only changes observed on or after this date. |
No output schema declared.
No examples provided.
getCoverage Corpus coverage ~124
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.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
getNorm Get statute text ~548
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.
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | – | Return the version stored for this date. |
| format | string | – | 'markdown' (default, compact, quotable) or 'json' for the structured payload. |
| law | string | yes | Law abbreviation, or a `law_key` (`slug` in search results) when an abbreviation is ambiguous. |
| ref | string | yes | Provision number without § or Art. A sub-unit ('Abs. 1', 'lit. f') is dropped: the whole provision is returned. |
No output schema declared.
No examples provided.
listCasePassages List case passages ~417
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.
| Name | Type | Req | Description |
|---|---|---|---|
| around | integer|string | – | A Randnummer as the court printed it. Returns a window of `limit` passages centred on it. Not combinable with `offset`. |
| case | string | yes | A juris doknr, an ECLI, or this site's decision URL as `search` returns it. |
| limit | integer | – | – |
| offset | integer | – | – |
No output schema declared.
No examples provided.
listCitedAuthorities List cited authorities ~163
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.
| Name | Type | Req | Description |
|---|---|---|---|
| case | string | yes | A juris doknr, an ECLI, or this site's decision URL as `search` returns it. |
No output schema declared.
No examples provided.
listCitingDecisions List citing decisions ~464
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.
| Name | Type | Req | Description |
|---|---|---|---|
| case | string | – | A juris doknr, an ECLI, or this site's decision URL as `search` returns it. |
| law | string | – | – |
| limit | integer | – | – |
| offset | integer | – | Rows to skip, for reading past the first page. |
| ref | string | – | – |
| sort | string | – | 'weight' (default) is citation weight, then court tier, then recency. 'recent' is newest decision first; where it cannot be computed the answer falls back to 'weight' and says so in `sort_applied`. |
No output schema declared.
No examples provided.
listNormVersions List statute versions ~196
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.
| Name | Type | Req | Description |
|---|---|---|---|
| law | string | yes | – |
| ref | string | yes | – |
No output schema declared.
No examples provided.
resolveIdentifiers Resolve legal citations ~778
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…
| Name | Type | Req | Description |
|---|---|---|---|
| citations | array | yes | The citations, verbatim as you hold them. |
| include | array | – | Opt-in extra payload. 'text' returns a norm's FULL text instead of the 300-character stub — the stub is the same 300 characters whichever Absatz you cited, so never verify a quotation against it. 'le… |
No output schema declared.
No examples provided.
search Search German law ~397
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.
| Name | Type | Req | Description |
|---|---|---|---|
| include_repealed | boolean | – | Include repealed (aufgehobene) provisions. Off by default; turn it on when researching an older state of the law. |
| limit | integer | – | – |
| q | string | yes | German query. Keywords, a citation, or a full question. |
| scope | string | – | 'all' (default) searches both. Narrow only when you know which corpus answers. |
No output schema declared.
No examples provided.
What is the nu:legal Deutsches Recht MCP server?
nu:legal Deutsches Recht is an MCP server listed in the public MCP registry as eu.nulegal/recht. German federal and Land statutes plus court decisions for agents. Keyless, read-only, CC BY 4.0. This page covers its hosted endpoint (https://recht.nulegal.eu/v1/mcp).
Is the nu:legal Deutsches Recht MCP server safe to use?
nu:legal Deutsches Recht scores 72 out of 100 on VerifyMCP. 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 nu:legal Deutsches Recht MCP server expose?
nu:legal Deutsches Recht exposes 9 tools: resolveIdentifiers, search, getNorm, listNormVersions, listCitingDecisions, and 4 more. Their descriptions and schemas cost roughly 3,209 tokens of context every time the server is loaded.
Does the nu:legal Deutsches Recht MCP server require authentication?
No. We connected to nu:legal Deutsches Recht without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.
Is the nu:legal Deutsches Recht MCP server still maintained?
nu:legal Deutsches Recht is still listed as active in the MCP registry. We last reached this channel on 27 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.