Skip to main content
Glama

eurlex-mcp-server

CI npm version License: MIT Node.js MCP

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 as Paragraph 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/ASK queries directly against Cellar for questions the other tools can't express

  • Consolidated 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 null instead of Cellar's 9999-12-31 sentinel for open-ended validity), in-force status, authors, legal basis, EuroVoc descriptors, and directory codes

  • Flexible identifiers -- eurlex_fetch, eurlex_metadata, and eurlex_structure accept 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 structuredContent payload validated against a published outputSchema, alongside the JSON text block

  • Offset-based pagination -- eurlex_fetch, eurlex_consolidated, and eurlex_summary return next_offset so long documents can be read in successive calls

  • All 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-server

Or with npx:

npx -y eurlex-mcp-server

Configuration

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-server

VS 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=DEU

For 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

MCP_ALLOWED_HOSTS

no (but strongly recommended for public deployments)

Comma-separated list of allowed Host header values. Must match the header exactly, including the port if the server isn't reachable on the default HTTP(S) port.

MCP_ALLOWED_ORIGINS

no

Comma-separated list of allowed Origin header values. Only enforced when MCP_ALLOWED_ORIGINS is set together with MCP_ALLOWED_HOSTS.

EURLEX_DEFAULT_LANGUAGE

no

Default language (Cellar 3-letter code, case-insensitive) used when a tool call omits language; unset or invalid falls back to ENG. Read once at startup and applied to all sessions. Also honored under stdio -- see Default language.

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.at

This 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

eurlex_search

Title-substring search over legislation

eurlex_fetch

Full text of an act (by CELEX / ELI / OJ reference)

eurlex_metadata

Structured metadata for an act

eurlex_citations

Citation graph (cites / cited-by / amends / …)

eurlex_by_eurovoc

Thematic search by EuroVoc concept

eurlex_consolidated

Latest in-force consolidated text

eurlex_case_law

CJEU judgments, orders, and AG opinions

eurlex_transposition

National transposition measures for a directive

eurlex_structure

Document outline with plain-text offsets

eurlex_summary

Plain-language LEGISSUM summary

eurlex_sparql

Raw read-only SPARQL escape hatch

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

query

string

yes

--

Title substring to match (3-500 chars), e.g. "artificial intelligence high risk"

resource_type

string

no

"any"

Document type filter: REG, DIR, DEC, JUDG, REG_IMPL, REG_DEL, DIR_IMPL, DIR_DEL, DEC_IMPL, DEC_DEL, ORDER, OPIN_AG, RECO, any

language

string

no

"ENG"

Language for titles and full text: any of the 24 official EU languages (Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA)

limit

number

no

10

Max results (1-50)

date_from

string

no

--

Filter from date, format: YYYY-MM-DD

date_to

string

no

--

Filter to date, format: YYYY-MM-DD

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

celex_id

string

no*

--

CELEX identifier, e.g. "32024R1689" for the AI Act

eli

string

no*

--

