Validate, look up and resolve addresses to Nigeria's NIPOST digital postcodes (NDAPS).
Developer tools for Nigeria's National Digital Alphanumeric Postcode System (NDAPS), the building-level postcode NIPOST launched in October 2026: libraries for Rust and Python, an MCP server for AI assistants, 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.
| 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-mcp | MCP server: validate, look up, autocomplete, find by location, resolve addresses | uvx ng-postcode-mcp | 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.
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_..." }
}
}
}
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"
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");
| 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.
spec/vectors.json, so they cannot drift apart.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.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.Observed on 3 October 2026:
status (valid, not_found, invalid) and verified. A malformed code is answered with HTTP 200 and status: invalid, not an error.code, the value of the next segment. The documented label is not sent.depth.postcode, display and distance_m, nearest first.403 level_not_granted.EK-01-A03-FK-01, the example used throughout NIPOST's docs, is reported as not assigned.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
CI runs formatting, linting, type checks and tests for every package. Releases publish from tags (v* is tagged after a crates.io release; py-v*, mcp-v* and agent-v* publish to PyPI and the MCP Registry) through trusted publishing, so no tokens are stored.
MIT
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
uvx ng-postcode-mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-adeniyikayodee-ng-postcode": {
"command": "uvx",
"args": [
"ng-postcode-mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceng-postcode-mcppypiNigeria Postcode works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.