Documentation

rechtspraak CLI

rechtspraak-pp-cli

Install

npx -y @mvanhorn/printing-press-library install rechtspraak

Installs the CLI binary and the agent skill for Claude Code, Codex, Cursor, Gemini CLI, Copilot, and more. Add --cli-only or --skill-only for one half. Requires Node.

Documentation

The first CLI for Dutch court decisions with rich local narrowing for long-tail legal keywords, an appeal-chain walker, and an MCP server.

Every Dutch ECLI from data.rechtspraak.nl, indexed locally so include/exclude/phrase/regex narrowing cuts a 1000-result topic down to a usable set — the upstream API has no free-text search, so this is the only place that workflow exists. Walks the cassation chain in one command, exports vindplaatsen as BibTeX, and exposes every command as an MCP tool — the first MCP server for Dutch case law.

Quick Start

# Pull the last week of decisions into the local SQLite cache.
rechtspraak-pp-cli sync --since 7d

# List recent Hoge Raad tax-law decisions — agent-shaped output.
rechtspraak-pp-cli uitspraken search --court HR --subject belastingrecht --agent

# Pull the inhoudsindicatie (summary) for a specific decision.
rechtspraak-pp-cli uitspraken get --id ECLI:NL:HR:2024:1 --summary-only --agent

# Walk the full appeal chain (rechtbank → hof → Hoge Raad plus A-G conclusie).
rechtspraak-pp-cli chain ECLI:NL:HR:2024:1 --agent

# Export the vindplaatsen as BibTeX for a brief's footnotes.
rechtspraak-pp-cli citations ECLI:NL:HR:2024:1 --format bibtex

# Run as an MCP server for Claude Desktop or any MCP-aware agent.
rechtspraak-pp-cli mcp serve

Unique Features

These capabilities aren't available in any other tool for this API.

Graph walks across decisions

  • chain — Walk the cassation, conclusie, and eerdere-aanleg graph for a Dutch court decision in both directions and print the full chain as a tree or JSON.

    Use this whenever an agent needs the full procedural history of a Dutch decision (cassation chain, A-G conclusie, lower-court rulings) in one call instead of clicking through rechtspraak.nl tabs by hand.

    rechtspraak-pp-cli chain ECLI:NL:HR:2024:1 --depth 5 --agent
    
  • citations — Extract the citation list (vindplaatsen) for a decision and emit as BibTeX, CSV, or JSON ready for legal-brief footnotes.

    Reach for this when an agent is drafting a Dutch legal brief and needs the citation list for a cited decision without parsing raw RDF/XML.

    rechtspraak-pp-cli citations ECLI:NL:HR:2024:1 --format bibtex
    
  • conclusie — Given a Hoge Raad decision ECLI, return the matching A-G conclusie (or reverse).

    When an agent reads a Hoge Raad ruling, immediately pull the Advocate-General's conclusie so the reasoning context is in scope.

    rechtspraak-pp-cli conclusie ECLI:NL:HR:2024:1 --agent
    

Local state that compounds

  • dossier — List every decision sharing a case number across instances, sorted chronologically.

    Use this when tracking a single Dutch case across the rechtbank, gerechtshof, and Hoge Raad — the API offers no case-file filter, only the local index does.

    rechtspraak-pp-cli dossier 22/00155 --agent
    
  • watch — Poll for new decisions matching a filter, dedupe against the local SQLite, and emit only the new ECLIs — cron-friendly with --quiet.

    Wire this into a cron or agent loop to receive only newly-published Dutch court decisions on your filter — no manual rechtspraak.nl refreshing.

    rechtspraak-pp-cli watch --court HR --subject belastingrecht --since 7d --quiet --agent
    
  • sync archive — Download the official weekly full-corpus archive and bulk-insert to the local SQLite — orders of magnitude faster than paging the Atom feed for backfills.

    Use this when bootstrapping a research corpus or rebuilding the local DB; live sync against the Atom feed is the wrong tool for backfills.

    rechtspraak-pp-cli sync archive --week 2024-W01
    

Agent-native plumbing

  • code — Bidirectional offline lookup against the Instanties controlled vocabulary — court code to full name and PSI URI, or fuzzy name to code.

    When an agent needs to resolve a Dutch court name, code, or PSI URI without round-tripping to the API, this is the lookup.

    rechtspraak-pp-cli code RBAMS --agent
    
  • mcp serve — Expose every rechtspraak command as an MCP tool — the first MCP server for Dutch case law.

    Wire this into Claude Desktop or any MCP-aware agent to give it native access to Dutch court decisions, citations, and case-files.

    rechtspraak-pp-cli mcp serve
    
  • ecli parse — Pure-local regex parse of an ECLI into country, court, year, and sequence — with validation — and ecli url for the deeplink.

    Use this whenever an agent needs to validate or destructure an ECLI before fetching content or chaining into another command.

    rechtspraak-pp-cli ecli parse ECLI:NL:HR:2024:1 --json
    
  • narrow — Read an ECLI list from stdin (or piped from search/watch/sync), fetch each decision's content from the live API (one HTTP call per ECLI, paced via the shared rate limiter), apply local include/exclude/phrase/regex filters against title+summary+body, and emit the narrowed list — the defining workflow for keyword-overlap-heavy Dutch legal research.

    Use this when a metadata-only search returns hundreds or thousands of decisions and an agent needs to narrow by phrasing — chain it after search, watch, or sync. The same vocabulary (--keyword, --exclude, --phrase, --regex) also lives on search directly for single-shot use.

    rechtspraak-pp-cli uitspraken search --subject strafrecht --court HR --from 2024-01-01 --agent | rechtspraak-pp-cli narrow --keyword huurprijs --exclude "kort geding" --phrase "huurprijswijziging" --agent
    