European Legislation Identifier, short (reg/2016/679) or full (http://data.europa.eu/eli/reg/2016/679/oj); resolved to a CELEX via Cellar

oj_ref

string

no*

--

Post-2023 Official Journal reference, e.g. "OJ:L_202401689" (AI Act); resolved to a CELEX via Cellar

language

string

no

"ENG"

Language: any of the 24 official EU languages (Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA)

format

string

no

"xhtml"

Output format: xhtml (structured) or plain (tags stripped, whitespace collapsed, entities decoded)

max_chars

number

no

20000

Max characters returned per call (1000-50000)

offset

number

no

0

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

celex_id

string

no*

--

CELEX identifier, e.g. "32024R1689"

eli

string

no*

--

European Legislation Identifier, short or full form; resolved to a CELEX via Cellar

oj_ref

string

no*

--

Post-2023 Official Journal reference, e.g. "OJ:L_202401689"; resolved to a CELEX via Cellar

language

string

no

"ENG"

Language for titles and EuroVoc labels: any of the 24 official EU languages (Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA)

* Provide exactly one of celex_id, eli, or oj_ref.

Notes on the response:

  • authors lists the resolved agent names (e.g. "European Parliament", "Council of the European Union") instead of an empty array.

  • legal_basis lists 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) are null when absent -- including Cellar's 9999-12-31 sentinel for acts with no defined end of validity, which is normalized to null. When Cellar holds several values, date_document and date_transposition report the earliest and date_end_of_validity the latest.

  • date_entry_into_force and date_application are distinct: the GDPR entered into force on 2016-05-24 but applies from 2018-05-25. Cellar stores every such "date of effect" under one property; dates_effect lists all of them ascending with a type (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 carries type: "unknown", and date_entry_into_force is the earliest date not before date_document.

  • directory_codes are human-readable ("{code-tail}: {label}", where code-tail is 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

celex_id

string

yes

--

CELEX identifier, e.g. "32024R1689"

language

string

no

"ENG"

Language for titles: any of the 24 official EU languages (Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA)

direction

string

no

"both"

cites (outgoing), cited_by (incoming), or both

limit

number

no

20

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

concept

string

yes

--

EuroVoc concept: label (e.g. "artificial intelligence") or URI (e.g. "http://eurovoc.europa.eu/4424")

resource_type

string

no

"any"

Document type filter (same values as eurlex_search)

language

string

no

"ENG"

Language: any of the 24 official EU languages (Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA)

limit

number

no

10

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

celex_id

string

no*

--

CELEX ID of the original act, e.g. "32016R0679" (GDPR). Alternative to doc_type+year+number; must be a sector-3 CELEX (3YYYY[R|L|D]NNNN)

doc_type

string

no*

--

Document type: reg (regulation), dir (directive), dec (decision). Alternative to celex_id; provide together with year and number

year

number

no*

--

Year of the act (1950-2100), e.g. 2024. Required together with doc_type and number when celex_id is not used

number

number

no*

--

Document number, e.g. 1689. Required together with doc_type and year when celex_id is not used

language

string

no

"ENG"

Language: any of the 24 official EU languages (Cellar 3-letter code, e.g. DEU, ENG, FRA, POL, SPA)

format

string

no

"xhtml"

Output format: xhtml or plain

max_chars

number

no

20000

Max characters returned per call (1000-50000)

offset

number

no

0

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

query

string

no*

--

Title/party substring (3-500 chars). CJEU titles start with a "Judgment of the Court …" prefix, so party names appear after it

celex_id

string

no*

--

Sector-6 CELEX of a specific ruling, e.g. "62012CJ0131" (Google Spain)

ecli

string

no*

--

European Case Law Identifier, e.g. "ECLI:EU:C:2014:317"

related_celex

string

no*

--

CELEX of a legal act (e.g. "32016R0679" GDPR); returns the case law interpreting that act

court

string

no

"any"

COURT_JUSTICE, GENERAL_COURT, or any

type

string

no

"any"

JUDG, ORDER, OPIN_AG, or any

language

string

no

"ENG"

Language of the title: any of the 24 official EU languages (Cellar 3-letter code)

limit

number

no

10

Max results (1-50)

date_from

string

no

--

Filter from this judgment date, format YYYY-MM-DD

date_to

string

no

--

Filter up to this judgment date, format YYYY-MM-DD

* 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

celex_id

string

yes

--

Sector-3 CELEX of the directive, e.g. "32022L2555" (NIS2) or "31995L0046" (Data Protection Directive)

country

string

no

--

Filter by EU 2-letter member-state code (ISO 3166-1 alpha-2, except Greece = EL), e.g. "DE", "FR". Omit for all member states

language

string

no

"ENG"

Sets the locale of each eurlex_url (Cellar 3-letter code); does not translate NIM titles

limit

number

no

20

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

celex_id

string

no*

--

CELEX identifier, e.g. "32024R1689"

eli

string

no*

--

European Legislation Identifier, short or full form; resolved to a CELEX via Cellar

oj_ref

string

no*

--

Post-2023 Official Journal reference, e.g. "OJ:L_202401689"; resolved to a CELEX via Cellar

language

string

no

"ENG"

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

celex_id

string

yes

--

CELEX of the act to summarize, e.g. "32016R0679" (GDPR) or "32022R2065" (Digital Services Act)

language

string

no

"ENG"

Language of the summary (Cellar 3-letter code); summaries are typically available in all 24 languages

max_chars

number

no

20000

Max characters returned per call (1000-50000)

offset

number

no

0

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

query

string

yes

--

A raw SPARQL 1.1 SELECT/ASK query (10-5000 chars) against the Cellar endpoint

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

32024R1689

AI Act (Regulation 2024/1689)

32016R0679

GDPR (Regulation 2016/679)

32022R2065

Digital Services Act (Regulation 2022/2065)

62014CJ0131

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 build

Commands

Command

Description

pnpm dev

Start dev server with hot reload

pnpm build

Compile TypeScript

pnpm test

Run unit tests

pnpm test:watch

Run tests in watch mode

pnpm test:integration

Run integration tests (hits real API)

pnpm start

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_chars slices (default 20,000 characters) to stay within LLM context limits -- use offset/next_offset on eurlex_fetch/eurlex_consolidated/eurlex_summary to 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_eurovoc queries with resource_type or date filters if this happens.

  • Search ordering: eurlex_search results 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

MIT

Available Tools

11 tools
eurlex_by_eurovocA
Read-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.

NameRequiredDescriptionDefault
limitNoMaximum number of results
conceptYesEuroVoc concept: a label (e.g. 'artificial intelligence') or a URI (e.g. 'http://eurovoc.europa.eu/4424')
languageNoLanguage 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_typeNoDocument type filterany

Output Schema

NameRequiredDescription
totalYesNumber of results in `results`
resultsYesActs tagged with the EuroVoc concept

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds meaningful behavioral context beyond that: concept input may be a label or URI, and label resolution automatically falls back across all 24 official EU languages if the request language has no match.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then adds the most important semantic detail about concept resolution. It is dense but contains no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, full schema coverage, rich annotations, and an output schema, the description is largely complete for correct invocation. It could add more about EuroVoc concept matching behavior, such as whether narrower concepts are included, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds real meaning for the concept and language parameters, particularly the cross-language label fallback, while limit and resource_type remain adequately documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Searches EU legal acts by EuroVoc thematic concept.' It also distinguishes the tool from generic keyword search by explaining it is the right tool for 'documents about X' when the term may not appear in the title.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states the intended use case: topical searches where the exact term may be absent from the title. It does not explicitly name eurlex_search or other sibling alternatives, nor does it state when not to use this tool, so it falls short of full when/when-not/alternatives guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_case_lawA
Read-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.

NameRequiredDescriptionDefault
ecliNoEuropean Case Law Identifier, e.g. "ECLI:EU:C:2014:317" (Google Spain).
typeNoProcedure type filter: JUDG=judgment, ORDER=court order, OPIN_AG=Advocate General opinion, any=all case-law document types (incl. procedural notices).any
courtNoCourt filter: COURT_JUSTICE=Court of Justice, GENERAL_COURT=General Court, any=both.any
limitNoMaximum number of results
queryNoTitle 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_toNoFilter up to this judgment date, format YYYY-MM-DD
celex_idNoSector-6 CELEX identifier of a specific ruling, e.g. "62012CJ0131" (Google Spain).
languageNoLanguage 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_fromNoFilter from this judgment date onward, format YYYY-MM-DD
related_celexNoCELEX of a legal act (e.g. "32016R0679" for the GDPR); returns the case law that interprets that act.

Output Schema

NameRequiredDescription
totalYesNumber of entries in `results`
resultsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower. The description still adds real behavioral context: the boilerplate title prefix that affects query matching, and that a ruling without a title in the requested language yields no result. It stops short of discussing pagination or rate limits, so a 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded — the scope statement comes first, then the four lookup modes, then filters and differentiation. It is longer than typical, but each sentence carries selection-relevant information; the return-field listing is the only mildly redundant part given an output schema exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter search tool with an output schema and full annotation coverage, the description supplies everything needed to call it correctly: required-input semantics, combinability, filter interactions, and sibling differentiation. Nothing an agent needs for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage the baseline is 3, but the description adds meaning beyond the schema: it explains query as case-insensitive contiguous phrase matching and warns that party names follow a boilerplate prefix, and clarifies related_celex as act-to-case-law traversal. These are genuine disambiguations not present in the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Finds CJEU case law') and enumerates the document types it covers (JUDG, ORDER, OPIN_AG) across two courts. It explicitly distinguishes itself from eurlex_search, so an agent can route between them without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit lookup modes ('four ways (at least one required, combinable)') with concrete examples for each, plus how to narrow with court/type/language/date filters. It also names the sibling alternative and the condition that selects it ('searches legislation by title' vs. case law).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_citationsA
Read-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.

NameRequiredDescriptionDefault
limitNoMaximum number of results
celex_idYesCELEX identifier, e.g. '32024R1689'
languageNoLanguage of the title, as a Cellar 3-letter code (any of the 24 official EU languages, e.g. DEU, ENG, FRA, POL, SPA)ENG
directionNoDirection: cites=acts referenced by this document, cited_by=acts referencing this document, both=a balanced split of both directionsboth

Output Schema

NameRequiredDescription
totalYesNumber of entries in `citations`
countsYesHow the returned citations split across the two directions
celex_idYesThe act whose citations were queried
citationsYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a read-only, idempotent, non-destructive, open-world operation. The description adds meaningful behavioral detail beyond that: direction="both" splits the limit evenly, does not back-fill from the richer side, and may return fewer than limit results, with a counts field reporting each side.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and relationship types, followed by the non-obvious balanced-split caveat. Both sentences earn their place and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given full schema coverage, annotations covering safety, and an output schema, the description is complete enough to invoke correctly. It additionally explains the subtle result-count behavior that an agent would otherwise miss.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds real meaning for direction and its interaction with limit, especially the non-obvious balanced split behavior, though it does not elaborate on celex_id or language beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it finds citation relationships for an EU legal act, and it enumerates the relationship types. It is clear what the tool does, but it does not explicitly differentiate itself from sibling tools such as eurlex_fetch or eurlex_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the direction values and the balanced behavior of direction="both", which helps an agent choose parameters. However, it does not explicitly say when to use this tool versus sibling tools or when not to use it, so usage guidance is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_consolidatedA
Read-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).

NameRequiredDescriptionDefault
yearNoYear of the act, e.g. 2024. Required together with doc_type and number when celex_id is not used.
formatNoOutput format: xhtml=structured XHTML, plain=text with XHTML tags strippedxhtml
numberNoDocument number, e.g. 1689. Required together with doc_type and year when celex_id is not used.
offsetNoCharacter offset for pagination (0-based)
celex_idNoCELEX 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_typeNoDocument type: reg=regulation, dir=directive, dec=decision. Alternative to celex_id — provide together with year and number.
languageNoLanguage 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_charsNoMaximum number of characters returned

Output Schema

NameRequiredDescription
yearYes
numberYes
offsetYesThe offset this window was sliced from
contentYesThe consolidated text in the requested window/format
eli_urlYesELI URL of the consolidated act
doc_typeYes
languageYes
truncatedYesTrue when more text remains beyond this window
next_offsetYesOffset to request next, or null when there is no more content
total_charsYesLength of the full processed document
returned_charsYesLength of `content`
consolidated_celexYesResolved consolidated CELEX, e.g. "02016R0679-20160504"
consolidation_dateYesISO date from the CELEX "-YYYYMMDD" suffix, or null when absent

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered structurally. The description adds one genuine behavioral fact — that amendments are merged into the returned text — but omits the fallback behavior when an act has no consolidated version and says nothing about truncation/pagination despite offset and max_chars existing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with what is retrieved, followed by the identification rule and its constraint. No filler, no repetition of enum values or defaults already in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 optional params, three enums, a full schema and an output schema, the description covers the two identification paths and the CELEX restriction well. The remaining gap is behavioral edge cases (no consolidated version available, pagination continuation), which keep it short of a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds real value beyond the schema by stating the mutual-exclusivity constraint (exactly one of celex_id vs doc_type + year + number) and by narrowing celex_id to sector-3 secondary-law CELEX with the 3YYYY[R|L|D]NNNN pattern, which the schema pattern alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Fetches the latest consolidated (currently in-force) version of an EU legal act via ELI, with all amendments merged in.' The 'consolidated / currently in-force / amendments merged' qualifier implicitly distinguishes it from eurlex_fetch or eurlex_search, but no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a strong usage rule for the input forms ('provide exactly one of the two'), but that is parameter-level guidance rather than tool-selection guidance. It never says when to prefer this over eurlex_fetch, eurlex_search, or eurlex_structure, nor what to do if no consolidated version exists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_fetchA
Read-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.

NameRequiredDescriptionDefault
eliNoEuropean 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.
formatNoOutput format: xhtml=structured XHTML, plain=text with XHTML tags strippedxhtml
offsetNoCharacter offset for pagination (0-based)
oj_refNoOfficial 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_idNoCELEX identifier, e.g. "32024R1689" (AI Act). Provide exactly one of celex_id, eli, or oj_ref.
languageNoLanguage 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_charsNoMaximum number of characters returned

Output Schema

NameRequiredDescription
offsetYesThe offset this window was sliced from
contentYesThe document text in the requested window/format
celex_idYesThe resolved CELEX ID the text was fetched for
languageYesCellar 3-letter language code of the text
truncatedYesTrue when more text remains beyond this window
source_urlYesCellar REST URL of the fetched resource
next_offsetYesOffset to request next, or null when there is no more content
total_charsYesLength of the full processed document
returned_charsYesLength of `content`

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld/non-destructive, so the safety profile is covered. The description adds real behavioral detail beyond them: the one-of-three identifier rule (with implicit Cellar resolution) and the offset/next_offset continuation loop that terminates when next_offset is null. It doesn't mention failure modes such as an unresolvable identifier or a language with no available text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler: purpose first, then the identifier options, then pagination. Front-loaded and every clause carries an actionable instruction.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary; the description instead covers the two things the schema cannot — which identifiers are acceptable and how to loop over pages. For a 7-parameter, fully documented read tool, nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above baseline by giving concrete identifier examples and, more importantly, the cross-parameter pagination workflow (pass the previous response's next_offset until null) that is not expressed in any single schema field. The format/language/max_chars semantics are left entirely to the schema, which is reasonable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Fetches the full text of an EU legal act") that is immediately distinguishable from siblings like eurlex_search, eurlex_metadata, eurlex_structure and eurlex_summary. The three accepted identifier forms are named inline, so an agent knows it can address the resource three different ways.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Provide exactly one" of celex_id/eli/oj_ref gives an explicit invocation constraint, and the pagination sentence tells the agent how to continue reading a long act. It stops short of naming alternatives (e.g. eurlex_structure or eurlex_summary for non-full-text needs), so sibling routing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_metadataA
Read-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.

