eurlex-mcp-server
This server provides direct access to EU legal documents and case law via the EUR-Lex Cellar API — no API key required. It offers 11 tools for searching, fetching, and analyzing EU legal documents:
eurlex_search: Search EU legal acts by title substring, with optional filters for document type, language, and date range.eurlex_fetch: Retrieve full text of any act by CELEX ID, ELI, or Official Journal reference, with pagination for long documents.eurlex_metadata: Get structured metadata (dates, in-force status, authors, legal basis, EuroVoc descriptors, directory codes).eurlex_citations: Explore citation graphs — which acts a document cites, which cite it, and amendment/repeal relationships.eurlex_by_eurovoc: Thematic search by EuroVoc concept label or URI, even when the term doesn't appear in the title.eurlex_consolidated: Fetch the latest in-force, amendment-merged text of regulations, directives, or decisions.eurlex_case_law: Search CJEU judgments, orders, and Advocate General opinions by party name, ECLI, CELEX, or related legal act.eurlex_transposition: List national implementing measures (NIMs) for a directive, filterable by member state.eurlex_structure: Get a document outline with character offsets for chapters, articles, annexes, and judgment paragraphs — enabling targeted reading.eurlex_summary: Retrieve the official plain-language LEGISSUM editorial summary of an act.eurlex_sparql: Run read-only SPARQL SELECT/ASK queries directly against the Cellar endpoint for advanced custom lookups.
Additional features: supports all 24 official EU languages, accepts multiple identifier formats (CELEX, ELI, OJ references), includes built-in retry with backoff and in-process caching for resilience and performance.
Search and retrieve EU law via the EUR-Lex Cellar API, providing tools for searching legal acts, fetching full text, metadata, citation graphs, EuroVoc-based discovery, and consolidated versions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@eurlex-mcp-serverFind EU regulations about artificial intelligence from 2024"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
eurlex-mcp-server
Search and retrieve EU law via the EUR-Lex Cellar API -- an MCP server that gives AI assistants direct access to EU regulations, directives, court decisions, and more. No API key required.
What You Can Do
Ask your AI assistant questions like:
"Find EU regulations about artificial intelligence from 2024"
"Show me the full text of the AI Act (32024R1689)"
"What EuroVoc topics are assigned to the GDPR?"
"Which EU acts are about cybersecurity as a topic, even if the word isn't in the title?"
"Which documents cite the Digital Services Act?"
"Search for directives about renewable energy"
"Get the consolidated version of Regulation 2016/679 (GDPR)"
"Which CJEU judgments interpret the GDPR?"
"Look up the Court of Justice ruling with ECLI ECLI:EU:C:2014:317"
"How did Germany transpose the NIS2 Directive?"
"Outline the AI Act, then show me just Article 5"
"Give me the plain-language summary of the Digital Services Act"
Related MCP server: Comprehensive EU Law MCP Server
Features
11 specialized tools for searching, fetching, and analyzing EU legal documents (see Tool Reference)
EuroVoc thesaurus search -- find documents by EU taxonomy concepts, with automatic label fallback across all 24 languages
CJEU case law -- find judgments, orders, and Advocate General opinions by ECLI, CELEX, party/title, or the act they interpret
National transposition measures (NIM) -- list how member states transposed a given directive into national law
Document outline + targeted reading -- get an act's table of contents with plain-text offsets, then jump straight to a specific article with
eurlex_fetch; for CJEU case law (CELEX sector 6) the outline also lists each numbered judgment paragraph asParagraph N, so you can jump to a specific paragraph the same way (paragraph detection is language-independent)Plain-language summaries -- retrieve the EU's LEGISSUM summary of an act
Raw SPARQL escape hatch -- run read-only
SELECT/ASKqueries directly against Cellar for questions the other tools can't expressConsolidated versions -- retrieve the latest in-force text of regulations, directives, and decisions, identified by CELEX ID or by doc type + year + number
Citation graph -- explore which documents cite or are cited by a given act, with a balanced split between the two directions
Structured metadata -- dates (with
nullinstead of Cellar's9999-12-31sentinel for open-ended validity), in-force status, authors, legal basis, EuroVoc descriptors, and directory codesFlexible identifiers --
eurlex_fetch,eurlex_metadata, andeurlex_structureaccept a CELEX ID, an ELI (e.g.reg/2016/679), or a post-2023 Official Journal reference (e.g.OJ:L_202401689)Structured output -- every tool returns a machine-readable
structuredContentpayload validated against a publishedoutputSchema, alongside the JSON text blockOffset-based pagination --
eurlex_fetch,eurlex_consolidated, andeurlex_summaryreturnnext_offsetso long documents can be read in successive callsAll 24 official EU languages -- request titles and full text in any official EU language (default English; configurable via
EURLEX_DEFAULT_LANGUAGE)No API key required -- uses the public EUR-Lex Cellar SPARQL endpoint
Resilient by default -- automatic retry with backoff on transient Cellar errors, and in-process caching of EuroVoc labels, consolidated-CELEX lookups, and metadata to cut latency on repeat requests
Quick Start
pnpm dlx eurlex-mcp-serverOr with npx:
npx -y eurlex-mcp-serverConfiguration
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"eurlex": {
"command": "npx",
"args": ["-y", "eurlex-mcp-server"],
"env": {
"EURLEX_DEFAULT_LANGUAGE": "DEU"
}
}
}
}The env block is optional. Set EURLEX_DEFAULT_LANGUAGE to change the default language every
tool uses when no language parameter is passed -- see Default language below.
The other MCP clients below accept the same env block.
Claude Code
claude mcp add eurlex-mcp-server -- npx -y eurlex-mcp-serverVS Code
Add to .vscode/mcp.json:
{
"servers": {
"eurlex": {
"command": "npx",
"args": ["-y", "eurlex-mcp-server"]
}
}
}Cursor
Add to .cursor/mcp.json:
{
"mcpServers": {
"eurlex": {
"command": "npx",
"args": ["-y", "eurlex-mcp-server"]
}
}
}Windsurf
Add to ~/.windsurf/mcp.json:
{
"mcpServers": {
"eurlex": {
"command": "npx",
"args": ["-y", "eurlex-mcp-server"]
}
}
}Default language
Language-aware tools default to English (ENG) when no language parameter is passed. Set the
EURLEX_DEFAULT_LANGUAGE environment variable to change that default to any of the 24 official EU
languages, given as a Cellar 3-letter code (case-insensitive, e.g. DEU, FRA, POL). It is read
once at startup and applies to both transports (stdio and HTTP); for an HTTP deployment it sets
the default for every session of the process. An unset or invalid value falls back to ENG (an
invalid value also logs a one-line warning to stderr). A per-call language parameter always
overrides this default.
EURLEX_DEFAULT_LANGUAGE=DEUFor stdio MCP clients, set it via the env block in the client config (see the Claude Desktop
example above).
HTTP Transport (Remote Deployments)
When running the server over HTTP (pnpm start:http / dist/http.js) instead of stdio, it's exposed
to any client that can reach it over the network. To protect against DNS rebinding attacks, set these
environment variables:
Variable | Required | Description |
| no (but strongly recommended for public deployments) | Comma-separated list of allowed |
| no | Comma-separated list of allowed |
| no | Default language (Cellar 3-letter code, case-insensitive) used when a tool call omits |
Important: If your server runs behind a reverse proxy or load balancer, ensure it forwards the original Host header unmodified (e.g. nginx proxy_set_header Host $host;), otherwise MCP_ALLOWED_HOSTS validation will reject all legitimate traffic — the SDK compares the raw Host header as an exact string.
Production example:
MCP_ALLOWED_HOSTS=mcp.honeyfield.atThis protection is opt-in. If MCP_ALLOWED_HOSTS is not set, the server starts as before and logs
a one-line startup warning (MCP_ALLOWED_HOSTS not set — DNS rebinding protection disabled). Any public
deployment should set MCP_ALLOWED_HOSTS to its public hostname(s).
Tool Reference
The server exposes 11 read-only tools. Every tool returns both a JSON text block and a machine-readable structuredContent payload validated against a published outputSchema, so MCP clients can consume either representation. Tools that return titles or document text accept a language parameter taking any of the 24 official EU languages as a Cellar 3-letter code (default ENG, or whatever EURLEX_DEFAULT_LANGUAGE is set to): BUL, SPA, CES, DAN, DEU, EST, ELL, ENG, FRA, GLE, HRV, ITA, LAV, LIT, HUN, MLT, NLD, POL, POR, RON, SLK, SLV, FIN, SWE.
Tool | Purpose |
| Title-substring search over legislation |
| Full text of an act (by CELEX / ELI / OJ reference) |
| Structured metadata for an act |
| Citation graph (cites / cited-by / amends / …) |
| Thematic search by EuroVoc concept |
| Latest in-force consolidated text |
| CJEU judgments, orders, and AG opinions |
| National transposition measures for a directive |
| Document outline with plain-text offsets |
| Plain-language LEGISSUM summary |
| Raw read-only SPARQL escape hatch |
eurlex_search
Searches EU legal acts by title substring -- a contiguous, case-insensitive phrase match against the document title, not tokenized full-text search. For thematic discovery (the term may not appear in the title) use eurlex_by_eurovoc instead. Results are sorted newest-first within the fetched sample: for very broad single-word queries this is not guaranteed to be the globally newest match -- narrow with resource_type or date_from/date_to if that matters. The response no longer echoes the internal SPARQL query.
Parameter | Type | Required | Default | Description |
| string | yes | -- | Title substring to match (3-500 chars), e.g. |
| string | no |
| Document type filter: |
| string | no |
| Language for titles and full text: any of the 24 official EU languages (Cellar 3-letter code, e.g. |
| number | no |
| Max results (1-50) |
| string | no | -- | Filter from date, format: |
| string | no | -- | Filter to date, format: |
eurlex_fetch
Retrieve the full text of a document, identified by exactly one of celex_id, eli, or oj_ref. Long documents are paginated: the response includes returned_chars, total_chars, and next_offset (pass it as the next call's offset to keep reading; next_offset is null once there's nothing left).
Parameter | Type | Required | Default | Description |
| string | no* | -- | CELEX identifier, e.g. |
| string | no* | -- | European Legislation Identifier, short ( |
| string | no* | -- | Post-2023 Official Journal reference, e.g. |
| string | no |
| Language: any of the 24 official EU languages (Cellar 3-letter code, e.g. |
| string | no |
| Output format: |
| number | no |
| Max characters returned per call (1000-50000) |
| number | no |
| Character offset into the processed document, for pagination |
* Provide exactly one of celex_id, eli, or oj_ref.
eurlex_metadata
Retrieve structured metadata for a document: dates (document, entry into force, application, end of validity, transposition), in-force status, authors, legal basis, EuroVoc descriptors, and directory codes. Identified by exactly one of celex_id, eli, or oj_ref (same identifier inputs as eurlex_fetch).
Parameter | Type | Required | Default | Description |
| string | no* | -- | CELEX identifier, e.g. |
| string | no* | -- | European Legislation Identifier, short or full form; resolved to a CELEX via Cellar |
| string | no* | -- | Post-2023 Official Journal reference, e.g. |
| string | no |
| Language for titles and EuroVoc labels: any of the 24 official EU languages (Cellar 3-letter code, e.g. |
* Provide exactly one of celex_id, eli, or oj_ref.
Notes on the response:
authorslists the resolved agent names (e.g. "European Parliament", "Council of the European Union") instead of an empty array.legal_basislists the CELEX IDs of the acts this document is based on.Date fields (
date_document,date_entry_into_force,date_end_of_validity,date_transposition,date_application) arenullwhen absent -- including Cellar's9999-12-31sentinel for acts with no defined end of validity, which is normalized tonull. When Cellar holds several values,date_documentanddate_transpositionreport the earliest anddate_end_of_validitythe latest.date_entry_into_forceanddate_applicationare distinct: the GDPR entered into force on2016-05-24but applies from2018-05-25. Cellar stores every such "date of effect" under one property;dates_effectlists all of them ascending with atype(entry_into_force,application,partial_application) and the article note (e.g."Partial application See Art 113(a)"). The types come from Cellar's work notice; if that request fails, or the notice states no type for a date, the entry carriestype: "unknown", anddate_entry_into_forceis the earliest date not beforedate_document.directory_codesare human-readable ("{code-tail}: {label}", wherecode-tailis the fragment after the last/of the directory-code URI), not raw URIs.
eurlex_citations
Explore the citation graph of a document -- which acts it cites, which acts cite it, and amends/based-on/repeals relations.
Parameter | Type | Required | Default | Description |
| string | yes | -- | CELEX identifier, e.g. |
| string | no |
| Language for titles: any of the 24 official EU languages (Cellar 3-letter code, e.g. |
| string | no |
|
|
| number | no |
| Max results (1-100) |
With direction: "both", the two directions are queried and split evenly (roughly limit / 2 each) so that a burst of recent cited_by entries can't crowd out cites results. The response includes a counts: { cites, cited_by } object reporting how many of each were actually found.
eurlex_by_eurovoc
Find documents by EuroVoc thesaurus concept (label or URI).
Parameter | Type | Required | Default | Description |
| string | yes | -- | EuroVoc concept: label (e.g. |
| string | no |
| Document type filter (same values as |
| string | no |
| Language: any of the 24 official EU languages (Cellar 3-letter code, e.g. |
| number | no |
| Max results (1-50) |
eurlex_consolidated
Retrieve the consolidated (in-force) version of a regulation, directive, or decision. Identify the act with either celex_id or doc_type + year + number -- provide exactly one of the two forms. Like eurlex_fetch, the content is paginated via offset/max_chars/next_offset. The response also includes consolidated_celex (e.g. "02016R0679-20160504") and consolidation_date ("2016-05-04", parsed from that CELEX's date suffix; null if the resolved CELEX has none).
Parameter | Type | Required | Default | Description |
| string | no* | -- | CELEX ID of the original act, e.g. |
| string | no* | -- | Document type: |
| number | no* | -- | Year of the act (1950-2100), e.g. |
| number | no* | -- | Document number, e.g. |
| string | no |
| Language: any of the 24 official EU languages (Cellar 3-letter code, e.g. |
| string | no |
| Output format: |
| number | no |
| Max characters returned per call (1000-50000) |
| number | no |
| Character offset into the processed document, for pagination |
* Exactly one of celex_id or the doc_type+year+number triple must be provided.
eurlex_case_law
Search Court of Justice of the EU case law -- judgments, orders, and Advocate General opinions of the Court of Justice and the General Court. Provide at least one of query, celex_id, ecli, or related_celex (they may be combined). Each result gives celex, ecli, title, date, type, and eurlex_url. Use this for case law; eurlex_search covers only legislation.
Parameter | Type | Required | Default | Description |
| string | no* | -- | Title/party substring (3-500 chars). CJEU titles start with a |
| string | no* | -- | Sector-6 CELEX of a specific ruling, e.g. |
| string | no* | -- | European Case Law Identifier, e.g. |
| string | no* | -- | CELEX of a legal act (e.g. |
| string | no |
|
|
| string | no |
|
|
| string | no |
| Language of the title: any of the 24 official EU languages (Cellar 3-letter code) |
| number | no |
| Max results (1-50) |
| string | no | -- | Filter from this judgment date, format |
| string | no | -- | Filter up to this judgment date, format |
* Provide at least one of query, celex_id, ecli, or related_celex.
eurlex_transposition
List the national implementing measures (NIMs) EU member states enacted to transpose a directive into national law -- for transposition and compliance tracking. Each result gives the member state, the national measure's title (in that state's own official language, not translated), its date, the sector-7 NIM CELEX, and a EUR-Lex URL. total_found reports the full count; results is capped at limit. Regulations and decisions generally have no NIMs.
Parameter | Type | Required | Default | Description |
| string | yes | -- | Sector-3 CELEX of the directive, e.g. |
| string | no | -- | Filter by EU 2-letter member-state code (ISO 3166-1 alpha-2, except Greece = |
| string | no |
| Sets the locale of each |
| number | no |
| Max measures returned (1-100) |
eurlex_structure
Return the outline (table of contents) of an act -- its chapters, sections, articles, and annexes -- each with a character offset into the document's plain text. Use it as a map for targeted reading: read an article's offset, then call eurlex_fetch(celex_id, format:"plain", offset, max_chars) to jump straight to that article. Pass the same language to the follow-up fetch and keep format:"plain" -- offsets are language- and plain-text-specific. Heading recognition covers English, German, and French. For case-law documents (CELEX sector 6, e.g. CJEU judgments) the outline additionally lists each numbered judgment paragraph as "Paragraph N" (level 4); numbered-paragraph detection is language-independent (it keys on the paragraph number, not heading words), so you can get the offset of e.g. paragraph 72 of a judgment and jump eurlex_fetch straight to it. Each outline entry has level (1=part/title/annex, 2=chapter, 3=section, 4=article/paragraph), label (e.g. "Article 5", "Paragraph 72"), title, and offset; total_headings is the full count and the list is capped at 300 for very large acts (truncated=true).
Parameter | Type | Required | Default | Description |
| string | no* | -- | CELEX identifier, e.g. |
| string | no* | -- | European Legislation Identifier, short or full form; resolved to a CELEX via Cellar |
| string | no* | -- | Post-2023 Official Journal reference, e.g. |
| string | no |
| Language of the document to outline (Cellar 3-letter code); heading labels and offsets are language-specific |
* Provide exactly one of celex_id, eli, or oj_ref.
eurlex_summary
Return the EU's own plain-language "summary of legislation" (LEGISSUM) for an act -- a good quick overview before reading the full legal text. Paginated like eurlex_fetch (offset/max_chars/next_offset). total_summaries is 0 when no summary exists (many acts have none); when several exist, the primary summary's text is returned and the rest are listed in other_summaries.
Parameter | Type | Required | Default | Description |
| string | yes | -- | CELEX of the act to summarize, e.g. |
| string | no |
| Language of the summary (Cellar 3-letter code); summaries are typically available in all 24 languages |
| number | no |
| Max characters returned per call (1000-50000) |
| number | no |
| Character offset into the processed summary, for pagination |
eurlex_sparql
Expert escape hatch: run a raw, read-only SPARQL query directly against the Cellar endpoint for questions the other tools cannot express. Requires knowledge of the CDM ontology -- see the eurlex_guide prompt for a property cheat sheet. Read-only: only SELECT and ASK are accepted; SPARQL Update and federated SERVICE clauses are rejected. A SELECT with no top-level LIMIT gets LIMIT 50 appended; a top-level LIMIT above 100 is rejected. The response carries vars/bindings (SELECT) or boolean (ASK) plus row_count, returned_rows, and a truncated flag (bindings are dropped whole to stay within a ~40,000-char budget).
Parameter | Type | Required | Default | Description |
| string | yes | -- | A raw SPARQL 1.1 |
CELEX Number Schema
CELEX identifiers uniquely identify EU legal documents. The format is:
[sector][year][type][number]Sector (1 digit):
3= legislation,6= case law,7= national transposition measures (the sectors these tools cover)Year (4 digits): year of the document
Type (1-2 letters):
R= regulation,L= directive,D= decision,J= judgment, etc.Number: sequential number
Examples:
CELEX | Document |
| AI Act (Regulation 2024/1689) |
| GDPR (Regulation 2016/679) |
| Digital Services Act (Regulation 2022/2065) |
| Court of Justice case C-131/14 |
Development
Setup
git clone https://github.com/Honeyfield-Org/eurlex-mcp-server.git
cd eurlex-mcp-server
pnpm install
pnpm buildCommands
Command | Description |
| Start dev server with hot reload |
| Compile TypeScript |
| Run unit tests |
| Run tests in watch mode |
| Run integration tests (hits real API) |
| Start production server |
Testing
pnpm test # unit tests
pnpm test:integration # integration tests (hits real API)
pnpm test:integration tests/integration/effectDates.integration.test.ts # one file — no "--"Limitations
Rate limits: The EUR-Lex Cellar API is public but may throttle excessive requests.
Document availability: Not all documents have full text in all languages.
Consolidated versions: Only available for regulations, directives, and decisions.
Response size: Full text is returned per call in
max_charsslices (default 20,000 characters) to stay within LLM context limits -- useoffset/next_offsetoneurlex_fetch/eurlex_consolidated/eurlex_summaryto read the rest.SPARQL timeouts: Complex queries may occasionally time out on the Cellar endpoint despite the built-in retry with backoff; narrow broad
eurlex_search/eurlex_by_eurovocqueries withresource_typeor date filters if this happens.Search ordering:
eurlex_searchresults are sorted newest-first within the fetched sample only -- for very broad queries this is not guaranteed to be the single globally newest match.
Troubleshooting
invalid outputSchema: JSON Schema declares an unsupported dialect ("$schema": ".../draft-07/schema#")
Some MCP client builds (Claude Desktop, Cowork, Claude Code releases that bundle a
pre-release @modelcontextprotocol/client 2.0.0-alpha/beta) reject every tool call with:
Error: Tool '<name>' has an invalid outputSchema: JSON Schema declares an unsupported
dialect ("$schema": "http://json-schema.org/draft-07/schema#"). The default validator
supports JSON Schema 2020-12 only; ...The error fires inside the client before any request reaches this server. Since
v2.4.0 the server omits the $schema key from its tool schemas, which every client
accepts (a schema without $schema is read as 2020-12 per the MCP spec). If you still see
the error you are running an older server build: npx caches versions, so use
npx -y eurlex-mcp-server@latest, or pull the current Docker image. Background: this
repo's issue #49; the client-side check was relaxed upstream in
@modelcontextprotocol/client 2.0.0 (modelcontextprotocol/typescript-sdk#2532).
Contributing
See CONTRIBUTING.md for development setup, architecture overview, and submission guidelines.
License
Available Tools
11 toolseurlex_by_eurovocARead-onlyIdempotent
Searches EU legal acts by EuroVoc thematic concept — the right tool for "documents about X" when the term may not appear in the title. Accepts a concept label in any official EU language (e.g. "artificial intelligence") or a EuroVoc URI; label resolution automatically falls back across all 24 official EU languages if the request language has no match, so the example works regardless of the default language.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results | |
| concept | Yes | EuroVoc concept: a label (e.g. 'artificial intelligence') or a URI (e.g. 'http://eurovoc.europa.eu/4424') | |
| language | No | Language of the title and EuroVoc labels, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA) | ENG |
| resource_type | No | Document type filter | any |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Number of results in `results` |
| results | Yes | Acts tagged with the EuroVoc concept |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, and the description adds a non-obvious behavioral detail: label resolution automatically falls back across all 24 official EU languages. This extra transparency is useful and does not contradict any annotations. No side effects or rate limits are mentioned, but none are expected for a read-only search.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured paragraph that is concise yet informative. It front-loads the core purpose, then adds a use case, an example, and a key behavior. No redundant or filler content is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides enough context for a user to call the tool correctly. It mentions the concept input, language fallback, and the fact that it searches by EuroVoc. Since the context signals indicate an output schema exists, the description is not required to detail return values. The description is complete for the tool's intended use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all parameters (concept, language, resource_type, limit) with descriptions. The description adds clarifying examples ('artificial intelligence', a EuroVoc URI) and explains the language fallback behavior for the `language` parameter. This goes beyond the schema's basic descriptions, providing practical guidance on how to construct valid queries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Searches EU legal acts by EuroVoc thematic concept'. It also gives a specific use case ('documents about X' when the term may not appear in the title) and provides a concrete example ('artificial intelligence'). This distinguishes it from sibling search tools and leaves no ambiguity about its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly identifies the tool as 'the right tool for "documents about X" when the term may not appear in the title', giving a clear condition for use. It also explains the language fallback behavior, which helps the user understand how to supply the concept. It does not explicitly mention alternatives or when not to use it, but the guidance is sufficient for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_case_lawARead-onlyIdempotent
Finds Court of Justice of the EU (CJEU) case law — judgments (JUDG), orders (ORDER), and Advocate General opinions (OPIN_AG) of the Court of Justice and the General Court. Look up rulings four ways (at least one required, combinable): query=title/party substring (e.g. "Schrems"), celex_id=a sector-6 CELEX (e.g. "62012CJ0131"), ecli=a European Case Law Identifier (e.g. "ECLI:EU:C:2014:317"), or related_celex=a legal act's CELEX (e.g. "32016R0679") to get the case law interpreting that act. Narrow with court (COURT_JUSTICE/GENERAL_COURT), type, language, and date_from/date_to. Unlike eurlex_search (which searches legislation by title), this tool is scoped to case law and understands ECLIs and act-to-case-law relations. Each hit returns celex, ecli, title, date, type, and eurlex_url.
| Name | Required | Description | Default |
|---|---|---|---|
| ecli | No | European Case Law Identifier, e.g. "ECLI:EU:C:2014:317" (Google Spain). | |
| type | No | Procedure type filter: JUDG=judgment, ORDER=court order, OPIN_AG=Advocate General opinion, any=all case-law document types (incl. procedural notices). | any |
| court | No | Court filter: COURT_JUSTICE=Court of Justice, GENERAL_COURT=General Court, any=both. | any |
| limit | No | Maximum number of results | |
| query | No | Title substring to search for among case law, e.g. "Schrems" or a party name. Matched as a contiguous phrase, case-insensitive. Note: CJEU titles begin with a boilerplate prefix ("Judgment of the Court …"); party names appear after it. | |
| date_to | No | Filter up to this judgment date, format YYYY-MM-DD | |
| celex_id | No | Sector-6 CELEX identifier of a specific ruling, e.g. "62012CJ0131" (Google Spain). | |
| language | No | Language of the title, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA). A ruling with no title in this language yields no result. | ENG |
| date_from | No | Filter from this judgment date onward, format YYYY-MM-DD | |
| related_celex | No | CELEX of a legal act (e.g. "32016R0679" for the GDPR); returns the case law that interprets that act. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Number of entries in `results` |
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already provide readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds useful behavioral context such as how query matching works (contiguous phrase, case-insensitive, boilerplate prefix) and that rulings without a title in the selected language yield no result. This goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, with the main purpose first and parameter-specific guidance following. Every sentence adds value, with examples and clarifications that are useful without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and is rich, the description does not need to explain return values. It provides comprehensive guidance on all parameters, explains edge cases (language availability, query prefix behavior), and differentiates from sibling tools, making it complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description adds significant semantic detail beyond the schema, including clear examples for ecli, celex_id, related_celex, explains the query matching behavior and the meaning of type/court enums, and notes the language limitation. The description adds value beyond the already thorough schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds CJEU case law and explicitly distinguishes it from eurlex_search which searches legislation. It specifies the resource (CJEU case law) and the action (finds), and differentiates from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool versus alternatives, stating 'Unlike eurlex_search (which searches legislation by title), this tool is scoped to case law and understands ECLIs and act-to-case-law relations.' This clearly signals the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_citationsARead-onlyIdempotent
Finds citation relationships for an EU legal act: cites, cited_by, amends/amended_by, based_on/basis_for, repeals/repealed_by. direction="both" runs a balanced split so recent cited_by entries cannot crowd out cites results; the response's counts field reports how many of each side were found. The limit is divided evenly between the two directions and is not back-filled from the richer side, so direction="both" can return fewer than limit total results even when one side has more matches available.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results | |
| celex_id | Yes | CELEX identifier, e.g. '32024R1689' | |
| language | No | Language of the title, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA) | ENG |
| direction | No | Direction: cites=acts referenced by this document, cited_by=acts referencing this document, both=a balanced split of both directions | both |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Number of entries in `citations` |
| counts | Yes | How the returned citations split across the two directions |
| celex_id | Yes | The act whose citations were queried |
| citations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, idempotentHint), the description reveals additional behavioral nuances: the balanced split ensures recent cited_by entries do not crowd out cites, the response includes a counts field, and the limit is not back-filled. These details are not present in the annotations and help set expectations for the response shape and edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the main purpose, then elaborates on the direction behavior. However, there is some redundancy: the balanced split and counts field are described, then repeated with alternative wording about the limit division. This repetition adds a bit of bloat but does not obscure meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's core behavior, including defaults, edge cases (fewer results when balanced), and a key response field (counts). The context signals indicate an output schema is available, which would supply the full response structure. Overall, the description is sufficient to call the tool correctly without missing critical information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter has a descriptive entry, including enum values and defaults. The description adds a little extra context for the 'direction' parameter (e.g., explaining the balanced split in more narrative form), but it largely echoes the parameter descriptions. Since the schema already carries the semantic weight, the additional description provides only marginal value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Finds') and the resource ('citation relationships for an EU legal act'), distinguishing it from sibling tools like eurlex_search or eurlex_metadata. It also specifies the key directional options and the balanced split behavior, making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong contextual cues about when to use the tool (e.g., when citation relationships are needed) and explains the behavior of the 'direction' parameter, including the balanced split and potential reduction in results. It does not explicitly name alternative tools or exclusion criteria, but the detail is sufficient for a typical caller to decide when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_consolidatedARead-onlyIdempotent
Fetches the latest consolidated (currently in-force) version of an EU legal act via ELI, with all amendments merged in. Identify the act with celex_id (e.g. "32016R0679") OR with doc_type + year + number — provide exactly one of the two. celex_id must be a sector-3 secondary-law CELEX (3YYYY[R|L|D]NNNN).
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | Year of the act, e.g. 2024. Required together with doc_type and number when celex_id is not used. | |
| format | No | Output format: xhtml=structured XHTML, plain=text with XHTML tags stripped | xhtml |
| number | No | Document number, e.g. 1689. Required together with doc_type and year when celex_id is not used. | |
| offset | No | Character offset for pagination (0-based) | |
| celex_id | No | CELEX ID of the original act, e.g. "32016R0679" (GDPR). Alternative to doc_type + year + number — provide exactly one of the two input forms. Must be a sector-3 secondary-law CELEX (pattern 3YYYY[R|L|D]NNNN). | |
| doc_type | No | Document type: reg=regulation, dir=directive, dec=decision. Alternative to celex_id — provide together with year and number. | |
| language | No | Language of the returned text, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA) | ENG |
| max_chars | No | Maximum number of characters returned |
Output Schema
| Name | Required | Description |
|---|---|---|
| year | Yes | |
| number | Yes | |
| offset | Yes | The offset this window was sliced from |
| content | Yes | The consolidated text in the requested window/format |
| eli_url | Yes | ELI URL of the consolidated act |
| doc_type | Yes | |
| language | Yes | |
| truncated | Yes | True when more text remains beyond this window |
| next_offset | Yes | Offset to request next, or null when there is no more content |
| total_chars | Yes | Length of the full processed document |
| returned_chars | Yes | Length of `content` |
| consolidated_celex | Yes | Resolved consolidated CELEX, e.g. "02016R0679-20160504" |
| consolidation_date | Yes | ISO date from the CELEX "-YYYYMMDD" suffix, or null when absent |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, idempotentHint, and destructiveHint=false, establishing safety. The description adds that it merges amendments, which is a behavioral detail. It does not mention pagination or error behavior, but those are not required given the strong annotation coverage. No contradictions with annotations are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences with no filler. It front-loads the main action, then explains identification requirements and the CELEX pattern. Every sentence contributes useful information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (8 parameters, two mutually exclusive input forms), the description covers the essential usage constraints and the output context is handled by the existing output schema. It does not need to explain return values because an output schema is present. The description is complete for an agent to correctly invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of parameters, including enums and patterns. The description adds the key constraint that celex_id and doc_type+year+number are mutually exclusive ('provide exactly one of the two') and clarifies the CELEX format as '3YYYY[R|L|D]NNNN,' which goes beyond the schema pattern. This enhances the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it 'Fetches the latest consolidated (currently in-force) version of an EU legal act via ELI, with all amendments merged in.' It uses a specific verb and resource, and the title 'Get consolidated EU legal act' reinforces the purpose. It is distinguishable from siblings like eurlex_fetch or eurlex_metadata, which focus on other aspects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete usage guidance by specifying the two identification forms (celex_id or doc_type+year+number) and the requirement to 'provide exactly one of the two.' It also explains the CELEX pattern. However, it does not explicitly contrast with sibling tools (e.g., when to use this vs. eurlex_fetch for non-consolidated versions), which would make the guidance more explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_fetchARead-onlyIdempotent
Fetches the full text of an EU legal act. Identify it by celex_id (e.g. "32024R1689"), by eli (e.g. "reg/2016/679" or a full ELI URL), or by oj_ref (post-2023 Official Journal reference, e.g. "OJ:L_202401689") — provide exactly one. Paginate long documents with offset and max_chars: pass the previous response's next_offset to continue reading until it is null.
| Name | Required | Description | Default |
|---|---|---|---|
| eli | No | European Legislation Identifier (ELI), short or full form, e.g. "reg/2016/679" or "http://data.europa.eu/eli/reg/2016/679/oj" (GDPR). Resolved to a CELEX ID via Cellar. Provide exactly one of celex_id, eli, or oj_ref. | |
| format | No | Output format: xhtml=structured XHTML, plain=text with XHTML tags stripped | xhtml |
| offset | No | Character offset for pagination (0-based) | |
| oj_ref | No | Official Journal reference in the post-2023 scheme, e.g. "OJ:L_202401689" (AI Act). Resolved to a CELEX ID via Cellar. Provide exactly one of celex_id, eli, or oj_ref. | |
| celex_id | No | CELEX identifier, e.g. "32024R1689" (AI Act). Provide exactly one of celex_id, eli, or oj_ref. | |
| language | No | Language of the full text, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA) | ENG |
| max_chars | No | Maximum number of characters returned |
Output Schema
| Name | Required | Description |
|---|---|---|
| offset | Yes | The offset this window was sliced from |
| content | Yes | The document text in the requested window/format |
| celex_id | Yes | The resolved CELEX ID the text was fetched for |
| language | Yes | Cellar 3-letter language code of the text |
| truncated | Yes | True when more text remains beyond this window |
| source_url | Yes | Cellar REST URL of the fetched resource |
| next_offset | Yes | Offset to request next, or null when there is no more content |
| total_chars | Yes | Length of the full processed document |
| returned_chars | Yes | Length of `content` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is consistent with the readOnlyHint, idempotentHint, and destructiveHint annotations, but it does not add any behavioral context beyond those annotations (e.g., no side effects, no rate limits, no error behavior). Since annotations already cover the safety profile, this is adequate but not enhanced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, tightly packed with essential operational details (identifier selection, pagination) and contains no extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the detailed output schema and high parameter coverage, the description provides sufficient context for invocation: identifier selection, pagination, and format choice. No critical information is missing for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of parameters, so baseline is 3. The description adds extra clarity on pagination semantics (pass previous next_offset) and the mutual exclusivity of identifier parameters, which exceeds the schema-only information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches the full text of an EU legal act, and identifies the three mutually exclusive identifier options (celex_id, eli, oj_ref). This is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on pagination (using offset and max_chars, passing next_offset) and insists on providing exactly one identifier. However, it does not explicitly compare against sibling tools (e.g., eurlex_summary, eurlex_metadata) to indicate when this tool is preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_metadataARead-onlyIdempotent
Fetches metadata for an EU legal act: dates (document, entry into force, application, end of validity, transposition), in-force status, authors, legal basis (CELEX IDs of the acts it is based on), EuroVoc descriptors, and directory codes. date_entry_into_force and date_application are distinct (e.g. the GDPR entered into force on 2016-05-24 but applies from 2018-05-25); dates_effect lists every effect date with its type. Identify the act by celex_id (e.g. "32024R1689"), by eli (e.g. "reg/2016/679" or a full ELI URL), or by oj_ref (post-2023 Official Journal reference, e.g. "OJ:L_202401689") — provide exactly one.
| Name | Required | Description | Default |
|---|---|---|---|
| eli | No | European Legislation Identifier (ELI), short or full form, e.g. "reg/2016/679" or "http://data.europa.eu/eli/reg/2016/679/oj" (GDPR). Resolved to a CELEX ID via Cellar. Provide exactly one of celex_id, eli, or oj_ref. | |
| oj_ref | No | Official Journal reference in the post-2023 scheme, e.g. "OJ:L_202401689" (AI Act). Resolved to a CELEX ID via Cellar. Provide exactly one of celex_id, eli, or oj_ref. | |
| celex_id | No | CELEX identifier, e.g. "32024R1689" (AI Act). Provide exactly one of celex_id, eli, or oj_ref. | |
| language | No | Language of the title and EuroVoc labels, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA) | ENG |
Output Schema
| Name | Required | Description |
|---|---|---|
| title | Yes | |
| authors | Yes | |
| celex_id | Yes | |
| in_force | Yes | In-force status, or null when unknown |
| eurlex_url | Yes | |
| legal_basis | Yes | CELEX IDs of the acts this act is based on |
| dates_effect | Yes | All entry-into-force and application dates Cellar holds for the act, ascending, each with its type and article note. Empty when Cellar holds none. |
| date_document | Yes | ISO date, or null when absent |
| resource_type | Yes | |
| directory_codes | Yes | Directory-code entries as "{code}: {label}", or the bare code when unlabelled |
| date_application | Yes | ISO date from which the act (or its remaining provisions) applies, or null when the act has no separate application date or the type could not be determined |
| eurovoc_concepts | Yes | |
| date_transposition | Yes | ISO date, or null when absent |
| date_end_of_validity | Yes | ISO date, or null when absent or the open-ended 9999-12-31 sentinel |
| date_entry_into_force | Yes | ISO date the act entered into force, or null when absent. Distinct from date_application: e.g. the GDPR entered into force on 2016-05-24 but applies from 2018-05-25. See dates_effect for every date Cellar holds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is transparent about the resolution behavior ('Resolved to a CELEX ID via Cellar') and it is consistent with the readOnlyHint, idempotentHint, and destructiveHint annotations. It does not hide side effects or claim mutating behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well organized and informative, but it repeats 'Provide exactly one of celex_id, eli, or oj_ref' in each identifier parameter description. This is a minor redundancy rather than a structural problem.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema is available, the description does not need to enumerate return fields. It covers all invocation inputs, gives realistic examples, and states the language default, making it sufficient for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all four parameters, and the description adds valuable meaning: concrete examples for each identifier type, the exact-one-of constraint, and clarification that language controls title and EuroVoc labels. This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Fetches metadata for an EU legal act', which is a specific verb and resource. It clearly enumerates the metadata types (dates, in-force status, authors, legal basis, EuroVoc descriptors, directory codes) and distinguishes this from a full-text fetch or search tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on how to invoke the tool: identify an act by celex_id, eli, or oj_ref and provide exactly one, with optional language. It does not explicitly name sibling tools or state when not to use it, but the lookup semantics are sufficiently clear from the wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_searchARead-onlyIdempotent
Searches EU legal acts by title substring (contiguous phrase, case-insensitive — not tokenized full-text search). For topic-based discovery use eurlex_by_eurovoc instead. Broad single-word terms can be slow; narrow with resource_type or date_from/date_to. Supports all 24 official EU languages (pass the Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA); match the query term to the chosen language. Results are newest-first within the fetched sample, not necessarily the globally newest match for very broad queries.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results | |
| query | Yes | Title substring to search for, e.g. "artificial intelligence high risk". Matched as a contiguous phrase, case-insensitive. | |
| date_to | No | Filter up to this date, format YYYY-MM-DD | |
| language | No | Language of the title and full text, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA) | ENG |
| date_from | No | Filter from this date onward, format YYYY-MM-DD | |
| resource_type | No | Document type filter: REG=regulation, DIR=directive, DEC=decision, JUDG=judgment, REG_IMPL=implementing regulation, REG_DEL=delegated regulation, RECO=recommendation, ORDER=court order, OPIN_AG=Advocate General opinion | any |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Number of results in `results` |
| results | Yes | Matching acts, newest-first within the sample |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses behavior beyond the annotations: it explains that matching is a contiguous, case-insensitive phrase (not tokenized full-text), and that results are newest-first within the fetched sample, not necessarily globally newest for broad queries.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct yet information-dense, consisting of multiple short clauses that cover the main purpose, usage caveats, language support, and result ordering without unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and the detailed parameter descriptions, the tool description is complete for an agent to decide when and how to use it, including performance hints and result ordering nuances.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already provides descriptions for all parameters, the description adds extra semantic clarity, such as instructing users to match the query term to the chosen language and explaining that language applies to both title and full text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches EU legal acts by title substring, and explicitly differentiates it from eurlex_by_eurovoc for topic-based discovery. The verb and resource are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance on when to use this tool versus the alternative (topic-based discovery via eurlex_by_eurovoc) and advises narrowing broad queries with resource_type or date filters to avoid slow performance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_sparqlARead-onlyIdempotent
Expert escape hatch: run a raw, read-only SPARQL 1.1 query directly against the EU Publications Office (Cellar) endpoint when the higher-level tools (eurlex_search, eurlex_metadata, eurlex_citations, eurlex_case_law, eurlex_transposition, eurlex_summary, …) cannot express what you need. Requires knowledge of the CDM ontology — READ THE eurlex_guide PROMPT FIRST for the property cheat sheet (celex, title, language, dates, citations, case law, transposition, summaries). Only SELECT and ASK are allowed; SPARQL Update (INSERT/DELETE/…) and federated SERVICE clauses are rejected before the query is sent. A SELECT with no top-level LIMIT gets LIMIT 50 appended (set limit_added); a top-level LIMIT above 100 is rejected. The response mirrors SPARQL JSON — vars + bindings for SELECT, boolean for ASK — plus row_count and a truncated flag (whole rows are dropped past ~40k characters). CELEX/ELI literals are typed xsd:string, so match them with FILTER(STR(?x) = "..."). Example: PREFIX cdm: http://publications.europa.eu/ontology/cdm# SELECT ?celex WHERE { ?w cdm:resource_legal_id_celex ?celex . FILTER(STR(?celex) = "32016R0679") } LIMIT 1
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | A raw SPARQL 1.1 query against the EU Publications Office (Cellar) endpoint. Read-only: only SELECT and ASK are accepted (SPARQL Update and federated SERVICE clauses are rejected). If a SELECT has no top-level LIMIT one is appended automatically; a top-level LIMIT above 100 is rejected. Uses the CDM ontology — see the eurlex_guide prompt for the property cheat sheet. Example: PREFIX cdm: <http://publications.europa.eu/ontology/cdm#> SELECT ?celex WHERE { ?w cdm:resource_legal_id_celex ?celex . FILTER(STR(?celex) = "32016R0679") } LIMIT 1 |
Output Schema
| Name | Required | Description |
|---|---|---|
| vars | No | Projected variable names (SELECT only) |
| boolean | No | ASK result (present only for ASK queries) |
| bindings | No | Raw SPARQL binding rows, possibly truncated (SELECT only) |
| row_count | Yes | Total rows the query returned; null for ASK |
| truncated | Yes | True when whole rows were dropped to fit the char budget |
| limit_added | No | Present (true) only when the tool auto-appended the default LIMIT |
| returned_rows | Yes | Rows included after char-budget truncation; null for ASK |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint/openWorldHint/idempotentHint/destructiveHint, and the description reinforces and expands on them: only SELECT/ASK are accepted, SPARQL Update and federated SERVICE are rejected, LIMIT is auto-appended or capped, and response truncation is described. The example and type note about xsd:string literals add concrete behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries meaningful operational detail; it is organized from purpose to constraints to output and example. It is slightly repetitive with the input schema description, but not padded enough to lose clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a raw query execution tool, the description covers what the tool does, when to use it, what queries are allowed, what happens with LIMIT, what the response looks like (SPARQL JSON, row_count, truncated flag), and how to correctly compare CELEX/ELI literals. An agent has enough information to use it correctly without external context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single query parameter is thoroughly documented: it includes min/max lengths, restrictions on query forms, the automatic LIMIT behavior, the CDM ontology context, a concrete example query, and the CELEX/ELI string-matching caveat. This goes far beyond the schema's basic property description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('run a raw, read-only SPARQL 1.1 query') and a specific resource ('EU Publications Office (Cellar) endpoint'). It explicitly frames itself as an escape hatch for when higher-level tools cannot express the need, distinguishing it from the sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use this when higher-level tools cannot express what is needed, and directs the agent to read the eurlex_guide prompt first for ontology knowledge. It also clearly states the allowed query forms, the automatic LIMIT behavior, and the rejection of UPDATE/SERVICE clauses.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_structureARead-onlyIdempotent
Returns the outline (table of contents) of an EU legal act — its chapters, sections, articles and annexes — each with a character offset into the document's plain text. Use it as a map for targeted reading: read an article's offset from the outline, then call eurlex_fetch(celex_id, format:"plain", offset, max_chars) with that offset to jump straight to that article instead of paging from the top of a long act. Identify the act by celex_id (e.g. "32024R1689"), eli, or oj_ref — provide exactly one. Each outline entry has: level (1=part/title/annex, 2=chapter, 3=section, 4=article), label (e.g. "Article 5", "CHAPTER III"), title (the heading's subtitle, e.g. "Prohibited AI practices"), and offset. total_headings is the full count; the returned list is capped at 300 for very large acts (truncated=true). Heading offsets are specific to the chosen language and to plain (tag-stripped) text — pass the SAME language to the follow-up eurlex_fetch call and keep format:"plain". Heading recognition covers English, German and French documents. For case-law documents (CELEX sector 6, e.g. CJEU judgments) the outline additionally lists each numbered judgment paragraph as "Paragraph N" (level 4); numbered-paragraph detection works in any language (it keys on the paragraph number, not heading words) — so you can get the offset of, say, paragraph 72 of a judgment and jump eurlex_fetch straight to it.
| Name | Required | Description | Default |
|---|---|---|---|
| eli | No | European Legislation Identifier (ELI), short or full form, e.g. "reg/2016/679" or "http://data.europa.eu/eli/reg/2016/679/oj" (GDPR). Resolved to a CELEX ID via Cellar. Provide exactly one of celex_id, eli, or oj_ref. | |
| oj_ref | No | Official Journal reference in the post-2023 scheme, e.g. "OJ:L_202401689" (AI Act). Resolved to a CELEX ID via Cellar. Provide exactly one of celex_id, eli, or oj_ref. | |
| celex_id | No | CELEX identifier, e.g. "32024R1689" (AI Act). Provide exactly one of celex_id, eli, or oj_ref. | |
| language | No | Language of the document to outline, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA). Heading labels are language-specific; the returned offsets index the plain text of THIS language, so pass the same language to the follow-up eurlex_fetch call. | ENG |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Present only when no headings were found or the outline was truncated |
| outline | Yes | Headings in document order |
| celex_id | Yes | The resolved CELEX ID (echoed for the follow-up eurlex_fetch) |
| language | Yes | |
| returned | Yes | Number of headings in `outline` (<= total_headings) |
| truncated | Yes | True when `outline` was capped below total_headings |
| source_url | Yes | |
| total_chars | Yes | Length of the plain text the offsets index into (matches eurlex_fetch total_chars) |
| total_headings | Yes | Total headings detected before the returned-list cap |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses language-specific offsets, the dependency on plain text, the 300-entry cap with truncation flag, and the heading-recognition coverage, all beyond the read-only annotation. It also explains the paragraph-number detection logic for judgments, giving the agent accurate expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is richly informative but remains focused, covering purpose, usage, and key behavioral details without extraneous content. It is structured with clear separators, making it easy to scan. Slight repetition of parameter constraints is minor and acceptable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's output structure, usage scenario, language handling, size limits, and case-law extensions, leaving no major gaps. It even specifies the follow-up call pattern, ensuring the agent knows how to apply the offsets.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While the schema already describes all parameters, the description adds the crucial note that offsets are language-specific and advises passing the same language to the follow-up fetch call. It also clarifies the relationship between celex_id, eli, and oj_ref, requiring exactly one, which is echoed but reinforced.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the outline (table of contents) of an EU legal act with character offsets, distinguishing it from other document tools. The verb 'returns' and the specific resource make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly advises using this tool as a map for targeted reading, telling the agent to read an article's offset and follow up with eurlex_fetch. This gives clear when-to-use guidance, including the special case of case-law paragraphs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_summaryARead-onlyIdempotent
Returns the EU's official plain-language summary (LEGISSUM) of a legal act — a short editorial overview written for non-lawyers ("what is the aim", "key points", "from when does it apply"), NOT the binding legal text. Input is the act's celex_id (e.g. "32016R0679" for the GDPR, "32022R2065" for the Digital Services Act) and a language (any of the 24 official EU languages; summaries are usually available in all of them). Output is the summary text (plain, HTML stripped) plus its LEGISSUM id, title, last-update date, an obsolete flag, and source_url (the EUR-Lex summary page). Long summaries paginate via max_chars/offset exactly like eurlex_fetch — pass the previous response's next_offset to continue. Several thousand major acts have a summary; many acts have none (you get a clear "no summary" message). When an act has several summaries the most current non-obsolete one is returned and the rest are listed in other_summaries. For the full legal text use eurlex_fetch; for structured metadata use eurlex_metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Character offset for pagination (0-based) | |
| celex_id | Yes | CELEX identifier of the EU act to summarize, e.g. "32016R0679" (GDPR) or "32022R2065" (Digital Services Act). LEGISSUM summaries exist for several thousand major acts; many acts have none. | |
| language | No | Language of the summary text, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA). Summaries are typically available in all 24 languages. | ENG |
| max_chars | No | Maximum number of characters returned |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | No | ISO date of the returned summary, or '' |
| title | No | |
| offset | No | The offset this window was sliced from |
| content | No | Summary text (plain, HTML stripped), sliced to window |
| celex_id | Yes | The act CELEX that was queried |
| language | Yes | |
| obsolete | No | True when the returned summary is flagged obsolete |
| truncated | No | True when more content remains beyond this window |
| source_url | No | EUR-Lex legislative-summary (LSU) page for the act |
| legissum_id | No | LEGISSUM id of the returned (primary) summary |
| next_offset | No | Offset to request next, or null when there is no more content |
| total_chars | No | Length of the full processed summary |
| returned_chars | No | Length of `content` |
| other_summaries | No | Other summaries for the same act (present only when total_summaries > 1) |
| total_summaries | Yes | Total LEGISSUM summaries linked to this act; 0 means none was found |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description aligns with the annotations (readOnlyHint, idempotentHint, destructiveHint) and adds behavioral details not covered by annotations: pagination behavior ('pass the previous response's next_offset to continue'), selection of the most current summary, and the 'no summary' message. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured paragraph that leads with purpose, then input/output details, pagination, edge cases, and ends with alternative tools. It contains no redundancy and all information is directly relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the full context: input format, output contents (summary text, id, title, date, flag, source_url, other_summaries), pagination, edge cases (no summary, multiple summaries), and sibling tools. It is complete for an agent to know when and how to use this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All four parameters (celex_id, language, offset, max_chars) are explained in the schema. The description adds semantic layer: celex_id examples, language availability across 24 EU languages, and pagination 'exactly like eurlex_fetch'. This enriches the schema descriptions, which already had 100% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's function: 'Returns the EU's official plain-language summary (LEGISSUM) of a legal act'. It distinguishes this from the binding legal text and explicitly contrasts with sibling tools (eurlex_fetch for full text, eurlex_metadata for metadata), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: 'For the full legal text use eurlex_fetch; for structured metadata use eurlex_metadata.' It also explains when no summary is available and that the most current non-obsolete summary is returned, giving clear conditions for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurlex_transpositionARead-onlyIdempotent
Lists the national implementing measures (NIMs) EU member states enacted to transpose a given EU directive into national law — the answer to "how did member state X implement directive Y" for transposition and compliance tracking. Input celex_id is the directive's sector-3 CELEX (e.g. "32022L2555" for NIS2, "31995L0046" for the Data Protection Directive); optionally filter by country (2-letter member-state code, e.g. "DE"). Each result gives the member state, the national measure's title (in that state's own official language — not translated), its date, the sector-7 NIM CELEX reference, and a EUR-Lex URL. total_found reports the full count; results is capped at limit. For the directive itself use eurlex_fetch/eurlex_metadata; regulations and decisions have no NIMs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of measures to return (1–100). The response also reports total_found (the full count). | |
| country | No | Optional filter: EU 2-letter member-state code (ISO 3166-1 alpha-2, except Greece which is "EL" in EU usage), e.g. "DE", "AT", "FR". Omit to return measures from all member states. | |
| celex_id | Yes | Sector-3 CELEX of the EU directive whose national transposition measures you want, e.g. "32022L2555" (NIS2) or "31995L0046" (Data Protection Directive). Member states transpose directives (CELEX type letter L); regulations and decisions generally have no national implementing measures. | |
| language | No | Sets the locale of each result's eurlex_url (as a Cellar 3-letter code, any of the 24 official EU languages). NOTE: a national implementing measure's title is stored only in the member state's own official language and is returned as-is — this field does NOT translate titles. | ENG |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| celex_id | Yes | The directive CELEX that was queried |
| returned | Yes | Number of measures in `results` (<= limit) |
| total_found | Yes | Full number of matching measures; when > returned, `results` was truncated |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavior beyond the annotations: it discloses that titles are returned as-is in the member state's own language, that total_found reports the full count while results are capped, and that omitting country returns all member states. These details complement the readOnlyHint and idempotentHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is comprehensive yet tightly structured, with no redundant sentences. Each sentence conveys a distinct fact (purpose, input, filter, output, language caveat, exclusions). It is long but every part is informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 parameters, enums, output schema), the description provides all necessary context: what the response contains (total_found, results), how filters behave, examples for celex_id, and clear boundaries versus sibling tools. Nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description enriches each parameter: celex_id includes pattern and examples, country explains the EU-specific 'EL' exception, language clarifies it does not translate titles, and limit is described in the schema. The description adds real semantic value beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists national implementing measures for a given EU directive, phrased as the answer to a concrete question. It distinguishes from siblings by noting that regulations/decisions have no NIMs and directing the directive itself to eurlex_fetch/eurlex_metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly guides when to use this tool (transposition/compliance tracking) and when not to (regulations/decisions; directive itself via other tools). It also clarifies the optional country filter and the language field's non-translation caveat.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v2.4.2- Changed
eurlex_by_eurovoc2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - removed
Output schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#"
- Changed
eurlex_case_law2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - removed
Output schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#"
- Added
eurlex_citations - Added
eurlex_consolidated - Changed
eurlex_fetch2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - removed
Output schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#"
- Added
eurlex_metadata - Added
eurlex_search - Added
eurlex_sparql - Changed
eurlex_structure2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - removed
Output schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#"
- Changed
eurlex_summary2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - removed
Output schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#"
- Changed
eurlex_transposition2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - removed
Output schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#"
11 tool updates
v2.3.0- Changed
eurlex_by_eurovoc1 field changed- changed
Input schema / properties / language / defaultPrevious value: -"DEU"New value: +"ENG"
- Changed
eurlex_case_law1 field changed- changed
Input schema / properties / language / defaultPrevious value: -"DEU"New value: +"ENG"
- Removed
eurlex_citations - Removed
eurlex_consolidated - Changed
eurlex_fetch1 field changed- changed
Input schema / properties / language / defaultPrevious value: -"DEU"New value: +"ENG"
- Removed
eurlex_metadata - Removed
eurlex_search - Removed
eurlex_sparql - Changed
eurlex_structure1 field changed- changed
Input schema / properties / language / defaultPrevious value: -"DEU"New value: +"ENG"
- Changed
eurlex_summary1 field changed- changed
Input schema / properties / language / defaultPrevious value: -"DEU"New value: +"ENG"
- Changed
eurlex_transposition1 field changed- changed
Input schema / properties / language / defaultPrevious value: -"DEU"New value: +"ENG"
11 tool updates
v2.2.0- First observed
eurlex_by_eurovoc - First observed
eurlex_case_law - First observed
eurlex_citations - First observed
eurlex_consolidated - First observed
eurlex_fetch - First observed
eurlex_metadata - First observed
eurlex_search - First observed
eurlex_sparql - First observed
eurlex_structure - First observed
eurlex_summary - First observed
eurlex_transposition
TDQS
Scored across 11 tools
Each tool targets a distinct operation: searching, fetching full text, metadata, citations, EuroVoc search, consolidated versions, case law, transposition, structure, summaries, and raw SPARQL. Even the search-like tools (search, by_eurovoc, case_law) are clearly separated by scope and documented with explicit use cases.
All tools share the consistent 'eurlex_' prefix and mostly use clear verb-like descriptors (search, fetch, metadata, citations, structure, summary, sparql). A few names are noun-phrases rather than verbs (by_eurovoc, case_law, transposition, consolidated), but the pattern is predictable and unambiguous.
Eleven tools is well-suited to the breadth of EUR-Lex data: covering search, retrieval, metadata, relationships, case law, transposition, structure, summaries, and an expert SPARQL escape hatch. No redundant tools; each earns its place.
The toolset covers the full lifecycle of accessing EU legal acts: discovery (search, EuroVoc), retrieval (fetch, consolidated), metadata, relationships (citations), specialized domains (case law, transposition, summaries), and structural navigation (structure). The raw SPARQL endpoint fills any remaining gaps, making the surface effectively complete.
Maintenance
Related MCP Connectors
Search EU legislation, CJEU case law, and treaties; traverse CELLAR graph; browse EuroVoc concepts.
Temporal search and comparison for official Luxembourg and reviewed EU law, with provenance.
Official EUR-Lex, UK, US, and gazette search, metadata fetch, and change-only watches.
Resolve, search and verify legal citations against the official sources, with provenance.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables searching and quoting EU legislation with verifiable EUR-Lex citations, including GDPR, NIS2, DORA, and the EU AI Act.3 npmMIT
- AlicenseNot gradedqualityFmaintenanceProvides structured access to EU treaties, regulations, directives, and CJEU case law via 14 tools for searching, retrieving, and analyzing legislation and court decisions.Apache 2.0

LexAPI MCPofficial
AlicenseAqualityCmaintenanceEnables querying EU legal documents, case law, and citation graphs through natural language using the LexAPI.1025 npm3MIT- AlicenseAqualityDmaintenanceEnables querying and analyzing Spanish (BOE) and EU (EUR-Lex) legal documents, with advanced search, PDF extraction, and cross-reference detection.847 npm2MIT