All files / src/tools getCommitteeInfo.ts

100% Statements 12/12
75% Branches 3/4
100% Functions 1/1
100% Lines 12/12

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                                                                                                                13x   13x   13x 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 } from '../schemas/europeanParliament.js';
import { epClient } from '../clients/europeanParliamentClient.js';
import { buildApiParams } from './shared/paramBuilder.js';
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> {
  // Validate input
  const params = GetCommitteeInfoSchema.parse(args);
  
  try {
    // Return current active bodies if showCurrent is true
    if (params.showCurrent === true) {
      const result = await epClient.getCurrentCorporateBodies();
      return {
        content: [{
          type: 'text',
          text: JSON.stringify(result, null, 2)
        }]
      };
    }
 
    // Fetch committee info from EP API (only pass defined properties)
    const apiParams = buildApiParams(params, [
      { from: 'id', to: 'id' },
      { from: 'abbreviation', to: 'abbreviation' },
    ]);
    
    const result = await epClient.getCommitteeInfo(apiParams as Parameters<typeof epClient.getCommitteeInfo>[0]);
    
    // Validate output
    const validated = CommitteeSchema.parse(result);
    
    // Return MCP-compliant response
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(validated, null, 2)
      }]
    };
  } catch (error) {
    // Handle errors without exposing internal details
    const errorMessage = error instanceof Error ? error.message : 'Unknown error';
    throw new Error(`Failed to retrieve committee information: ${errorMessage}`);
  }
}
 
/**
 * 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
      }
    }
  }
};