nu:legal Deutsches Recht
Server Details
German federal and Land statutes plus court decisions for agents. Keyless, read-only.
- Status
- Healthy
- Uptime
- 100.0% over 42 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- nulegal-startup/recht-mcp
- GitHub Stars
- 1
- Server Listing
- recht-mcp
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 9 tools
Each tool has a distinct role: search for discovery, resolveIdentifiers for exact citation lookup, getNorm/listNormVersions for provision text and history, and case/citation tools for reading decisions and graphs. The potentially confusable pair listCitedAuthorities vs listCitingDecisions is clearly separated as outgoing vs incoming citations by their descriptions.
All names use lowerCamelCase and clear domain nouns, which is predictable. The main minor inconsistency is the mix of verb families: get*, list*, resolve*, and search, rather than one uniform verb_noun convention.
Nine tools is well-scoped for a legal research server, with no excessive surface and no single trivial tool. Each tool earns its place by covering a distinct part of the research workflow.
The read-only legal-research surface is strong: search, exact citation resolution, provision text and versions, decision passages, incoming/outgoing citations, changes, and coverage. Minor gaps include no explicit browse/list-all-provisions tool for a given law, though search and getNorm provide workarounds.
Available Tools
9 toolsgetChangesChange FeedARead-onlyIdempotentInspect
What changed here, as JSON. Two ways to read it.
The cursor feed (send kinds, or cursor): everything that changed, oldest first, readable to the end without gaps: decisions added or changed, provisions with a new text (new Fassung, new provision, new law), and new citation links (decision X now cites Y, or decision Y gained a citer). Start with kinds (and since, default 7 days ago), then pass next_cursor back unchanged, with the same filters, until has_more is false; keep the cursor and poll with it later.
Without those arguments: the provisions that got a new text recently, newest first. Poll it with since set to the newest observed you have processed.
observed / observed_at is when the change reached this service, not when a court decided or a law came into force. Say so if you report a date. The window is the last 120 days; a provision's own history is listNormVersions.
| Name | Required | Description | Default |
|---|---|---|---|
| law | No | Cursor feed: a law abbreviation (BGB). Leaves out links between decisions. | |
| land | No | Cursor feed: a Land code (BY, NW, SN, BB, ...) or BUND. | |
| court | No | Cursor feed: a court, as the court segment of a decision URL (bgh). | |
| kinds | No | Cursor feed: which kinds (decision, law, citation). | |
| limit | No | Default 50 (date list) or 100 (cursor feed). | |
| since | No | Only changes observed on or after this date (cursor feed: at most 120 days back, default 7). | |
| cursor | No | Cursor feed: `next_cursor` of the previous call, unchanged. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description adds material behavior not in them: a 120-day window, the crucial caveat that `observed` is ingestion time rather than decision or enactment date (with an instruction to say so when reporting), and the requirement to keep filters stable across cursor pages. That is exactly the kind of operational context an agent cannot get from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The two-mode structure is front-loaded ('Two ways to read it') and each paragraph maps to one mode, so scanning is easy. It is nonetheless dense prose that could be tightened, e.g. the reporting caveat sentence, though that content is genuinely useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, no-required-argument tool with no output schema, the description covers the return shape (JSON with `next_cursor`, `has_more`, `observed`), pagination lifetime, poll strategy, and the 120-day horizon. An agent can call it correctly and reuse cursors without further information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each parameter; the description goes further by explaining the mode-selection semantics of `kinds` and `cursor`, the 7-day default for `since`, and the identity between `next_cursor` in the response and the `cursor` input. Minor room left: it does not explain how `law`/`land`/`court` interact or whether they apply to the date-list mode.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (a change feed of decisions, provision texts, and citation links) and enumerates the exact change types returned, including concrete examples like 'new Fassung, new provision, new law' and 'decision X now cites Y'. It also distinguishes the tool's scope from listNormVersions for a single provision's history, so an agent can identify it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit decision rule: if you send `kinds` or `cursor`, you get the full cursor feed; without those arguments you get the recent-newest-first provision list. It further prescribes the calling sequence (start with `kinds` and `since`, pass `next_cursor` back unchanged with the same filters until `has_more` is false) and names listNormVersions as the alternative for per-provision history.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCoverageCorpus coverageARead-onlyIdempotentInspect
What the corpus holds and what it does not: laws, decisions, courts, the version archive and the Länder covered. Call it before you report that something does not exist. The answer's coverage block is /v1/coverage: statutes per Land (statutes: full_text, partial or none), decisions per court level, the citation graph and what every version date is, all from one daily table. Example: {}
| Name | Required | Description | Default |
|---|---|---|---|
| court | No | Adds `courts` with only the courts whose name, slug or ECLI code contains this ('köln', 'BVerwG'). | |
| include | No | `["courts"]` adds `courts`: the court registry (slug, names, branch, level, Land, ECLI court code, decision count), at most 25 rows, busiest first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and non-destructive, so the description is not carrying the safety burden. It adds genuine behavioral context beyond that: the payload is the /v1/coverage block, statutes carry full_text/partial/none status, versions are date-keyed, and everything comes from one daily-refreshed table (a freshness signal not encoded anywhere else).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences plus a call example, front-loaded with the purpose and then the usage rule. Slightly dense in the third sentence ("all from one daily table" is compressed), but no filler or restatement of the name/title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must convey the return shape — it does, naming the `coverage` block and its sub-sections (statutes per Land with status, decisions per court level, citation graph, version dates). Remaining gaps are minor: response size and whether output is paginated or aggregated are unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the schema already explains `court` matching and what `include: ["courts"]` adds (max 25 rows, busiest first). The description earns a point above baseline by supplying "Example: {}", which signals that the zero-argument call is valid and is the default way to get the full coverage picture.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States precisely what the tool reports: which laws, decisions, courts, version archive and Länder the corpus holds, and explicitly what it does not hold. That negative-space framing distinguishes it cleanly from search (which returns hits) and getNorm/getChanges (which return documents).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete prescriptive trigger: "Call it before you report that something does not exist." That is a clear when-to-use rule tied to a specific agent failure mode. No explicit when-not condition or named sibling alternative, so it stops short of the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getNormGet statute textARead-onlyIdempotentInspect
The text of one provision (§ or Article) as Markdown. law is the abbreviation ('BGB', 'StGB', 'DSGVO'; Hessen: 'HBO'), ref the number ('573', '3a'). For the text on a past date add as_of (YYYY-MM-DD; versions are held from 2019-06-10; for EU acts, the EMRK and some Landesrecht from the day their held text applies). The answer says how many versions are held (versions_held) and how many decisions cite the provision (cited_by). A version date is not always its Inkrafttreten: date_basis says what it is. For most federal law it is the day the text was first seen here; for an EU act it is the day its text applies (applies_from). With compare_to (YYYY-MM-DD) the answer adds diff, the word diff to the version stored for that date. DATES: each version carries date_basis, in_force_from (a date the source states) and observed_from (first seen here), each with its *_basis; the one we do not hold is null. Example: {"law": "BGB", "ref": "573"}
| Name | Required | Description | Default |
|---|---|---|---|
| law | Yes | Law abbreviation, or a `law_key` (`slug` in search results) when an abbreviation is ambiguous. | |
| ref | Yes | Provision number without § or Art. A sub-unit ('Abs. 1', 'lit. f') is dropped: the whole provision is returned. | |
| as_of | No | Return the version stored for this date. | |
| format | No | 'markdown' (default, compact, quotable) or 'json' for the structured payload. | markdown |
| compare_to | No | Compare with the version stored for this date: the answer adds `diff`, the word diff between the two versions (the older one is `from`), each side with its `date_basis`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already declaring read-only, idempotent, non-destructive behavior, the description goes well beyond them: it explains that the answer includes `versions_held` and `cited_by`, that `date_basis` may differ from Inkrafttreten, and that `diff` is a word diff with the older side as `from`. This is unusually rich behavioral context for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and argument shapes, and the optional-parameter semantics follow in a logical order. It is dense but mostly earns its length, though the standalone 'DATES:' sentence partially repeats the `date_basis` explanation given earlier.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must carry return-value semantics — and it does, naming `versions_held`, `cited_by`, `diff`, and the date basis fields plus null handling. For a 5-parameter, enum-bearing lookup tool this is complete enough to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description's parameter prose (law = abbreviation, ref = number, compare_to adds `diff`) largely restates what the schema already documents; it adds only marginal format detail (e.g. 'Hessen: HBO') beyond structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+format: 'The text of one provision (§ or Article) as Markdown', and clarifies the shape of both required arguments. It does not name any sibling (e.g. listNormVersions or getChanges) to differentiate itself, so an agent must infer the boundary from the sibling list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear conditional guidance for the optional parameters: use `as_of` for text on a past date, `compare_to` to get a word diff, and notes coverage limits (versions held from 2019-06-10). It stops short of explicitly excluding/redirecting to alternatives like listNormVersions when only version metadata is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listCasePassagesList case passagesARead-onlyIdempotentInspect
Read a decision: its paragraphs, each with the court's Randnummer (rn) and a link. case takes an ECLI, our decision URL or an Aktenzeichen. Jump to a Randnummer with around, page with offset and limit. The first page also says how often the decision is cited and by whom. The answer carries card: typed headnotes (Leitsatz apart from Orientierungssatz), the tenor where the source marks it, cited_norms, fundstellen, cite_as; never generated text. Example: {"case": "bgh/2017-03-29/viii-zr-45-16", "around": 15, "limit": 5}
| Name | Required | Description | Default |
|---|---|---|---|
| case | Yes | A stored decision id, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a decision is named; a key that names two decisions answers `ambiguous` with `candidates`. | |
| lang | No | Language of the decision text: 'de' or 'en'. Default: German when it exists, else English. | |
| limit | No | ||
| around | No | A Randnummer as the court printed it. Returns a window of `limit` passages centred on it. Not combinable with `offset`. | |
| offset | No | ||
| include | No | `["proceeding"]` adds `proceeding`: the Verfahrensgang (earlier and later decisions of the same proceeding) as the courts' records state it. No outcome is stated. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, and the description adds genuinely new context: passages are verbatim and 'never generated text', the first page carries citation counts with citers, and Leitsatz is kept apart from Orientierungssatz. It does not cover error or edge behavior beyond what the schema already says about ambiguous keys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, and the dense backtick-heavy sentences each convey a distinct fact (input forms, navigation, first-page citations, card contents). Slightly compressed phrasing around `card` costs a little readability but nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does real work by naming the response fields (`rn`, link, citation info, typed `card` members) and giving a worked example call. It stops short of describing pagination totals or the overall response envelope, which an agent would still have to discover at runtime.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
At 67% schema coverage the schema carries most of the load, but the description adds workflow semantics — `around` as a jump-to-Randnummer window, `limit` as page size — plus a concrete combined example that shows how the parameters compose. `lang` and `include` are left entirely to the schema, so it is not fully compensating.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Read a decision: its paragraphs, each with the court's Randnummer and a link' — which is unmistakably distinct from siblings like search or listCitingDecisions. The opening clause alone tells an agent what it gets back.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the navigation modes (jump with `around`, page with `offset`/`limit`) and notes that `case` accepts an ECLI, URL, or Aktenzeichen as `search` returns it, which implies the typical search-then-read flow. It never explicitly names an alternative tool or states when not to use this one, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listCitedAuthoritiesList cited authoritiesARead-onlyIdempotentInspect
What one decision cites: the provisions (with how often) and the decisions it relies on. Example: {"case": "bgh/2017-03-29/viii-zr-45-16"}
| Name | Required | Description | Default |
|---|---|---|---|
| case | Yes | A stored decision id, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a decision is named; a key that names two decisions answers `ambiguous` with `candidates`. | |
| lang | No | Language of the decision text: 'de' or 'en'. Default: German when it exists, else English. | |
| offset | No | Skip this many cited decisions (pages of 50). Follow `pagination.next_offset`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the description carries a lighter burden. It adds genuine content beyond that by disclosing the shape of the return payload: provisions with citation frequency plus the relied-upon decisions. Remaining gaps like pagination are handled by the schema's offset description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences: the purpose is front-loaded and the example immediately follows as concrete grounding. No filler, no redundant restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must convey what comes back, and it does state the two result categories (provisions with counts, cited decisions). Fully complete treatment would also mention result ordering or pagination at a behavioral level, though the offset parameter's schema description largely covers paging.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the case identifier formats, the language default, and the offset/paging semantics thoroughly. The description repeats the case example already present in the schema and adds no new parameter meaning, which is the baseline expectation when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb-like operation and resource: 'What one decision cites: the provisions (with how often) and the decisions it relies on.' This clearly conveys the direction of the citation traversal. It does not, however, explicitly name the sibling listCitingDecisions as the inverse operation, so the agent must infer the distinction from the wording alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the phrase 'What one decision cites' signals that this tool answers an outgoing-citations question, which implicitly contrasts with listCitingDecisions. There is no explicit 'use this when…' statement, no exclusion, and no mention of alternatives for reverse lookups.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listCitingDecisionsList citing decisionsARead-onlyIdempotentInspect
Who cites this: the decisions citing a provision (law + ref) or a decision (case). Ranked by weight; sort: "recent" gives the newest first. Each citer links to the Randnummer where it cites. The graph is built over every decision held, federal, Land and EU courts alike, and links federal, EU and Land provisions; it does not link Hessen provisions, which answer total: 0 with coverage.complete_for_this_norm: false: then fall back to search on the provision's wording. coverage carries the counts for the provision's jurisdiction. Example: {"law": "BGB", "ref": "573", "sort": "recent", "limit": 5} or {"case": "bgh/2017-03-29/viii-zr-45-16"}
| Name | Required | Description | Default |
|---|---|---|---|
| law | No | ||
| ref | No | ||
| case | No | A stored decision id, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a decision is named; a key that names two decisions answers `ambiguous` with `candidates`. | |
| sort | No | '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`. | weight |
| limit | No | ||
| offset | No | Rows to skip, for reading past the first page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only/idempotent annotations, the description discloses important behavioral traits: default ranking by weight, `sort: "recent"` behavior, per-citer Randnummer links, and the graph's coverage across federal, Land, and EU courts. It also explicitly warns about the Hessen-provision coverage gap and the fallback behavior, which is exactly the kind of non-obvious limitation an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the tool's purpose and input modes, then moves through ranking, coverage caveats, and examples without filler. Despite covering multiple behaviors, it remains compact and every sentence carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only graph-listing tool with no output schema, the description is complete enough: it explains the two input modes, default sorting, per-citer linkage, coverage limitations, and the special `total: 0`/`coverage.complete_for_this_norm` outcome. The `case` parameter's ambiguity behavior is also covered in the schema, leaving no major unexplained behavior needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 50% schema description coverage, the description adds meaningful semantics by pairing `law` + `ref` for provisions, explaining `case` for decisions, and clarifying `sort: "recent"`. It also supplies concrete usage examples including `limit`. The main gap is that `limit` and `offset` are not further explained in the description, though `offset` is covered in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource and direction: 'the decisions citing a provision (`law` + `ref`) or a decision (`case`)'. The phrase 'Who cites this' clearly distinguishes this tool from the inverse sibling listCitedAuthorities, which covers cited authorities rather than citing decisions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage conditions for both accepted input modes: provision via `law` + `ref`, or decision via `case`. It also gives a specific fallback to `search` when Hessen provisions are not linked and return `total: 0` with `coverage.complete_for_this_norm: false`. It does not explicitly route the agent to listCitedAuthorities for the reverse relationship, so it falls short of full when/when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listNormVersionsList statute versionsARead-onlyIdempotentInspect
Every stored version of one provision with its dates, newest first. Use it to see when a provision changed, then read a version with getNorm as_of. at_archive_floor marks a text that was already in force when the archive began. To compare two versions, call getNorm(compare_to=…): the answer's diff is the word diff, and each side says what its date is (date_basis: in_force, eurlex_consolidation, source_stated, observed or archive_floor), so a floor date stays visible. DATES: each version carries date_basis, in_force_from (a date the source states) and observed_from (first seen here), each with its *_basis; the one we do not hold is null. Example: {"law": "BGB", "ref": "288"}
| Name | Required | Description | Default |
|---|---|---|---|
| law | Yes | ||
| ref | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnly/idempotent safety; the description adds the ordering guarantee, the `at_archive_floor` marker semantics, the rule that the unheld date is null, and the full `date_basis` vocabulary. That is substantive behavior an agent cannot get from the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the sibling routing are front-loaded, and the DATES block is genuinely informational. It loses a point for redundancy — the `date_basis` value list appears twice, once inline and once in the closing parenthetical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on the return-value burden and largely discharges it by naming the version fields and their basis semantics. Only the input-side detail (what exactly `ref` accepts) is left thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry both parameters, and it only does so implicitly through the example {"law": "BGB", "ref": "288"}. That implies statute code plus provision number, but format edge cases (ranges, abbreviations vs full names) are never stated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — every stored version of one provision — plus ordering (newest first), which immediately separates it from getNorm (single version) and getChanges. An agent can tell what it returns without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes usage: use this to see when a provision changed, then read a version with getNorm `as_of`, and use `getNorm(compare_to=…)` to diff two versions. When-to-use and concrete alternatives are both named with their selecting conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolveIdentifiersResolve legal citationsARead-onlyIdempotentInspect
Look up German legal citations, up to 100 at once: a § or Article, an Aktenzeichen, an ECLI or a Fundstelle. Use it to find a decision by its docket and to check a citation before you state it. Pass each citation as you hold it, with court and date: they pick the right decision where a docket repeats. It never guesses. A miss is not_in_corpus; attested / known_missing means the decision exists but its text is not held; date_mismatch / court_mismatch mean your citation is wrong there. A found decision carries cited_by: how many decisions cite it, and the top citers with a link to the Randnummer where they do. Example: {"citations": ["BGH, Urteil vom 29.03.2017 - VIII ZR 45/16", "§ 573 Abs. 2 BGB"]}
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | 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. 'leitsatz' returns a decision's whole Leitsatz instead of its preview. An unknown value is refused, not ignored. | |
| citations | Yes | The citations, verbatim as you hold them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent safety, and the description goes well beyond them: it discloses that the tool never guesses, defines each outcome status (not_in_corpus, attested, known_missing, date_mismatch, court_mismatch) and explains the cited_by payload. This is exactly the behavioral context an agent needs before trusting a result.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and scope, then status semantics, then an example; nearly every sentence carries operational meaning. It is dense and status-heavy but well ordered, with little waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description explains return outcomes and the cited_by structure, and covers the disambiguation rule for docket collisions. An agent can call it and interpret results correctly without further information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3, but the description adds real meaning beyond the schema: pass citations verbatim with court and date because those fields disambiguate repeated dockets. The worked example reinforces the exact input shape.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('look up German legal citations') plus the accepted citation forms (§/Article, Aktenzeichen, ECLI, Fundstelle) and batch limit. This is clearly distinguishable from siblings like search or getNorm, which retrieve documents rather than validate citations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use: 'find a decision by its docket' and 'check a citation before you state it'. It does not name sibling tools as alternatives (e.g. search, getNorm), so routing is implied rather than fully bounded.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearch German lawARead-onlyIdempotentInspect
Find statutes and decisions on a topic or a question, in one call. Use it when you hold no citation yet. German keywords or a full question both work; decisions are matched by meaning. A decision hit carries url (pass it as case to the decision tools), ecli and cited_by; a statute hit carries slug and ref_norm (pass them as law and ref to getNorm). Full text is held for Bayern, Brandenburg, Hessen, Nordrhein-Westfalen and Sachsen (see getCoverage). Hessen rows (jurisdiction 'HE'): pass law_key as law and ref_norm as ref to getNorm. Decisions can be filtered by court, court_level, state, panel, from/to and decision_type, and sorted with sort (relevance, weight: most cited first, newest); the answer counts them in cases_total. Example: {"q": "Eigenbedarf Kündigung Härtefall"}
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | German query. Keywords, a citation, or a full question. | |
| to | No | ||
| from | No | ||
| sort | No | relevance | |
| court | No | One court, by its slug: bgh, bverwg, olg-koeln, ovg-sachsen. | |
| limit | No | ||
| panel | No | A Senat of `court`: 'VIII. Zivilsenat', '2. Strafsenat' (BGH), '7. Senat' (BAG, BFH, BSG, BVerwG, BVerfG). | |
| scope | No | 'all' (default) searches both. Narrow only when you know which corpus answers. | all |
| state | No | A Land code (BY) or name slug (bayern), or bund / eu. | |
| court_level | No | ||
| decision_type | No | ||
| include_repealed | No | Include repealed (aufgehobene) provisions. Off by default; turn it on when researching an older state of the law. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description goes further by disclosing result shapes (url/ecli/cited_by for decisions, slug/ref_norm for statutes) and the handoff protocol into getNorm and the decision tools. It also flags a genuine quirk (Hessen rows need law_key/ref_norm) and corpus coverage limits via getCoverage. It stops short of describing result volume, ranking behavior beyond the sort enum, or empty-result behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the citation-absence rule, then chained output/interop details, then filters, then an example — a sensible order. It is dense and parenthetical-heavy (semicolon-joined clauses about Hessen and field names), but almost every clause carries operational information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter discovery tool with no output schema, it covers the essentials: what comes back, how to route those fields into downstream tools, which corpora are covered, and how to constrain results. Remaining gaps (pagination behavior past limit, cases_total semantics, what happens on zero hits) are minor but real for a tool this broad.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
At 50% schema coverage the description does real work: it explains that q accepts German keywords or a full question and that decisions are matched semantically, enumerates which filters apply to decisions (court, court_level, state, panel, from/to, decision_type), and glosses the sort values as "relevance, weight: most cited first, newest." It adds little for limit (default 10, max 50, undescribed in both places) and leaves `sort`'s "weight" only partially defined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource plus the scope of the corpus: "Find statutes and decisions on a topic or a question, in one call." It also pre-empts confusion with the citation-driven siblings by stating "Use it when you hold no citation yet," so the agent can classify it against resolveIdentifiers/getNorm without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States a clear entry condition ("when you hold no citation yet") and repeats narrowing policy in the schema text ("Narrow only when you know which corpus answers"). What it never does is name the alternative tool to use when a citation IS held, leaving the agent to infer resolveIdentifiers as the counterpart.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
- Changed
listCasePassages2 fields changed- changed
Input schema / properties / case / descriptionPrevious value: -"A juris doknr, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a doknr is; a key that names two decisions answers `ambiguous` with `candidates`."New value: +"A stored decision id, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a decision is named; a key that names two decisions answers `ambiguous` with `candidates`." - changed
Input schema / properties / case / examplesPrevious value: -[ - "KORE313182017", - "ECLI:DE:BGH:2017:290317UVIIIZR45.16.0" -]New value: +[ + "bgh/2017-03-29/viii-zr-45-16", + "ECLI:DE:BGH:2017:290317UVIIIZR45.16.0" +]
- Changed
listCitedAuthorities2 fields changed- changed
Input schema / properties / case / descriptionPrevious value: -"A juris doknr, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a doknr is; a key that names two decisions answers `ambiguous` with `candidates`."New value: +"A stored decision id, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a decision is named; a key that names two decisions answers `ambiguous` with `candidates`." - changed
Input schema / properties / case / examplesPrevious value: -[ - "KORE313182017" -]New value: +[ + "bgh/2017-03-29/viii-zr-45-16" +]
- Changed
listCitingDecisions1 field changed- changed
Input schema / properties / case / descriptionPrevious value: -"A juris doknr, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a doknr is; a key that names two decisions answers `ambiguous` with `candidates`."New value: +"A stored decision id, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a decision is named; a key that names two decisions answers `ambiguous` with `candidates`."
3 tool updates
- Changed
listCasePassages1 field changed- changed
Input schema / properties / case / descriptionPrevious value: -"A juris doknr, an ECLI, or this site's decision URL as `search` returns it."New value: +"A juris doknr, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a doknr is; a key that names two decisions answers `ambiguous` with `candidates`."
- Changed
listCitedAuthorities1 field changed- changed
Input schema / properties / case / descriptionPrevious value: -"A juris doknr, an ECLI, or this site's decision URL as `search` returns it."New value: +"A juris doknr, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a doknr is; a key that names two decisions answers `ambiguous` with `candidates`."
- Changed
listCitingDecisions1 field changed- changed
Input schema / properties / case / descriptionPrevious value: -"A juris doknr, an ECLI, or this site's decision URL as `search` returns it."New value: +"A juris doknr, an ECLI, or this site's decision URL as `search` returns it. The canonical decision key `{court}/{date}/{slug}` (e.g. `bgh/2024-07-10/viii-zr-276-23`) is accepted wherever a doknr is; a key that names two decisions answers `ambiguous` with `candidates`."
1 tool update
- Changed
search8 fields changed- added
Input schema / properties / courtAdded value: +{ + "description": "One court, by its slug: bgh, bverwg, olg-koeln, ovg-sachsen.", + "type": "string" +} - added
Input schema / properties / court_levelAdded value: +{ + "enum": [ + "federal", + "higher", + "regional", + "lower", + "state_constitutional", + "european", + "other" + ], + "type": "string" +} - added
Input schema / properties / decision_typeAdded value: +{ + "enum": [ + "urteil", + "beschluss", + "gerichtsbescheid", + "schlussantraege" + ], + "type": "string" +} - added
Input schema / properties / fromAdded value: +{ + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" +} - added
Input schema / properties / panelAdded value: +{ + "description": "A Senat of `court`: 'VIII. Zivilsenat', '2. Strafsenat' (BGH), '7. Senat' (BAG, BFH, BSG, BVerwG, BVerfG).", + "type": "string" +} - added
Input schema / properties / sortAdded value: +{ + "default": "relevance", + "enum": [ + "relevance", + "weight", + "newest" + ], + "type": "string" +} - added
Input schema / properties / stateAdded value: +{ + "description": "A Land code (BY) or name slug (bayern), or bund / eu.", + "type": "string" +} - added
Input schema / properties / toAdded value: +{ + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" +}
3 tool updates
- Changed
getCoverage2 fields changed- added
Input schema / properties / courtAdded value: +{ + "description": "Adds `courts` with only the courts whose name, slug or ECLI code contains this ('köln', 'BVerwG').", + "type": "string" +} - added
Input schema / properties / includeAdded value: +{ + "description": "`[\"courts\"]` adds `courts`: the court registry (slug, names, branch, level, Land, ECLI court code, decision count), at most 25 rows, busiest first.", + "items": { + "enum": [ + "courts" + ], + "type": "string" + }, + "type": "array" +}
- Changed
getNorm1 field changed- added
Input schema / properties / compare_toAdded value: +{ + "description": "Compare with the version stored for this date: the answer adds `diff`, the word diff between the two versions (the older one is `from`), each side with its `date_basis`.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" +}
- Changed
listCasePassages1 field changed- added
Input schema / properties / includeAdded value: +{ + "description": "`[\"proceeding\"]` adds `proceeding`: the Verfahrensgang (earlier and later decisions of the same proceeding) as the courts' records state it. No outcome is stated.", + "items": { + "enum": [ + "proceeding" + ], + "type": "string" + }, + "type": "array" +}
4 tool updates
- Changed
getChanges8 fields changed- added
Input schema / properties / courtAdded value: +{ + "description": "Cursor feed: a court, as the court segment of a decision URL (bgh).", + "maxLength": 200, + "type": "string" +} - added
Input schema / properties / cursorAdded value: +{ + "description": "Cursor feed: `next_cursor` of the previous call, unchanged.", + "maxLength": 1000, + "type": "string" +} - added
Input schema / properties / kindsAdded value: +{ + "description": "Cursor feed: which kinds (decision, law, citation).", + "items": { + "enum": [ + "decision", + "law", + "citation" + ] + }, + "type": "array" +} - added
Input schema / properties / landAdded value: +{ + "description": "Cursor feed: a Land code (BY, NW, SN, BB, ...) or BUND.", + "maxLength": 8, + "type": "string" +} - added
Input schema / properties / lawAdded value: +{ + "description": "Cursor feed: a law abbreviation (BGB). Leaves out links between decisions.", + "maxLength": 200, + "type": "string" +} - removed
Input schema / properties / limit / defaultRemoved value: -50 - added
Input schema / properties / limit / descriptionAdded value: +"Default 50 (date list) or 100 (cursor feed)." - changed
Input schema / properties / since / descriptionPrevious value: -"Only changes observed on or after this date."New value: +"Only changes observed on or after this date (cursor feed: at most 120 days back, default 7)."
- Changed
getNorm1 field changed- added
Input schema / properties / as_of / examplesAdded value: +[ + "2021-01-01" +]
- Changed
listCasePassages1 field changed- added
Input schema / properties / case / examplesAdded value: +[ + "KORE313182017", + "ECLI:DE:BGH:2017:290317UVIIIZR45.16.0" +]
- Changed
listCitedAuthorities1 field changed- added
Input schema / properties / case / examplesAdded value: +[ + "KORE313182017" +]
Related MCP Connectors
Lawyers in Germany from the official Bundesrechtsanwaltskammer register. Keyless, read-only.
German court decisions and statutes with citation checks. OAuth 2.1 or Bearer token.
German law via Ansvar Gateway. Cited, OAuth + paid tier.
Verified, citable German & EU law for any LLM. Daily updates from official sources, hosted in DE.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides read-only access to current German federal law, supporting legislation search, provision retrieval, and citation handling.Apache 2.0
- AlicenseNot gradedqualityAmaintenanceCite-grade German legal-text infrastructure for LLM agents, providing access to federal, Länder, and EU laws with cryptographic provenance.2Apache 2.0
- AlicenseAqualityBmaintenanceEnables AI agents to retrieve the verbatim text of German federal and state statutes, search official case law from BGH, BAG and BVerfG, and compute procedurally exact deadlines under §§ 187–193 BGB with weekend and public-holiday adjustment. It also supplies structured statutory-element blueprints with burden-of-proof allocation and assembles citation-secured research dossiers for pleadings.6MIT
- AlicenseNot gradedqualityFmaintenanceEnables querying over 6,800 German federal statutes, case law, and legislative preparatory works with verbatim source text. Integrates EU law cross-references and provides citation validation and legal stance building.160 npm23Apache 2.0
Glama MCP Gateway
Add one secure layer between your agents and this server.