NameRequiredDescriptionDefault
eliNoEuropean 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_refNoOfficial 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_idNoCELEX identifier, e.g. "32024R1689" (AI Act). Provide exactly one of celex_id, eli, or oj_ref.
languageNoLanguage 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

NameRequiredDescription
titleYes
authorsYes
celex_idYes
in_forceYesIn-force status, or null when unknown
eurlex_urlYes
legal_basisYesCELEX IDs of the acts this act is based on
dates_effectYesAll 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_documentYesISO date, or null when absent
resource_typeYes
directory_codesYesDirectory-code entries as "{code}: {label}", or the bare code when unlabelled
date_applicationYesISO 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_conceptsYes
date_transpositionYesISO date, or null when absent
date_end_of_validityYesISO date, or null when absent or the open-ended 9999-12-31 sentinel
date_entry_into_forceYesISO 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

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, idempotent, non-destructive, and open-world, so the bar is lower. The description still adds real domain behavior: that eli/oj_ref are resolved to a CELEX ID, the distinction between date_entry_into_force and date_application (with the GDPR example), and that dates_effect lists effect dates by type. It does not say what happens on resolution failure or ambiguous input, but with annotations and an output schema this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and resource, then the returned fields, then the identifier options. Three sentences, no filler; the GDPR parenthesis earns its place by disambiguating two easily confused date fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only metadata lookup, the description plus annotations, full parameter coverage, and an output schema leave nothing an agent needs in order to call it correctly; it even clarifies the entry-into-force vs application-date semantics that would otherwise be a common mistake.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter including the exactly-one-of constraint and the language enum with its default. The description's identifier examples and the GDPR date illustration add little beyond what is in the schema; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (fetches) and resource (metadata for an EU legal act) and enumerates the exact fields returned: dates, in-force status, authors, legal basis, EuroVoc descriptors, directory codes. This clearly distinguishes it from siblings like eurlex_fetch (full text), eurlex_summary, or eurlex_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The field enumeration makes the use case clear (you want dates/status/authors, not text), and the identifier rules ('provide exactly one' of celex_id, eli, oj_ref) constrain invocation. However, it never explicitly names a sibling or says when NOT to use this tool versus eurlex_fetch or eurlex_consolidated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_sparqlA
Read-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

