For developers
Lex is MCP-native: you bring the model, Lex brings the evidence. 10 read-only tools over signed indexes, no key, no account, no rate limit on the endpoint.
Connect
claude mcp add --transport http lex https://law.soufien.lu/mcp
{ "mcpServers": { "lex": { "url": "https://law.soufien.lu/mcp" } } }{ "type": "mcp", "server_label": "lex", "server_url": "https://law.soufien.lu/mcp", "require_approval": "never" }curl -X POST https://law.soufien.lu/mcp -H 'Content-Type: application/json' \
-d '{ "jsonrpc":"2.0", "id":1, "method":"tools/call",
"params": { "name":"as_of",
"arguments": { "work":"eu-eurlex:32016r0679",
"date":"2019-03-15", "mode":"select", "anchors":"art_33" } } }'The 10 tools
| tool | arguments | answers |
|---|---|---|
| as_of | work, date, [language], [mode: full\|outline\|select], [anchors] | the text in force on a date. outline lists article anchors only; select returns just the anchors you name, use it, codes are large. |
| article_history | work, anchor | every distinct text one article has had, as validity intervals, plus renumbering events. |
| timeline | work | all versions of a work with their validity windows. |
| diff | work, from, to | what changed between two versions. |
| in_force_on | date, [publisher], [document_type], [limit], [offset] | everything that applied on a given day. |
| search | query, [publisher], [as_of], [document_type], [language], [limit] | provision-level full-text search; hits are articles, with permalinks. |
| provenance | lex_id | source URI, retrieval time, record hash, the append-only observation chain. |
| coverage | [publisher] | what is held, and what is knowably missing. |
| cited_by | work, [limit] | which articles point AT this law, from the cross-references the publisher writes into its own text. Answers "what depends on this", "who amended it". |
| changes_in_period | from_date, to_date, [publisher], [document_type], [order], [limit], [offset] | across the corpus: which works gained versions in a window, and how many. The aggregate counterpart of diff and timeline, which cover one work. |
Try the joysticks
This calls the same public endpoint your model would. No key, nothing installed , the JSON below is exactly what an MCP client receives.
↑ pick a tool and press "Call it"
It refuses rather than guesses
Every tool returns an envelope with a status. The refusals are part of the contract: no_version_for_date · unknown_work · unknown_anchor · anchor_not_in_version · no_provision_history · text_withheld · outside_observed_window. Build against them: an empty result and a refusal are different things.
Or skip the API, take the data
Every provision of every version, one row each, licence and attribution inline. 3,167 versions carry full text.
SELECT * FROM read_parquet('https://github.com/SFHAJJI/lex-articles/releases/latest/download/eu-eurlex-provisions.parquet');
Also published as .jsonl.gz. Python examples (standard library only, no pip install) live in examples/ , load provisions, resolve a point in time, verify the hash chain, call this MCP endpoint.
The repositories
| repo | what it is | licence |
|---|---|---|
| lex | the engine: ingest, derive, index, MCP server, this site | Apache-2.0 |
| lex-articles | derived layer, one Markdown+JSON record per article per version | CC-BY-4.0 |
| lex-corpus-lu-legilux | evidence layer, Legilux's own files, verbatim, plus signed nightly index | CC-BY-4.0 |
| lex-corpus-eu-eurlex | evidence layer, EUR-Lex/Cellar files, verbatim | EU reuse |
Why four? Evidence and derivation are kept apart on purpose: the evidence repos are append-only and never rewritten, so a derived record can always be traced back to the exact bytes a state published. The full model →
Everything on this page is exercised by the project's own test and eval suites, and the endpoint is rebuilt nightly. How it was built → · Verify it yourself →