@cyanheads/eur-lex-mcp-server 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +3 -2
- package/changelog/0.2.x/0.2.1.md +16 -0
- package/changelog/0.3.x/0.3.0.md +26 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +4 -2
- package/dist/config/server-config.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-cases.tool.d.ts +6 -6
- package/dist/mcp-server/tools/definitions/eurlex-get-cases.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-cases.tool.js +54 -20
- package/dist/mcp-server/tools/definitions/eurlex-get-cases.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.d.ts +12 -0
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.js +130 -23
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-lookup-celex.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-search-documents.tool.d.ts +5 -5
- package/dist/mcp-server/tools/definitions/eurlex-search-documents.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-search-documents.tool.js +63 -24
- package/dist/mcp-server/tools/definitions/eurlex-search-documents.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +24 -12
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/services/cellar-sparql/cdm-labels.d.ts +9 -0
- package/dist/services/cellar-sparql/cdm-labels.d.ts.map +1 -1
- package/dist/services/cellar-sparql/cdm-labels.js +16 -0
- package/dist/services/cellar-sparql/cdm-labels.js.map +1 -1
- package/dist/services/eurlex-content/eurlex-content-service.d.ts +42 -9
- package/dist/services/eurlex-content/eurlex-content-service.d.ts.map +1 -1
- package/dist/services/eurlex-content/eurlex-content-service.js +135 -30
- package/dist/services/eurlex-content/eurlex-content-service.js.map +1 -1
- package/package.json +1 -1
- package/server.json +7 -7
|
@@ -1,11 +1,86 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview EurLexContentService — HTTP client for
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* @fileoverview EurLexContentService — HTTP client for EU act full-text content.
|
|
3
|
+
*
|
|
4
|
+
* Sources content from the EU Publications Office CELLAR content-negotiation
|
|
5
|
+
* resolver (`publications.europa.eu/resource/celex/{CELEX}`) — the same host the
|
|
6
|
+
* metadata SPARQL pipeline already queries — rather than the legacy
|
|
7
|
+
* `eur-lex.europa.eu` legal-content endpoint, which is now fronted by an AWS WAF
|
|
8
|
+
* that returns a JavaScript bot-challenge stub instead of the act text (issue #16).
|
|
9
|
+
*
|
|
10
|
+
* Content negotiation:
|
|
11
|
+
* - `Accept`: HTML acts vary by document family — OJ legislation exposes
|
|
12
|
+
* `application/xhtml+xml`, CJEU judgments expose `text/html`, so the HTML path
|
|
13
|
+
* tries both. The XML path requests Formex 4 (`application/xml;type=fmx4`),
|
|
14
|
+
* which CELLAR serves directly for single-part acts and returns HTTP 300
|
|
15
|
+
* (multiple manifestation streams) for multi-part OJ acts — treated as
|
|
16
|
+
* unavailable rather than reconstructed.
|
|
17
|
+
* - `Accept-Language`: CELLAR requires an ISO 639-2/T (three-letter) code and
|
|
18
|
+
* 400s on a missing one or on a bibliographic 639-2/B code (`ger`, `fre`);
|
|
19
|
+
* EUR-Lex two-letter codes are mapped before the request.
|
|
20
|
+
*
|
|
21
|
+
* Defense in depth: any response carrying an AWS WAF challenge signature is
|
|
22
|
+
* refused (never surfaced as content) and raised as a ServiceUnavailable error,
|
|
23
|
+
* so a challenge stub can never again be reported as `contentAvailable: true`.
|
|
5
24
|
* @module services/eurlex-content/eurlex-content-service
|
|
6
25
|
*/
|
|
7
26
|
import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
8
27
|
import { withRetry } from '@cyanheads/mcp-ts-core/utils';
|
|
28
|
+
/**
|
|
29
|
+
* Map EUR-Lex two-letter language codes to the ISO 639-2/T (terminological,
|
|
30
|
+
* three-letter) codes CELLAR's content-negotiation resolver accepts in
|
|
31
|
+
* `Accept-Language`. CELLAR rejects bibliographic 639-2/B codes (`ger`, `fre`,
|
|
32
|
+
* `dut`, …), so the terminological forms (`deu`, `fra`, `nld`, …) are used.
|
|
33
|
+
*/
|
|
34
|
+
const LANGUAGE_TO_ISO_639_2 = {
|
|
35
|
+
EN: 'eng',
|
|
36
|
+
FR: 'fra',
|
|
37
|
+
DE: 'deu',
|
|
38
|
+
ES: 'spa',
|
|
39
|
+
IT: 'ita',
|
|
40
|
+
PL: 'pol',
|
|
41
|
+
PT: 'por',
|
|
42
|
+
NL: 'nld',
|
|
43
|
+
CS: 'ces',
|
|
44
|
+
DA: 'dan',
|
|
45
|
+
EL: 'ell',
|
|
46
|
+
ET: 'est',
|
|
47
|
+
FI: 'fin',
|
|
48
|
+
HU: 'hun',
|
|
49
|
+
LT: 'lit',
|
|
50
|
+
LV: 'lav',
|
|
51
|
+
MT: 'mlt',
|
|
52
|
+
RO: 'ron',
|
|
53
|
+
SK: 'slk',
|
|
54
|
+
SL: 'slv',
|
|
55
|
+
SV: 'swe',
|
|
56
|
+
BG: 'bul',
|
|
57
|
+
HR: 'hrv',
|
|
58
|
+
GA: 'gle',
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* `Accept` values tried per format, in order. HTML resolves to `application/xhtml+xml`
|
|
62
|
+
* for OJ legislation and `text/html` for CJEU judgments; the first to return a body
|
|
63
|
+
* wins. XML requests Formex 4 only.
|
|
64
|
+
*/
|
|
65
|
+
const ACCEPT_BY_FORMAT = {
|
|
66
|
+
html: ['application/xhtml+xml', 'text/html'],
|
|
67
|
+
xml: ['application/xml;type=fmx4'],
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* AWS WAF bot-challenge signatures. `awswaf` matches the challenge.js host
|
|
71
|
+
* (`token.awswaf.com`), the cookie-domain list, and the `AwsWafIntegration`
|
|
72
|
+
* calls; `gokuprops` matches the per-request challenge blob. Both are
|
|
73
|
+
* WAF-specific and never appear in legitimate EU legal text. Matched
|
|
74
|
+
* case-insensitively against the response head.
|
|
75
|
+
*/
|
|
76
|
+
const CHALLENGE_MARKERS = ['awswaf', 'gokuprops'];
|
|
77
|
+
/** Bodies shorter than this (after trimming) are treated as empty/unavailable. */
|
|
78
|
+
const MIN_CONTENT_LENGTH = 100;
|
|
79
|
+
/** True when a response body carries an AWS WAF bot-challenge signature. */
|
|
80
|
+
function isChallengeResponse(body) {
|
|
81
|
+
const head = body.slice(0, 4096).toLowerCase();
|
|
82
|
+
return CHALLENGE_MARKERS.some((marker) => head.includes(marker));
|
|
83
|
+
}
|
|
9
84
|
export class EurLexContentService {
|
|
10
85
|
baseUrl;
|
|
11
86
|
timeoutMs;
|
|
@@ -14,26 +89,28 @@ export class EurLexContentService {
|
|
|
14
89
|
this.timeoutMs = serverConfig.sparqlQueryTimeoutMs;
|
|
15
90
|
}
|
|
16
91
|
/**
|
|
17
|
-
* Build the
|
|
18
|
-
* Pattern: /
|
|
92
|
+
* Build the CELLAR content-negotiation URL for a CELEX number.
|
|
93
|
+
* Pattern: /resource/celex/{CELEX} (format + language come from request headers).
|
|
19
94
|
*/
|
|
20
|
-
buildContentUrl(celexNumber
|
|
21
|
-
|
|
22
|
-
return `${this.baseUrl}/legal-content/${language}/TXT/${fmt}/?uri=CELEX:${celexNumber}`;
|
|
95
|
+
buildContentUrl(celexNumber) {
|
|
96
|
+
return `${this.baseUrl}/resource/celex/${encodeURIComponent(celexNumber)}`;
|
|
23
97
|
}
|
|
24
98
|
/**
|
|
25
99
|
* Fetch the full text content of an EU act by CELEX number.
|
|
26
100
|
* If the requested language is unavailable, falls back to English.
|
|
27
101
|
* Returns `contentAvailable: false` with an empty string if both attempts fail.
|
|
102
|
+
*
|
|
103
|
+
* Throws ServiceUnavailable if the content host returns an AWS WAF bot-challenge
|
|
104
|
+
* stub — a challenge is never reported as available content.
|
|
28
105
|
*/
|
|
29
106
|
async fetchContent(celexNumber, language, format, ctx) {
|
|
30
|
-
const primary = await this.
|
|
107
|
+
const primary = await this.fetchForLanguage(celexNumber, language, format, ctx);
|
|
31
108
|
if (primary !== null) {
|
|
32
109
|
return { content: primary, language, format, contentAvailable: true };
|
|
33
110
|
}
|
|
34
|
-
// Language fallback: try English if primary language failed
|
|
111
|
+
// Language fallback: try English if primary language failed.
|
|
35
112
|
if (language !== 'EN') {
|
|
36
|
-
const fallback = await this.
|
|
113
|
+
const fallback = await this.fetchForLanguage(celexNumber, 'EN', format, ctx);
|
|
37
114
|
if (fallback !== null) {
|
|
38
115
|
return {
|
|
39
116
|
content: fallback,
|
|
@@ -47,36 +124,64 @@ export class EurLexContentService {
|
|
|
47
124
|
return { content: '', language, format, contentAvailable: false };
|
|
48
125
|
}
|
|
49
126
|
/**
|
|
50
|
-
*
|
|
51
|
-
* empty
|
|
127
|
+
* Resolve content for one language by trying each `Accept` variant for the
|
|
128
|
+
* format. Returns the first non-empty body, or null when none of the variants
|
|
129
|
+
* yield content (so the caller can fall back to English). Throws when a variant
|
|
130
|
+
* returns a bot-challenge stub.
|
|
52
131
|
*/
|
|
53
|
-
async
|
|
54
|
-
const
|
|
132
|
+
async fetchForLanguage(celexNumber, language, format, ctx) {
|
|
133
|
+
const isoLanguage = LANGUAGE_TO_ISO_639_2[language];
|
|
134
|
+
if (!isoLanguage)
|
|
135
|
+
return null;
|
|
136
|
+
for (const accept of ACCEPT_BY_FORMAT[format]) {
|
|
137
|
+
const outcome = await this.fetchVariant(celexNumber, accept, isoLanguage, ctx);
|
|
138
|
+
if (outcome.kind === 'challenge') {
|
|
139
|
+
throw serviceUnavailable(`The EU content endpoint returned a bot-challenge interstitial instead of the act text for CELEX ${celexNumber}.`, {
|
|
140
|
+
celexNumber,
|
|
141
|
+
reason: 'content_challenge',
|
|
142
|
+
recovery: {
|
|
143
|
+
hint: 'The content host is behind a WAF/bot challenge. Retry shortly; metadata remains ' +
|
|
144
|
+
'reachable via content_mode "metadata_only". A persistent challenge means ' +
|
|
145
|
+
'EURLEX_CONTENT_BASE_URL points at a WAF-protected host rather than the EU ' +
|
|
146
|
+
'Publications Office CELLAR resolver.',
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (outcome.kind === 'content')
|
|
151
|
+
return outcome.text;
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Single content-negotiation request for one `Accept`/`Accept-Language` pair.
|
|
157
|
+
* Non-2xx responses (404 = no datastream of that type, 300 = multi-part Formex,
|
|
158
|
+
* 4xx/5xx) and network failures resolve to `none` so callers can try the next
|
|
159
|
+
* variant or language. A WAF challenge body resolves to `challenge`. The inner
|
|
160
|
+
* function only throws on a `fetch` rejection, so `withRetry` retries transient
|
|
161
|
+
* network errors but never a 404 or a challenge.
|
|
162
|
+
*/
|
|
163
|
+
fetchVariant(celexNumber, accept, isoLanguage, ctx) {
|
|
164
|
+
const url = this.buildContentUrl(celexNumber);
|
|
55
165
|
return withRetry(async () => {
|
|
56
166
|
const response = await fetch(url, {
|
|
57
|
-
headers: { Accept:
|
|
167
|
+
headers: { Accept: accept, 'Accept-Language': isoLanguage },
|
|
58
168
|
signal: AbortSignal.timeout(this.timeoutMs),
|
|
59
169
|
redirect: 'follow',
|
|
60
170
|
});
|
|
61
|
-
if (
|
|
62
|
-
return
|
|
63
|
-
}
|
|
171
|
+
if (!response.ok)
|
|
172
|
+
return { kind: 'none' };
|
|
64
173
|
const text = await response.text();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (text.trim().length < 100) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
return text;
|
|
174
|
+
if (isChallengeResponse(text))
|
|
175
|
+
return { kind: 'challenge' };
|
|
176
|
+
if (text.trim().length < MIN_CONTENT_LENGTH)
|
|
177
|
+
return { kind: 'none' };
|
|
178
|
+
return { kind: 'content', text };
|
|
74
179
|
}, {
|
|
75
|
-
operation: 'EurLexContentService.
|
|
180
|
+
operation: 'EurLexContentService.fetchVariant',
|
|
76
181
|
baseDelayMs: 1000,
|
|
77
182
|
maxRetries: 2,
|
|
78
183
|
signal: ctx.signal,
|
|
79
|
-
}).catch(() =>
|
|
184
|
+
}).catch(() => ({ kind: 'none' }));
|
|
80
185
|
}
|
|
81
186
|
}
|
|
82
187
|
// --- Init/accessor pattern ---
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurlex-content-service.js","sourceRoot":"","sources":["../../../src/services/eurlex-content/eurlex-content-service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"eurlex-content-service.js","sourceRoot":"","sources":["../../../src/services/eurlex-content/eurlex-content-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/eur-lex-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"mcpName": "io.github.cyanheads/eur-lex-mcp-server",
|
|
5
5
|
"description": "Search EU legislation, CJEU case law, and treaties; traverse the CELLAR relationship graph; resolve EuroVoc concepts via MCP. STDIO or Streamable HTTP.",
|
|
6
6
|
"type": "module",
|
package/server.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/eur-lex-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.3.0",
|
|
10
10
|
"remotes": [
|
|
11
11
|
{
|
|
12
12
|
"type": "streamable-http",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
20
20
|
"identifier": "@cyanheads/eur-lex-mcp-server",
|
|
21
21
|
"runtimeHint": "bun",
|
|
22
|
-
"version": "0.
|
|
22
|
+
"version": "0.3.0",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"name": "EURLEX_CONTENT_BASE_URL",
|
|
43
|
-
"description": "
|
|
43
|
+
"description": "Base URL of the EU Publications Office CELLAR content-negotiation resolver that serves act full text; override e.g. for a local mirror.",
|
|
44
44
|
"format": "string",
|
|
45
45
|
"isRequired": false,
|
|
46
|
-
"default": "
|
|
46
|
+
"default": "http://publications.europa.eu"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"name": "SPARQL_QUERY_TIMEOUT_MS",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
77
77
|
"identifier": "@cyanheads/eur-lex-mcp-server",
|
|
78
78
|
"runtimeHint": "bun",
|
|
79
|
-
"version": "0.
|
|
79
|
+
"version": "0.3.0",
|
|
80
80
|
"packageArguments": [
|
|
81
81
|
{
|
|
82
82
|
"type": "positional",
|
|
@@ -138,10 +138,10 @@
|
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
"name": "EURLEX_CONTENT_BASE_URL",
|
|
141
|
-
"description": "
|
|
141
|
+
"description": "Base URL of the EU Publications Office CELLAR content-negotiation resolver that serves act full text; override e.g. for a local mirror.",
|
|
142
142
|
"format": "string",
|
|
143
143
|
"isRequired": false,
|
|
144
|
-
"default": "
|
|
144
|
+
"default": "http://publications.europa.eu"
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
"name": "SPARQL_QUERY_TIMEOUT_MS",
|