NameRequiredDescriptionDefault
queryYesA 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

NameRequiredDescription
varsNoProjected variable names (SELECT only)
booleanNoASK result (present only for ASK queries)
bindingsNoRaw SPARQL binding rows, possibly truncated (SELECT only)
row_countYesTotal rows the query returned; null for ASK
truncatedYesTrue when whole rows were dropped to fit the char budget
limit_addedNoPresent (true) only when the tool auto-appended the default LIMIT
returned_rowsYesRows included after char-budget truncation; null for ASK

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, but the description adds substantial operational context beyond them. It discloses automatic LIMIT 50 appending, rejection of top-level LIMIT above 100, SPARQL JSON response shape, row_count and truncated behavior, and the ~40k character truncation rule.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, and the remaining sentences each carry operational value: prerequisites, allowed query types, limit behavior, response format, literal typing, and a concrete example. It is dense but not redundant for a complex expert tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and the single free-form query parameter, the description is complete enough to call correctly. An output schema exists, and the description still explains response shape and truncation, while also covering safety constraints, query limits, and ontology prerequisites.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents the single query parameter and many constraints. The description still adds useful query-building semantics, especially the CDM ontology guide reference and the caveat that CELEX/ELI literals are typed xsd:string and should be matched with FILTER(STR(?x) = ...).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: run a raw, read-only SPARQL 1.1 query against the EU Publications Office Cellar endpoint. It explicitly distinguishes itself from named higher-level siblings and frames itself as an expert escape hatch for cases they cannot express.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use this tool versus alternatives: only when eurlex_search, eurlex_metadata, eurlex_citations, and others cannot express the need. It also gives prerequisites and exclusions, including reading the eurlex_guide prompt first and disallowing SPARQL Update or federated SERVICE clauses.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_structureA
Read-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.