Recipes

Iteratively narrow an over-broad result set

rechtspraak-pp-cli uitspraken search --subject strafrecht --court HR --from 2024-01-01 --keyword huurprijs --exclude "kort geding" --phrase "huurprijswijziging" --annotate-count --agent

Upstream API returns metadata-only matches; without --scan-body the --keyword/--exclude/--phrase/--regex flags filter against title+summary in-memory (no fetch). With --scan-body each candidate's body is fetched and matched as well. --annotate-count prints total/fetched/post-narrow counts after the run.

Walk the full procedural history of a Hoge Raad decision

rechtspraak-pp-cli chain ECLI:NL:HR:2024:1 --agent --select chain.ecli,chain.court,chain.date,chain.type

The response is deeply nested across instances; the dotted --select projection keeps the agent's context lean by emitting only the chain skeleton.

Daily new-decision watch with narrowing

rechtspraak-pp-cli watch --court HR --subject belastingrecht --since 1d --keyword "omkering bewijslast" --quiet --agent

Exits silently if no new decisions match both the upstream filter (HR + belastingrecht + last 24h) AND the local keyword filter — drop-in for cron + mail.

Pipe-compose narrowing across commands

rechtspraak-pp-cli uitspraken search --court HR --from 2024-01-01 --json | jq -r '.[] .ecli' | rechtspraak-pp-cli narrow --keyword belastingrecht --exclude conclusie --agent

Read ECLIs from any source, apply local filters, emit narrowed list — the same vocabulary as search but composable across pipelines.

Bibliography export for a brief

rechtspraak-pp-cli citations ECLI:NL:HR:2024:1 --format bibtex

Emits the vindplaatsen as BibTeX entries with stable keys — paste directly into a LaTeX brief.

Resolve a court name to its PSI URI

rechtspraak-pp-cli code "Rechtbank Amsterdam" --json --select code,name,psi_uri

Fully offline after first sync; useful in agent chains that need to construct a search filter.

Usage

Run rechtspraak-pp-cli --help for the full command reference and flag list.

Commands

courts

Dutch courts (Instanties) controlled vocabulary - 79KB authoritative list

  • rechtspraak-pp-cli courts - List every Dutch rechtsprekende instantie with PSI URI, full name, afkorting code, type, and Begin/EndDate. Begin/EndDate enable court-succession lookup (Wet Herziening Gerechtelijke Kaart).

foreign-courts

Foreign courts (BuitenlandseInstanties) referenced by Dutch decisions

  • rechtspraak-pp-cli foreign-courts - Foreign court catalog: ECHR, CJEU, and ~5000 EU member-state courts with PSI URI, multilingual name, and country code

foreign-decisions

Non-Dutch decisions registered with LJN codes (NietNederlandseUitspraken)

  • rechtspraak-pp-cli foreign-decisions - Bridge from foreign ECLIs (CJEU, ECHR) to old Dutch LJN codes - ~173k entries

procedures

Procedure types (Proceduresoorten) controlled vocabulary

  • rechtspraak-pp-cli procedures - Procedure types (cassatie, hoger beroep, kort geding, etc.) with PSI URIs

relations

Formal relation types (FormeleRelaties) between decisions

  • rechtspraak-pp-cli relations - Relation taxonomy: each relation type pairs from/to court tiers and lists the canonical AfhandelingsWijze (disposition outcomes: bekrachtiging, vernietiging, niet ontvankelijk, etc.)

subjects

Subject areas (Rechtsgebieden) controlled vocabulary - hierarchical

  • rechtspraak-pp-cli subjects - Subject-area taxonomy with PSI URIs, names, and parent-child hierarchy

uitspraken

Search and fetch Dutch court decisions (ECLI register)

  • rechtspraak-pp-cli uitspraken get - Fetch a single decision by ECLI - returns full RDF metadata plus the inhoudsindicatie summary and the uitspraak body when available.
  • rechtspraak-pp-cli uitspraken image - Fetch an embedded image from a decision body by its imagedata identifier
  • rechtspraak-pp-cli uitspraken search - Search the ECLI index by date, court, subject, type. Per IVO 1.15: same-type params are OR-unioned, cross-type params are AND-combined. Local --keyword/--exclude/--phrase/--regex flags filter against title+summary by default; --scan-body fetches each entry's body for matching against title+summary+body. --procedure is also filtered locally (the upstream API silently ignores procedure=).

