Skip to main content
Glama

ng-postcode

CI crates.io PyPI MCP server npm npm MCP server

Developer tools for Nigeria's National Digital Alphanumeric Postcode System (NDAPS), the building-level postcode NIPOST launched in October 2026: libraries for Rust, Python, JavaScript, and Java, MCP servers for AI assistants on PyPI and npm, and a resolver that turns described addresses into postcodes.

A postcode has 11 characters in five segments, written EK-01-A03-FK-01: state, LGA, district, area and building unit.

Packages

Package

What it does

Install

Source

ng-postcode (Rust)

Parse, validate and format codes offline; client for the postcode.gov.ng API

cargo add ng-postcode

src/, docs

ng-postcode (Python)

The same behaviour, with sync and async clients

pip install ng-postcode

python/

ng-postcode-js

The same behaviour for JavaScript and TypeScript, with a fetch client

npm install ng-postcode-js

js/packages/ng-postcode-js

ng-postcode and ng-postcode-api (Java)

The same behaviour for Java 17 and later; the core has no dependencies

io.github.adeniyikayodee:ng-postcode-api

java/

ng-postcode-mcp

MCP server: validate, look up, autocomplete, find by location, resolve addresses

uvx ng-postcode-mcp

mcp/

ng-postcode-mcp (npm)

The same server for Node, without address resolution

npx ng-postcode-mcp

js/packages/ng-postcode-mcp

ng-address-resolver

Resolve free-text addresses to postcodes, only as precisely as the evidence allows (pre-alpha)

pip install ng-address-resolver

agent/

Each package has its own README with full usage.

For online stores, ng-postcode-woocommerce is a WooCommerce plugin built on the same rules and the same shared test cases: it checks and tidies the postcode at checkout, finds it from the customer's location, and makes shipping zones match on postcode prefixes.

Related MCP server: io.github.stucchi/italy-opendata

Quick start

AI assistants

The MCP server works with any MCP client. It runs over stdio as uvx ng-postcode-mcp, with the API key in the environment. Most clients take this entry in their MCP settings:

{
  "mcpServers": {
    "ng-postcode": {
      "command": "uvx",
      "args": ["ng-postcode-mcp"],
      "env": { "NG_POSTCODE_API_KEY": "nipost_live_..." }
    }
  }
}

To run it with Node, use "command": "npx" and "args": ["-y", "ng-postcode-mcp"]; that edition has every tool except address resolution. Per-client steps for Cursor, VS Code, Codex, Claude and others are in the MCP server README. Validation works without a key. The server is listed in the MCP Registry as io.github.Adeniyikayodee/ng-postcode.

Python

from ng_postcode import Postcode, parse

match parse("ek 01 a03 fk 01"):
    case Postcode() as code:
        print(code, code.compact)  # EK-01-A03-FK-01 EK01A03FK01
    case error:
        print(error)               # e.g. "invalid lga segment"

JavaScript and TypeScript

import { Postcode, parse } from "ng-postcode-js";

const code = parse("ek 01 a03 fk 01");
if (code instanceof Postcode) {
  console.log(String(code), code.compact); // EK-01-A03-FK-01 EK01A03FK01
} else {
  console.log(String(code));               // e.g. "invalid lga segment"
}

Java

import io.github.adeniyikayodee.ngpostcode.Postcode;

if (Postcode.parse("ek 01 a03 fk 01") instanceof Postcode code) {
    System.out.println(code + " " + code.compact()); // EK-01-A03-FK-01 EK01A03FK01
}

Rust

use ng_postcode::{Postcode, Segment};

let code: Postcode = "ek 01 a03 fk 01".parse()?;
assert_eq!(code.to_string(), "EK-01-A03-FK-01");
assert_eq!(code.prefix(Segment::Area), "EK-01-A03-FK");

The format

Segment

Example

Shape

State

EK

2 letters

LGA

01

2 digits, 01 to 99

District

A03

3 letters or digits

Area

FK

2 letters

Building unit