NameRequiredDescriptionDefault
eliNoEuropean 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_refNoOfficial 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_idNoCELEX identifier, e.g. "32024R1689" (AI Act). Provide exactly one of celex_id, eli, or oj_ref.
languageNoLanguage 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

NameRequiredDescription
noteNoPresent only when no headings were found or the outline was truncated
outlineYesHeadings in document order
celex_idYesThe resolved CELEX ID (echoed for the follow-up eurlex_fetch)
languageYes
returnedYesNumber of headings in `outline` (<= total_headings)
truncatedYesTrue when `outline` was capped below total_headings
source_urlYes
total_charsYesLength of the plain text the offsets index into (matches eurlex_fetch total_chars)
total_headingsYesTotal headings detected before the returned-list cap

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld, and the description adds substantial behavior beyond them: a hard cap of 300 headings with a truncated=true flag, offsets being language- and format-specific, heading recognition limited to ENG/DEU/FRA, and paragraph-level outlining for CELEX sector 6 case-law that works in any language. These are exactly the non-obvious traits an agent needs to avoid misuse.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and the recommended call pattern before detail, and each sentence carries information (offsets, cap, language coupling, case-law paragraphs). It is on the long side and repeats some language-matching guidance already present in the schema, costing a point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite an output schema existing, the description covers the return shape (level, label, title, offset, total_headings, truncated), the truncation edge case, cross-language offset pitfalls, and case-law paragraph exceptions. An agent has everything needed to call it and consume the result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3, but the description adds real semantics: heading recognition is only reliable for English, German and French documents, and offsets are tied to the language passed here, which must be reused on the follow-up fetch. Much of the 'provide exactly one of celex_id, eli, oj_ref' wording duplicates the schema, keeping this from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource: returns the outline (table of contents) of an EU legal act, enumerating chapters, sections, articles and annexes with character offsets. This is clearly distinguishable from siblings like eurlex_fetch and eurlex_search, and the tool's role as a navigation map is stated outright.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit workflow: read an article's offset from the outline, then call eurlex_fetch(celex_id, format:"plain", offset, max_chars) to jump straight in 'instead of paging from the top of a long act'. It names the alternative tool and the precise condition that selects it, plus the constraint to reuse the same language and format.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_summaryA
Read-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.

