Get Fixed Locations
getFixedLocationsRetrieve fixed locations (lockers) in Romania. Filter by locality, carrier, or search by name and address.
Instructions
Retrieves fixed locations (lockers) for a country. Requires country_code. Optional filters: locality_id, carrier_id (single or comma-separated list), locality_name+county_name combination.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| country_code | Yes | The country code - must be 'RO' (Romania) | |
| locality_id | No | Optional locality ID to filter by | |
| carrier_id | No | Optional carrier ID: Single ID (1=Cargus, 2=DPD, 3=FAN Courier, 4=GLS, 6=Sameday, 16=Bookurier) or comma-separated list (e.g., '1,2,3') | |
| locality_name | No | Optional locality name to filter by (must be used with county_name) | |
| county_name | No | Optional county name to filter by (must be used with locality_name) | |
| search | No | Optional search term to filter by name or address (minimum 2 characters, partial match, case-insensitive) |
Implementation Reference
- The main tool handler function 'registerGetFixedLocationsTool' that registers the 'getFixedLocations' tool with the MCP server. It validates inputs (country_code required, locality_name+county_name paired), calls the API client, formats response with location details (name, type, carrier, address, coordinates), and handles errors.
export function registerGetFixedLocationsTool(server: McpServer): void { // Create API client instance // Register getFixedLocations tool server.registerTool( "getFixedLocations", { title: "Get Fixed Locations", description: "Retrieves fixed locations (lockers) for a country. Requires country_code. Optional filters: locality_id, carrier_id (single or comma-separated list), locality_name+county_name combination.", inputSchema: { country_code: z .enum(["RO"]) .describe("The country code - must be 'RO' (Romania)"), locality_id: z .number() .min(1) .optional() .describe("Optional locality ID to filter by"), carrier_id: z .union([ z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(6), z.literal(16), z.string().regex(/^(\d+,)*\d+$/), ]) .optional() .describe( "Optional carrier ID: Single ID (1=Cargus, 2=DPD, 3=FAN Courier, 4=GLS, 6=Sameday, 16=Bookurier) or comma-separated list (e.g., '1,2,3')", ), locality_name: z .string() .min(2) .max(100) .optional() .describe( "Optional locality name to filter by (must be used with county_name)", ), county_name: z .string() .min(2) .max(100) .optional() .describe( "Optional county name to filter by (must be used with locality_name)", ), search: z .string() .min(2) .max(100) .optional() .describe( "Optional search term to filter by name or address (minimum 2 characters, partial match, case-insensitive)", ), }, }, async (args: any) => { // Get API key from async context const apiKey = apiKeyStorage.getStore(); if (!apiKey) { return { content: [ { type: "text", text: "Error: X-API-KEY header is required", }, ], }; } // Create API client with customer's API key const client = new EuroparcelApiClient(apiKey); try { if (!args.country_code) { return { content: [ { type: "text", text: "Error: country_code parameter is required", }, ], }; } // Validate locality_name and county_name combination if ( (args.locality_name && !args.county_name) || (!args.locality_name && args.county_name) ) { return { content: [ { type: "text", text: "Error: locality_name and county_name must be used together", }, ], }; } logger.info("Fetching fixed locations", args); // Build parameters object const params: any = {}; if (args.locality_id) params.locality_id = args.locality_id; if (args.carrier_id) params.carrier_id = args.carrier_id; if (args.locality_name) params.locality_name = args.locality_name; if (args.county_name) params.county_name = args.county_name; if (args.search) params.search = args.search; const locations = await client.getFixedLocations( args.country_code, params, ); logger.info(`Retrieved ${locations.length} fixed locations`); let formattedResponse = `Found ${locations.length} fixed locations in ${args.country_code}`; // Show applied filters const filters = []; if (args.locality_id) filters.push(`locality_id: ${args.locality_id}`); if (args.locality_name && args.county_name) filters.push(`locality: ${args.locality_name}, ${args.county_name}`); if (args.carrier_id) filters.push(`carrier_id: ${args.carrier_id}`); if (args.search) filters.push(`search: "${args.search}"`); if (filters.length > 0) { formattedResponse += ` (filtered by ${filters.join(", ")})`; } formattedResponse += ":\n\n"; locations.forEach((location) => { formattedResponse += `${location.name} (ID: ${location.id})\n`; formattedResponse += ` Type: ${location.fixed_location_type}\n`; formattedResponse += ` Carrier: ${location.carrier_name}\n`; formattedResponse += ` Address: ${location.address}\n`; formattedResponse += ` Location: ${location.locality_name}, ${location.county_name}\n`; formattedResponse += ` Drop-off: ${location.allows_drop_off ? "Yes" : "No"}\n`; formattedResponse += ` Coordinates: ${location.coordinates.lat}, ${location.coordinates.long}\n\n`; }); return { content: [ { type: "text", text: formattedResponse, }, ], }; } catch (error: any) { logger.error("Failed to fetch fixed locations", error); return { content: [ { type: "text", text: `Error fetching fixed locations: ${error.message || "Unknown error"}`, }, ], }; } }, ); logger.info("getFixedLocations tool registered successfully"); } - Zod input schema defining the tool's parameters: country_code (required, 'RO' only), locality_id (optional number), carrier_id (optional single number 1/2/3/4/6/16 or comma-separated string), locality_name + county_name (optional pair), and search (optional string for name/address filtering).
inputSchema: { country_code: z .enum(["RO"]) .describe("The country code - must be 'RO' (Romania)"), locality_id: z .number() .min(1) .optional() .describe("Optional locality ID to filter by"), carrier_id: z .union([ z.literal(1), z.literal(2), z.literal(3), z.literal(4), z.literal(6), z.literal(16), z.string().regex(/^(\d+,)*\d+$/), ]) .optional() .describe( "Optional carrier ID: Single ID (1=Cargus, 2=DPD, 3=FAN Courier, 4=GLS, 6=Sameday, 16=Bookurier) or comma-separated list (e.g., '1,2,3')", ), locality_name: z .string() .min(2) .max(100) .optional() .describe( "Optional locality name to filter by (must be used with county_name)", ), county_name: z .string() .min(2) .max(100) .optional() .describe( "Optional county name to filter by (must be used with locality_name)", ), search: z .string() .min(2) .max(100) .optional() .describe( "Optional search term to filter by name or address (minimum 2 characters, partial match, case-insensitive)", ), }, - src/tools/locations/index.ts:20-24 (registration)Registration of the tool via registerGetFixedLocationsTool(server) call, aggregated alongside other location tools in the registerLocationTools function.
registerGetFixedLocationsTool(server); registerGetFixedLocationByIdTool(server); logger.info("All location tools registered successfully"); } - src/api/client.ts:222-238 (helper)API client helper method 'getFixedLocations' that makes an HTTP GET request to /locations/fixedlocations/{countryCode} with optional query params and returns a Promise of FixedLocation[].
async getFixedLocations( countryCode: string, params?: { locality_id?: number; carrier_id?: number | string; locality_name?: string; county_name?: string; }, ): Promise<FixedLocation[]> { const response = await this.client.get<FixedLocation[]>( `/locations/fixedlocations/${countryCode}`, { params, }, ); return response.data; } - src/types/index.ts:137-157 (helper)Type definition for the FixedLocation interface returned by the tool, including fields: id, fixed_location_type, carrier_id/name, locality_id/name, county_id/name, country_code, name, address, allows_drop_off, is_active, coordinates (lat/long), schedule, payment_type.
export interface FixedLocation { id: number; fixed_location_type: string; carrier_id: number; carrier_name: string; locality_id: number; locality_name: string; county_id: number; county_name: string; country_code: string; name: string; address: string; allows_drop_off: boolean; is_active: boolean; coordinates: { lat: number; long: number; }; schedule: any; payment_type: string; }