01

2 digits, 01 to 99

Input may be hyphenated, spaced or compact, in either case. The compact form matches ^[A-Z]{2}(0[1-9]|[1-9][0-9])[A-Z0-9]{3}[A-Z]{2}(0[1-9]|[1-9][0-9])$. A well-formed code is not necessarily assigned to a building; only the NIPOST API can confirm that.

Passing a postcode between systems

docs/schemas/postcode-reference.schema.json defines a small JSON object for handing a location from one system or AI agent to another: the code, its level (state to building), and optionally a confidence and whether NIPOST confirmed it. A resolved or partial resolve_address answer already fits it.

Design

  • One behaviour, four languages: Rust, Python, JavaScript and Java all run the cases in spec/, so they cannot drift apart. The Node MCP server registers its tools from spec/mcp.json, which the Python server generates.

  • Offline first: parsing and validation never touch the network. API access is a separate, optional layer.

  • Errors are values: expected failures, such as a malformed code or a rejected API key, come back as return values.

  • Careful with money and guesses: the MCP server caps lookups at the free level unless told otherwise, and never corrects a mistyped code into a paid call. The resolver gives an area or district code when that is all the evidence supports.

Status

  • The NIPOST API needs a key for every endpoint, from the developer dashboard. Offline validation needs nothing.

  • The API layer is tested against responses captured from the live API with a level 1 key, kept in spec/responses.json. Run scripts/live_check.py with your own key to repeat the comparison. Lookup levels 2 and up need a higher-access key and are tested only against NIPOST's documented examples.

  • The resolver and the resolve_address tool are pre-release. They work against the live API, but their accuracy on real addresses is unmeasured. Described addresses need a geocoder you run or pay for; text alone rarely identifies a building, so ask users for a location pin when the exact building matters.

Where the live API differs from its docs

Observed on 3 October 2026:

  • Every endpoint needs a key, including search, assembly and level 1 lookup, which the docs describe as public.

  • Lookup also returns status (valid, not_found, invalid) and verified. A malformed code is answered with HTTP 200 and status: invalid.

  • Autocomplete suggestions carry only code, the value of the next segment. The documented label is not sent.

  • Reverse geocoding also returns depth.

  • Nearby search, which the docs leave unspecified, returns a list of postcode, display and distance_m, nearest first.

  • Asking for a level the key lacks returns 403 level_not_granted.

  • An empty autocomplete query never gets a response, so the libraries refuse to send one.

  • EK-01-A03-FK-01, the example used throughout NIPOST's docs, is reported as not assigned.

Development

See CONTRIBUTING.md for the shared spec, how to add a language, and the commit standards.

cargo test --all-features                              # Rust
cd python && uv run --group dev pytest                 # Python library
cd mcp && uv run --group dev pytest                    # MCP server
cd agent && uv run --group dev pytest                  # resolver
cd js && npm ci && npm test                            # JavaScript library and Node MCP server
cd java && ./mvnw verify                               # Java libraries

CI runs formatting, linting, type checks and tests for every package. Releases publish from tags (v* to crates.io; py-v*, mcp-v* and agent-v* to PyPI and the MCP Registry; js-v* and js-mcp-v* to npm) through trusted publishing, so no tokens are stored. Maven Central has no trusted publishing, so java-v* uses a token and a signing key held as environment secrets, and the upload is published by hand.

License

MIT

Available Tools

5 tools
autocomplete_postcodeAutocomplete a Nigerian postcodeB
Read-onlyIdempotent

Suggest completions for the next segment of a partly typed postcode.

ParametersJSON Schema
NameRequiredDescriptionDefault
partialYesThe start of a code, e.g. 'EK 01 A'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
segmentYesThe segment being completed.
suggestionsYes

TDQS

B3.3/5.0
Behavior2/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so safety and repeatability are covered. The description adds essentially nothing beyond the title and annotations — no mention of how many suggestions are returned, ordering, or behavior on non-matching prefixes.

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

Conciseness5/5

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

