The EP MCP Server implements a 4-layer defense-in-depth security architecture aligned with OWASP best practices, ISO 27001, NIST CSF 2.0, and GDPR requirements. Since the server operates as an MCP stdio process (not a network-exposed server), the primary security concerns are:
Input validation β prevent malformed or malicious MCP tool arguments
API abuse prevention β protect EP Open Data Portal from overuse
Data privacy β GDPR-compliant handling of MEP personal data
Audit trail β full traceability of all data access
The server does not handle authentication tokens, passwords, or payment data, significantly reducing the attack surface.
π‘οΈ 4-Layer Security Architecture
flowchart TD
MCP_IN["MCP Tool Invocation\n(args: unknown)"]
subgraph L1["Layer 1: Input Validation"]
ZOD["Zod Schema Validation\nStrict type checking, format enforcement"]
ZE["ZodError β MCP error response"]
end
subgraph L2["Layer 2: Rate Limiting"]
RL["Token Bucket Rate Limiter\n100 tokens/minute"]
RLE["Rate limit exceeded β 429 response"]
end
subgraph L3["Layer 3: Audit Logging"]
AL["Audit Logger\nTool name, params (PII-stripped), timestamp, user context"]
end
subgraph L4["Layer 4: GDPR Compliance"]
GDPR["Data Minimization\nPurpose Limitation\nStorage Limitation"]
end
EP_API["EP Open Data Portal API v2\n(HTTPS/TLS)"]
RESULT["Tool Result β MCP Client"]
MCP_IN --> ZOD
ZOD -->|"invalid"| ZE
ZOD -->|"valid"| RL
RL -->|"exceeded"| RLE
RL -->|"token available"| AL
AL --> GDPR
GDPR --> EP_API
EP_API --> RESULT
π Security Controls Inventory
Control ID
Control Name
Type
Implementation
Status
SC-001
Input Validation
Preventive
Zod schema per tool (61 schemas)
β Implemented
SC-002
Rate Limiting
Preventive
Token bucket, 100 req/min
β Implemented
SC-003
Audit Logging
Detective
AuditLogger singleton, all invocations
β Implemented
SC-004
GDPR Data Minimization
Preventive
Field selection, no over-fetching
β Implemented
SC-005
TLS in Transit
Preventive
HTTPS to EP API, Node TLS defaults
β Implemented
SC-006
Dependency Scanning
Detective
Dependabot, npm audit
β Implemented
SC-007
Static Analysis
Preventive
ESLint, TypeScript strict mode
β Implemented
SC-008
Secret Detection
Preventive
No secrets in codebase; env vars only
β Implemented
SC-009
Error Sanitization
Preventive
Internal errors not leaked to MCP clients
β Implemented
SC-010
Health Monitoring
Detective
HealthService singleton
β Implemented
SC-011
Metrics Collection
Detective
MetricsService, rate/error tracking
β Implemented
SC-012
Branded Types
Preventive
Zod branded types for EP identifiers
β Implemented
βοΈ Threat Mitigation Mapping (STRIDE)
Threat Category
Specific Threat
Likelihood
Impact
Mitigation
Spoofing
Fake MCP client identity
Low
Low
stdio transport β client is the spawning process
Tampering
Malicious tool arguments
Medium
Medium
SC-001: Zod validation rejects malformed input
Repudiation
Deny data access occurred
Medium
Medium
SC-003: Immutable audit log with timestamps
Information Disclosure
MEP PII over-exposure
Medium
High
SC-004: Data minimization, GDPR controls
Information Disclosure
Internal error details leaked
Low
Medium
SC-009: Error sanitization
Denial of Service
EP API flooding
Medium
High
SC-002: Rate limiter blocks bursts
Denial of Service
Memory exhaustion via cache
Low
Medium
LRU eviction (max 500 entries)
Elevation of Privilege
Unauthorized tool access
Low
Low
No auth layer needed β local stdio process
Elevation of Privilege
Prototype pollution via input
Low
Medium
SC-001: Zod validation with strict mode
Supply Chain
Malicious npm package
Medium
High
SC-006: Dependabot, npm audit, lockfile
π Authentication and Authorization
Current Model (v1.1)
The EP MCP Server operates as a local stdio process spawned by the MCP client (e.g., Claude Desktop). The security model relies on OS-level process isolation:
No network authentication β the server is not network-exposed
No user credentials β the server does not handle user tokens
Process isolation β only the spawning MCP client can communicate via stdio
EP API access β public open data, no authentication required by EP
Trust Boundaries
flowchart LR
subgraph TrustHigh["High Trust Zone"]
OS["Operating System"]
User["Local User Account"]
end
subgraph TrustMedium["Medium Trust Zone"]
MCP["MCP Client Process\n(Claude Desktop / Cursor)"]
Server["EP MCP Server Process"]
end
subgraph TrustLow["Low Trust Zone"]
Input["Tool Arguments\n(from AI-generated content)"]
end
subgraph External["Untrusted External"]
EPAPI["EP Open Data Portal\n(public internet)"]
end
OS --> MCP
MCP --> Server
Server --> Input
Input -->|"Zod validation"| Server
Server -->|"HTTPS"| EPAPI
Key principle: Tool arguments are treated as untrusted input regardless of their origin, since AI models may generate unexpected parameter values.
π Session and Action Tracking
All user interactions with the MCP server are tracked through the integrated audit and metrics systems:
Session Tracking Model
flowchart LR
subgraph SessionContext["Session Context"]
STDIO["stdio Connection\n(1 session per process)"]
TC["Tool Call Counter"]
TS["Session Start Time"]
end
subgraph ActionTracking["Action Tracking"]
AL["AuditLogger\n(every tool invocation)"]
MS["MetricsService\n(aggregated counters)"]
HS["HealthService\n(process health)"]
end
STDIO --> AL
STDIO --> MS
AL --> TC
MS --> TS
HS --> TC
Tracked Actions
Action Type
Tracked Fields
Storage
Purpose
Tool invocation
Tool name, sanitized params, timestamp, duration
stderr audit log
Full traceability
API request
URL, status, duration, cache hit/miss
MetricsService
Performance monitoring
Rate limit event
Token count, refill status, rejection
stderr audit log
Abuse detection
Error occurrence
Error type (no stack trace), tool context
stderr audit log
Incident response
Cache operation
Key, hit/miss, eviction
MetricsService
Efficiency tracking
Action Tracking Implementation
No persistent session storage β session state is in-memory only (process-scoped)
PII stripping β all logged parameters have personal data fields removed before logging
Structured logging β JSON format on stderr for machine-parseable audit trail
Per-tool metrics β invocation count, error count, average duration per tool
π Data Integrity and Auditing
Data Integrity Controls
Control
Implementation
Verification
Source integrity
All data sourced from official EP API over HTTPS/TLS
TLS certificate validation
Transport integrity
HTTPS with TLS 1.2+ for all API calls
Node.js default TLS verification
Cache integrity
In-memory LRU cache (no persistent storage) β no disk tampering risk
Process isolation
Schema validation
Zod schemas validate all API responses before processing
TypeScript strict mode + runtime validation
Audit immutability
Audit logs written to stderr (append-only within process)
No log modification API exposed
Package integrity
npm lockfile with exact versions, SLSA Level 3 provenance
Provenance attestations, Sigstore signing
Audit Trail Architecture
flowchart TD
ToolCall["Tool Invocation"] --> AuditLog["AuditLogger.logToolCall()"]
AuditLog --> PIIStrip["PII Stripping\n(remove personal data fields)"]
PIIStrip --> Format["JSON Structured Format"]
Format --> Stderr["stderr Output\n(append-only)"]
Stderr --> External["External Log Collection\n(host-managed)"]
Audit Log Fields
Field
Type
Description
timestamp
ISO 8601
Event occurrence time
toolName
string
MCP tool identifier
parameters
object
Sanitized input parameters (PII removed)
resultStatus
enum
success, error, rate_limited
durationMs
number
Execution duration
errorType
string?
Error category (no stack traces)
cacheHit
boolean?
Whether result came from cache
π‘οΈ Data Protection and GDPR
Personal Data Inventory
Data Category
EP API Endpoint
GDPR Basis
Retention in Cache
Minimization Applied
MEP Names
/meps/{id}
Public role (Art. 6.1.e)
15 min TTL
Name, group only
MEP Contact
/meps/{id}
Legitimate interest
15 min TTL
Official EP address only
MEP Votes
/votes
Public interest
15 min TTL
Vote record, no commentary
MEP Attendance
/plenary-sessions
Public interest
15 min TTL
Session data only
MEP Declarations
/meps/{id}/declarations
Public role
15 min TTL
Official declarations only
GDPR Principles Implementation
Principle
Implementation
Lawfulness
Processing public parliamentary records per Art. 6.1.e (public interest)
Purpose Limitation
Data used solely for parliamentary intelligence queries
Data Minimization
Field selection queries β only request needed attributes
Accuracy
Data sourced directly from official EP API
Storage Limitation
LRU cache with 15-min TTL; no persistent storage
Integrity and Confidentiality
HTTPS transport, no local file system writes
Accountability
Audit logging of all data access requests
π Network Security and Perimeter Protection
Outbound Connections
Destination
Protocol
Port
TLS
Purpose
data.europarl.europa.eu
HTTPS
443
TLS 1.2+
EP Open Data Portal API v2
EP Vocabulary endpoints
HTTPS
443
TLS 1.2+
AT4EU taxonomy lookups
Security Headers (Outbound Requests)
// Applied to all EP API requests headers: { 'Accept': 'application/json', 'User-Agent': 'European-Parliament-MCP-Server/1.1', 'Accept-Encoding': 'gzip, deflate, br' }
No Inbound Network Exposure
Server operates exclusively via stdio (no listening sockets)
No HTTP server, no WebSocket server in current v1.1