# All files / src/tools getCommitteeInfo.ts

82.6% Statements 19/23
66.66% Branches 4/6
66.66% Functions 2/3
85.71% Lines 18/21

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
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144

    13x
    13x

    5x
    5x
    5x

    8x
    8x
    1x
    1x
    1x
    1x

    7x

    7x

    6x

    6x

    1x

    1x

    4x

     /**
     * MCP Tool: get_committee_info
     *
     * Retrieve European Parliament committee information
     *
     * **Intelligence Perspective:** Maps committee power structures, membership networks,
     * and policy domain specialization for institutional analysis and influence mapping.
     *
     * **Business Perspective:** Powers committee monitoring products for industry associations,
     * trade groups, and corporate government affairs tracking specific policy areas.
     *
     * **Marketing Perspective:** Highlights structured access to EP's 20+ standing committees—
     * compelling for policy monitoring platforms and civic tech integrations.
     *
     * ISMS Policy: SC-002 (Input Validation), AC-003 (Least Privilege)
     */

    import { GetCommitteeInfoSchema, CommitteeSchema, PaginatedResponseSchema } from '../schemas/europeanParliament.js';
    import { epClient } from '../clients/europeanParliamentClient.js';
    import { buildToolResponse } from './shared/responseBuilder.js';
    import { buildApiParams } from './shared/paramBuilder.js';
    import { ToolError } from './shared/errors.js';
    import { z } from 'zod';
    import type { ToolResult } from './shared/types.js';

    /**
     * Handles the get_committee_info MCP tool request.
     *
     * Retrieves European Parliament committee (corporate body) information including
     * composition, chair, vice-chairs, members, meeting schedules, and policy areas.
     * Supports lookup by committee ID, abbreviation, or listing all current active bodies.
     *
     * @param args - Raw tool arguments, validated against {@link GetCommitteeInfoSchema}
     * @returns MCP tool result containing committee details or a list of current active corporate bodies
     * @throws - If `args` fails schema validation (e.g., missing required fields or invalid format)
     * - If the European Parliament API is unreachable or returns an error response
     *
     * @example
     * ```typescript
     * // Lookup by abbreviation
     * const result = await handleGetCommitteeInfo({ abbreviation: 'ENVI' });
     * // Returns detailed info for the Environment Committee
     *
     * // List all current active bodies
     * const all = await handleGetCommitteeInfo({ showCurrent: true });
     * // Returns all currently active EP corporate bodies
     * ```
     *
     * @security - Input is validated with Zod before any API call.
     * - Personal data in responses is minimised per GDPR Article 5(1)(c).
     * - All requests are rate-limited and audit-logged per ISMS Policy AU-002.
     * @since 0.8.0
     * @see {@link getCommitteeInfoToolMetadata} for MCP schema registration
     * @see {@link handleGetCommitteeDocuments} for retrieving documents produced by committees
     */
    export async function handleGetCommitteeInfo(
      args: unknown
    ): Promise<ToolResult> {
      let params: ReturnType<typeof GetCommitteeInfoSchema.parse>;
      try {
        params = GetCommitteeInfoSchema.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_committee_info',
            operation: 'validateInput',
            message: `Invalid parameters: ${fieldErrors}`,
            isRetryable: false,
            cause: error,
          });
        }
        throw error;
      }

      try {
        if (params.showCurrent === true) {
          const result = await epClient.getCurrentCorporateBodies();
          const outputSchema = PaginatedResponseSchema(CommitteeSchema);
          const validated = outputSchema.parse(result);
          return buildToolResponse(validated);
        }

        const apiParams = buildApiParams(params, [
          { from: 'id', to: 'id' },
          { from: 'abbreviation', to: 'abbreviation' },
        ]);

        const result = await epClient.getCommitteeInfo(apiParams);

        const validated = CommitteeSchema.parse(result);

        return buildToolResponse(validated);
      } catch (error: unknown) {
        Iif (error instanceof z.ZodError) {
          const fieldErrors = error.issues.map(e => `${e.path.join('.')}: ${e.message}`).join('; ');
          throw new ToolError({
            toolName: 'get_committee_info',
            operation: 'validateOutput',
            message: `Unexpected EP API response format: ${fieldErrors}`,
            isRetryable: false,
            cause: error,
          });
        }
        throw new ToolError({
          toolName: 'get_committee_info',
          operation: 'fetchData',
          message: 'Failed to retrieve committee information',
          isRetryable: true,
          cause: error,
        });
      }
    }

    /**
     * Tool metadata for MCP registration
     */
    export const getCommitteeInfoToolMetadata = {
      name: 'get_committee_info',
      description: 'Retrieve detailed information about EP corporate bodies/committees. Query by ID, abbreviation, or set showCurrent=true for all current active bodies. Returns composition, chair, vice-chairs, members, meeting schedules, and areas of responsibility.',
      inputSchema: {
        type: 'object' as const,
        properties: {
          id: {
            type: 'string',
            description: 'Committee identifier',
            minLength: 1,
            maxLength: 100
          },
          abbreviation: {
            type: 'string',
            description: 'Committee abbreviation (e.g., "ENVI", "AGRI", "ECON")',
            minLength: 1,
            maxLength: 20
          },
          showCurrent: {
            type: 'boolean',
            description: 'If true, returns all current active corporate bodies',
            default: false
          }
        }
      }
    };