Plugs Claude directly into the European Union's CELLAR database and EUR-Lex content APIs. Seven tools cover the full research workflow: keyword search across 2.7 million legislative acts with EuroVoc subject filtering, full-text retrieval in 24 languages, CELEX and ELI citation resolution, CJEU case law search, and graph traversal for amendments, consolidations, and legal basis chains. Raw SPARQL access included when you need custom CDM ontology queries. Built on the public CELLAR endpoint, so no API key required. Reach for this when you're doing EU regulatory analysis, tracking transposition measures, or need structured access to treaties and directives instead of scraping HTML.
CELLAR_SPARQL_ENDPOINTdefault: http://publications.europa.eu/webapi/rdf/sparqlCELLAR SPARQL endpoint URL override (e.g., for a local Virtuoso mirror).
EURLEX_CONTENT_BASE_URLdefault: https://eur-lex.europa.euEUR-Lex content API base URL override.
SPARQL_QUERY_TIMEOUT_MSdefault: 55000Client-side timeout for SPARQL requests in milliseconds.
MAX_SPARQL_RESULTSdefault: 100Enforced ceiling on LIMIT in all generated SPARQL queries.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_PUBLIC_URLPublic origin for deployments behind a TLS-terminating reverse proxy (e.g. https://mcp.example.com).
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
Search EU legislation, CJEU case law, and treaties; traverse the CELLAR relationship graph; resolve EuroVoc concepts via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://eur-lex.caseyjhand.com/mcp
Seven tools covering EU legal research — document discovery, content retrieval, citation resolution, case law, relationship graph traversal, EuroVoc thesaurus lookup, and raw SPARQL access:
| Tool | Description |
|---|---|
eurlex_search_documents | Search EU legislation, treaties, and preparatory acts across the CELLAR corpus. Filters by document type, date range, EuroVoc concept, author institution, and in-force status. |
eurlex_get_document | Fetch structured metadata and full text (HTML or Formex4 XML) for a work by CELEX number or ELI URI. |
eurlex_lookup_celex | Resolve any EU legal citation — CELEX number, ELI URI, or Official Journal reference — to the canonical CELLAR work. |
eurlex_get_cases | Search CJEU and General Court case law — judgments, orders, and Advocate General opinions — by case number, party name, subject, or date range. |
eurlex_get_relations | Traverse the CELLAR relationship graph: amendment chain, consolidated versions, legal basis, citation network, and national transposition measures. |
eurlex_browse_subjects | Search the EuroVoc multilingual thesaurus to resolve human-readable terms to EuroVoc concept IDs — required before using the eurovoc_concept filter in eurlex_search_documents. |
eurlex_query_sparql | Execute a raw SPARQL SELECT query against the CELLAR Virtuoso endpoint. Results capped at 100; use only when curated tools don't cover the needed CDM ontology traversal. |
eurlex_search_documentsSearch EU legislation, treaties, preparatory acts, and more across the 2.7M+ work CELLAR corpus.
REG, DIR, DEC, TREATY, and more)date_from, date_to)eurlex_browse_subjects first to resolve concept IDsoffset and configurable limit (max 100)eurlex_get_documenteurlex_get_documentFetch the notice and full text of an EU legal act.
32016R0679) or ELI URIseurlex_lookup_celexResolve EU legal identifiers to canonical CELLAR works.
identifier_type: "auto" (default); set explicitly when auto-detection failseurlex_get_document or eurlex_get_relationseurlex_get_casesSearch CJEU and General Court case law.
CJEU or GC), and case type (judgment, order, ag_opinion)eurlex_search_documents — case law (CELEX sector 6) has its own search parameters and practitioner workflowseurlex_get_relationsTraverse the CELLAR relationship graph for a given work.
cdm:work_cites_work in both directions)eurlex_query_sparqleurlex_browse_subjectsResolve human-readable terms to EuroVoc concept IDs.
eurovoc_concept filter in eurlex_search_documents| Type | Name | Description |
|---|---|---|
| Resource | eurlex://document/{celexNumber} | Metadata snapshot for a CELLAR work — type, date, title, author institution, in-force flag |
| Resource | eurlex://document/{celexNumber}/relations | Relationship summary for a work: amendment chain, consolidations, legal basis, cited-by count |
| Prompt | eurlex_comparative_analysis | Frames a comparative legal analysis across EU and US law for a given policy domain |
All resource data is also reachable via tools. Resources provide stable-URI injectable context for agents that support MCP resources.
Built on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1EUR-Lex-specific:
CellarSparqlService POSTs application/x-www-form-urlencoded SPARQL with CDM prefix declarations built in; server-side LIMIT enforcement (max 100) prevents Virtuoso timeout abuseEurLexContentService fetches full HTML or Formex4 XML via the canonical legal-content/{LANG}/TXT/ URL pattern (CELLAR work URIs return 400 on direct GET — this avoids that)Virtuoso 37000 Error body is parsed and re-raised as ServiceUnavailable (transient/timeout) or InvalidParams (syntax error)reason codes let agents branch on outcomes without parsing textAgent-friendly output:
eurlex_browse_subjects before attempting concept-filtered searcheseurlex_lookup_celex surfaces CELEX confirmation and work existence upfront, preventing downstream errors in document or relation fetchesunavailable reasons and language_unavailable signals let agents retry or explain to users with structured data, not string parsingA public instance is available at https://eur-lex.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"eur-lex-mcp-server": {
"type": "streamable-http",
"url": "https://eur-lex.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file. No API key is required.
{
"mcpServers": {
"eur-lex-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/eur-lex-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"eur-lex-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/eur-lex-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"eur-lex-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/eur-lex-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/eur-lex-mcp-server.git
cd eur-lex-mcp-server
bun install
cp .env.example .env
# All server-specific vars have sensible defaults — no required vars
All configuration is validated at startup via Zod schemas in src/config/server-config.ts.
| Variable | Description | Default |
|---|---|---|
CELLAR_SPARQL_ENDPOINT | CELLAR SPARQL endpoint URL override (e.g., for a local Virtuoso mirror). | http://publications.europa.eu/webapi/rdf/sparql |
EURLEX_CONTENT_BASE_URL | EUR-Lex content API base URL override. | https://eur-lex.europa.eu |
SPARQL_QUERY_TIMEOUT_MS | Client-side timeout for SPARQL requests in milliseconds. | 55000 |
MAX_SPARQL_RESULTS | Enforced ceiling on LIMIT in all generated SPARQL queries. | 100 |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t eur-lex-mcp-server .
docker run --rm -p 3010:3010 eur-lex-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/eur-lex-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools, resources, and prompts; initializes services. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/services/cellar-sparql | CELLAR SPARQL service — POST client, binding mapper, LIMIT enforcement, CDM PREFIX declarations. |
src/services/eurlex-content | EUR-Lex content API service — GET client for legal-content/{LANG}/TXT/ URL pattern with language fallback. |
src/mcp-server/tools | Tool definitions (*.tool.ts). Seven tools across document search, retrieval, resolution, case law, relations, EuroVoc, and raw SPARQL. |
src/mcp-server/resources | Resource definitions (*.resource.ts). Metadata and relations resources. |
src/mcp-server/prompts | Prompt definitions (*.prompt.ts). Comparative analysis prompt. |
tests/ | Unit and integration tests mirroring src/. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/*/definitions/index.tsIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp
io.github.sarahpark/google-search-console