NameRequiredDescriptionDefault
offsetNoCharacter offset for pagination (0-based)
celex_idYesCELEX 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.
languageNoLanguage 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_charsNoMaximum number of characters returned

Output Schema

NameRequiredDescription
dateNoISO date of the returned summary, or ''
titleNo
offsetNoThe offset this window was sliced from
contentNoSummary text (plain, HTML stripped), sliced to window
celex_idYesThe act CELEX that was queried
languageYes
obsoleteNoTrue when the returned summary is flagged obsolete
truncatedNoTrue when more content remains beyond this window
source_urlNoEUR-Lex legislative-summary (LSU) page for the act
legissum_idNoLEGISSUM id of the returned (primary) summary
next_offsetNoOffset to request next, or null when there is no more content
total_charsNoLength of the full processed summary
returned_charsNoLength of `content`
other_summariesNoOther summaries for the same act (present only when total_summaries > 1)
total_summariesYesTotal LEGISSUM summaries linked to this act; 0 means none was found

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, but the description adds substantial behavioral context beyond those flags. It discloses the output fields, the obsolete flag, other_summaries handling, the clear 'no summary' outcome, and pagination behavior via max_chars/offset and next_offset.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then efficiently covers scope, parameters, pagination, missing summaries, and alternatives. Every sentence contributes operational information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description need not carry the full return-value explanation, but it still provides enough context about returned fields and pagination. Combined with clear alternatives and edge-case handling, the definition is complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents celex_id, language, max_chars, and offset. The description still adds useful semantics by giving concrete celex_id examples, noting language availability across the 24 official EU languages, and explaining pagination continuation via next_offset.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it returns the EU's official plain-language LEGISSUM summary of a legal act. It explicitly distinguishes this from the binding legal text and names eurlex_fetch and eurlex_metadata as alternatives, so an agent can identify the tool's role without inspecting the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains when to use this tool versus alternatives: use eurlex_fetch for full legal text and eurlex_metadata for structured metadata. It also covers edge cases, including acts with no summary and acts with multiple summaries where the most current non-obsolete one is returned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eurlex_transpositionA
Read-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.

