OLDP MCP Server
The Open Legal Data Platform exposes a Model Context Protocol (MCP) server, enabling AI agents (Claude, Cursor, etc.) to search, retrieve, and navigate German legal data including court decisions and legislation with cross-references.
Quick Start
Claude Desktop / Claude Code
Add to your claude_desktop_config.json:
{
"mcpServers": {
"oldp": {
"url": "https://de.openlegaldata.io/mcp"
}
}
}
Claude.ai (Custom Connector)
Go to Settings → Connectors → Add Custom Connector
Enter URL:
https://de.openlegaldata.io/mcpClick Add — works immediately without login
Claude Code CLI
claude mcp add --transport http oldp https://de.openlegaldata.io/mcp
Authentication
The MCP server supports two modes:
Mode |
How it works |
Rate limit |
|---|---|---|
Anonymous |
No login required |
500 requests/hour (shared for Anthropic IPs) |
Authenticated |
OAuth 2.0 login with OLDP account |
1,000 requests/hour (per user) |
OAuth Flow
The server implements OAuth 2.0 with PKCE and Dynamic Client Registration (RFC 7591). Discovery endpoints:
/.well-known/oauth-protected-resource— Resource metadata/.well-known/oauth-authorization-server— Authorization server metadata/oauth/register/— Dynamic Client Registration/oauth/authorize/— Authorization endpoint/oauth/token/— Token endpoint
Available Tools
Discovery
Tool |
Description |
|---|---|
|
Platform coverage summary: total cases, laws, courts, date ranges |
|
Browse/filter courts by type, state, jurisdiction, level of appeal |
|
List available law books (BGB, StGB, GG, etc.) with section counts |
Search
Tool |
Description |
|---|---|
|
Full-text search via Elasticsearch. Returns snippets, not full text. Accepts citation-graph filters ( |
|
Full-text search across law sections. Returns snippets only |
|
Structured ORM filtering by court, date, file number, ECLI, etc. |
See Search for the full filter matrix and combined-search examples across all three surfaces.
Retrieval
Tool |
Description |
|---|---|
|
Full case by ID/slug. Truncated at 30k chars; use |
|
Law text by book code + section (e.g. “BGB” + “823”) |
|
Detailed court info: name, address, contact, case count |
Cross-References
Tool |
Description |
Backend |
|---|---|---|
|
Check if Aktenzeichen, ECLI, or § reference exists in the database |
SQL |
|
Forward refs: which laws and cases does a decision cite? |
SQL |
|
Reverse refs: which cases cite a given decision? |
Elasticsearch |
|
All cases interpreting a specific statute section |
Elasticsearch |
The same data is queryable via the
REST API’s citation surfaces:
nested actions like /api/cases/<id>/references/ for case-by-case
lookups, plus a flat /api/references/ resource with slug-based
filters (cited_by_law__book__slug=bgb&cited_by_law__slug=823) for
cross-cutting graph queries the MCP tools can’t express. The REST
nested actions and the MCP tools share a single service layer and
the same backends — references / forward-refs paths via the ORM,
citing_cases paths via Elasticsearch — so payload shapes match.
When Elasticsearch is unavailable, get_citing_cases and
get_cases_for_law return a structured error envelope rather than
silently degrading:
// Transient timeout — same query is sub-100ms after segments are
// paged in. Agent should wait + retry.
{"error": "Search timed out…", "retryable": true, "hint": "…"}
// Hard outage — retrying immediately won't help.
{"error": "Citation graph is temporarily unavailable. Try again in a few minutes.", "retryable": false}
Agents should branch on retryable rather than parsing the message.
See docs/elasticsearch.md
for the underlying CaseIndex.cited_laws / CaseIndex.cited_cases
fields.
Statistics
Tool |
Description |
|---|---|
|
Aggregated counts by court, year, jurisdiction |
Usage Examples
Legal Research
“Find BGH decisions from 2023 about § 823 BGB”
search_cases(query="§ 823 BGB", court_code="BGH", start_date="2023-01-01", end_date="2023-12-31")get_case(case_id=12345)for full textget_case_references(case_id=12345)for cited laws/cases
Citation Verification
“Is ‘VI ZR 123/22’ a valid BGH file number?”
validate_citation(citation="VI ZR 123/22")
Legislative Impact Analysis
“How is § 1004 BGB interpreted in case law?”
get_cases_for_law(book_code="BGB", section="1004")get_case(case_id=...)for relevant decisions
Design Principles
Verbatim text only: No AI-generated summaries. The agent summarizes; we provide the source.
Search → Retrieve pattern: Search returns snippets;
get_case/get_law_sectionreturns full text.Citation validation: Built-in hallucination guard for legal citations.
Content truncation: Cases truncated at 30k chars by default to protect context windows.
Disclaimer
This data is provided for informational purposes only and is not a substitute for professional legal advice. References are automatically extracted and may be incomplete. Verify critical citations against the full text.
Technical Details
Transport: Streamable HTTP at
/mcpPackage:
django-mcp-serverv0.5.7OAuth:
django-oauth-toolkitv3.xSearch: Elasticsearch 7.17 via django-haystack