Skip to main content
Glama
europarcel
by europarcel

Postal Code Reverse Lookup

postalCodeReverse

Look up locality, county, and street information for any Romanian postal code to validate addresses for shipping.

Instructions

Get locality, county and street information for a given postal code. Parameters: country_code (required), postal_code (required)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
country_codeYesThe country code - must be 'RO' (Romania)
postal_codeYesThe postal code to look up (e.g., '010123')

Implementation Reference

  • The main handler function that executes the postalCodeReverse tool logic. It validates inputs (country_code, postal_code), calls the API client, formats results grouped by locality, and returns a text response.
      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 {
          // Validate required parameters
          if (!args.country_code) {
            return {
              content: [
                {
                  type: "text",
                  text: "Error: country_code parameter is required",
                },
              ],
            };
          }
    
          if (!args.postal_code || typeof args.postal_code !== "string") {
            return {
              content: [
                {
                  type: "text",
                  text: "Error: postal_code parameter is required",
                },
              ],
            };
          }
    
          logger.info("Reverse lookup postal code", {
            country_code: args.country_code,
            postal_code: args.postal_code,
          });
    
          const results = await client.postalCodeReverse(
            args.country_code.toUpperCase(),
            args.postal_code,
          );
    
          logger.info(`Found ${results.length} results for postal code`);
    
          let formattedResponse = `Results for postal code ${args.postal_code} in ${args.country_code.toUpperCase()}:\n\n`;
    
          if (results.length === 0) {
            formattedResponse += "No results found for this postal code.";
          } else {
            // Group by locality
            const groupedByLocality = results.reduce(
              (acc: Record<number, typeof results>, result) => {
                if (!acc[result.locality_id]) {
                  acc[result.locality_id] = [];
                }
                acc[result.locality_id].push(result);
                return acc;
              },
              {},
            );
    
            Object.entries(groupedByLocality).forEach(([_, localityResults]) => {
              const first = localityResults[0];
              formattedResponse += `📍 ${first.name_and_county}\n`;
              formattedResponse += `   Locality ID: ${first.locality_id}\n`;
              formattedResponse += `   County: ${first.county_name} (${first.county_code})\n`;
              formattedResponse += `   Streets:\n`;
    
              localityResults.forEach((result) => {
                formattedResponse += `     • ${result.street_name}\n`;
              });
    
              formattedResponse += "\n";
            });
          }
    
          return {
            content: [
              {
                type: "text",
                text: formattedResponse,
              },
            ],
          };
        } catch (error: any) {
          logger.error("Failed to reverse lookup postal code", error);
    
          return {
            content: [
              {
                type: "text",
                text: `Error looking up postal code: ${error.message || "Unknown error"}`,
              },
            ],
          };
        }
      },
    );
  • Input schema definition for the postalCodeReverse tool using Zod. Defines country_code as enum ['RO'] and postal_code as a string (4-50 chars) with descriptions.
    {
      title: "Postal Code Reverse Lookup",
      description:
        "Get locality, county and street information for a given postal code. Parameters: country_code (required), postal_code (required)",
      inputSchema: {
        country_code: z
          .enum(["RO"])
          .describe("The country code - must be 'RO' (Romania)"),
        postal_code: z
          .string()
          .min(4)
          .max(50)
          .describe("The postal code to look up (e.g., '010123')"),
      },
  • The registration function registerPostalCodeReverseTool that registers the 'postalCodeReverse' tool with the MCP server using server.registerTool().
    export function registerPostalCodeReverseTool(server: McpServer): void {
      // Create API client instance
    
      // Register postalCodeReverse tool
      server.registerTool(
        "postalCodeReverse",
        {
          title: "Postal Code Reverse Lookup",
          description:
            "Get locality, county and street information for a given postal code. Parameters: country_code (required), postal_code (required)",
          inputSchema: {
            country_code: z
              .enum(["RO"])
              .describe("The country code - must be 'RO' (Romania)"),
            postal_code: z
              .string()
              .min(4)
              .max(50)
              .describe("The postal code to look up (e.g., '010123')"),
          },
        },
        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 {
            // Validate required parameters
            if (!args.country_code) {
              return {
                content: [
                  {
                    type: "text",
                    text: "Error: country_code parameter is required",
                  },
                ],
              };
            }
    
            if (!args.postal_code || typeof args.postal_code !== "string") {
              return {
                content: [
                  {
                    type: "text",
                    text: "Error: postal_code parameter is required",
                  },
                ],
              };
            }
    
            logger.info("Reverse lookup postal code", {
              country_code: args.country_code,
              postal_code: args.postal_code,
            });
    
            const results = await client.postalCodeReverse(
              args.country_code.toUpperCase(),
              args.postal_code,
            );
    
            logger.info(`Found ${results.length} results for postal code`);
    
            let formattedResponse = `Results for postal code ${args.postal_code} in ${args.country_code.toUpperCase()}:\n\n`;
    
            if (results.length === 0) {
              formattedResponse += "No results found for this postal code.";
            } else {
              // Group by locality
              const groupedByLocality = results.reduce(
                (acc: Record<number, typeof results>, result) => {
                  if (!acc[result.locality_id]) {
                    acc[result.locality_id] = [];
                  }
                  acc[result.locality_id].push(result);
                  return acc;
                },
                {},
              );
    
              Object.entries(groupedByLocality).forEach(([_, localityResults]) => {
                const first = localityResults[0];
                formattedResponse += `📍 ${first.name_and_county}\n`;
                formattedResponse += `   Locality ID: ${first.locality_id}\n`;
                formattedResponse += `   County: ${first.county_name} (${first.county_code})\n`;
                formattedResponse += `   Streets:\n`;
    
                localityResults.forEach((result) => {
                  formattedResponse += `     • ${result.street_name}\n`;
                });
    
                formattedResponse += "\n";
              });
            }
    
            return {
              content: [
                {
                  type: "text",
                  text: formattedResponse,
                },
              ],
            };
          } catch (error: any) {
            logger.error("Failed to reverse lookup postal code", error);
    
            return {
              content: [
                {
                  type: "text",
                  text: `Error looking up postal code: ${error.message || "Unknown error"}`,
                },
              ],
            };
          }
        },
      );
    
      logger.info("postalCodeReverse tool registered successfully");
    }
  • API client method postalCodeReverse that makes the GET request to /search/postal-code-reverse/{countryCode}/{postalCode} endpoint and returns PostalCodeResult[].
    async postalCodeReverse(
      countryCode: string,
      postalCode: string,
    ): Promise<PostalCodeResult[]> {
      const response = await this.client.get<PostalCodeResult[]>(
        `/search/postal-code-reverse/${countryCode}/${postalCode}`,
      );
      return response.data;
    }
  • TypeScript interface PostalCodeResult defining the response shape: locality_id, locality_name, name_and_county, county_name, county_code, street_name.
    export interface PostalCodeResult {
      locality_id: number;
      locality_name: string;
      name_and_county: string;
      county_name: string;
      county_code: string;
      street_name: string;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does not disclose any behavioral traits like side effects, rate limits, or that it is a read-only operation. Minimal context beyond the action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences. The first sentence front-loads the purpose. However, the second line listing parameters is slightly redundant given the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema is provided, and the description only hints at the return values (locality, county, street). It lacks details on response format or structure, which would help an agent understand the tool's output.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with both parameters already described in the input schema. The description text redundantly lists the parameters but adds no new meaning beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'Get' and the resource 'locality, county and street information for a given postal code'. It is distinct from sibling tools like searchLocalities and searchStreets, which are for forward lookups.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool or when not to. It implies usage for reverse lookup by postal code, but no alternatives or exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/europarcel/mcp-docker'

If you have feedback or need assistance with the MCP directory API, please join our Discord server