NameRequiredDescriptionDefault
limitNoMaximum number of measures to return (1–100). The response also reports total_found (the full count).
countryNoOptional 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_idYesSector-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.
languageNoSets 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

NameRequiredDescription
resultsYes
celex_idYesThe directive CELEX that was queried
returnedYesNumber of measures in `results` (<= limit)
total_foundYesFull number of matching measures; when > returned, `results` was truncated

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds non-obvious behavioral details: results are capped at limit while total_found reports the full count, and national measure titles are returned in the member state's own official language and are not translated. It does not discuss rate limits or pagination beyond the cap, so it falls short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then moves through examples, filtering, and return semantics. It is dense and informative, though fairly long; nearly every sentence adds value, but it could be tightened slightly without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even though an output schema exists, the description explains the key return fields (member state, national measure title, date, sector-7 NIM CELEX, EUR-Lex URL) and the total_found/limit relationship. Combined with the annotations and full schema coverage, an agent has everything needed to invoke and interpret the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description still adds useful meaning: it explains that celex_id must be a sector-3 directive CELEX with examples (NIS2, Data Protection Directive), clarifies the country code convention, and emphasizes that language only affects the eurlex_url locale, not NIM titles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: it lists national implementing measures enacted to transpose a given EU directive. It also explicitly distinguishes this from eurlex_fetch/eurlex_metadata and notes that regulations and decisions have no NIMs, so an agent can tell exactly what this tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states the use case (transposition and compliance tracking), names the sibling tools to use for the directive itself, and explicitly excludes regulations and decisions. It also explains the optional country filter and says to omit it to return all member states.

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.

  1. 11 tool updatesv2.4.4
    • Changedeurlex_by_eurovoc3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / total / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total / minimum
        Added value: +-9007199254740991
    • Changedeurlex_case_law3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / total / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total / minimum
        Added value: +-9007199254740991
    • Changedeurlex_citations7 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / counts / properties / cited_by / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / counts / properties / cited_by / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / counts / properties / cites / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / counts / properties / cites / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total / minimum
        Added value: +-9007199254740991
    • Changedeurlex_consolidated14 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / number / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / offset / maximum
        Added value: +9007199254740991
      • changedOutput schema / properties / next_offset / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 9007199254740991,
        +    "minimum": -9007199254740991,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / number / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / number / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / offset / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / offset / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / returned_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / returned_chars / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_chars / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / year / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / year / minimum
        Added value: +-9007199254740991
    • Changedeurlex_fetch9 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / offset / maximum
        Added value: +9007199254740991
      • changedOutput schema / properties / next_offset / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 9007199254740991,
        +    "minimum": -9007199254740991,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / offset / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / offset / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / returned_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / returned_chars / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_chars / minimum
        Added value: +-9007199254740991
    • Changedeurlex_metadata1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedeurlex_search3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / total / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total / minimum
        Added value: +-9007199254740991
    • Changedeurlex_sparql4 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / bindings / items / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • changedOutput schema / properties / returned_rows / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 9007199254740991,
        +    "minimum": -9007199254740991,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / row_count / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 9007199254740991,
        +    "minimum": -9007199254740991,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedeurlex_structure11 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / outline / items / properties / level / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / outline / items / properties / level / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / outline / items / properties / offset / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / outline / items / properties / offset / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / returned / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / returned / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_chars / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_headings / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_headings / minimum
        Added value: +-9007199254740991
    • Changedeurlex_summary11 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / offset / maximum
        Added value: +9007199254740991
      • changedOutput schema / properties / next_offset / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 9007199254740991,
        +    "minimum": -9007199254740991,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / offset / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / offset / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / returned_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / returned_chars / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_chars / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_chars / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_summaries / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_summaries / minimum
        Added value: +-9007199254740991
    • Changedeurlex_transposition5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / returned / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / returned / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_found / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_found / minimum
        Added value: +-9007199254740991
  2. 11 tool updatesv2.4.2
    • Changedeurlex_by_eurovoc2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedeurlex_case_law2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Addedeurlex_citations
    • Addedeurlex_consolidated
    • Changedeurlex_fetch2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Addedeurlex_metadata
    • Addedeurlex_search
    • Addedeurlex_sparql
    • Changedeurlex_structure2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedeurlex_summary2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
    • Changedeurlex_transposition2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedOutput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
  3. 11 tool updatesv2.3.0
    • Changedeurlex_by_eurovoc1 field changed
      • changedInput schema / properties / language / default
        Previous value: -"DEU"New value: +"ENG"
    • Changedeurlex_case_law1 field changed
      • changedInput schema / properties / language / default
        Previous value: -"DEU"New value: +"ENG"
    • Removedeurlex_citations
    • Removedeurlex_consolidated
    • Changedeurlex_fetch1 field changed
      • changedInput schema / properties / language / default
        Previous value: -"DEU"New value: +"ENG"
    • Removedeurlex_metadata
    • Removedeurlex_search
    • Removedeurlex_sparql
    • Changedeurlex_structure1 field changed
      • changedInput schema / properties / language / default
        Previous value: -"DEU"New value: +"ENG"
    • Changedeurlex_summary1 field changed
      • changedInput schema / properties / language / default
        Previous value: -"DEU"New value: +"ENG"
    • Changedeurlex_transposition1 field changed
      • changedInput schema / properties / language / default
        Previous value: -"DEU"New value: +"ENG"
  4. 11 tool updatesv2.2.0
    • First observedeurlex_by_eurovoc
    • First observedeurlex_case_law
    • First observedeurlex_citations
    • First observedeurlex_consolidated
    • First observedeurlex_fetch
    • First observedeurlex_metadata
    • First observedeurlex_search
    • First observedeurlex_sparql
    • First observedeurlex_structure
    • First observedeurlex_summary
    • First observedeurlex_transposition