A single front-loaded sentence with no filler; every word contributes to the meaning.

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?

An output schema exists so return values need not be described, and annotations cover the safety profile. What is missing is sibling routing and any sense of result shape or matching behavior, leaving this roughly minimal for an autocomplete tool.

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?

With one parameter at 100% schema coverage, the schema already documents 'partial' including an example format ('EK 01 A'). The description references the partial-code concept but adds no format or matching semantics beyond the schema, so it sits at the baseline.

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

Purpose4/5

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

States a specific verb ('suggest completions') and resource ('postcode') with the scope of a partial input. It is clearly distinguishable from validate_postcode and lookup_postcode in broad terms, but never names or contrasts with those siblings explicitly.

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?

'Partly typed postcode' is an implied trigger condition, so an agent can infer this is for in-progress input rather than a complete code. However, no alternatives or exclusions are given (e.g., use lookup_postcode once the code is complete), leaving the routing decision to inference.

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

find_postcode_at_locationFind the postcode at a locationA
Read-onlyIdempotent

Return the postcode of the nearest building to a coordinate in Nigeria.

Names and the house address are withheld unless NG_POSTCODE_MAX_LEVEL is 2 or more.

ParametersJSON Schema
NameRequiredDescriptionDefault
latitudeYesLatitude in decimal degrees, e.g. 7.6211.
longitudeYesLongitude in decimal degrees, e.g. 5.2214.
max_distance_mNoSearch radius in metres. Defaults to 25.

Output Schema

ParametersJSON Schema
NameRequiredDescription
areaYesEnclosing area code, e.g. EK-01-A03-FK.
unitYes
depthNoHow deep the match goes, e.g. unit.
foundYesFalse when no building is within the radius.
stateYes
messageYes
districtYes
radius_mYesThe radius the API actually applied.

TDQS

A4/5.0
Behavior4/5

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

Annotations already cover safety (readOnly, idempotent, openWorld), but the description adds a genuinely non-obvious behavior: names and house address are withheld unless NG_POSTCODE_MAX_LEVEL is 2 or more. That explains a conditional output shape an agent would otherwise misread as a failure. It still doesn't say what happens when no building falls inside the radius.

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

Conciseness5/5

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

Two sentences, zero filler. The primary behavior (return postcode of nearest building to a coordinate in Nigeria) is front-loaded, and the conditional output caveat follows immediately after.

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

Completeness4/5

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

An output schema exists, so return-value structure needn't be restated, and the description covers the one surprising output behavior (field withholding). The remaining gap is the no-result / out-of-radius case and whether max_distance_m truncates or errors, which an agent would benefit from knowing.

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 description coverage is 100% and all three parameters carry their own descriptions and bounds, so the schema does the heavy lifting. The description adds only the contextual constraint that the coordinate must be in Nigeria, which is mild added value rather than new syntax or format detail. Baseline 3 is appropriate.

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?

States a specific verb (Return) plus resource (postcode of the nearest building) and a precise scope (a coordinate in Nigeria). This cleanly separates it from siblings like lookup_postcode (by postcode) and resolve_address (by address), so an agent can route correctly without opening any schema.

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 reverse-geocoding use case (coordinate in, postcode out) is implied clearly enough that an agent can infer when to pick this over the postcode-first siblings. However, it never explicitly names an alternative or states a when-not condition, e.g. what to do if the caller has an address instead of a coordinate.

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

lookup_postcodeLook up a Nigerian postcodeB
Read-onlyIdempotent

Confirm a postcode is assigned and, at higher levels, return its address details.

ParametersJSON Schema
NameRequiredDescriptionDefault
levelNo1: validity only (free). 2: adds the administrative and recent house address. 3: adds building use. Levels 2+ consume NIPOST credits.
postcodeYesCode in any style, e.g. EK-01-A03-FK-01.

Output Schema

