All files / src/tools getMEPDeclarations.ts

94.44% Statements 17/18
83.33% Branches 5/6
100% Functions 2/2
93.75% Lines 15/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122                                                                                                                              16x 16x   6x 6x 6x                     10x 10x 1x 1x     9x       9x   9x       8x   1x                   4x                            
/**
 * MCP Tool: get_mep_declarations
 *
 * Retrieve MEP declarations of financial interests.
 * Supports single declaration lookup by docId or list with year filtering.
 *
 * **Intelligence Perspective:** Financial declarations enable conflict-of-interest
 * detection, lobbying pattern analysis, and transparency assessment for MEP profiling.
 *
 * **Business Perspective:** Declaration data supports compliance monitoring products
 * and corporate governance risk assessment services.
 *
 * **EP API Endpoints:**
 * - `GET /meps-declarations` (list)
 * - `GET /meps-declarations/{doc-id}` (single)
 *
 * ISMS Policy: SC-002 (Input Validation), DP-001 (Data Protection)
 * @gdpr Access is audit-logged per GDPR Art. 6(1)(e)
 */
 
import { GetMEPDeclarationsSchema } from '../schemas/europeanParliament.js';
import { epClient } from '../clients/europeanParliamentClient.js';
import { buildToolResponse } from './shared/responseBuilder.js';
import { ToolError } from './shared/errors.js';
import { z } from 'zod';
import type { ToolResult } from './shared/types.js';
 
/**
 * Handles the get_mep_declarations MCP tool request.
 *
 * Retrieves MEP declarations of financial interests filed under the Rules of Procedure.
 * Supports both single-declaration lookup by document ID and list retrieval with optional
 * year filtering. Financial declaration data enables conflict-of-interest detection,
 * lobbying pattern analysis, and transparency assessments.
 *
 * @param args - Raw tool arguments, validated against {@link GetMEPDeclarationsSchema}
 * @returns MCP tool result containing either a single MEP financial declaration document
 *   or a paginated list of declarations, optionally filtered by filing year
 * @throws - If `args` fails schema validation (e.g., invalid year or limit
 *   out of range 1–100)
 * - If the European Parliament API is unreachable or returns an error response
 *
 * @example
 * ```typescript
 * // List declarations for a specific year
 * const result = await handleGetMEPDeclarations({ year: 2024, limit: 20 });
 * // Returns up to 20 financial declarations filed in 2024
 *
 * // Fetch a single declaration by document ID
 * const single = await handleGetMEPDeclarations({ docId: 'DECL-2024-001' });
 * // Returns the full declaration document
 * ```
 *
 * @security - Input is validated with Zod before any API call.
 * - Access to financial declarations (personal data) is audit-logged per GDPR Art. 6(1)(e)
 *   and ISMS Policy AU-002. Data minimisation applied per GDPR Article 5(1)(c).
 * @since 0.8.0
 * @see {@link getMEPDeclarationsToolMetadata} for MCP schema registration
 * @see {@link handleGetMEPDetails} for retrieving broader MEP profile information
 */
export async function handleGetMEPDeclarations(args: unknown): Promise<ToolResult> {
  // Validate input — ZodErrors here are client mistakes (non-retryable)
  let params: ReturnType<typeof GetMEPDeclarationsSchema.parse>;
  try {
    params = GetMEPDeclarationsSchema.parse(args);
  } catch (error: unknown) {
    Eif (error instanceof z.ZodError) {
      const fieldErrors = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join('; ');
      throw new ToolError({
        toolName: 'get_mep_declarations',
        operation: 'validateInput',
        message: `Invalid parameters: ${fieldErrors}`,
        isRetryable: false,
        cause: error,
      });
    }
    throw error;
  }
 
  try {
    if (params.docId !== undefined) {
      const result = await epClient.getMEPDeclarationById(params.docId);
      return buildToolResponse(result);
    }
 
    const apiParams: Record<string, unknown> = {
      limit: params.limit,
      offset: params.offset,
    };
    if (params.year !== undefined) apiParams['year'] = params.year;
 
    const result = await epClient.getMEPDeclarations(
      apiParams as Parameters<typeof epClient.getMEPDeclarations>[0]
    );
 
    return buildToolResponse(result);
  } catch (error: unknown) {
    throw new ToolError({
      toolName: 'get_mep_declarations',
      operation: 'fetchData',
      message: 'Failed to retrieve MEP declarations',
      isRetryable: true,
      cause: error,
    });
  }
}
/** Tool metadata for get_mep_declarations */
export const getMEPDeclarationsToolMetadata = {
  name: 'get_mep_declarations',
  description:
    'Get MEP declarations of financial interests filed under the Rules of Procedure. Supports single declaration lookup by docId or list with year filter. Data source: European Parliament Open Data Portal. GDPR: Access is audit-logged.',
  inputSchema: {
    type: 'object' as const,
    properties: {
      docId: { type: 'string', description: 'Document ID for single declaration lookup' },
      year: { type: 'number', description: 'Filter by filing year (e.g., 2024)' },
      limit: { type: 'number', description: 'Maximum results to return (1-100)', default: 50 },
      offset: { type: 'number', description: 'Pagination offset', default: 0 },
    },
  },
};