euparliamentmonitor 0.8.45 → 0.8.47
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/README.md +1 -1
- package/package.json +3 -3
- package/scripts/aggregator/analysis-aggregator.d.ts +25 -0
- package/scripts/aggregator/analysis-aggregator.js +27 -1
- package/scripts/aggregator/article-generator.js +13 -5
- package/scripts/aggregator/article-html.js +9 -5
- package/scripts/constants/config.d.ts +11 -0
- package/scripts/constants/config.js +31 -0
- package/scripts/mcp/ep-mcp-client.d.ts +10 -11
- package/scripts/mcp/ep-mcp-client.js +12 -13
- package/scripts/types/mcp.d.ts +1 -1
package/README.md
CHANGED
|
@@ -163,7 +163,7 @@ The published platform at **[euparliamentmonitor.com](https://euparliamentmonito
|
|
|
163
163
|
|
|
164
164
|
**MCP Server Integration**: The project uses the
|
|
165
165
|
[European-Parliament-MCP-Server](https://github.com/Hack23/European-Parliament-MCP-Server)
|
|
166
|
-
v1.2.
|
|
166
|
+
v1.2.15 for accessing real EU Parliament data via the Model Context Protocol.
|
|
167
167
|
|
|
168
168
|
- **MCP Server Status**: ✅ Fully operational — 60+ EP data tools available
|
|
169
169
|
(feeds, direct lookups, analytical tools, intelligence correlation)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "euparliamentmonitor",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.47",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "European Parliament Intelligence Platform - Monitor political activity with systematic transparency",
|
|
6
6
|
"main": "scripts/index.js",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"husky": "9.1.7",
|
|
159
159
|
"jscpd": "4.0.9",
|
|
160
160
|
"lint-staged": "16.4.0",
|
|
161
|
-
"mermaid": "
|
|
161
|
+
"mermaid": "11.14.0",
|
|
162
162
|
"papaparse": "5.5.3",
|
|
163
163
|
"prettier": "3.8.3",
|
|
164
164
|
"ts-api-utils": "2.5.0",
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
"node": ">=25"
|
|
172
172
|
},
|
|
173
173
|
"dependencies": {
|
|
174
|
-
"european-parliament-mcp-server": "1.2.
|
|
174
|
+
"european-parliament-mcp-server": "1.2.15",
|
|
175
175
|
"markdown-it": "^14.1.1",
|
|
176
176
|
"markdown-it-anchor": "^9.2.0",
|
|
177
177
|
"markdown-it-attrs": "^4.3.1",
|
|
@@ -2,6 +2,17 @@ import { type ArtifactSection } from './artifact-order.js';
|
|
|
2
2
|
/** Raw manifest shape as committed by the analysis pipeline. */
|
|
3
3
|
export interface AnalysisManifest {
|
|
4
4
|
readonly articleType: string;
|
|
5
|
+
/**
|
|
6
|
+
* Legacy plural variant emitted by some pre-aggregator-pipeline workflows.
|
|
7
|
+
* Used as a fallback when `articleType` is absent so historic runs with
|
|
8
|
+
* `articleTypes: ["<slug>"]` can still be aggregated.
|
|
9
|
+
*/
|
|
10
|
+
readonly articleTypes?: readonly string[];
|
|
11
|
+
/**
|
|
12
|
+
* Legacy field emitted by older breaking-run manifests. Used as the last
|
|
13
|
+
* fallback when neither `articleType` nor `articleTypes` is present.
|
|
14
|
+
*/
|
|
15
|
+
readonly runType?: string;
|
|
5
16
|
readonly runId?: string;
|
|
6
17
|
readonly date?: string;
|
|
7
18
|
readonly analysisDir?: string;
|
|
@@ -167,6 +178,20 @@ export declare function renderAnalysisIndex(included: readonly IncludedArtifact[
|
|
|
167
178
|
* @returns Markdown block containing the guide table
|
|
168
179
|
*/
|
|
169
180
|
export declare function renderReaderIntelligenceGuide(sections: readonly TocSection[], included: readonly IncludedArtifact[]): string;
|
|
181
|
+
/**
|
|
182
|
+
* Resolve the article-type slug from a manifest, tolerating legacy schemas.
|
|
183
|
+
*
|
|
184
|
+
* Resolution order (highest precedence first):
|
|
185
|
+
* 1. `articleType` — canonical singular field
|
|
186
|
+
* 2. `articleTypes[0]` — pre-aggregator-pipeline plural array
|
|
187
|
+
* 3. `runType` — legacy field on older breaking-run manifests
|
|
188
|
+
*
|
|
189
|
+
* Falls back to `'unknown'` when none of the above is a non-empty string.
|
|
190
|
+
*
|
|
191
|
+
* @param manifest - Parsed manifest (any of the supported schemas)
|
|
192
|
+
* @returns Article-type slug usable as a filename component
|
|
193
|
+
*/
|
|
194
|
+
export declare function resolveArticleTypeFromManifest(manifest: AnalysisManifest): string;
|
|
170
195
|
/**
|
|
171
196
|
* Read, clean, and concatenate every artifact declared by the run's manifest
|
|
172
197
|
* (with discovery fallback when manifest.files is missing), returning a
|
|
@@ -471,6 +471,32 @@ function appendSection(runDir, runDirRelPath, sectionId, sectionTitle, paths, se
|
|
|
471
471
|
}
|
|
472
472
|
sectionMarkdown.push('');
|
|
473
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Resolve the article-type slug from a manifest, tolerating legacy schemas.
|
|
476
|
+
*
|
|
477
|
+
* Resolution order (highest precedence first):
|
|
478
|
+
* 1. `articleType` — canonical singular field
|
|
479
|
+
* 2. `articleTypes[0]` — pre-aggregator-pipeline plural array
|
|
480
|
+
* 3. `runType` — legacy field on older breaking-run manifests
|
|
481
|
+
*
|
|
482
|
+
* Falls back to `'unknown'` when none of the above is a non-empty string.
|
|
483
|
+
*
|
|
484
|
+
* @param manifest - Parsed manifest (any of the supported schemas)
|
|
485
|
+
* @returns Article-type slug usable as a filename component
|
|
486
|
+
*/
|
|
487
|
+
export function resolveArticleTypeFromManifest(manifest) {
|
|
488
|
+
if (typeof manifest.articleType === 'string' && manifest.articleType) {
|
|
489
|
+
return manifest.articleType;
|
|
490
|
+
}
|
|
491
|
+
const first = manifest.articleTypes?.[0];
|
|
492
|
+
if (typeof first === 'string' && first) {
|
|
493
|
+
return first;
|
|
494
|
+
}
|
|
495
|
+
if (typeof manifest.runType === 'string' && manifest.runType) {
|
|
496
|
+
return manifest.runType;
|
|
497
|
+
}
|
|
498
|
+
return 'unknown';
|
|
499
|
+
}
|
|
474
500
|
/**
|
|
475
501
|
* Read, clean, and concatenate every artifact declared by the run's manifest
|
|
476
502
|
* (with discovery fallback when manifest.files is missing), returning a
|
|
@@ -516,7 +542,7 @@ export function aggregateAnalysisRun(options) {
|
|
|
516
542
|
consumed.add(p);
|
|
517
543
|
}
|
|
518
544
|
const tradecraftFiles = options.tradecraftFiles ?? discoverTradecraftFiles(repoRoot);
|
|
519
|
-
const articleType = manifest
|
|
545
|
+
const articleType = resolveArticleTypeFromManifest(manifest);
|
|
520
546
|
const date = manifest.date ?? guessDateFromRunDir(runDirRelPath);
|
|
521
547
|
const runId = manifest.runId ?? path.basename(runDir);
|
|
522
548
|
const gateResult = latestGateResult(manifest);
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import fs from 'fs';
|
|
20
20
|
import path from 'path';
|
|
21
21
|
import { pathToFileURL } from 'url';
|
|
22
|
-
import { aggregateAnalysisRun } from './analysis-aggregator.js';
|
|
22
|
+
import { aggregateAnalysisRun, resolveArticleTypeFromManifest, } from './analysis-aggregator.js';
|
|
23
23
|
import { resolveArticleMetadata, extractStrongProseLine, } from './article-metadata.js';
|
|
24
24
|
import { renderMarkdown } from './markdown-renderer.js';
|
|
25
25
|
import { wrapArticleHtml, getArticleFilename } from './article-html.js';
|
|
@@ -528,14 +528,21 @@ function readRunCandidate(runDir, manifestPath) {
|
|
|
528
528
|
catch {
|
|
529
529
|
return null;
|
|
530
530
|
}
|
|
531
|
-
|
|
531
|
+
// Resolve via the same precedence used by the aggregator (articleType →
|
|
532
|
+
// articleTypes[0] → runType) so legacy-schema manifests are picked up by
|
|
533
|
+
// batch mode rather than silently skipped.
|
|
534
|
+
const articleType = resolveArticleTypeFromManifest(parsed);
|
|
532
535
|
if (!articleType || articleType === 'unknown')
|
|
533
536
|
return null;
|
|
534
537
|
const dateFromManifest = typeof parsed.date === 'string' ? parsed.date : '';
|
|
535
538
|
const date = /^\d{4}-\d{2}-\d{2}$/.test(dateFromManifest)
|
|
536
539
|
? dateFromManifest
|
|
537
540
|
: dateFromRunPath(runDir);
|
|
538
|
-
const runId = typeof parsed.runId === 'string' && parsed.runId
|
|
541
|
+
const runId = typeof parsed.runId === 'string' && parsed.runId
|
|
542
|
+
? parsed.runId
|
|
543
|
+
: typeof parsed.runId === 'number'
|
|
544
|
+
? String(parsed.runId)
|
|
545
|
+
: path.basename(runDir);
|
|
539
546
|
return { runDir, articleType, date, runId };
|
|
540
547
|
}
|
|
541
548
|
/**
|
|
@@ -609,8 +616,9 @@ function readManifestMetadata(runDir) {
|
|
|
609
616
|
try {
|
|
610
617
|
const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
611
618
|
const manifest = {};
|
|
612
|
-
|
|
613
|
-
|
|
619
|
+
const resolvedType = resolveArticleTypeFromManifest(parsed);
|
|
620
|
+
if (resolvedType && resolvedType !== 'unknown') {
|
|
621
|
+
Object.assign(manifest, { articleType: resolvedType });
|
|
614
622
|
}
|
|
615
623
|
if (typeof parsed.date === 'string') {
|
|
616
624
|
Object.assign(manifest, { date: parsed.date });
|
|
@@ -10,11 +10,15 @@
|
|
|
10
10
|
* consistent with the rest of the site.
|
|
11
11
|
*
|
|
12
12
|
* The output is a complete HTML5 document. No inline `<script>` is emitted
|
|
13
|
-
* in the body. Mermaid is loaded from the vendored ESM bundle
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* in the body. Mermaid is loaded from the same-origin vendored ESM bundle
|
|
14
|
+
* (copied to `js/vendor/mermaid/` by `scripts/copy-vendor.js`) via
|
|
15
|
+
* `<script type="module" src="../js/mermaid-init.js?v=<MERMAID_VERSION>" defer>`
|
|
16
|
+
* so CSP stays `script-src 'self'`. The `?v=` query parameter is sourced
|
|
17
|
+
* from `devDependencies.mermaid` in `package.json` (a fixed pin like
|
|
18
|
+
* `11.14.0`); regenerating articles after a Mermaid bump invalidates
|
|
19
|
+
* browser and CloudFront caches automatically.
|
|
16
20
|
*/
|
|
17
|
-
import { BASE_URL, createThemeToggleButton, THEME_TOGGLE_SCRIPT } from '../constants/config.js';
|
|
21
|
+
import { BASE_URL, createThemeToggleButton, MERMAID_VERSION, THEME_TOGGLE_SCRIPT, } from '../constants/config.js';
|
|
18
22
|
import { ALL_LANGUAGES, LANGUAGE_NAMES, LANGUAGE_FLAGS, PAGE_TITLES, SKIP_LINK_TEXTS, HEADER_SUBTITLE_LABELS, THEME_TOGGLE_LABELS, TOC_ARIA_LABELS, getLocalizedString, getTextDirection, } from '../constants/languages.js';
|
|
19
23
|
import { escapeHTML } from '../utils/file-utils.js';
|
|
20
24
|
import { buildSiteFooter } from '../templates/section-builders.js';
|
|
@@ -181,7 +185,7 @@ ${hreflangLinks}
|
|
|
181
185
|
<meta name="theme-color" content="#003399">
|
|
182
186
|
<link rel="stylesheet" href="../styles.css">
|
|
183
187
|
<script type="application/ld+json">${jsonLdString}</script>
|
|
184
|
-
<script type="module" src="../js/mermaid-init.js" defer></script>
|
|
188
|
+
<script type="module" src="../js/mermaid-init.js?v=${MERMAID_VERSION}" defer></script>
|
|
185
189
|
</head>
|
|
186
190
|
<body>
|
|
187
191
|
<a href="#main" class="skip-link">${escapeHTML(skipLinkText)}</a>
|
|
@@ -33,6 +33,17 @@ export declare const ARTICLE_TYPE_MONTH_IN_REVIEW = ArticleCategory.MONTH_IN_REV
|
|
|
33
33
|
export declare const ARG_SEPARATOR = "=";
|
|
34
34
|
/** Application version read from package.json */
|
|
35
35
|
export declare const APP_VERSION: string;
|
|
36
|
+
/**
|
|
37
|
+
* Pinned Mermaid bundle version, read from `devDependencies.mermaid` in
|
|
38
|
+
* `package.json`. Used as a cache-busting query parameter on the
|
|
39
|
+
* `mermaid-init.js` script tag in generated article HTML so a Mermaid
|
|
40
|
+
* version bump in `package.json` automatically invalidates browser /
|
|
41
|
+
* CloudFront caches the next time articles are regenerated. Any leading
|
|
42
|
+
* semver range character (`^`, `~`, `>=`) is stripped — the contract for
|
|
43
|
+
* this repo is a fixed pin (e.g. `"mermaid": "11.14.0"`), but stripping
|
|
44
|
+
* keeps us robust if the pin is briefly relaxed during a dependency update.
|
|
45
|
+
*/
|
|
46
|
+
export declare const MERMAID_VERSION: string;
|
|
36
47
|
/**
|
|
37
48
|
* Generate theme toggle HTML button markup with a localized aria-label.
|
|
38
49
|
* Renders a moon (light→dark) and sun (dark→light) icon; CSS controls visibility.
|
|
@@ -61,6 +61,37 @@ export const APP_VERSION = (() => {
|
|
|
61
61
|
return '0.0.0';
|
|
62
62
|
}
|
|
63
63
|
})();
|
|
64
|
+
/**
|
|
65
|
+
* Pinned Mermaid bundle version, read from `devDependencies.mermaid` in
|
|
66
|
+
* `package.json`. Used as a cache-busting query parameter on the
|
|
67
|
+
* `mermaid-init.js` script tag in generated article HTML so a Mermaid
|
|
68
|
+
* version bump in `package.json` automatically invalidates browser /
|
|
69
|
+
* CloudFront caches the next time articles are regenerated. Any leading
|
|
70
|
+
* semver range character (`^`, `~`, `>=`) is stripped — the contract for
|
|
71
|
+
* this repo is a fixed pin (e.g. `"mermaid": "11.14.0"`), but stripping
|
|
72
|
+
* keeps us robust if the pin is briefly relaxed during a dependency update.
|
|
73
|
+
*/
|
|
74
|
+
export const MERMAID_VERSION = (() => {
|
|
75
|
+
try {
|
|
76
|
+
const pkgPath = path.join(PROJECT_ROOT, 'package.json');
|
|
77
|
+
const parsed = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
78
|
+
if (typeof parsed === 'object' && parsed !== null && 'devDependencies' in parsed) {
|
|
79
|
+
const devDeps = parsed.devDependencies;
|
|
80
|
+
if (typeof devDeps === 'object' && devDeps !== null && 'mermaid' in devDeps) {
|
|
81
|
+
const raw = devDeps.mermaid;
|
|
82
|
+
if (typeof raw === 'string' && raw.trim() !== '') {
|
|
83
|
+
return raw.replace(/^[\^~><=\s]+/, '').trim();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
console.warn('Invalid or missing "devDependencies.mermaid" in package.json, falling back to 0.0.0');
|
|
88
|
+
return '0.0.0';
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.warn('Failed to read mermaid version from package.json:', err);
|
|
92
|
+
return '0.0.0';
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
64
95
|
/**
|
|
65
96
|
* Generate theme toggle HTML button markup with a localized aria-label.
|
|
66
97
|
* Renders a moon (light→dark) and sun (dark→light) icon; CSS controls visibility.
|
|
@@ -7,7 +7,7 @@ import { MCPConnection } from './mcp-connection.js';
|
|
|
7
7
|
import type { MCPClientOptions, MCPToolResult, GetMEPsOptions, GetPlenarySessionsOptions, SearchDocumentsOptions, GetParliamentaryQuestionsOptions, GetCommitteeInfoOptions, MonitorLegislativePipelineOptions, AssessMEPInfluenceOptions, AnalyzeCoalitionDynamicsOptions, DetectVotingAnomaliesOptions, ComparePoliticalGroupsOptions, VotingRecordsOptions, VotingPatternsOptions, GenerateReportOptions, AnalyzeLegislativeEffectivenessOptions, AnalyzeCommitteeActivityOptions, TrackMEPAttendanceOptions, AnalyzeCountryDelegationOptions, GeneratePoliticalLandscapeOptions, GetCurrentMEPsOptions, GetSpeechesOptions, GetProceduresOptions, GetAdoptedTextsOptions, GetEventsOptions, GetMeetingActivitiesOptions, GetMeetingDecisionsOptions, GetMEPDeclarationsOptions, GetIncomingMEPsOptions, GetOutgoingMEPsOptions, GetHomonymMEPsOptions, GetPlenaryDocumentsOptions, GetCommitteeDocumentsOptions, GetPlenarySessionDocumentsOptions, GetPlenarySessionDocumentItemsOptions, GetControlledVocabulariesOptions, GetExternalDocumentsOptions, GetMeetingForeseenActivitiesOptions, GetProcedureEventsOptions, GetMeetingPlenarySessionDocumentsOptions, GetMeetingPlenarySessionDocumentItemsOptions, NetworkAnalysisOptions, SentimentTrackerOptions, EarlyWarningSystemOptions, ComparativeIntelligenceOptions, CorrelateIntelligenceOptions, GetAllGeneratedStatsOptions, GetMEPsFeedOptions, GetEventsFeedOptions, GetProceduresFeedOptions, GetAdoptedTextsFeedOptions, GetMEPDeclarationsFeedOptions, GetDocumentsFeedOptions, GetPlenaryDocumentsFeedOptions, GetCommitteeDocumentsFeedOptions, GetPlenarySessionDocumentsFeedOptions, GetExternalDocumentsFeedOptions, GetParliamentaryQuestionsFeedOptions, GetCorporateBodiesFeedOptions, GetControlledVocabulariesFeedOptions, GetProcedureEventByIdOptions, GetFreshProceduresOptions } from '../types/index.js';
|
|
8
8
|
/**
|
|
9
9
|
* Canonical list of tools exposed by the European Parliament MCP gateway
|
|
10
|
-
* (`european-parliament-mcp-server@1.2.
|
|
10
|
+
* (`european-parliament-mcp-server@1.2.15`). The news workflows, prompt
|
|
11
11
|
* library (`.github/prompts/07-mcp-reference.md`), and the integration test
|
|
12
12
|
* suite all reference this list so a regression that adds/removes a tool
|
|
13
13
|
* fails a single drift guard
|
|
@@ -22,7 +22,7 @@ export declare const EP_MCP_TOOLS: readonly string[];
|
|
|
22
22
|
* covering the two shapes historically emitted by the EP MCP server.
|
|
23
23
|
*
|
|
24
24
|
* 1. **Uniform envelope** (all feeds as of
|
|
25
|
-
* `european-parliament-mcp-server@1.2.
|
|
25
|
+
* `european-parliament-mcp-server@1.2.15`) —
|
|
26
26
|
* `{status:"unavailable", items:[], generatedAt:"..."}` established by
|
|
27
27
|
* Hack23/European-Parliament-MCP-Server#301 and extended to
|
|
28
28
|
* `get_events_feed`/`get_procedures_feed` by
|
|
@@ -133,21 +133,20 @@ export declare class EuropeanParliamentMCPClient extends MCPConnection {
|
|
|
133
133
|
*
|
|
134
134
|
* @remarks
|
|
135
135
|
* This repository is currently documented/configured against
|
|
136
|
-
* `european-parliament-mcp-server@1.2.
|
|
136
|
+
* `european-parliament-mcp-server@1.2.15`.
|
|
137
137
|
*
|
|
138
|
-
* **
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* Under that newer upstream contract:
|
|
138
|
+
* **Upstream date-filter contract (v1.2.14+, active on the pinned v1.2.15 server):** the upstream server
|
|
139
|
+
* applies a server-side post-filter on `dateFrom`/`dateTo` before serialisation, because the
|
|
140
|
+
* EP Open Data Portal `/meetings` endpoint silently ignores its `date-from`/`date-to` query
|
|
141
|
+
* parameters (Defect #5). Under this contract:
|
|
143
142
|
* - `data[]` contains only sessions within the requested window.
|
|
144
143
|
* - `total` reflects the **filtered** count, not the raw upstream count.
|
|
145
144
|
* - Per-window session counts are reproducible because the EP-side regression is masked by
|
|
146
145
|
* the upstream post-filter.
|
|
147
146
|
*
|
|
148
|
-
* No local post-filter is applied here.
|
|
149
|
-
*
|
|
150
|
-
*
|
|
147
|
+
* No local post-filter is applied here. The repository is pinned to v1.2.15, so the
|
|
148
|
+
* date-filter guarantees above apply; consumers running against an older server image
|
|
149
|
+
* (pre-v1.2.14) must not assume them.
|
|
151
150
|
*/
|
|
152
151
|
getPlenarySessions(options?: GetPlenarySessionsOptions): Promise<MCPToolResult>;
|
|
153
152
|
/**
|
|
@@ -10,7 +10,7 @@ import { ProcedureSeenCache } from './procedure-seen-cache.js';
|
|
|
10
10
|
import { recordPendingDocument, markDocumentResolved, getPendingDocumentsForReprobe, escalateExpiredDocuments, getPendingDocumentsSummary, } from './pending-documents.js';
|
|
11
11
|
/**
|
|
12
12
|
* Canonical list of tools exposed by the European Parliament MCP gateway
|
|
13
|
-
* (`european-parliament-mcp-server@1.2.
|
|
13
|
+
* (`european-parliament-mcp-server@1.2.15`). The news workflows, prompt
|
|
14
14
|
* library (`.github/prompts/07-mcp-reference.md`), and the integration test
|
|
15
15
|
* suite all reference this list so a regression that adds/removes a tool
|
|
16
16
|
* fails a single drift guard
|
|
@@ -114,7 +114,7 @@ const CONTENT_NOT_YET_AVAILABLE_SUBSTRING = 'document indexed but content not ye
|
|
|
114
114
|
/**
|
|
115
115
|
* Classify an error message into a diagnostic error category.
|
|
116
116
|
*
|
|
117
|
-
* Maps EP MCP Server v1.2.
|
|
117
|
+
* Maps EP MCP Server v1.2.15 structured error codes and generic HTTP/network
|
|
118
118
|
* errors into one of six broad categories used for logging and retry decisions:
|
|
119
119
|
*
|
|
120
120
|
* Returned categories (priority order):
|
|
@@ -130,7 +130,7 @@ const CONTENT_NOT_YET_AVAILABLE_SUBSTRING = 'document indexed but content not ye
|
|
|
130
130
|
*/
|
|
131
131
|
function classifyToolError(message) {
|
|
132
132
|
const lowerMsg = message.toLowerCase();
|
|
133
|
-
// EP MCP Server v1.2.
|
|
133
|
+
// EP MCP Server v1.2.15 structured error codes (matched case-insensitively)
|
|
134
134
|
if (lowerMsg.includes('internal_error')) {
|
|
135
135
|
return 'INTERNAL_ERROR';
|
|
136
136
|
}
|
|
@@ -189,7 +189,7 @@ function _parseResultPayload(result) {
|
|
|
189
189
|
* covering the two shapes historically emitted by the EP MCP server.
|
|
190
190
|
*
|
|
191
191
|
* 1. **Uniform envelope** (all feeds as of
|
|
192
|
-
* `european-parliament-mcp-server@1.2.
|
|
192
|
+
* `european-parliament-mcp-server@1.2.15`) —
|
|
193
193
|
* `{status:"unavailable", items:[], generatedAt:"..."}` established by
|
|
194
194
|
* Hack23/European-Parliament-MCP-Server#301 and extended to
|
|
195
195
|
* `get_events_feed`/`get_procedures_feed` by
|
|
@@ -449,21 +449,20 @@ export class EuropeanParliamentMCPClient extends MCPConnection {
|
|
|
449
449
|
*
|
|
450
450
|
* @remarks
|
|
451
451
|
* This repository is currently documented/configured against
|
|
452
|
-
* `european-parliament-mcp-server@1.2.
|
|
452
|
+
* `european-parliament-mcp-server@1.2.15`.
|
|
453
453
|
*
|
|
454
|
-
* **
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* Under that newer upstream contract:
|
|
454
|
+
* **Upstream date-filter contract (v1.2.14+, active on the pinned v1.2.15 server):** the upstream server
|
|
455
|
+
* applies a server-side post-filter on `dateFrom`/`dateTo` before serialisation, because the
|
|
456
|
+
* EP Open Data Portal `/meetings` endpoint silently ignores its `date-from`/`date-to` query
|
|
457
|
+
* parameters (Defect #5). Under this contract:
|
|
459
458
|
* - `data[]` contains only sessions within the requested window.
|
|
460
459
|
* - `total` reflects the **filtered** count, not the raw upstream count.
|
|
461
460
|
* - Per-window session counts are reproducible because the EP-side regression is masked by
|
|
462
461
|
* the upstream post-filter.
|
|
463
462
|
*
|
|
464
|
-
* No local post-filter is applied here.
|
|
465
|
-
*
|
|
466
|
-
*
|
|
463
|
+
* No local post-filter is applied here. The repository is pinned to v1.2.15, so the
|
|
464
|
+
* date-filter guarantees above apply; consumers running against an older server image
|
|
465
|
+
* (pre-v1.2.14) must not assume them.
|
|
467
466
|
*/
|
|
468
467
|
async getPlenarySessions(options = {}) {
|
|
469
468
|
return this.safeCallTool('get_plenary_sessions', options, '{"data": [], "total": 0}');
|
package/scripts/types/mcp.d.ts
CHANGED
|
@@ -404,7 +404,7 @@ export type FeedTimeframe = 'today' | 'one-day' | 'one-week' | 'one-month' | 'cu
|
|
|
404
404
|
* These feeds serve a server-defined window. Historically (pre-v1.2.13) they
|
|
405
405
|
* rejected `timeframe`/`startDate` with `INVALID_PARAMS`
|
|
406
406
|
* (Hack23/European-Parliament-MCP-Server#377); as of
|
|
407
|
-
* `european-parliament-mcp-server@1.2.
|
|
407
|
+
* `european-parliament-mcp-server@1.2.15` (PR #379) the server silently
|
|
408
408
|
* ignores those params on fixed-window tools. The client continues to omit
|
|
409
409
|
* them so intent matches behaviour and so we remain compatible with any
|
|
410
410
|
* older pinned server version in downstream environments.
|