Rechtspraak MCP Server
# Rechtspraak MCP Server
MCP (Model Context Protocol) server for searching and analyzing Dutch case law from [rechtspraak.nl](https://rechtspraak.nl). Provides advanced search capabilities with query expansion, legal synonyms, faceting, and citation analysis.
## Table of Contents
- [Features](#features)
- [Architecture](#architecture)
- [Installation](#installation)
- [Usage](#usage)
- [Interactive CLI](#interactive-cli)
- [MCP Server](#mcp-server)
- [Direct Entry Points](#direct-entry-points)
- [Development](#development)
- [Example Queries](#example-queries)
- [License](#license)
- [Contributing](#contributing)
## Features
### š MCP Server
- **Advanced Search**: Full-text search with query expansion and Dutch legal synonyms
- **Faceted Search**: Filter by court, legal area, date range, and procedure type
- **Citation Analysis**: Extract and analyze case citations (incoming and outgoing)
- **Similar Cases**: Find similar cases using MoreLikeThis algorithm
- **Legal Article Search**: Search cases by specific legal articles
- **Trend Analysis**: Analyze temporal trends in case law
- **Query Expansion**: Automatic expansion with legal terms and synonyms
- **Rate Limiting & Caching**: Built-in governance layer for production use
### š„ Data Import
- Fetch case law XML from rechtspraak.nl feeds
- Extract links and download case files
- Automated batch processing
### š Indexing
- Parse XML documents with structured sections
- Enrich with metadata (court types, legal domains, procedures)
- Full-text indexing in Solr
- Schema management and validation
## Architecture
```
src/
āāā mcp/ # MCP server (main feature)
ā āāā mcp_server.py # MCP server implementation
ā āāā mcp_schemas.py # Pydantic schemas for all tools
ā āāā solr_adapter.py # Solr query adapter with advanced features
ā āāā governance.py # Rate limiting & caching
ā āāā legal_synonyms.py # Dutch legal synonyms expansion
ā āāā reference_data.py # Court/procedure reference data
ā
āāā importer/ # Data import from rechtspraak.nl
ā āāā extract_links.py
ā āāā fetch_link_files.py
ā āāā fetch_content.py
ā
āāā indexing/ # XML parsing and Solr indexing
ā āāā xml_parser.py
ā āāā solr_indexer.py
ā āāā solr_setup.py
ā āāā reindex_all.py
ā
āāā cli.py # CLI for indexing
āāā config.py # Configuration
```
## Installation
### Prerequisites
- Python 3.13+
- [uv](https://docs.astral.sh/uv/) (Python package manager)
- Docker & Docker Compose (for Solr)
### Setup
1. Clone the repository:
```bash
git clone <repository-url>
cd rechtspraak-solr
```
2. Start Solr with Docker:
```bash
docker-compose up -d solr
```
3. Install dependencies:
```bash
uv sync
```
4. Configure environment variables (create `.env` from `.env.example`):
```bash
cp .env.example .env
```
5. Setup Solr collection and schema:
```bash
uv run rechtspraak-setup
```
## Usage
### Interactive CLI
Run the interactive menu for all operations:
```bash
python main.py
```
Or use direct commands:
```bash
# Data pipeline
python main.py fetch-links 2023-01-01 2023-12-31
python main.py extract-links 2023-01-01 2023-12-31
python main.py fetch-content
# Indexing
python main.py reindex # Full reindex (delete + setup + index)
python main.py index # Index data only
python main.py fix-schema # Configure schema only
# MCP server
python main.py mcp # Start MCP server
python main.py test-mcp # Test connection
# Utilities
python main.py health # System health check
python main.py test-reference # Test reference data
```
### MCP Server
The MCP server supports two modes:
1. **Local Mode (stdio)**: For Claude Desktop/Code running on your machine
2. **HTTP Mode (SSE)**: For remote access via API
#### Local Mode - Configuration for Claude Desktop
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"rechtspraak": {
"command": "uv",
"args": [
"--directory",
"/path/to/rechtspraak-solr",
"run",
"rechtspraak-mcp"
],
"env": {
"SOLR_URL": "http://localhost:8983/solr",
"SOLR_COLLECTION": "rechtspraak"
}
}
}
}
```
#### Local Mode - Configuration for Claude Code
Add to your Claude Code config (`.claude/settings.local.json` in project):
```json
{
"mcp": {
"servers": {
"rechtspraak": {
"command": "uv",
"args": [
"--directory",
"/path/to/rechtspraak-solr",
"run",
"rechtspraak-mcp"
],
"env": {
"SOLR_URL": "http://localhost:8983/solr",
"SOLR_COLLECTION": "rechtspraak"
}
}
}
}
}
```
#### HTTP Mode - Remote Access
For production deployment with remote access:
1. **Start HTTP server**:
```bash
docker-compose up -d
```
2. **Configure nginx** (see `config/nginx.conf` for complete example):
```nginx
location /sse {
proxy_pass http://127.0.0.1:8000/sse;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
}
```
3. **Security**: Set `MCP_API_KEY` environment variable in your `.env` file
#### Connecting to Remote MCP Servers
Claude Desktop/Code only supports stdio transport natively, not SSE/HTTP. To connect to remote MCP servers, use the included `mcp-sse-client.js` bridge client:
**Add to Claude Desktop config** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"rechtspraak": {
"command": "node",
"args": [
"/path/to/rechtspraak-solr/mcp-sse-client.js"
],
"env": {
"BASE_URL": "https://rechtspraak-nl-mcp.knowably.ai",
"SSE_PATH": "/sse",
"API_KEY": "your-api-key-here"
}
}
}
}
```
**Optional environment variables for mcp-sse-client.js:**
- `CLIENT_NAME` - Custom client name (default: "mcp-sse-client")
- `VERBOSE` - Enable detailed logging (set to "true")
- `MAX_RETRIES` - Max connection attempts (default: 3)
- `RETRY_DELAY_MS` - Delay between retries in milliseconds (default: 2000)
- `CONNECTION_TIMEOUT_MS` - Connection timeout in milliseconds (default: 30000)
The bridge client acts as a local stdio process that Claude can communicate with, while internally translating requests to SSE/HTTP for the remote server. It includes automatic reconnection, configurable timeouts, and graceful error handling
#### Available MCP Tools
The server provides the following tools:
- `cases_search` - Search cases with filters and faceting
- `cases_get_by_ecli` - Get specific case by ECLI identifier
- `cases_expand_query` - Expand query with legal synonyms
- `cases_highlight_passages` - Extract relevant passages from a case
- `cases_rerank` - Rerank cases by relevance
- `cases_get_similar` - Find similar cases
- `cases_search_by_article` - Search by legal article
- `cases_validate_ecli` - Validate ECLI format
- `cases_bulk_get` - Batch retrieve multiple cases
- `cases_analyze_trend` - Analyze temporal trends
- `cases_get_statistics` - Get comprehensive statistics
- `cases_get_court_stats` - Compare courts
- `cases_get_citations` - Extract citations
- `cases_compare` - Compare multiple cases
- `cases_extract_entities` - Extract legal entities
- `system_health` - Check system health
### Direct Entry Points
You can also use the entry points directly:
```bash
# Full reindex
uv run rechtspraak-reindex
# Index specific directory
uv run rechtspraak-index --data-dir ./data
# Setup collection and schema
uv run rechtspraak-setup
# Start MCP server
uv run rechtspraak-mcp
```
## Development
### Project Structure
- **MCP Server**: Main feature providing search API via MCP protocol
- **Data Importer**: Tools to fetch case law from rechtspraak.nl
- **Indexing**: XML parsing and Solr indexing with enrichment
- **CLI**: Command-line tools for management tasks
### Testing
```bash
# Check MCP server
uv run rechtspraak-mcp
# Test indexing
uv run rechtspraak-index --data-dir ./test-data --verbose
```
## Example Queries
Once connected to an MCP client (Claude Desktop/Code), you can ask:
- "Search for cases about 'aansprakelijkheid' in the last 5 years"
- "Find cases citing ECLI:NL:HR:2019:1234"
- "What are the trends in 'arbeidsrecht' cases from 2015 to 2023?"
- "Find similar cases to ECLI:NL:RBDHA:2020:5678"
- "Search cases mentioning Article 6:162 BW"
- "Compare courts Hoge Raad and Rechtbank Amsterdam for tax cases"
## License
Do whatever you want
TDQS
Scored across 16 tools
Each tool targets a distinct function: search, retrieval, analysis, citations, entities, validation, and health checking. There is no ambiguity between tools; even similar-sounding ones like 'cases_get_statistics' and 'cases_get_court_stats' have clear differences.
All tools except the single health check follow a consistent 'cases_verb' pattern, using snake_case for verbs. This predictability aids agent selection and understanding.
With 16 tools covering search, retrieval, analysis, and validation, the count is well-scoped for a legal research server. No tool feels superfluous, and the set is neither too sparse nor bloated.
The tool surface covers core workflows: search, fetch, compare, analyze trends, extract citations/entities, and health check. Minor gaps exist, such as a dedicated tool to list available courts or legal areas, but these are indirectly supported via search filters.