Output Formats

# Human-readable table (default in terminal, JSON when piped)
rechtspraak-pp-cli courts

# JSON for scripting and agents
rechtspraak-pp-cli courts --json

# Filter to specific fields
rechtspraak-pp-cli courts --json --select id,name,status

# Dry run — show the request without sending
rechtspraak-pp-cli courts --dry-run

# Agent mode — JSON + compact + no prompts in one flag
rechtspraak-pp-cli courts --agent

Agent Usage

This CLI is designed for AI agent consumption:

  • Non-interactive - never prompts, every input is a flag
  • Pipeable - --json output to stdout, errors to stderr
  • Filterable - --select id,name returns only fields you need
  • Previewable - --dry-run shows the request without sending
  • Read-only by default - this CLI does not create, update, delete, publish, send, or mutate remote resources
  • Offline-friendly - sync/search commands can use the local SQLite store when available
  • Agent-safe by default - no colors or formatting unless --human-friendly is set

Exit codes: 0 success, 2 usage error, 3 not found, 5 API error, 7 rate limited, 10 config error.

Health Check

rechtspraak-pp-cli doctor

Verifies configuration and connectivity to the API.

Configuration

Config file: ~/.config/rechtspraak-pp-cli/config.toml

Static request headers can be configured under headers; per-command header overrides take precedence.

Troubleshooting

Not found errors (exit code 3)

  • Check the resource ID is correct
  • Run the list command to see available items

API-specific

  • search with --keyword or --phrase returns zero results despite expected matches — By default uitspraken search matches --keyword/--exclude/--phrase/--regex against title + Atom summary only. Party/company names and many substantive terms live in the decision body, not the headnote. Pass --scan-body to fetch each entry's body and match against title+summary+body. One HTTP call per entry, rate-limited via the shared limiter, so scope tightly with --from/--to and --court first.
  • search reports a higher total than the entries returned — A single call fetches one page (size --max, default 100; server caps at 1000). Pass --max-pages N to sweep further pages. The CLI always emits a stderr truncation warning when upstream total > fetched.
  • search returns more results than expected even with --procedure cassatie — The upstream API silently ignores procedure=; the CLI filters locally against Proceduresoorten metadata after sync. Confirm the procedure name resolves with rechtspraak-pp-cli procedures list.
  • search returns empty results from the API — Confirm the subject area name resolves to a PSI URI with rechtspraak-pp-cli subjects list — many spelling variants exist.
  • get ECLI returns metadata only, no summary — Pass --summary or --full to request return=DOC from the content endpoint.
  • Atom feed paging is slow for multi-year backfills — Bulk weekly-archive ingest (sync archive) is deferred to v0.2 — see README ## Known Gaps. For backfills today, paginate the search endpoint with --from-offset N over a tight date window (server caps at 1000 results per request).
  • court name not recognised — Run rechtspraak-pp-cli code <name-or-code> to see the canonical name and PSI URI.

Known Gaps

This v0.1 ships the 9 highest-value novel commands fully implemented against the live API. Five additional commands from the original design are deferred to a follow-up polish session — each is honestly stubbed below, with the implementation sketch so a contributor can pick them up cleanly:

  • sync archive — bulk-ingest the official weekly full-corpus archive. The IVO 1.15 doc references a periodic ZIP at the open-data page; the format is not yet probed in this run. The current sync walks the Atom feed serially. Implementation: probe the archive URL pattern, parse the ZIP, bulk-insert RDF files. Deferred because it requires understanding the archive format which the public docs only hint at.
  • judges <name> — find all decisions where a contributor (rechter / raadsheer / staatsraad / A-G) participated. The schema exposes dcterms:contributor; this needs a local SQLite index built during sync. The Atom feed alone does not include contributors, so this requires per-ECLI content fetches during sync. Implementation: extend the sync command to populate a contributors table, then add judges <name> as a SQL query.
  • landmark <name> / landmarks list — look up "spraakmakende zaken" by nickname (Lindenbaum/Cohen, Quint/Te Poel). Schema provides dcterms:alternative. Needs the same local-index pattern as judges.
  • cites-law BWB:...laws <ECLI> — the Dutch statutory-law citation graph. Each Decision's dcterms:references carries embedded BWB / CVDR / CELEX / ECLI cross-references with resourceIdentifier attributes. The parser scaffolds these (see internal/rechtspraak/parser.go) but the XML namespace handling for body-level refs needs an extra pass.
  • refs <ECLI> — extract every body-level reference (BWB, CVDR, EU CELEX, cross-jurisdiction ECLI) for a decision. Same underlying parsing as cites-law.

Track these in this CLI's polish issue.


Sources & Inspiration

This CLI was built by studying these projects and resources:

Generated by CLI Printing Press

For agents: pass /documentation/rechtspraak/agents.md to install this CLI from a prompt.