ParametersJSON Schema
NameRequiredDescription
validYesWhether the code is assigned to a building.
statusNovalid, not_found, or invalid for a malformed code.
postcodeYes
verifiedNo
point_geometryNoLevel 5, unstructured.
building_use_statusYesLevel 3 and up, e.g. residential.
other_building_infoNoLevel 4 and up, unstructured.
recent_house_addressYesLevel 2 and up. Personal data.
administrative_addressYesLevel 2 and up.

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, openWorldHint and idempotentHint, so the safety profile is covered. The description adds that output depth scales with level, which is useful, but the credit-consumption behavior for levels 2+ lives only in the schema, not the description.

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?

A single compact sentence with no filler, and the primary behavior (confirm assignment) is front-loaded ahead of the secondary tiered behavior. Efficient, though it leaves room that could have been spent on sibling routing.

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?

An output schema exists, so return-value explanation is unnecessary, and the parameter set is tiny. However, for a tool in a dense family of five similar postcode tools, the absence of any differentiation or usage context leaves the definition only minimally complete.

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 description coverage is 100%: the schema fully documents both postcode format and the five level tiers including credit cost. The description adds no syntax, format or default detail beyond what the schema already provides, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb+resource: confirming a postcode is assigned and returning address details at higher levels. It is clear what the tool does, but it does not explicitly distinguish itself from the sibling validate_postcode, which plausibly covers the same 'is it assigned' check.

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

Usage Guidelines2/5

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

The description offers no when-to-use or when-not guidance and never names an alternative, despite four closely related siblings (validate_postcode, autocomplete_postcode, find_postcode_at_location, resolve_address). The only routing signal ('at higher levels') refers to the level parameter, which the schema already explains.

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

resolve_addressResolve a Nigerian address to a postcodeA
Read-onlyIdempotent

Turn a described Nigerian address into a postcode, only as precisely as the evidence allows.

A full building code comes only from a postcode written in the address, a location pin, or a landmark that is the address itself. Otherwise the result is an area or district prefix with a question for the user. Read the address yourself and fill landmarks and geocode_queries; the address text is sent to the configured geocoder.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesThe address exactly as the user gave it.
latitudeNoLatitude of a location pin the user shared.
landmarksNoLandmarks named in the address, each with how the address relates to it. Use 'at' only when the address is the landmark itself.
longitudeNoLongitude of that pin. Give it with latitude.
geocode_queriesNoUp to three map search strings you derive from the address: named places and streets with the town and state, most specific first, without directional words like 'back of'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
codeYesA full postcode at building level, else a prefix.
levelYes
methodYes
statusYes
evidenceYes
questionYesWhat to ask the user to get a better answer.
confidenceYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already cover readOnly/openWorld/idempotent, and the description adds real behavioral value beyond them: the tiered precision model, the fact that the address text is forwarded to an external geocoder, and the fallback that returns a `question` to the user rather than a false-precise code. It does not add rate limits or auth context, but for a read-only resolver this is solid disclosure.

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?

Purpose is front-loaded, followed by the precision rule and the parameter-filling instruction. The opening clause ('only as precisely as the evidence allows') is slightly awkward but the whole thing is four tight sentences with little waste.

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

Completeness4/5

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

An output schema exists, so return-shape explanation is unnecessary; the description still flags the `question` fallback, which is the key non-obvious output behavior. Combined with the precision tiers and param guidance, an agent has what it needs, with the main omission being sibling routing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description meaningfully clarifies that `landmarks` and `geocode_queries` are agent-derived from reading the address rather than passed verbatim, and echoes the 'at' = address-is-the-landmark rule. That goes beyond the structured field text.

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

Purpose4/5

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

States a specific verb + resource ('Turn a described Nigerian address into a postcode') with the unique twist that output precision varies with evidence. The distinction from siblings like lookup_postcode and validate_postcode is implied by 'described address' vs a written code, though no sibling is named explicitly.

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?

It explains the outcome tiers (full building code vs area prefix with a `question`) and instructs the agent to derive `landmarks` and `geocode_queries`, but it never states when to choose this over the four siblings (lookup_postcode, autocomplete_postcode, validate_postcode, find_postcode_at_location). Usage is implied rather than routed.

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

validate_postcodeValidate a Nigerian postcodeA
Read-onlyIdempotent

Check a postcode's structure offline and return its canonical forms and segments.

Free and instant. Does not confirm the code is assigned to a building; use lookup_postcode for that.

ParametersJSON Schema
NameRequiredDescriptionDefault
postcodeYesCode in any style, e.g. 'ek 01 a03 fk 01'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorYesWhy the code is malformed.
validYesWhether the code is well formed. It may still be unassigned.
spacedYesForm shown to people, e.g. EK 01 A03 FK 01.
compactYesCompact form for storage, e.g. EK01A03FK01.
postcodeYesCanonical form, e.g. EK-01-A03-FK-01.
segmentsYes
suggestionYesA well-formed code if look-alike characters (O/0, I/1, S/5, B/8) were the only problem. Confirm it with the user before using it.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so safety is covered. The description still adds value by disclosing that the check is offline and that it does not verify real-world assignment of the code — a semantic limit the annotations cannot express. It stops short of saying what happens on a malformed input (error vs. invalid result).

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

Conciseness5/5

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

Three short sentences, zero filler, with the core purpose and the cost/scope caveat front-loaded before the sibling pointer. Every sentence earns its place.

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

Completeness4/5

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

An output schema exists, so return shapes need not be explained, and annotations cover the safety profile. Purpose, scope limit, and the alternative tool are all present; only the failure-mode behavior for an invalid postcode is left unstated.

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?

With one parameter at 100% schema description coverage, the schema already documents the input, including the any-style example. The description adds no format or normalization detail beyond the schema, so the baseline 3 applies.

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?

States a specific verb and resource ('Check a postcode's structure') plus what it returns ('canonical forms and segments'), and explicitly distinguishes itself from lookup_postcode. An agent can tell it apart from autocomplete_postcode or resolve_address without opening a schema.

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

Usage Guidelines5/5

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

Gives an explicit when-not ('Does not confirm the code is assigned to a building') and names the alternative to use instead ('use lookup_postcode for that'). It also frames the cost profile ('Free and instant'), which helps an agent prefer this over a heavier lookup.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.4.1
    • Changedfind_postcode_at_location2 fields changed
      • addedInput schema / properties / latitude / description
        Added value: +"Latitude in decimal degrees, e.g. 7.6211."
      • addedInput schema / properties / longitude / description
        Added value: +"Longitude in decimal degrees, e.g. 5.2214."
    • Changedresolve_address2 fields changed
      • changedInput schema / properties / latitude / description
        Previous value: -"A location pin the user shared."New value: +"Latitude of a location pin the user shared."
      • addedInput schema / properties / longitude / description
        Added value: +"Longitude of that pin. Give it with latitude."
  2. 5 tool updatesv0.2.4
    • First observedautocomplete_postcode
    • First observedfind_postcode_at_location
    • First observedlookup_postcode
    • First observedresolve_address
    • First observedvalidate_postcode

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct input/output: autocomplete (partial->completions), validate (offline structure), lookup (assignment + address), find_postcode_at_location (coords->postcode), resolve_address (address text->postcode). The only mild overlap is validate vs lookup, but descriptions explicitly contrast them (offline structural check vs assignment confirmation).

Naming Consistency4/5

All names are snake_case with a verb_noun feel (autocomplete_postcode, lookup_postcode, validate_postcode, resolve_address). find_postcode_at_location is longer and inserts a preposition, a minor deviation, but still readable and consistent in style.

Tool Count5/5

Five tools is well-scoped for a postcode service, covering forward lookup, reverse lookup, validation, autocomplete, and address resolution with no redundancy or filler.

Completeness4/5

The surface covers the main lifecycle: autocomplete, validate, lookup, coordinate->postcode, and address->postcode. Minor gaps exist (e.g. no batch lookup or postcode->coordinate reverse), but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers