io.github.cyanheads/eur-lex-mcp-server
REMOTE · EUR-LEX.CASEYJHAND.COM · 2 COMPONENTS · SCANNED AUG 3
Search EU legislation, CJEU case law, and treaties; traverse CELLAR graph; browse EuroVoc concepts.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score →
Endpoint Security66
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation not fully verified: no authorisation is required to call this server, and 7 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe. See how to fix → View diagnostics → Unverified
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC is configured correctly; the domain's records validate against the full chain to the root. View diagnostics → Pass
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability72
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 3116 tokens (~445/item across 7 items; 7 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management27
- Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Add this component to your MCP client. Where a client-specific snippet is available, pick your client below and copy it straight into your config; otherwise use the connection detail shown.
remote · eur-lex.caseyjhand.com
claude mcp add --transport http cyanheads-eur-lex-mcp-server https://eur-lex.caseyjhand.com/mcp
[mcp_servers.cyanheads-eur-lex-mcp-server] url = "https://eur-lex.caseyjhand.com/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"cyanheads-eur-lex-mcp-server": {
"type": "remote",
"url": "https://eur-lex.caseyjhand.com/mcp",
"enabled": true
}
}
} openclaw mcp add cyanheads-eur-lex-mcp-server --url https://eur-lex.caseyjhand.com/mcp --transport streamable-http
mcp_servers:
cyanheads-eur-lex-mcp-server:
url: "https://eur-lex.caseyjhand.com/mcp" {
"mcpServers": {
"cyanheads-eur-lex-mcp-server": {
"type": "http",
"url": "https://eur-lex.caseyjhand.com/mcp"
}
}
} The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 3 Aug 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.
- 1 Aug 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.
- 31 Jul 26 +1
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 30 Jul 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 29 Jul 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.
- 28 Jul 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.
- 27 Jul 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 26 Jul 26 65
First indexed and scored.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 3 Aug 2026 · Probed https://eur-lex.caseyjhand.com/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=caseyjhand.com | CN=WE1,O=Google Trust Services,C=US | 7 Jul 2026 | 5 Oct 2026 | ECDSA 256 | ECDSA-SHA256 | 5aad900eb2055a0b0ea55912ec19680c |
| SANs: caseyjhand.com, *.caseyjhand.com | ||||||
| CN=WE1,O=Google Trust Services,C=US (CA) | CN=GTS Root R4,O=Google Trust Services LLC,C=US | 13 Dec 2023 | 20 Feb 2029 | ECDSA 256 | ECDSA-SHA384 | 7ff31977972c224a76155d13b6d685e3 |
| CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) | CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE | 15 Nov 2023 | 28 Jan 2028 | ECDSA 384 | SHA256-RSA | 7fe530bf331343bedd821610493d8a1b |
DNSSEC secure
Validation of eur-lex.caseyjhand.com. — Secure
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| com. | present | 19718 | 13 | Verified |
| caseyjhand.com. | present | 2371 | 13 | Verified |
| eur-lex.caseyjhand.com. | Verified address RRset verified with the apex keys |
Authentication No authorisation required
The endpoint answered without asking for a token. Anyone who knows the URL can reach it.
| Result | No authorisation required |
|---|---|
| HTTP status | 200 |
| Header | Value |
|---|---|
| strict-transport-security | max-age=63072000; includeSubDomains; preload |
| x-content-type-options | nosniff |
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://eur-lex.caseyjhand.com/mcp | Verified | 200 | |
| http (plaintext) | http://eur-lex.caseyjhand.com/mcp | HTTPS enforced | 301 | https://eur-lex.caseyjhand.com/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability.
eurlex_browse_subjects Browse EuroVoc Subjects ~185
Search the EuroVoc thesaurus, resolving a keyword into concept URIs usable in the eurovoc_concept subject filter of eurlex_search_documents. Returns each concept URI, its preferred label in the requested language, code, and broader (parent) label, ordered alphabetically by label.
| Name | Type | Req | Description |
|---|---|---|---|
| keyword | string | yes | Search term to match against EuroVoc concept labels (e.g. "privacy", "agriculture", "trade"). |
| language | string | — | Language code for concept labels (e.g. "en", "fr", "de"). Case-insensitive — "EN" and "en" behave identically. Defaults to English. |
| limit | integer | — | Maximum number of EuroVoc concepts to return (1–50). Defaults to 20. |
| offset | integer | — | Pagination offset — number of concepts to skip. Defaults to 0. |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | — | The limit that was applied to this response. |
| concepts | array | yes | Matching EuroVoc concepts ordered alphabetically by label. |
| offset | number | yes | Pagination offset used for this response. |
| shown | number | — | Number of concepts returned in this response. |
| total | number | yes | Number of concepts returned in this response. |
| truncated | boolean | — | True when the returned list was capped at the limit and more concepts may exist. |
No examples provided.
eurlex_get_cases Search CJEU/GC Case Law ~429
Search CJEU and General Court case law — judgments, orders, and Advocate General opinions — by case number, court, case type, keyword, and date range. By default only these primary records are returned; derivative judicial information notices, case abstracts, summaries, and corrigenda are excluded so distinct cases fill the page (set include_derivative to include them). Keyword matches English case titles (which carry party names) and CELEX strings; there is no full-text body search. Returns each case with its court, date, and type, plus — parsed from the title where present — the parties, subject matter, and case reference.
| Name | Type | Req | Description |
|---|---|---|---|
| case_number | string | — | Case number in standard format: C-{num}/{year} for CJEU or T-{num}/{year} for General Court (e.g. C-131/12). |
| case_type | — | — | Case type: judgment, order (procedural decision), or ag_opinion (Advocate General opinion). Omit to search all. |
| court | — | — | Court filter: CJEU = Court of Justice of the EU, GC = General Court. Omit to search both. |
| date_from | — | — | Start of date range in ISO 8601 format (YYYY-MM-DD). Leave blank or omit for no lower bound. |
| date_to | — | — | End of date range in ISO 8601 format (YYYY-MM-DD). Leave blank or omit for no upper bound. |
| include_derivative | boolean | — | Include derivative sector-6 records — judicial information notices, case abstracts, case summaries, and corrigenda — alongside primary judgments, orders, and AG opinions. Default false: these are exc… |
| keyword | string | — | Keyword to match against case titles and CELEX strings. |
| limit | integer | — | Maximum number of results to return (1–100). Defaults to 20. |
| offset | integer | — | Pagination offset — number of results to skip. Defaults to 0. |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | — | The limit that was applied to this page. |
| cases | array | yes | Matching case law records ordered by date descending. |
| offset | number | yes | Pagination offset used for this response. |
| query_echo | object | yes | Echo of filters applied to this search. Useful for diagnosing empty results. |
| shown | number | — | Number of cases returned in this page. |
| total | number | yes | Number of cases returned in this page (not a corpus-wide count). |
| truncated | boolean | — | True when the returned page was capped at the limit and more cases may exist. |
No examples provided.
eurlex_get_document Get EU Document ~869
Fetch the metadata and full text of an EU act by CELEX number, ELI URI, or work URI. Returns structured metadata (title, date, type, author institution, legal basis, EuroVoc subjects, in-force status) plus the act body as HTML, Markdown, or Formex4 XML, defaulting to English with automatic fallback. Large bodies are paged by default (offset/limit with has_more) or returned whole with content_mode "full"; use outline: true for a heading map and select to pull specific articles, chapters, recitals, or annexes.
| Name | Type | Req | Description |
|---|---|---|---|
| celex_number | string | — | CELEX number of the act to fetch (e.g. 32016R0679 for GDPR). Provide exactly one of celex_number, eli_uri, or work_uri. |
| content_mode | string | — | How much of the body to return. "paged" (default) returns a bounded character window (see offset/limit); "full" returns the entire body in one call (large acts can be hundreds of KB); "metadata_only"… |
| eli_uri | string | — | Work-level ELI URI of the act to fetch (e.g. http://data.europa.eu/eli/reg/2016/679, with or without the /oj suffix). Provide exactly one of celex_number, eli_uri, or work_uri. |
| format | string | — | Content format: "html" for the act text as served by EUR-Lex (default), "markdown" for that HTML converted to clean Markdown server-side, or "xml" for Formex4 structured XML. |
| language | string | — | Language code for document content (ISO 639-1 uppercase, e.g. EN, FR, DE). Defaults to EN, and falls back to EN if the requested language is unavailable. |
| limit | integer | — | Maximum characters to return in this window ("paged" mode only). Default 25000, max 100000. For the entire body in one response, use content_mode "full". |
| offset | integer | — | Character offset into the body where the returned window starts ("paged" mode only). Page forward by setting offset = content_offset + content_chars_returned from the previous call. Offsets are forma… |
| outline | boolean | — | Return a structural outline of the act — chapters, sections, articles, annexes, and recitals as a heading list, each with its character offset — instead of body text. Read a section by paging with it… |
| resolve | string | — | Which version to serve for a base act with newer consolidated versions. "as_requested" (default) returns the exact CELEX requested; "current_consolidated" serves the newest consolidated version inste… |
| select | object | — | Return only the text of specific sections by type and number, instead of a raw character window (Roman and Arabic numbers are equivalent). Sections are located in the body of the requested format, so… |
| work_uri | string | — | CELLAR work resource URI to fetch (e.g. http://publications.europa.eu/resource/cellar/3e485e15-11bd-11e6-ba9a-01aa75ed71a1) — the form returned by eurlex_lookup_celex, eurlex_get_relations, and eurle… |
| Name | Type | Req | Description |
|---|---|---|---|
| author_institution | string | — | Human-readable name of the primary (first) originating EU institution (e.g. "European Parliament", "Council of the EU"). For co-legislated acts, prefer author_institutions for the complete set. Absen… |
| author_institutions | array | — | All originating EU institutions, for co-legislated acts adopted by more than one body (e.g. ["European Parliament", "Council of the EU"]). Absent when none recorded. |
| celex_number | string | yes | Confirmed CELEX number for the retrieved work. |
| consolidated_as_of | string | — | Consolidation date of current_consolidated_celex in ISO 8601 (YYYY-MM-DD). Present only when is_superseded is true. |
| content | string | — | Body content of the act in the requested format and language. In "paged" mode a character window (see content_offset / content_chars_returned / has_more); in "full" mode the entire body; omitted in "… |
| content_available | boolean | yes | Whether body content was fetched from EUR-Lex. False in "metadata_only" mode (no fetch attempted) — use content_mode to distinguish "not requested" from "unavailable upstream". |
| content_chars_returned | integer | — | Number of body characters returned in this response (equals content length). Present when a body was fetched and available. |
| content_chars_total | integer | — | Total character length of the full document body. Present when content was fetched and available; use with content_offset to page through the entire act. |
| content_format | string | yes | Format of the returned content: "html", "markdown", or "xml". |
| content_mode | string | yes | Content mode applied to this response: "metadata_only", "paged", or "full". |
| content_offset | integer | — | Character offset where the returned content window begins. Present when a body was fetched and available. |
| current_consolidated_celex | string | — | CELEX of the newest consolidated version of the requested base act (e.g. 02014R0833-20260424) — fetch it with eurlex_get_document, or pass resolve "current_consolidated". Present only when is_superse… |
| date | string | — | Document date in ISO 8601 format (YYYY-MM-DD). |
| eurovoc_subjects | array | — | EuroVoc subject classifications. |
| has_more | boolean | yes | True when body content exists beyond the returned window. Page forward with offset = content_offset + content_chars_returned, or request content_mode "full". Always false in "metadata_only" mode. |
| in_force | boolean | — | Whether the act is currently in force. |
| is_superseded | boolean | — | True when a newer consolidated version of the requested base act exists (an unofficial reading aid merging later amendments), so the returned text may not include those amendments. Not a repeal/repla… |
| language | string | yes | Language code of the returned content. |
| language_fallback | string | — | Human-readable note explaining the fallback that occurred (e.g. "Requested FR content unavailable; returned EN"). Present only when a fallback happened. |
| legal_basis | array | — | Legal basis acts for this work. |
| outline | array | — | Structural outline of the act. Present only when outline is true; an empty array means no structure was detected. |
| requested_celex | string | — | The originally requested CELEX, echoed when resolve "current_consolidated" served a different (consolidated) work. celex_number holds the CELEX actually served. Absent when the served work is the one… |
| resource_type | string | — | Human-readable document type label (e.g. "Regulation", "Directive"). Absent for some older works. |
| selection | object | — | Outcome of a structural selection. Present only when select was used; content holds the matched sections joined in document order. |
| structure_detected | boolean | — | Whether any act structure was parsed from the body. Present when outline or select was used; false means no detectable chapter/article/annex structure — read it via offset/limit or content_mode "full… |
| title | string | — | Document title in the requested language (absent for some older works and judgments). |
| work_uri | string | — | CELLAR work URI. |
No examples provided.
eurlex_get_relations Get CELLAR Relationship Graph ~364
Traverse the one-hop CDM relationship graph of an EU act: what it amends or is amended by, what it repeals or is repealed by (explicit and implicit), its consolidated versions, its legal basis, and works that cite it. Returns direct relations only, paginated per relation type and direction. Requires a CELEX number or CELLAR work URI.
| Name | Type | Req | Description |
|---|---|---|---|
| celex_number | string | — | CELEX number of the work to traverse (e.g. 32016R0679). Provide exactly one of celex_number or work_uri. |
| limit | integer | — | Maximum related works per relation type and direction (1–100, default 100). Incoming edges are ordered newest-first, so the cap keeps the newest — page with offset for older ones. When truncated is t… |
| offset | integer | — | Pagination offset applied per relation type and direction — related works to skip (default 0). Page forward by adding limit; incoming edges are newest-first, so higher offsets reach older works. |
| relation_types | array | — | Subset of relation types to return; omit for all. Types: cites, amends, amended_by, repeals, repealed_by, implicitly_repeals, implicitly_repealed_by, legal_basis (treaty/article this act rests on), c… |
| work_uri | string | — | CELLAR work resource URI to traverse (e.g. http://publications.europa.eu/resource/cellar/3e485e15-11bd-11e6-ba9a-01aa75ed71a1). Used directly without CELEX resolution. Provide exactly one of celex_nu… |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | — | The per-direction cap applied to this page. |
| celex_number | string | — | CELEX number of the source work whose relations were traversed. Absent when addressed directly by work_uri. |
| empty_relation_types | array | yes | Requested relation types that returned zero relations in THIS page. Page-scoped: a type can appear here because all its edges sit beyond the current offset/limit window, not only because the act genu… |
| offset | number | yes | Pagination offset applied to this response (per relation type and direction). |
| relations | array | yes | Direct CDM relations for the requested work. |
| requested_relation_types | array | yes | The relation types this request traversed — the explicit relation_types list, or all types when it was omitted. Diff against the types present in relations[], or read empty_relation_types, to confirm… |
| shown | number | — | Number of relations returned in this page. |
| total | number | yes | Number of relations returned in this page (not a corpus-wide count). A direction that filled its cap sets truncated — page with offset for the rest. |
| truncated | boolean | — | True when at least one relation type/direction filled its per-direction cap and more related works may exist — page with offset. |
| work_uri | string | yes | CELLAR URI of the source work (the work_uri input, or resolved from the CELEX). |
No examples provided.
eurlex_lookup_celex Resolve EU Legal Citation ~154
Resolve an EU legal citation — a CELEX number or ELI URI — to its canonical CELLAR work, confirming it exists before you fetch or traverse it. Returns the work URI, confirmed CELEX number, document type, and date.
| Name | Type | Req | Description |
|---|---|---|---|
| identifier | string | yes | The EU legal citation to resolve: a CELEX number (e.g. 32016R0679) or a work-level ELI URI (e.g. http://data.europa.eu/eli/reg/2016/679, with or without the /oj suffix). |
| identifier_type | string | — | Format of the identifier. "auto" detects it automatically; supply "celex" or "eli" explicitly if detection fails. |
| Name | Type | Req | Description |
|---|---|---|---|
| celex_number | string | — | Confirmed CELEX number for the resolved work. |
| date | string | — | Document date in ISO 8601 format (YYYY-MM-DD). |
| found | boolean | yes | True when the identifier resolves to a CELLAR work; false when a well-formed CELEX/ELI matches no work in the corpus. A malformed or undetectable identifier raises ambiguous_identifier instead. |
| resource_type | string | — | CDM resource type URI indicating the document category (e.g. .../resource-type/REG for Regulation). Absent for some works. |
| work_uri | string | — | CELLAR work URI (stable resource identifier). |
No examples provided.
eurlex_query_sparql Raw CELLAR SPARQL Query ~285
Run a raw, read-only SPARQL SELECT against the CELLAR Virtuoso endpoint — an escape hatch for CDM ontology traversals the curated tools do not cover. Only SELECT is accepted; update forms and ASK/CONSTRUCT/DESCRIBE are rejected before execution, and results are capped at 100. The cdm:, skos:, and xsd: prefixes are auto-injected.
| Name | Type | Req | Description |
|---|---|---|---|
| sparql_query | string | yes | A read-only SPARQL SELECT query. Leading comments and PREFIX/BASE declarations are allowed; the cdm:, skos:, and xsd: prefixes are auto-injected. LIMIT is injected at 100 if absent, or capped to 100.… |
| timeout_hint | integer | — | Optional client-side timeout in milliseconds (1000–55000). Defaults apply when omitted; the endpoint hard limit is 60 seconds. |
| Name | Type | Req | Description |
|---|---|---|---|
| bindings | array | yes | Raw SPARQL binding rows. To extract a value from a row: row["varName"]?.value. Use the variables array to iterate in query order. |
| cap | number | — | The server-enforced result ceiling that was applied. |
| shown | number | — | Number of binding rows returned in this response. |
| total | number | yes | Number of binding rows returned (capped at 100 by the server). |
| truncated | boolean | — | True when the server-enforced result ceiling capped the rows and more may exist upstream — narrow the query with FILTERs to see the rest. |
| variables | array | yes | Variable names from the SELECT head, in query order. |
No examples provided.
eurlex_search_documents Search EU Documents ~480
Search EU legislation, treaties, and preparatory acts across the CELLAR corpus by document type, date range, EuroVoc subject, author institution, and in-force status. Keyword matches English titles and CELEX strings only — there is no full-text body search. Returns a page of CELEX numbers, work URIs, type labels, dates, and titles, newest first, each flagged with is_consolidated. At least one filter is required.
| Name | Type | Req | Description |
|---|---|---|---|
| author_institution | string | — | Author institution name (e.g. "European Parliament", "Council", "European Commission"), matched against the English names of EU corporate bodies. |
| date_from | — | — | Start of date range (YYYY-MM-DD), matched against document date. Omit for no lower bound. |
| date_to | — | — | End of date range (YYYY-MM-DD), matched against document date. Omit for no upper bound. |
| document_type | — | — | Document type: REG=Regulation, DIR=Directive, DEC=Decision, TREATY=Treaty, JUDG=Judgment, OPIN_AG=AG Opinion, PROP=Proposal, REC=Recommendation. Omit to search all types. A type filter excludes conso… |
| eurovoc_concept | — | — | EuroVoc concept URI to filter by subject (e.g. http://eurovoc.europa.eu/2828), obtained from eurlex_browse_subjects. Omit for no subject filter. |
| in_force | boolean | — | If true, restrict to acts currently in force. Omit to return all regardless of in-force status. |
| include_consolidated | boolean | — | When true and document_type is set, also match consolidated texts (CONS_TEXT) of that type — point-in-time versions that a plain type filter omits. No effect when document_type is omitted. Consolidat… |
| keyword | string | — | Keyword matched against English document titles via the full-text index (multi-word input is treated as a phrase), or against CELEX substrings. |
| limit | integer | — | Maximum number of results to return (1–100). Defaults to 20. |
| offset | integer | — | Pagination offset — number of results to skip. Defaults to 0. |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | — | The limit that was applied to this page. |
| documents | array | yes | Matching EU documents ordered by date descending. |
| offset | number | yes | Pagination offset used for this response. |
| query_echo | object | yes | Echo of filters applied to this search. Useful for diagnosing empty results. |
| shown | number | — | Number of documents returned in this page. |
| total | number | yes | Number of documents returned in this page (not a corpus-wide count). |
| truncated | boolean | — | True when the returned page was capped at the limit and more documents may exist. |
No examples provided.