TDQS

A4.4/5.0

Scored across 11 tools

Disambiguation5/5

Each tool has a clearly delineated purpose, and the descriptions actively disambiguate near-neighbors: eurlex_search (title substring) vs eurlex_by_eurovoc (topic-based), eurlex_search (legislation) vs eurlex_case_law, and eurlex_fetch vs eurlex_consolidated vs eurlex_summary vs eurlex_metadata each target a distinct facet (full text, merged in-force text, plain-language overview, structured metadata). eurlex_structure and eurlex_sparql are also unambiguous as a map and an expert escape hatch respectively.

Naming Consistency4/5

All names share a consistent eurlex_ snake_case prefix with a single-word suffix, which is highly predictable. There is minor mixing between verb-style suffixes (search, fetch) and noun/adjective-style suffixes (metadata, citations, structure, consolidated), but the pattern remains readable and each suffix accurately signals the operation.

Tool Count5/5

Eleven tools is well within the sweet spot and each earns its place by covering a genuinely distinct EUR-Lex capability (search, retrieval, metadata, citations, transposition, case law, summaries, structure, raw SPARQL). There is no obvious redundancy or filler in the set.

Completeness5/5

The surface covers the full lifecycle of EU legal research: discovery (search, eurovoc, case law), retrieval (fetch, consolidated, structure), enrichment (metadata, citations, summary, transposition), and an expert escape hatch (sparql). Cross-references between tools (e.g. structure offsets feeding fetch) close potential dead ends, and no major operation for the domain appears missing.

Maintenance

ActivityActive
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers